Иконка ресурса

FREE Deekay : 0.1.98 0.1.98

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using System.Linq;
using Oxide.Core.Plugins;
using UnityEngine;
using Facepunch;

namespace Oxide.Plugins
{
    [Info("Deekay", "k1lly0u", "0.1.98", ResourceId = 0)]
    class Deekay : RustPlugin
    {
        #region Fields
        [PluginReference]
        Plugin ZoneManager;

        static Deekay ins;
        private Hash<uint, DecayManager> dkEntities = new Hash<uint, DecayManager>();
        private bool isInitialized;
        #endregion

        #region Oxide Hooks        
        void OnServerInitialized()
        {
            ins = this;
            LoadVariables();
            InitializeConfigData();
        }
        void OnEntitySpawned(BaseNetworkable entity)
        {
            try
            {
                if (!isInitialized) return;
                string prefabName = entity.PrefabName;
                if (prefabName.Contains("autospawn") || prefabName.Contains("npc") || prefabName.Contains("static")) return;                
                if (entity is BaseCombatEntity)
                {
                    EntityDecay decayData = null;
                    if (entity is BuildingBlock)
                    {
                        if (configData.BuildingDecay.ContainsKey(prefabName))
                            configData.BuildingDecay[prefabName].TryGetValue((entity as BuildingBlock).grade, out decayData);
                    }
                    else
                    {
                        if (configData.EntityDecay.ContainsKey(prefabName))
                            configData.EntityDecay.TryGetValue(prefabName, out decayData);
                    }
                    if (decayData != null && decayData.IsEnabled)
                    {
                        if (!dkEntities.ContainsKey(entity.net.ID))
                            dkEntities.Add(entity.net.ID, new DecayManager(entity as BaseCombatEntity, decayData));                       
                    }
                }
            }
            catch { }         
        }
        void OnDoorOpened(Door door, BasePlayer player)
        {
            if (!configData._MonitorActivity || door == null) return;           
                DecayTouch(door.transform.position);
        }
        void OnStructureRepair(BaseCombatEntity entity, BasePlayer player)
        {
            if (!configData._MonitorActivity || entity == null) return;
                DecayTouch(entity.transform.position);
        }
        void OnStructureUpgrade(BaseCombatEntity entity, BasePlayer player, BuildingGrade.Enum grade)
        {
            if (entity == null || entity.IsDestroyed || !entity.IsValid()) return;
           
            EntityDecay decayData = null;
            string prefabName = entity.PrefabName;
            if (configData.BuildingDecay.ContainsKey(prefabName))
            {
                if (configData.BuildingDecay[prefabName].TryGetValue(grade, out decayData))
                {
                    if (!decayData.IsEnabled)
                    {
                        if (dkEntities.ContainsKey(entity.net.ID))
                        {
                            dkEntities[entity.net.ID].decayTimer?.Destroy();
                            dkEntities.Remove(entity.net.ID);
                        }
                        return;
                    }
                    if (dkEntities.ContainsKey(entity.net.ID))
                    {
                        dkEntities[entity.net.ID].decayTimer?.Destroy();
                        dkEntities[entity.net.ID] = new DecayManager(entity, decayData);
                    }
                    else dkEntities.Add(entity.net.ID, new DecayManager(entity, decayData));
                }
            }
        }
        void OnEntityKill(BaseNetworkable entity)
        {
            if (entity == null || entity?.net?.ID == null) return;
            if (dkEntities.ContainsKey(entity.net.ID))
            {
                dkEntities[entity.net.ID].decayTimer?.Destroy();
                dkEntities.Remove(entity.net.ID);
            }           
        }       
        void Unload()
        {
            foreach(var entity in dkEntities)
            {
                entity.Value.decayTimer?.Destroy();
            }
            dkEntities.Clear();
        }
        #endregion

        #region Functions        
        void InitializeConfigData()
        {
            bool hasChanged = false;
            foreach (var construction in PrefabAttribute.server.GetAll<Construction>())
            {
                if (construction?.deployable == null && !string.IsNullOrEmpty(construction.info.name.english))
                {
                    if (!configData.BuildingDecay.ContainsKey(construction.fullName))
                    {
                        configData.BuildingDecay.Add(construction.fullName, new Dictionary<BuildingGrade.Enum, EntityDecay>
                            {
                                { BuildingGrade.Enum.Metal, configData._DefaultDecay },
                                { BuildingGrade.Enum.Stone, configData._DefaultDecay },
                                { BuildingGrade.Enum.TopTier, configData._DefaultDecay },
                                { BuildingGrade.Enum.Twigs, configData._DefaultDecay },
                                { BuildingGrade.Enum.Wood, configData._DefaultDecay }
                            });
                        hasChanged = true;
                    }
                }
            }
           
            foreach (var item in ItemManager.GetItemDefinitions())
            {
                var deployable = item?.GetComponent<ItemModDeployable>();
                if (deployable == null) continue;
                if (!configData.EntityDecay.ContainsKey(deployable.entityPrefab.resourcePath))
                {
                    configData.EntityDecay.Add(deployable.entityPrefab.resourcePath, configData._DefaultDecay);
                    hasChanged = true;
                }
            }

            if (hasChanged)
                SaveConfig(configData);
            isInitialized = true;
            FindAllEntities();
        }
       
        void FindAllEntities()
        {
            PrintWarning("Finding all deekay-able entities");

            var entities = UnityEngine.Object.FindObjectsOfType<BaseCombatEntity>().Distinct();
            if (entities != null)
            {
                foreach (var entity in entities)
                {
                    if (entity == null || entity.IsDestroyed || !entity.IsValid()) continue;
                    string prefabName = entity.PrefabName;
                    if (string.IsNullOrEmpty(prefabName)) continue;
                    EntityDecay decayData;
                    if (!configData.EntityDecay.TryGetValue(prefabName, out decayData))
                    {
                        if (!configData.BuildingDecay.ContainsKey(prefabName)) continue;
                        if (!configData.BuildingDecay[prefabName].TryGetValue((entity as BuildingBlock).grade, out decayData)) continue;                        
                    }
                    if (decayData != null && decayData.IsEnabled && !dkEntities.ContainsKey(entity.net.ID))
                        timer.In(Random.Range(0.1f, 10f), () =>
                        {
                            if (entity != null && !entity.IsDestroyed && entity.IsValid() && !dkEntities.ContainsKey(entity.net.ID))
                                dkEntities.Add(entity.net.ID, new DecayManager(entity, decayData));
                        });
                }
            }
            PrintWarning("Waiting for decay managers to initialize");
            timer.In(10f, ()=> PrintWarning($"Added decay manager to {dkEntities.Count} entities"));
        }  
        void DecayTouch(Vector3 position)
        {
            List<BaseCombatEntity> list = Pool.GetList<BaseCombatEntity>();
            Vis.Entities<BaseCombatEntity>(position, configData._ActivityRadius, list, 2097408, QueryTriggerInteraction.Collide);
            for (int i = 0; i < list.Count; i++)
            {
                BaseCombatEntity entity = list[i];
                if (entity == null || entity.IsDestroyed || !entity.IsValid()) continue;
                DecayManager manager;
                if (dkEntities.TryGetValue(entity.net.ID, out manager))                
                    manager.ResetDecay();  
            }
        }     
        #endregion

        #region Component  
        class DecayManager
        {
            private BaseCombatEntity entity;
            private EntityDecay decayData;
            private float detectionRange;
            private bool isInPrivs = false;
            public Timer decayTimer;

            public DecayManager() { }
            public DecayManager(BaseCombatEntity entity, EntityDecay decayData)
            {
                this.entity = entity;
                this.decayData = decayData;
                detectionRange = ins.configData._DetectionRange;
                BeginDecay();
            }
            public void BeginDecay()
            {
                float decayRate = IsInPrivilege(false) ? decayData.InsidePrivilege.DecayRate : decayData.OutsidePrivilege.DecayRate;
                if (decayRate == 0)
                    decayTimer = ins.timer.In(300, BeginDecay);
                else decayTimer = ins.timer.Repeat(decayRate, 0, () => DealDamage());
            }
            public bool DealDamage()
            {
                if (entity == null || !entity.IsValid())
                    return false;

                if (entity.IsDestroyed)
                {
                    decayTimer?.Destroy();
                    ins.dkEntities.Remove(entity.net.ID);
                    return false;
                }

                if (ins.ZoneManager)
                {
                    var success = ins.ZoneManager.Call("EntityHasFlag", entity, "nodecay");
                    if (success is bool && (bool)success)
                        return true;
                }               
                
                float decayAmount = IsInPrivilege(true) ? decayData.InsidePrivilege.DamageRate : decayData.OutsidePrivilege.DamageRate;
                if (decayAmount == 0) return false;
                float amount = entity.MaxHealth() * decayAmount;
                if (entity.health <= amount)
                {
                    decayTimer?.Destroy();
                    ins.dkEntities.Remove(entity.net.ID);
                    entity.Die();
                    return true;                   
                }
                else entity.Hurt(amount, Rust.DamageType.Decay);
                return true;
            } 
            public bool IsInPrivilege(bool reset)
            {
                bool foundTC = false;
                var colliders = Pool.GetList<Collider>();
                Vis.Colliders(entity.transform.position + new Vector3(0, entity.bounds.max.y, 0), detectionRange, colliders, LayerMask.GetMask("Trigger"));
                foreach (var collider in colliders)
                {
                    if (collider.gameObject != null && collider.gameObject.GetComponentInParent<BuildingPrivlidge>() && collider.gameObject.name == "areaTrigger" && collider.gameObject.layer == 18) 
                        foundTC = true;  
                }
                Pool.FreeList(ref colliders);
                  
                if (foundTC && !isInPrivs)
                {
                    isInPrivs = true;
                    if (reset)
                        ResetDecay();
                }
                else if (!foundTC && isInPrivs)
                {
                    isInPrivs = false;
                    if (reset)
                        ResetDecay();
                }
                return foundTC;
            }
            public void ResetDecay()
            {
                decayTimer?.Destroy();
                BeginDecay();
            }
        }
        #endregion

        #region Commands
        [ConsoleCommand("dk.reset")]
        void ccmdDKReset(ConsoleSystem.Arg arg)
        {
            if (arg.Connection != null) return;
            configData.BuildingDecay.Clear();
            configData.EntityDecay.Clear();
            InitializeConfigData();
            SendReply(arg, "The config has been reset");
        }
        [ConsoleCommand("dk.rundecay")]
        void ccmdDKRun(ConsoleSystem.Arg arg)
        {
            if (arg.Connection != null) return;
            int decayCount = 0;

            ICollection<uint> keyCollection = dkEntities.Keys;
            uint[] keys = new uint[keyCollection.Count];
            keyCollection.CopyTo(keys, 0);

            for (int i = 0; i < keys.Length; i++)
            {
                var obj = dkEntities[keys[i]];
                if (obj.DealDamage())
                {
                    obj.ResetDecay();
                    ++decayCount;
                }
            }       
            SendReply(arg, $"{decayCount} entities have been dealt decay damage!");
        }
        #endregion

        #region Config        
        private ConfigData configData;
        class EntityDecay
        {
            public Rates InsidePrivilege { get; set; }
            public Rates OutsidePrivilege { get; set; }
            public bool IsEnabled { get; set; }
        } 
        class Rates
        {
            public float DamageRate { get; set; }
            public float DecayRate { get; set; }
        }
       
        class ConfigData
        {           
            public bool _MonitorActivity { get; set; }
            public float _ActivityRadius { get; set; }
            public float _DetectionRange { get; set; }
            public EntityDecay _DefaultDecay { get; set; }
            public Dictionary<string, EntityDecay> EntityDecay { get; set; }
            public Dictionary<string, Dictionary<BuildingGrade.Enum, EntityDecay>> BuildingDecay { get; set; }
        }
        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                _ActivityRadius = 40f,
                _DetectionRange = 0.25f,
                _DefaultDecay = new EntityDecay
                {
                    InsidePrivilege = new Rates
                    {
                        DamageRate = 0.05f,
                        DecayRate = 3600
                    },
                    OutsidePrivilege = new Rates
                    {                        
                        DamageRate = 0.2f,
                        DecayRate = 3600                    
                    },
                    IsEnabled = true
                },
                _MonitorActivity = true,
                BuildingDecay = new Dictionary<string, Dictionary<BuildingGrade.Enum, EntityDecay>>(),
                EntityDecay = new Dictionary<string, EntityDecay>()                    
            };
            SaveConfig(config);
        }
        private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
        #endregion               
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху