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

FREE FreeneticPyromid : 0.0.1 0.0.1

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

namespace Oxide.Plugins
{
    [Info("FreeneticPyromid", "MaltrzD", "0.0.1")]
    public class FreeneticPyromid : RustPlugin
    {
        private RuntimeDoorData cachedDoorData;
        private ConfigData _config;
        private Timer waitOnlineTimer;

        [PluginReference] private Plugin Notify;
        private Timer addRadiationTimerRef;

        public class RuntimeDoorData
        {
            public SlidingProgressDoor SlidingDoor;
            public Vector3 Center = new Vector3();

            public void ChangeDoorState(bool state)
            {
                if (state)
                {
                    SlidingDoor.AddEnergy(1000);
                    SlidingDoor.secondsToClose = 1000000;
                }
                else
                {
                    SlidingDoor.secondsToClose = 3;
                    SlidingDoor.currentEnergy = 0;
                }

                SlidingDoor.SendNetworkUpdateImmediate();
            }
        }

        private void Loaded()
        {
            ReadConfig();
        }
        private void Unload()
        {
            DestroyAllUI();
            cachedDoorData?.ChangeDoorState(false);
        }
        private void OnServerInitialized()
        {
            LoadImages();
            PrintCCTVs();

            var camera = FindCCTVCamera(_config.CameraId);
            if(camera == null)
            {
                PrintError("Не найдена камера с припиской!");
                return;
            }

            SlidingProgressDoor door = null;
            var doors = BaseEntity.serverEntities.OfType<SlidingProgressDoor>();
            foreach (var d in doors)
            {
                if(Vector3.Distance(camera.transform.position, d.transform.position) < 50)
                {
                    door = d;
                    break;
                }
            }

            if(door == null)
            {
                PrintError("Не удалось найти дверь в радиусе 50 метров от центра!");
                return;
            }

            Puts($"{door.energyForOpen}/{door.secondsToClose}/{door.storedEnergy}");

            cachedDoorData = new RuntimeDoorData()
            {
                SlidingDoor = door,
                Center = camera.transform.position
            };
            cachedDoorData.ChangeDoorState(false);

            Puts($"Первая проверка на онлайн через: {_config.FirstCheckTime}");
            timer.Once(_config.FirstCheckTime, CheckFirstTime);
        }
        private void OnPlayerConnected(BasePlayer player)
        {
            if(countDownTime > 0)
                DrawUIFull(player);
        }

        private void CheckFirstTime()
        {
            if(BasePlayer.activePlayerList.Count >= _config.MinFirstTimeOnline)
            {
                Puts("Онлайн набран, Запуск ивента!");
                StartEvent();
            }
            else
            {
                waitOnlineTimer = timer.Every(_config.CheckOnlineFirstTime, () =>
                {
                    if(BasePlayer.activePlayerList.Count >= _config.MinFirstTimeOnline)
                    {
                        waitOnlineTimer.Destroy();
                        waitOnlineTimer = null;

                        StartEvent();
                    }
                });
            }
        }

        private void StartEvent()
        {
            Puts("Ивент начался, дверь открыта!");

            foreach (var item in BasePlayer.activePlayerList)
                Notify?.CallHook("SendNotify", item.userID.Get(), 0, "Ивент Пирамида начался двери открыты!");

            cachedDoorData.ChangeDoorState(true);

            StartCountDownTimer();

            timer.Once(_config.EventDuration, OnEventEnd);

            if(addRadiationTimerRef != null)
            {
                addRadiationTimerRef.Destroy();
                addRadiationTimerRef = null;
            }
        }
        private void OnEventEnd()
        {
            Puts("Ивент закончен, дверь закрыта!");

            cachedDoorData.ChangeDoorState(false);

            DestroyAllUI();
            
            timer.Once(_config.DefaultStartEventTime, () => StartEvent());

            foreach (var item in BasePlayer.activePlayerList)
                Notify?.CallHook("SendNotify", item.userID.Get(), 0, $"Ивент Пирамида закончился двери закрыты!\nПокиньте Пирамиду у вас есть {_config.RadiationStartTime} секунд!");

            timer.Once(_config.RadiationStartTime, StartRadiation);
        }
        
        private void StartRadiation()
        {
            AddRadiation();
            addRadiationTimerRef = timer.Every(5, AddRadiation);
        }
        private void AddRadiation()
        {
            foreach (var p in BasePlayer.activePlayerList.Where(x => Vector3.Distance(cachedDoorData.Center, x.transform.position) < _config.Radius))
                p.ApplyRadiation(_config.RadiationLevel, false);
        }

        private object CanTeleport(BasePlayer player)
        {
            if(cachedDoorData != null && countDownTime > 0)
            {
                if(Vector3.Distance(player.transform.position, cachedDoorData.Center) < _config.Radius)
                {
                    Notify?.CallHook("SendNotify", player.userID.Get(), 0, "Вы не можете телепортироватся в месте ивента!");
                    return "";
                }
            }

            return null;
        }
        private object OnTeleportRequested(BasePlayer player, BasePlayer requester)
        {
            if (cachedDoorData != null && countDownTime > 0)
            {
                if (
                    Vector3.Distance(player.transform.position, cachedDoorData.Center) < _config.Radius 
                    || Vector3.Distance(requester.transform.position, cachedDoorData.Center) < _config.Radius)
                {
                    Notify?.CallHook("SendNotify", player.userID.Get(), 0, "Телепорт запрещен в месте ивента или из него!");

                    return "";
                }
            }

            return true;
        }
        private void PrintCCTVs()
        {
            Puts(BaseEntity.serverEntities.OfType<CCTV_RC>().Select(x => x.rcIdentifier).ToSentence());
        }
        private CCTV_RC FindCCTVCamera(string sub)
            => BaseEntity.serverEntities.OfType<CCTV_RC>().FirstOrDefault(x => x.rcIdentifier.ToLower().StartsWith(sub.ToLower()));

        #region [ UI ]
        private int countDownTime = 0;
        private Dictionary<BasePlayer, bool> changedViews = new Dictionary<BasePlayer, bool>(); //true == full

        private void StartCountDownTimer()
        {
            changedViews = new Dictionary<BasePlayer, bool>();

            foreach (var p in BasePlayer.activePlayerList) DrawUIFull(p);

            countDownTime = Convert.ToInt32(_config.EventDuration);
            CountDownTimer(countDownTime);
        }
        private void CountDownTimer(int time)
        {
            countDownTime = time;

            List<BasePlayer> full = new List<BasePlayer>();
            List<BasePlayer> small = new List<BasePlayer>();

            foreach (var p in BasePlayer.activePlayerList)
            {
                if (changedViews.ContainsKey(p))
                {
                    if(changedViews[p]) full.Add(p);
                    else small.Add(p);
                }
                else full.Add(p);
            }

            SendUpdateFull(full, time);
            SendUpdateSmall(small, time);

            if (time <= 0)
            {
                DestroyAllUI();
                return;
            }

            timer.Once(1, () => CountDownTimer(time - 1));
        }

        private void DrawUIFull(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "BG");

            var container = new CuiElementContainer();

            container.Add(new CuiElement
            {
                Parent = $"Overlay",
                Name = $"BG",

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "1 0.5",
                        AnchorMax = "1 0.5",
                        OffsetMin = "-174.5 -25.5",
                        OffsetMax = "0 25.5"
                    },
                    new CuiRawImageComponent()
                    {
                        Png = GetImage("BG"),
                        Color = "1 1 1 1",
                    },
                }
            });

            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"Filler",

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "1 0",
                        AnchorMax = "1 0",
                        OffsetMin = "-111.3084 5.9",
                        OffsetMax = "-7.631599 8.5"
                    },
                    new CuiRawImageComponent()
                    {
                        Png = GetImage("Filler"),
                        Color = "1 1 1 1",
                    },
                }
            });

            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"TimerText",

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = "-20.74615 -10.1",
                        OffsetMax = "79.86815 3.9"
                    },
                    new CuiTextComponent()
                    {
                        Text = "Осталось 10:00",
                        FontSize = 8,
                        FadeIn = 0f,
                        Color = "1 1 1 1",
                        Align = TextAnchor.MiddleRight,
                    },
                }
            });

            container.Add(new CuiButton()
            {
                Button =
                {
                    Color = "1 1 1 0",
                    Command = "pyramid.change.view",
                },
                Text =
                {
                    Align = TextAnchor.MiddleCenter,
                    Color = "1 1 1 0",
                    FontSize = 14,
                },
                RectTransform =
                {
                    AnchorMin = "0 0",
                    AnchorMax = "1 1",
                    OffsetMin = "0 0",
                    OffsetMax = "0 0",
                },
            }, $"BG", "Btn");

            CuiHelper.AddUi(player, container);

            SendUpdateFull(new BasePlayer[] { player }, countDownTime);
        }
        private void DrawUISmall(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "BG");

            var container = new CuiElementContainer();

            container.Add(new CuiElement
            {
                Parent = $"Overlay",
                Name = $"BG",

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "1 0.5",
                        AnchorMax = "1 0.5",
                        OffsetMin = "-64 -22.5",
                        OffsetMax = "0 22.5"
                    },
                    new CuiRawImageComponent()
                    {
                        Png = GetImage("BGSmall"),
                        Color = "1 1 1 1",
                    },
                }
            });

            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"Filler",

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = "-22.75 -20",
                        OffsetMax = "22.75 -17.5"
                    },
                    new CuiRawImageComponent()
                    {
                        Png = GetImage("FillerV2"),
                        Color = "1 1 1 1",
                    },
                }
            });

            container.Add(new CuiButton()
            {
                Button =
                {
                    Color = "1 1 1 0",
                    Command = "pyramid.change.view",
                },
                Text =
                {
                    Align = TextAnchor.MiddleCenter,
                    Color = "1 1 1 0",
                    FontSize = 14,
                },
                RectTransform =
                {
                    AnchorMin = "0 0",
                    AnchorMax = "1 1",
                    OffsetMin = "0 0",
                    OffsetMax = "0 0",
                },
            }, $"BG", "Btn");

            CuiHelper.AddUi(player, container);

            SendUpdateSmall(new BasePlayer[] { player }, countDownTime);
        }

        private void SendUpdateFull(IEnumerable<BasePlayer> players, int time)
        {
            int minutes = time / 60;
            int seconds = time % 60;

            float fillAmount = Mathf.Clamp01(time / _config.EventDuration);

            float offsetMinX = -115f;
            float fullWidth = 115f - 7.631599f;
            float currentWidth = fullWidth * fillAmount;
            float offsetMaxX = offsetMinX + currentWidth;

            var container = new CuiElementContainer();
            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"TimerText",
                Update = true,

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = "-20.74615 -10.1",
                        OffsetMax = "79.86815 3.9"
                    },
                    new CuiTextComponent()
                    {
                        Text = $"Осталось {minutes}:{seconds:D2}",
                        FontSize = 8,
                        FadeIn = 0f,
                        Color = "1 1 1 1",
                        Align = TextAnchor.MiddleRight,
                    },
                }
            });
            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"Filler",
                Update = true,

                Components =
                {
                    new CuiRectTransformComponent()
                    {
                        AnchorMin = "1 0",
                        AnchorMax = "1 0",
                        OffsetMin = $"{offsetMinX} 5.9",
                        OffsetMax = $"{offsetMaxX} 8.5"
                    },
                    new CuiRawImageComponent()
                    {
                        Png = GetImage("Filler"),
                        Color = "1 1 1 1",
                    },
                }
            });

            foreach (var player in players)
                CuiHelper.AddUi(player, container);
        }
        private void SendUpdateSmall(IEnumerable<BasePlayer> players, int time)
        {
            CuiElementContainer container = new CuiElementContainer();

            float fillAmount = Mathf.Clamp01(time / _config.EventDuration);
            float maxX = Mathf.Lerp(-22.75f, 22.75f, fillAmount);

            container.Add(new CuiElement
            {
                Parent = $"BG",
                Name = $"Filler",
                Update = true,

                Components =
                {
                    new CuiRectTransformComponent
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = $"-22.75 -20",
                        OffsetMax = $"{maxX} -17.5"
                    },
                    new CuiRawImageComponent
                    {
                        Png = GetImage("FillerV2"),
                        Color = "1 1 1 1"
                    }
                }
            });

            foreach (var player in players)
            {
                CuiHelper.AddUi(player, container);
            }
        }


        private void DestroyAllUI()
        {
            foreach (var p in BasePlayer.activePlayerList) CuiHelper.DestroyUi(p, "BG");
        }

        [ConsoleCommand("pyramid.change.view")]
        private void ChangeView(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;

            if (changedViews.ContainsKey(player))
            {
                bool view = changedViews[player] = !changedViews[player];

                if (view) DrawUIFull(player);
                else DrawUISmall(player);
            }
            else
            {
                changedViews.Add(player, false);
                DrawUISmall(player);
            }
        }


        [PluginReference] private Plugin ImageLibrary;
        public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary.Call("GetImage", shortname, skin);
        public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
        private void LoadImages()
        {
            AddImage("https://i.imgur.com/ctDdj0B.png", "BGSmall");
            AddImage("https://i.imgur.com/IBt1OqI.png", "BG");

            AddImage("https://i.imgur.com/D5PMyiM.png", "Filler");
            AddImage("https://i.imgur.com/AV27xvb.png", "FillerV2");
        }
        #endregion

        #region [ CONFIG ]
        class ConfigData
        {
            [JsonProperty("Радиус поиска двери и зоны запрещенного ТП")]
            public float Radius = 50;
            [JsonProperty("Rc Id камеры для поиска двери")]
            public string CameraId = "aboba";

            [JsonProperty("Через какое время будет первая проверка на онлайн")]
            public float FirstCheckTime = 7200;
            [JsonProperty("Мин.онлайн первой проверки")]
            public int MinFirstTimeOnline = 30;
            [JsonProperty("Проверка в секундах на онлайн, если первый онлайн не набран")]
            public float CheckOnlineFirstTime = 600;

            [JsonProperty("Интвервал между ивентами")]
            public float DefaultStartEventTime = 14400;
            [JsonProperty("Длительность ивента")]
            public float EventDuration = 900;

            [JsonProperty("Время между добавленим радиации")]
            public float RadiationInterval = 5;
            [JsonProperty("Начало радиации после ивента")]
            public float RadiationStartTime = 5;
            [JsonProperty("Колво радиации")]
            public float RadiationLevel = 25;
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData();
            SaveConfig(config);
        }
        void SaveConfig(object config)
        {
            Config.WriteObject(config, true);
        }
        void ReadConfig()
        {
            base.Config.Settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
            _config = Config.ReadObject<ConfigData>();
            SaveConfig(_config);
        }
        #endregion
    }
}

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