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

FREE PlanterBoxEvents : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//#define DEBUG

using Newtonsoft.Json;
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using VLB;

namespace Oxide.Plugins
{
    [Info("PlanterBoxEvents", "Tangerine", "1.0.0")]
    [Description("PlanterBoxEvents")]
    public class PlanterBoxEvents : RustPlugin
    {
        #region Variables

        private readonly HashSet<PlanterBox> _planters = new HashSet<PlanterBox>();
        private readonly HashSet<PlanterBox> _plantersWithEvent = new HashSet<PlanterBox>();

        private const string Permission = "planterboxevents.use";
        private const string ChickenPrefab = "assets/rust.ai/agents/chicken/chicken.prefab";
        private const string FireBallPrefab = "assets/bundled/prefabs/fireball_small.prefab";

        private static PlanterBoxEvents _plugin;

        private readonly List<BaseEventDefinition> _availableEvents = new ();
        
        #endregion

        #region Hooks

        void OnServerInitialized()
        {
            _plugin = this;
            
            permission.RegisterPermission(Permission, this);

            foreach (var networkable in BaseNetworkable.serverEntities)
            {
                if (networkable.IsValid() == false || networkable.IsDestroyed)
                    continue;

                if (networkable is PlanterBox planter == false)
                    continue;

                if (planter.OwnerID == 0 || HasPermission(planter.OwnerID.ToString(), Permission) == false)
                    continue;

                _planters.Add(planter);
            }

            _availableEvents.Add(_config.СhickenEvent);
            _availableEvents.Add(_config.FireEvent);
            
            timer.Every(_config.EventsTimerSeconds, TryInitializeEvents);
        }

        void Unload()
        {
            _plugin = null;
            _planters.Clear();
        }

        private void OnEntityBuilt(Planner plan, GameObject gameObject)
        {
            var planter = gameObject.GetComponent<PlanterBox>();

            if (planter == null)
                return;

            if (planter.OwnerID == 0 || HasPermission(planter.OwnerID.ToString(), Permission) == false)
                return;

            _planters.Add(planter);
        }

        #endregion

        #region Commands

        [ConsoleCommand("planterevent.start")]
        private void Console_PlanterEventStart(ConsoleSystem.Arg arg)
        {
            if (arg.IsAdmin == false) 
                return;

            var player = arg.Player();
            if (player == null)
            {
                SendReply(arg, "Only works from player console!");
                return;
            }

            var entites = Facepunch.Pool.GetList<PlanterBox>();
            try
            {
                Vis.Entities(player.transform.position, 5f, entites);
                if (entites.Count == 0)
                {
                    SendReply(arg, "No planter boxes found!");
                    return;
                }
                
                CreateEventFor(entites[0]);
                SendReply(arg, "Event created!");
            }
            finally
            {
                Facepunch.Pool.FreeList(ref entites);
            }
        }

        #endregion
        
        #region Core

        private void TryInitializeEvents()
        {
            foreach (var planter in _planters)
            {
                if (planter.children.Count == 0)
                    continue;

                if(_plantersWithEvent.Contains(planter))
                    continue;

                var random01 = Core.Random.Range(0, 1f);
                
#if DEBUG
                PrintToChat($"Chance: {random01}");
#endif
                
                var validEvents = _availableEvents.FindAll(x => x.Chance <= random01);
                if (validEvents.Count == 0)
                    continue;

                BaseEventDefinition eventDefinition = null;
                if (validEvents.Count > 1)
                {
                    eventDefinition = validEvents.GetRandom();
                }
                else
                {
                    eventDefinition = validEvents[0];
                }
                
                StartEvent(planter, eventDefinition);
            }

#if DEBUG
            PrintToChat($"TryInitiateEvents tick!");
#endif
        }

        private void CreateEventFor(PlanterBox planter)
        {
            StartEvent(planter, _availableEvents.GetRandom());
        }

        private void StartEvent(PlanterBox planter, BaseEventDefinition eventDefinition)
        {
            var growables = planter.children.FindAll(x => x is GrowableEntity);
            if (growables.Count == 0)
                return;
            
            GrowableEntity growable = null;
            if (growables.Count > 1)
            {
                growable = (GrowableEntity)growables.GetRandom();
            }
            else
            {
                growable = (GrowableEntity)growables[0];
            }
            
            var entity = eventDefinition.SpawnEntity(growable.transform.position + new Vector3(0, 0.2f, 0));
            if (entity == null)
            {
#if DEBUG
                PrintToChat($"Couldn't create event entity '{eventDefinition.GetType()}'");
#endif
                return;
            }

            ApplyEventDamage(planter, growable, entity, eventDefinition);

            var playerOwner = BasePlayer.FindByID(planter.OwnerID);
            if (playerOwner != null && playerOwner.IsConnected)
            {
                switch (eventDefinition)
                {
                    case ChickenEventDefinition:
                    {
                        PlayerMessage(playerOwner, LangKey.Chat_ChickensOnFarm);
                        break;
                    }
                    case FireEventDefinition:
                    {
                        PlayerMessage(playerOwner, LangKey.Chat_FarmOnFire);
                        break;
                    }
                }
            }
#if DEBUG
            PrintToChat($"Event '{eventDefinition.GetType()}' started at position: {planter.transform.position}");
#endif

        }

        private void ApplyEventDamage(PlanterBox planter, GrowableEntity growable, BaseEntity entity, BaseEventDefinition eventDefinition)
        {
            _plantersWithEvent.Add(planter);
            
            entity.SetParent(growable, true);
            var component = entity.GetOrAddComponent<PlanterEventHandler>();
            component.DamagePerTick = eventDefinition.DamagePerSecond;
        }
        
        #endregion

        #region Scripts

        private class PlanterEventHandler : MonoBehaviour
        {
            private GrowableEntity _growable;
            private BaseEntity _ownerEntity;
            private PlanterBox _planter;

            public float DamagePerTick = 1f;

            private void Start()
            {
                _ownerEntity = GetComponent<BaseEntity>();
                _growable = GetComponentInParent<GrowableEntity>();
                if (_growable == null)
                {
                    Destroy(this);
                    return;
                }

                _planter = _growable.planter;
                if (_planter == null)
                {
                    Destroy(this);
                    return;
                }
                
                InvokeRepeating(nameof(DamageTick), 1f, 1f);
            }

            private void DamageTick() 
            {
                if (_plugin == null || _plugin.IsLoaded == false)
                {
                    _ownerEntity.Kill();
                    Destroy(this);
                    return;
                }

                if (_ownerEntity == null || _ownerEntity.IsDestroyed)
                {
                    Destroy(this);
                    return;
                }
                
                _growable.SetHealth(_growable.health - DamagePerTick);
                _growable.SendNetworkUpdate();

                if (_growable.health <= 0)
                {
                    _plugin._plantersWithEvent.Remove(_growable.planter);
                    _growable.Kill();
                }
            }

            private void OnDestroy()
            {
                if (_plugin == null)
                    return;
#if DEBUG
                _plugin.PrintToChat($"Planter event handler was destroyed!");
#endif
                if(_planter != null)
                    _plugin._plantersWithEvent.Remove(_planter);
            }

        }

        #endregion
        
        #region Config

        private static PluginConfig _config;

        private class PluginConfig
        {
            [JsonProperty("Chicken event properties", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public ChickenEventDefinition СhickenEvent = new()
            {
                Chance = 0.1f,
                DamagePerSecond = 1.5f
            };
            
            [JsonProperty("Fire event properties", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public FireEventDefinition FireEvent = new()
            {
                Chance = 0.1f,
                DamagePerSecond = 2.5f
            };

            [JsonProperty("Time interval in seconds between each attempt to initialize events")]
            public float EventsTimerSeconds = 60f;
        }

        private class BaseEventDefinition
        {
            [JsonProperty("Damage per second")]
            public float DamagePerSecond = 0.5f;

            [JsonProperty("Chance to start event (range: 0 - 1, -1 to off event)")]
            public float Chance = 0.05f;

            public virtual BaseEntity SpawnEntity(Vector3 position)
            {
                throw new NotImplementedException();
            }
        }
        
        private class ChickenEventDefinition : BaseEventDefinition
        {
            public override BaseEntity SpawnEntity(Vector3 position)
            {
                var chicken = GameManager.server.CreateEntity(ChickenPrefab,  position) as Chicken;
                if (chicken == null)
                    return null;

                chicken.Spawn();
                if (chicken.brain != null)
                {
                    _plugin.timer.Once(1f, () =>
                    {
                        chicken.brain.CancelInvoke(chicken.brain.TickMovement);
                        BaseEntity.Query.Server.RemoveBrain(chicken);
                        chicken.HasBrain = false;
                    });
                }
                chicken.SendNetworkUpdate();
                return chicken;
            }
        }
        
        private class FireEventDefinition : BaseEventDefinition
        {
            public override BaseEntity SpawnEntity(Vector3 position)
            {
                var fireBall = GameManager.server.CreateEntity(FireBallPrefab, position) as FireBall;
                if (fireBall == null)
                    return null;
                
                fireBall.Spawn();
                fireBall.damagePerSecond = 0f;
                fireBall.CancelInvoke(fireBall.TryToSpread);
                fireBall.SendNetworkUpdate();
                return fireBall;
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<PluginConfig>();
                if (_config == null)
                {
                    LoadDefaultConfig();
                }
            }
            catch
            {
                for (var i = 0; i < 3; i++)
                {
                    PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
                }

                LoadDefaultConfig();
                return;
            }

            ValidateConfig();
            SaveConfig();
        }

        private void ValidateConfig()
        {
            if (Interface.Oxide.CallHook("OnConfigValidate") != null)
            {
                PrintWarning("Using default configuration...");
                _config = GetDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(_config);
        }

        protected override void LoadDefaultConfig()
        {
            _config = GetDefaultConfig();
        }

        private PluginConfig GetDefaultConfig()
        {
            return new PluginConfig
            {

            };
        }

        #endregion
        
        #region Localisation v0.0.1
        private enum LangKey
        {
            Chat_FarmOnFire,
            Chat_ChickensOnFarm
        }
        
        protected override void LoadDefaultMessages()
        {
            var dict = new Dictionary<LangKey, string>
            {
                [LangKey.Chat_FarmOnFire] = "Your farm caught on fire!",
                [LangKey.Chat_ChickensOnFarm] = "Chickens are destroying your farm!"
            };
            
            lang.RegisterMessages(dict.ToDictionary(x => x.Key.ToString(), x => x.Value), this);
        }
        
        private void PlayerMessage(BasePlayer player, LangKey message, params object[] args)
        {
            Player.Message(player, string.Format(GetLocal(player.UserIDString, message.ToString()), args), 0);// _config.ChatIconId);
        }
        
        private void PlayerMessage(BasePlayer player, string message, params object[] args)
        {
            Player.Message(player, string.Format(message, args), 0);// _config.ChatIconId);
        }
        
        private string GetLocal(string playerId, string key) => lang.GetMessage(key, this, playerId);
        
        private string GetLocal(string playerId, LangKey key) => lang.GetMessage(key.ToString(), this, playerId);
        
        #endregion
        
        #region Utils

        private bool HasPermission(string playerId, string name) => permission.UserHasPermission(playerId, name);

        #endregion
    }
}

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