C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using Rust;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using Facepunch;
namespace Oxide.Plugins
{
[Info("CupboardNoDecay", "Rick", "1.3.0")]
[Description("Use cupboard to protect from decay without consuming resources.")]
public class CupboardNoDecay : RustPlugin
{
private ConfigData configData;
void OnServerInitialized()
{
LoadVariables();
}
#region config
private class ConfigData
{
public bool CheckAuth { get; set; }
public bool DecayTwig { get; set; }
public bool DecayWood { get; set; }
public bool DecayStone { get; set; }
public bool DecayMetal { get; set; }
public bool DecayArmor { get; set; }
public float TwigRate { get; set; }
public float WoodRate { get; set; }
public float StoneRate { get; set; }
public float MetalRate { get; set; }
public float ArmorRate { get; set; }
public float EntityRadius { get; set; }
public string[] NeverDecay { get; set; }
}
protected override void LoadDefaultConfig()
{
string[] never = { "RHIB", "Rowboat", "HotAirBalloon", "minicopter.entity" };
SaveConfig(new ConfigData
{
CheckAuth = false,
DecayTwig = true,
DecayWood = false,
DecayStone = false,
DecayMetal = false,
DecayArmor = false,
TwigRate = 1.0f,
WoodRate = 0.0f,
StoneRate = 0.0f,
MetalRate = 0.0f,
ArmorRate = 0.0f,
EntityRadius = 30f,
NeverDecay = never
});
}
private void LoadVariables()
{
LoadConfigVariables();
SaveConfig();
}
void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
#endregion
#region Main
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
string entity_name = null;
if (!info.damageTypes.Has(DamageType.Decay))
{
return null;
}
try
{
entity_name = entity.LookupPrefab().name;
}
catch
{
return null;
}
string pos = entity.transform.position.ToString();
ulong hitEntityOwnerID = entity.OwnerID != 0 ? entity.OwnerID : info.HitEntity.OwnerID;
float before = info.damageTypes.Get(Rust.DamageType.Decay);
float multiplier = 1.0f;
// First, we check for protected entities (NeverDecay)
if (configData.NeverDecay.Contains(entity_name))
{
multiplier = 0.0f;
// Apply our damage rules and return
info.damageTypes.Scale(Rust.DamageType.Decay, multiplier);
return null;
}
// Second, we check for attached (BLOCK) or nearby (ENTITY) cupboard
BuildingBlock block = entity as BuildingBlock;
string isblock = "";
string buildGrade = "";
bool hascup = false;
if (block != null)
{
isblock = " (building block)";
hascup = CheckCupboardBlock(block, info, entity_name);
if (hascup)
{
multiplier = 0.0f;
switch (block.grade)
{
case BuildingGrade.Enum.Twigs:
if (configData.DecayTwig == true)
{
multiplier = configData.TwigRate;
}
break;
case BuildingGrade.Enum.Wood:
if (configData.DecayWood == true)
{
multiplier = configData.WoodRate;
}
break;
case BuildingGrade.Enum.Stone:
if (configData.DecayStone == true)
{
multiplier = configData.StoneRate;
}
break;
case BuildingGrade.Enum.Metal:
if (configData.DecayMetal == true)
{
multiplier = configData.MetalRate;
}
break;
case BuildingGrade.Enum.TopTier:
if (configData.DecayArmor == true)
{
multiplier = configData.ArmorRate;
}
break;
}
}
else
{
return null; // Standard damage rates apply
}
}
else if (CheckCupboardEntity(entity, info, entity_name))
{
// Unprotected Entity with cupboard
multiplier = 0.0f;
}
else
{
// Unprotected Entity with NO Cupboard
return null; // Standard damage rates apply
}
// Apply our damage rules and return
info.damageTypes.Scale(Rust.DamageType.Decay, multiplier);
return null;
}
// Check that an entity is in range of a cupboard
private bool CheckCupboardEntity(BaseEntity entity, HitInfo hitInfo, string name)
{
int targetLayer = LayerMask.GetMask("Construction", "Construction Trigger", "Trigger", "Deployed");
Collider[] hit = Physics.OverlapSphere(entity.transform.position, configData.EntityRadius, targetLayer);
// loop through hit layers and check for 'Building Privlidge'
foreach (var ent in hit)
{
BuildingPrivlidge privs = ent.GetComponentInParent<BuildingPrivlidge>();
if (privs != null)
{
// cupboard overlap.Entity safe from decay
if (configData.CheckAuth == true)
{
ulong hitEntityOwnerID = entity.OwnerID != 0 ? entity.OwnerID : hitInfo.HitEntity.OwnerID;
return CupboardAuthCheck(privs, hitEntityOwnerID);
}
else
{
return true;
}
}
}
if (hit.Length > 0)
{
return false;
}
else
{
}
return true;
}
// Check that a building block is owned by/attached to a cupboard
private bool CheckCupboardBlock(BuildingBlock block, HitInfo hitInfo, string ename = "unknown")
{
BuildingManager.Building building = block.GetBuilding();
if (building != null)
{
//if(building.buildingPrivileges == null)
if (building.GetDominatingBuildingPrivilege() == null)
{
return false;
}
// cupboard overlap.Block safe from decay.Check auth?
if (configData.CheckAuth == true)
{
ulong hitEntityOwnerID = block.OwnerID != 0 ? block.OwnerID : hitInfo.HitEntity.OwnerID;
foreach (var privs in building.buildingPrivileges)
{
if (CupboardAuthCheck(privs, hitEntityOwnerID) == true)
{
return true;
}
}
}
else
{
return true;
}
}
else
{
}
return false;
}
private bool CupboardAuthCheck(BuildingPrivlidge priv, ulong hitEntityOwnerID)
{
string hitId = null;
string entowner = null;
foreach (var auth in priv.authorizedPlayers.Select(x => x.userid).ToArray())
{
if (auth == hitEntityOwnerID)
{
return true;
}
}
return false;
}
#endregion
}
}