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

FREE TreasureBox : 0.2.60 0.2.60

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using UnityEngine.SceneManagement;
using Facepunch;
using Newtonsoft.Json;
namespace Oxide.Plugins {
    [Info("TreasureBox", "k1lly0u", "0.2.60", ResourceId = 0)]
    //  Слив плагинов server-rust by Apolo YouGame
    class TreasureBox : RustPlugin {
#region Fields
        [PluginReference]
        Plugin LustyMap, RustMap, Kits, Spawns, RandomSpawns, ZoneManager;
        private Timer nextEvent;
        private Timer timeToUnlock;
        private Timer timeToDestroy;
        private Timer uiTimer;
        private MapMarkerGenericRadius mapMarker;
        private BaseEntity container;
        private ConfigData.LootTables lootTable;
        private LayerMask layerMask;
        private double nextTrigger;
        private bool isUnlocked;
        private bool isLooted;
        private bool isBlocked;
        private bool isLoaded;
        private string reason = "Loading Plugin!";
        static string treasureIcon;
        static TreasureBox ins;
        private Dictionary<string, int> itemNameToId = new Dictionary<string, int>();
        private List<NPCController> npcPlayers = new List<NPCController>();
        const string smokeSignal = "assets/bundled/prefabs/fx/smoke_signal_full.prefab";
        const string containerEnt = "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab";
        const string markerEnt = "assets/prefabs/tools/map/genericradiusmarker.prefab";
        const string npcEnt = "assets/prefabs/npc/scientist/scientist.prefab";
#endregion
#region Oxide Hooks
        private void OnServerInitialized() {
            ins = this;
            lang.RegisterMessages(Messages, this);
            SubscribeToMethods(false);
            itemNameToId = ItemManager.itemList.ToDictionary(x => x.shortname, y => y.itemid);
            VerifySettings();
            DestroyZone();
            layerMask = (1 << 29);
            layerMask |= (1 << 18);
            layerMask = ~layerMask;
        }
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)  //  Слив плагинов server-rust by Apolo YouGame
        {
            if (!isLoaded) return;
            if (entity == null || info == null) return;
            if (entity == container) {
                info.damageTypes.ScaleAll(0);
                return;
            }
            BasePlayer victim = entity.ToPlayer();
            NPCController npc = info.InitiatorPlayer?.GetComponent<NPCController>();
            if (victim != null && npc != null) {
                if (configData.EventOptions.BotSettings.Accuracy < UnityEngine.Random.Range(1, 99)) {
                    info.damageTypes = new Rust.DamageTypeList();
                    info.HitEntity = null;
                    info.HitMaterial = 0;
                    info.PointStart = Vector3.zero;
                }
            }
        }
        private void OnItemAddedToContainer(ItemContainer itemContainer, Item item) {
            if (!isLoaded || container == null) return;
            if (itemContainer.entityOwner == null) return;
            if (container == itemContainer.entityOwner) {
                if (isBlocked) item.Drop(itemContainer.entityOwner.transform.position, Vector3.up);
            }
        }
        private void OnPlayerLootEnd(PlayerLoot loot) {
            if (!isLoaded || container == null) return;
            if (loot.entitySource != null && loot.entitySource == container) {
                ItemContainer itemContainer = container.GetComponent<StorageContainer>()?.inventory;
                if (itemContainer != null) {
                    if (!isLooted) {
                        isLooted = true;
                        string playerName = loot.GetComponentInParent<BasePlayer>()?.displayName;
                        if (!string.IsNullOrEmpty(playerName)) PrintToChat(string.Format(msg("eventWin"), playerName));
                    }
                    if (itemContainer.itemList.Count == 0) {
                        DestroyContainer();
                    }
                }
            }
        }
        private object CanBuild(Planner planner, Construction prefab, Construction.Target target) {
            if (!isLoaded || container == null) return null;
            if (configData.EventOptions.ZoneSettings.DisableBuilding) {
                if (Vector3.Distance(target.position, container.transform.position) < configData.EventOptions.ZoneSettings.ZoneRadius) {
                    BasePlayer player = planner?.GetOwnerPlayer();
                    if (player != null) SendReply(player, msg("nobuild", player.UserIDString));
                    return false;
                }
            }
            return null;
        }
        private void Unload() {
            ins = null;
            DestroyEvent();
            DestroyZone();
        }
        private void DestroyEvent() {
            if (nextEvent != null) nextEvent.Destroy();
            if (timeToUnlock != null) timeToUnlock.Destroy();
            if (timeToDestroy != null) timeToDestroy.Destroy();
            if (uiTimer != null) uiTimer.Destroy();
            foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Main);
            foreach (var player in npcPlayers) {
                if (player != null && player.player != null) player.player.DieInstantly();
            }
            npcPlayers.Clear();
            if (container != null) {
                var loot = container.GetComponent<StorageContainer>()?.inventory;
                if (loot != null) ClearContainer(loot);
                (container as BaseCombatEntity)?.DieInstantly();
            }
            if (mapMarker != null && !mapMarker.IsDestroyed) mapMarker.Kill();
            if (configData.MapOptions.Lusty.Enabled) RemoveMapMarker();
        }
#endregion
#region Functions
        private void SubscribeToMethods(bool isSubscribing) {
            if (isSubscribing) {
                Subscribe(nameof(OnPlayerLootEnd));
                Subscribe(nameof(OnItemAddedToContainer));
                Subscribe(nameof(OnEntityTakeDamage));
                Subscribe(nameof(CanBuild));
            }
            else {
                Unsubscribe(nameof(OnPlayerLootEnd));
                Unsubscribe(nameof(OnItemAddedToContainer));
                Unsubscribe(nameof(OnEntityTakeDamage));
                Unsubscribe(nameof(CanBuild));
            }
        }
        private void VerifySettings() {
            if (!configData.EventOptions.RandomSpawnPoints) {
                if (!Spawns) {
                    reason = "Spawns Database not found!";
                    PrintError("Spawns Database not found! Can not continue");
                    return;
                }
                if (string.IsNullOrEmpty(configData.EventOptions.Spawnfile)) {
                    reason = "No spawnfile has been set in the config!";
                    PrintError("No spawnfile has been set in the config! Can not continue");
                    return;
                }
                object success = Spawns.Call("GetSpawnsCount", configData.EventOptions.Spawnfile);
                if (success is string) {
                    reason = (string)success;
                    PrintError((string)success);
                    return;
                }
            }
            else {
                if (!RandomSpawns) {
                    reason = "RandomSpawns not found!";
                    PrintError("RandomSpawns can not be found! Can not continue");
                    return;
                }
            }
            if (configData.EventOptions.UISettings.Enabled && !string.IsNullOrEmpty(configData.EventOptions.UISettings.Icon)) Add(configData.EventOptions.UISettings.Icon);
            isLoaded = true;
            StartTimers();
        }
        private void StartTimers() {
            var time = UnityEngine.Random.Range(configData.Timers.MinInterval, configData.Timers.MaxInterval);
            nextTrigger = GrabCurrentTime() + time;
            nextEvent = timer.In((float)time, ()=> SpawnContainer());
        }
        private void SpawnContainer(object spawnLoc = null) {
            if (BasePlayer.activePlayerList.Count >= configData.EventOptions.MinPlayers) {
                Vector3 location = Vector3.zero;
                if (spawnLoc == null) {
                    if (configData.EventOptions.RandomSpawnPoints) {
                        object success = RandomSpawns.Call("GetSpawnPoint");
                        if (success != null) location = (Vector3)success;
                    }
                    else {
                        object success = Spawns.Call("GetRandomSpawn", configData.EventOptions.Spawnfile);
                        if (success is string) {
                            PrintError((string)success);
                            return;
                        }
                        location = (Vector3)success;
                    }
                }
                else location = (Vector3)spawnLoc;
                if (location == Vector3.zero) {
                    PrintError("There was a error retrieving a spawn location for the treasure box!");
                    return;
                }
                lootTable = configData.LootTable.GetRandom();
                if (lootTable == null) {
                    PrintError("Null loot table in config!");
                    return;
                }
                SubscribeToMethods(true);
                container = GameManager.server.CreateEntity(containerEnt, location, new Quaternion(), true);
                container.skinID = lootTable.SkinID;
                container.enableSaving = false;
                container.Spawn();
                isBlocked = false;
                timer.In(1, () => {
                    FillLootContainer(container);
                    isUnlocked = false;
                    isLooted = false;
                    NotifyEventStarted();
                    CreateNewZone();
                    SpawnBots();
                }
                );
            }
            else StartTimers();
        }
        private void CreateNewZone() {
            if (ZoneManager && configData.EventOptions.ZoneSettings.TempZone) {
                string[] flags = new string[configData.EventOptions.ZoneSettings.Flags.Length + 2];
                flags[0] = "radius";
                flags[1] = configData.EventOptions.ZoneSettings.ZoneRadius.ToString();
                for (int i = 0; i < configData.EventOptions.ZoneSettings.Flags.Length; i++) {
                    flags[i + 2] = configData.EventOptions.ZoneSettings.Flags[i];
                }
                ZoneManager.Call("CreateOrUpdateZone", "TreasureBox Zone", configData.EventOptions.ZoneSettings.Flags, container.transform.position);
            }
        }
        private void DestroyZone() {
            if (ZoneManager && configData.EventOptions.ZoneSettings.TempZone) {
                ZoneManager.Call("EraseZone", "TreasureBox Zone");
            }
        }
        private void ClearContainer(ItemContainer itemContainer) {
            if (itemContainer == null || itemContainer.itemList == null) return;
            while (itemContainer.itemList.Count > 0) {
                var item = itemContainer.itemList[0];
                item.RemoveFromContainer();
                item.Remove(0f);
            }
        }
        private void FillLootContainer(BaseEntity entity) {
            if (entity == null) return;
            ItemContainer itemContainer = entity.GetComponent<StorageContainer>()?.inventory;
            if (itemContainer == null) return;
            int count = UnityEngine.Random.Range(lootTable.Minimum, lootTable.Maximum);
            if (itemContainer.capacity < count) itemContainer.capacity = count;
            List<ConfigData.LootTables.LootItem> Items = new List<ConfigData.LootTables.LootItem>(lootTable.Items);
            for (int i = 0; i < count; i++) {
                ConfigData.LootTables.LootItem lootItem = Items.GetRandom();
                if (lootItem == null) continue;
                bool isBlueprint = lootItem.Name.EndsWith(".bp");
                string shortname = isBlueprint ? lootItem.Name.Substring(0, lootItem.Name.Length - 3) : lootItem.Name;
                if (!itemNameToId.ContainsKey(shortname)) {
                    PrintError($"Invalid item shortname set in loot list : {shortname}");
                    continue;
                }
                Item item = null;
                if (isBlueprint) {
                    item = ItemManager.CreateByItemID(-996920608, 1, 0);
                    item.blueprintTarget = itemNameToId[shortname];
                    item.amount = UnityEngine.Random.Range(lootItem.Minimum, lootItem.Maximum);
                }
                else item = ItemManager.CreateByName(shortname);
                if (item != null) {
                    item.amount = UnityEngine.Random.Range(lootItem.Minimum, lootItem.Maximum);
                    item.MoveToContainer(itemContainer, -1, false);
                }
                Items.Remove(lootItem);
            }
            isBlocked = true;
            container.SetFlag(BaseEntity.Flags.Locked, true);
            if (configData.EventOptions.SmokeEnabled) Effect.server.Run(smokeSignal, entity, 0, new Vector3(), new Vector3(), null, true);
        }
        private void NotifyEventStarted() {
            nextTrigger = GrabCurrentTime() + configData.Timers.Unlock;
            timeToUnlock = timer.In(configData.Timers.Unlock, UnlockContainer);
            if (configData.EventOptions.UISettings.Enabled) RefreshAllUI();
            PrintToChat(string.Format(msg("eventStart1"), FormatTime(configData.Timers.Unlock)));
            if (configData.EventOptions.BroadcastCoords) PrintToChat(string.Format(msg("broadcastCoords"), configData.EventOptions.UISettings.GridReference ? GetGridString(container.transform.position) : $"X: {Math.Round(container.transform.position.x, 1)}, Z: {Math.Round(container.transform.position.z, 1)}"));
            if (configData.MapOptions.Lusty.Enabled && !string.IsNullOrEmpty(configData.MapOptions.Lusty.Marker)) AddMapMarker();
            if (configData.MapOptions.Map.Enabled) {
                mapMarker = (MapMarkerGenericRadius)GameManager.server.CreateEntity(markerEnt, container.transform.position + (UnityEngine.Random.onUnitSphere * configData.MapOptions.Map.Offset), new Quaternion());
                mapMarker.enableSaving = false;
                mapMarker.Spawn();
                mapMarker.radius = configData.MapOptions.Map.Radius;
                mapMarker.alpha = configData.MapOptions.Map.Alpha;
                Color color = string.IsNullOrEmpty(lootTable.MarkerColor) ? ConvertToColor(configData.MapOptions.Map.Color) : ConvertToColor(lootTable.MarkerColor);
                Color color2 = new Color(0, 0, 0, 0);
                mapMarker.color1 = color;
                mapMarker.color2 = color2;
                mapMarker.SendUpdate();
                if (configData.MapOptions.Map.BroadcastMarker) PrintToChat(msg("broadcastMap"));
            }
        }
        private void UnlockContainer() {
            if (container != null) {
                container.SetFlag(BaseEntity.Flags.Locked, false);
                isUnlocked = true;
                nextTrigger = GrabCurrentTime() + configData.Timers.Loot;
                timeToDestroy = timer.In(configData.Timers.Loot, DestroyContainer);
                if (configData.EventOptions.UISettings.Enabled) RefreshAllUI();
                PrintToChat(string.Format(msg("containerUnlock"), FormatTime(configData.Timers.Loot)));
            }
            else StartTimers();
        }
        private void DestroyContainer() {
            if (container != null) {
                DestroyEvent();
                SubscribeToMethods(false);
                if (!isLooted) {
                    PrintToChat(msg("eventLose"));
                    DestroyZone();
                }
                else timer.In(configData.EventOptions.ZoneSettings.ActiveTime, DestroyZone);
                if (configData.MapOptions.Lusty.Enabled) RemoveMapMarker();
                if (configData.MapOptions.Map.Enabled && mapMarker != null && !mapMarker.IsDestroyed) mapMarker.Kill();
            }
            StartTimers();
        }
        private string FormatTime(double time) {
            TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
            var days = dateDifference.Days;
            var hours = dateDifference.Hours;
            hours += (days * 24);
            var mins = dateDifference.Minutes;
            var secs = dateDifference.Seconds;
            if (hours > 0) return string.Format("{0:00}:{1:00}:{2:00}", hours, mins, secs);
            else return string.Format("{0:00}:{1:00}", mins, secs);
        }
        private double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private Color ConvertToColor(string color) {
            if (color.StartsWith("#")) color = color.Substring(1);
            int red = int.Parse(color.Substring(0, 2), NumberStyles.AllowHexSpecifier);
            int green = int.Parse(color.Substring(2, 2), NumberStyles.AllowHexSpecifier);
            int blue = int.Parse(color.Substring(4, 2), NumberStyles.AllowHexSpecifier);
            return new Color((float)red / 255, (float)green / 255, (float)blue / 255);
        }
        private string GetGridString(Vector3 position) {
            Vector2 adjPosition = new Vector2((World.Size / 2) + position.x, (World.Size / 2) - position.z);
            return string.Format(msg("gridRef"), $"{NumberToString((int)(adjPosition.x / 150))}{(int)(adjPosition.y / 150)}");
        }
        private string NumberToString(int number) {
            bool a = number > 26;
            Char c = (Char)(65 + (a ? number - 26 : number));
            return a ? "A" + c : c.ToString();
        }
#endregion
#region NPC Controller
        private void SpawnBots() {
            if (!configData.EventOptions.BotSettings.Enabled) return;
            for (int i = 0; i < configData.EventOptions.BotSettings.Amount; i++) {
                Vector3 position = container.transform.position + (UnityEngine.Random.insideUnitSphere * 10);
                RaycastHit rayHit;
                if (Physics.Raycast(new Ray(position + (Vector3.up * 100), Vector3.down), out rayHit, 150, LayerMask.GetMask("Terrain", "Default", "World"))) {
                    position = rayHit.point;
                }
                else {
                    float terrainHeight = TerrainMeta.HeightMap.GetHeight(position);
                    if (position.y < terrainHeight) position.y = terrainHeight;
                }
                GameObject gameObject = Instantiate.GameObject(GameManager.server.FindPrefab(npcEnt), position, new Quaternion());
                gameObject.name = "assets/prefabs/npc/scientist/scientist.prefab";
                SceneManager.MoveGameObjectToScene(gameObject, Rust.Server.EntityScene);
                UnityEngine.Object.Destroy(gameObject.GetComponent<Spawnable>());
                if (!gameObject.activeSelf) gameObject.SetActive(true);
                NPCPlayerApex player = gameObject.GetComponent<NPCPlayerApex>();
                player.enableSaving = false;
                player.Spawn();
                npcPlayers.Add(player.gameObject.AddComponent<NPCController>());
            }
        }
        class NPCController : MonoBehaviour {
            public NPCPlayerApex player;
            private float maxDistance;
            private float npcRange;
            private Vector3 boxPosition;
            private List<Vector3> patrolPositions = new List<Vector3>();
            private int lastPatrolIndex = 0;
            private void Awake() {
                player = GetComponent<NPCPlayerApex>();
                enabled = false;
                maxDistance = ins.configData.EventOptions.BotSettings.MaxDistance;
                npcRange = ins.configData.EventOptions.BotSettings.Range;
                boxPosition = ins.container.transform.position;
                InitializeNPC();
            }
            private void InitializeNPC() {
                player.InitializeHealth(ins.configData.EventOptions.BotSettings.Health, ins.configData.EventOptions.BotSettings.Health);
                player.displayName = RandomUsernames.Get(UnityEngine.Random.Range(0, RandomUsernames.All.Length - 1));
                player.CancelInvoke(new Action(player.RadioChatter));
                if (!ins.configData.EventOptions.BotSettings.DropLoot) player.GetComponent<Scientist>().LootSpawnSlots = new LootContainer.LootSpawnSlot[0];
                player.Stats.AggressionRange = npcRange;
                if (ins.configData.EventOptions.BotSettings.Kits.Length > 0) {
                    string kitName = ins.configData.EventOptions.BotSettings.Kits.GetRandom();
                    if (!string.IsNullOrEmpty(kitName)) {
                        if (player.IsInvoking(player.EquipTest)) player.CancelInvoke(player.EquipTest);
                        player.inventory.Strip();
                        ins.NextTick(() => {
                            ins.Kits?.Call("GiveKit", new object[] {
                                player.GetComponent<BasePlayer>(), kitName
                            }
                            );
                            ins.timer.In(3, () => {
                                if (player.inventory.containerBelt.GetSlot(0) == null) {
                                    print($"[ERROR] [TreasureBox] - The kit '{kitName}' does not have a active weapon in the first slot of the tool belt.You must re-adjust the kit for NPC players to utilize a weapon!");
                                }
                                else {
                                    player.EquipTest();
                                    AttackEntity attackEntity = player.GetHeldEntity() as AttackEntity;
                                    if (attackEntity != null) attackEntity.effectiveRange = npcRange / 2;
                                }
                            }
                            );
                        }
                        );
                    }
                }
                GeneratePatrolPositions();
            }
            private void Update() {
                if (player.AttackTarget == null) {
                    if (Vector3.Distance(player.transform.position, patrolPositions[lastPatrolIndex]) < 5) lastPatrolIndex++;
                    if (lastPatrolIndex >= patrolPositions.Count) lastPatrolIndex = 0;
                    player.SetDestination(patrolPositions[lastPatrolIndex]);
                }
                else {
                    if (Vector3.Distance(player.transform.position, player.AttackTarget.transform.position) > npcRange) {
                        player.AttackTarget = null;
                        player.SetDestination(patrolPositions[lastPatrolIndex]);
                    }
                }
            }
            private void GeneratePatrolPositions() {
                for (int i = 0; i < 6; i++) {
                    Vector3 position = boxPosition + (UnityEngine.Random.onUnitSphere * maxDistance);
                    position.y = TerrainMeta.HeightMap.GetHeight(position);
                    patrolPositions.Add(position);
                }
                enabled = true;
            }
        }
#endregion
#region UI
        public class UI {
            static public CuiElementContainer CreateElementContainer(string panelName, string color, string aMin, string aMax, bool useCursor = false) {
                var NewElement = new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = color
                            }
                            , RectTransform = {
                                AnchorMin = aMin, AnchorMax = aMax
                            }
                            , CursorEnabled = useCursor
                        }
                        , new CuiElement().Parent = "Hud", panelName
                    }
                }
                ;
                return NewElement;
            }
            static public void AddImage(ref CuiElementContainer container, string panel, string png, string aMin, string aMax, float fadeOut = 0f) {
                container.Add(new CuiElement {
                    Name = CuiHelper.GetGuid(), Parent = panel, Components = {
                        new CuiRawImageComponent {
                            Png = png, Sprite = "assets/content/textures/generic/fulltransparent.tga"
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = aMin, AnchorMax = aMax
                        }
                    }
                }
                );
            }
            static public void CreateLabel(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter) {
                container.Add(new CuiLabel {
                    Text = {
                        Color = color, FontSize = size, Align = align, Text = text
                    }
                    , RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax
                    }
                }
                , panel);
            }
            public static string Color(string hexColor, float alpha) {
                if (hexColor.StartsWith("#")) hexColor = hexColor.TrimStart('#');
                int red = int.Parse(hexColor.Substring(0, 2), NumberStyles.AllowHexSpecifier);
                int green = int.Parse(hexColor.Substring(2, 2), NumberStyles.AllowHexSpecifier);
                int blue = int.Parse(hexColor.Substring(4, 2), NumberStyles.AllowHexSpecifier);
                return $"{(double)red / 255} {(double)green / 255} {(double)blue / 255} {alpha}";
            }
        }
#endregion
#region UI Creation
        private const string Main = "TreasureUIMain";
        private void CreateTreasureUI(BasePlayer player) {
            var MainCont = UI.CreateElementContainer(Main, UI.Color(configData.EventOptions.UISettings.UIBackgroundColor, configData.EventOptions.UISettings.UIOpacity), $"{configData.EventOptions.UISettings.XPosition} {configData.EventOptions.UISettings.YPosition}", $"{configData.EventOptions.UISettings.XPosition + configData.EventOptions.UISettings.XDimension} {configData.EventOptions.UISettings.YPosition + configData.EventOptions.UISettings.YDimension}");
            if (!string.IsNullOrEmpty(treasureIcon)) UI.AddImage(ref MainCont, Main, treasureIcon, "0.01 0.05", "0.12 0.95");
            UI.CreateLabel(ref MainCont, Main, "", string.Format(isUnlocked ? msg("despawnsIn", player.UserIDString) : msg("unlocksIn", player.UserIDString), configData.EventOptions.UISettings.GridReference ? GetGridString(container.transform.position) : $"X: {Math.Round(container.transform.position.x, 1)}, Z: {Math.Round(container.transform.position.z, 1)}", GetFormatTime()), 15, "0.14 0", "1 1", TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(player, Main);
            CuiHelper.AddUi(player, MainCont);
        }
        private string GetFormatTime() {
            var time = nextTrigger - GrabCurrentTime();
            double minutes = Math.Floor((double)(time / 60));
            time -= (int)(minutes * 60);
            return string.Format("{0:00}:{1:00}", minutes, time);
        }
        private void RefreshAllUI() {
            uiTimer = timer.Repeat(1, (int)(nextTrigger - GrabCurrentTime()) - 1, () => {
                foreach (var player in BasePlayer.activePlayerList) {
                    if (container == null) return;
                    if (!isLooted) CreateTreasureUI(player);
                    else CuiHelper.DestroyUi(player, Main);
                }
            }
            );
        }
#endregion
#region External Hooks
        private void AddMapMarker() {
            LustyMap?.Call("AddMarker", container.transform.position.x, container.transform.position.z, msg("iconName"), configData.MapOptions.Lusty.Marker);
            RustMap?.Call("AddTemporaryMarker", "treasurebox", false, 0.04f, 0.99f, container.transform, "treasurebox", configData.MapOptions.Lusty.Marker);
        }
        private void RemoveMapMarker() {
            LustyMap?.Call("RemoveMarker", msg("iconName"));
            RustMap?.Call("RemoveTemporaryMarkerByName", "treasurebox");
        }
#endregion
#region Commands
        [ChatCommand("th")]
        void cmdTH(BasePlayer player, string command, string[] args) {
            if (!isLoaded) {
                SendReply(player, "The plugin is not loaded because : " + reason);
                return;
            }
            if (args.Length == 0) {
                SendReply(player, $"<color=#ce422b>{Title}</color>  <color=#939393>v.</color><color=#ce422b>{Version}</color>");
                SendReply(player, "<color=#ce422b>/th info</color><color=#939393> - Shows the time remaining before the next event step and the position of the treasure box (if applicable)</color>");
                if (player.IsAdmin) {
                    SendReply(player, "<color=#ce422b>/th start</color><color=#939393> - Force start the event</color>");
                    SendReply(player, "<color=#ce422b>/th starthere</color><color=#939393> - Start a new event on your position</color>");
                    SendReply(player, "<color=#ce422b>/th cancel</color><color=#939393> - Cancels the current event</color>");
                    SendReply(player, "<color=#ce422b>/th unlock</color><color=#939393> - Pre-maturely unlock the treasure box</color>");
                }
            }
            else {
                switch (args[0].ToLower()) {
                    case "info" : string time = FormatTime(nextTrigger - GrabCurrentTime());
                    if (container != null) {
                        if (isUnlocked) SendReply(player, msg("isUnlocked", player.UserIDString));
                        else SendReply(player, string.Format(msg("nextUnlock", player.UserIDString), time));
                        SendReply(player, string.Format(msg("currentPos", player.UserIDString), configData.EventOptions.UISettings.GridReference ? GetGridString(container.transform.position) : $"X: {Math.Round(container.transform.position.x, 1)}, Z: {Math.Round(container.transform.position.z, 1)}"));
                    }
                    else SendReply(player, string.Format(msg("nextDrop", player.UserIDString), time));
                    return;
                    case "start" : if (!player.IsAdmin) return;
                    if (container != null) {
                        SendReply(player, "<color=#939393>There is already a event in progress!</color>");
                        return;
                    }
                    else {
                        nextEvent.Destroy();
                        SpawnContainer();
                        SendReply(player, "<color=#939393>You have force started the event!</color>");
                    }
                    return;
                    case "starthere" : if (!player.IsAdmin) return;
                    if (container != null) {
                        SendReply(player, "<color=#939393>There is already a event in progress!</color>");
                        return;
                    }
                    else {
                        nextEvent.Destroy();
                        SpawnContainer(player.transform.position);
                        SendReply(player, "<color=#939393>You have started a event on your position!</color>");
                    }
                    return;
                    case "cancel" : if (!player.IsAdmin) return;
                    if (container == null) {
                        SendReply(player, "<color=#939393>There is not currently a event in progress!</color>");
                        return;
                    }
                    else {
                        DestroyEvent();
                        DestroyZone();
                        StartTimers();
                        SendReply(player, "<color=#939393>You have cancelled the current event!</color>");
                    }
                    return;
                    case "unlock" : if (!player.IsAdmin) return;
                    if (container != null) {
                        if (isUnlocked) SendReply(player, "<color=#939393>The treasure box is already unlocked!</color>");
                        else {
                            timeToUnlock.Destroy();
                            UnlockContainer();
                            SendReply(player, "<color=#939393>You have unlocked the treasure box!</color>");
                        }
                    }
                    return;
                    default : SendReply(player, "<color=#939393>Invalid command</color>");
                    break;
                }
            }
        }
        [ConsoleCommand("th")]
        void ccmdTH(ConsoleSystem.Arg arg) {
            if (arg.Connection != null) return;
            if (!isLoaded) {
                SendReply(arg, "The plugin is not loaded because : " + reason);
                return;
            }
            if (arg.Args == null || arg.Args.Length == 0) {
                SendReply(arg, $"- {Title}  v.{Version}   - {Author} @ www.chaoscode.io -");
                SendReply(arg, "th start - Force start the event");
                SendReply(arg, "th cancel - Cancels the current event");
                SendReply(arg, "th unlock - Manually unlock the treasure box");
                SendReply(arg, "th clearicon - Clears any TH related icons from the map");
            }
            else {
                switch (arg.Args[0].ToLower()) {
                    case "start" : if (container != null) SendReply(arg, "There is already a event in progress!");
                    else {
                        nextEvent.Destroy();
                        SpawnContainer();
                        SendReply(arg, "You have force started the event!");
                    }
                    return;
                    case "cancel" : if (container == null) SendReply(arg, "There is not currently a event in progress!");
                    else {
                        DestroyEvent();
                        DestroyZone();
                        StartTimers();
                        SendReply(arg, "You have cancelled the current event!");
                    }
                    return;
                    case "unlock" : if (container == null) SendReply(arg, "There is not currently a event in progress!");
                    else {
                        if (isUnlocked) SendReply(arg, "The treasure box is already unlocked!");
                        else {
                            timeToUnlock.Destroy();
                            UnlockContainer();
                            SendReply(arg, "You have unlocked the treasure box!");
                        }
                    }
                    return;
                    case "clearicon" : RemoveMapMarker();
                    return;
                    default : SendReply(arg, "Invalid command");
                    break;
                }
            }
        }
#endregion
#region Imagery
        private WWW info;
        public void Add(string url) {
            info = new WWW(url);
            TryDownloadImage();
        }
        void TryDownloadImage() {
            if (!info.isDone) {
                timer.In(1, TryDownloadImage);
                return;
            }
            if (!string.IsNullOrEmpty(info.error)) {
                PrintError(string.Format("Failed to load the Treasure Icon! Error: {0}", info.error));
                return;
            }
            else treasureIcon = FileStorage.server.Store(info.bytes, FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
        }
#endregion
#region Config
        private ConfigData configData;
        class ConfigData {
            [JsonProperty(PropertyName = "Event Timers")]
            public EventTimers Timers {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Event Options")]
            public Options EventOptions {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Loot Containers (Chosen at random)")]
            public List<LootTables> LootTable {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Map Options")]
            public MapIntegration MapOptions {
                get;
                set;
            }
            public class LootTables {
                [JsonProperty(PropertyName = "Container skin ID")]
                public ulong SkinID {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Minimum amount of items to spawn")]
                public int Minimum {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Maximum amount of items to spawn")]
                public int Maximum {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Map marker color override (hex)")]
                public string MarkerColor {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Loot list")]
                public List<LootItem> Items {
                    get;
                    set;
                }
                public class LootItem {
                    [JsonProperty(PropertyName = "Item shortname")]
                    public string Name {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Minimum amount of item")]
                    public int Minimum {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Maximum amount of item")]
                    public int Maximum {
                        get;
                        set;
                    }
                }
            }
            public class EventTimers {
                [JsonProperty(PropertyName = "Minimum time between events (seconds)")]
                public int MinInterval {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Maximum time between events (seconds)")]
                public int MaxInterval {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Amount of time before the box unlocks (seconds)")]
                public int Unlock {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Amount of time the box will remain on the map (seconds)")]
                public int Loot {
                    get;
                    set;
                }
            }
            public class MapIntegration {
                [JsonProperty(PropertyName = "Ingame map integration")]
                public MapOptions Map {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "LustyMap intergration")]
                public LustyOptions Lusty {
                    get;
                    set;
                }
                public class MapOptions {
                    [JsonProperty(PropertyName = "Show a radius marker on the map")]
                    public bool Enabled {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "The radius of the marker")]
                    public float Radius {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Maximum amount to offset the marker position from the box position")]
                    public float Offset {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Marker color (hex)")]
                    public string Color {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Marker transparency (0.0 - 1.0)")]
                    public float Alpha {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Broadcast information about the marker to chat")]
                    public bool BroadcastMarker {
                        get;
                        set;
                    }
                }
                public class LustyOptions {
                    [JsonProperty(PropertyName = "Show a icon on LustyMap")]
                    public bool Enabled {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "URL of the icon to be used")]
                    public string Marker {
                        get;
                        set;
                    }
                }
            }
            public class Options {
                [JsonProperty(PropertyName = "Use RandomSpawns for box spawn points")]
                public bool RandomSpawnPoints {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Use a spawn file for box spawn points")]
                public string Spawnfile {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Minimum players required online to trigger the event")]
                public int MinPlayers {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Show a smoke signal on the box location")]
                public bool SmokeEnabled {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Broadcast the box co-ordinates to chat")]
                public bool BroadcastCoords {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "UI Options")]
                public UIOptions UISettings {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Event Zone Options")]
                public ZoneOptions ZoneSettings {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "NPC Options")]
                public BotOptions BotSettings {
                    get;
                    set;
                }
                public class UIOptions {
                    [JsonProperty(PropertyName = "Enabled the UI display")]
                    public bool Enabled {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Display grid reference instead of coordinates")]
                    public bool GridReference {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "URL of the icon to be used in the UI")]
                    public string Icon {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Position - X Start")]
                    public float XPosition {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Position - Y Start")]
                    public float YPosition {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Position - X Dimensions")]
                    public float XDimension {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Position - Y Dimensions")]
                    public float YDimension {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "UI background color (hex)")]
                    public string UIBackgroundColor {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "UI transparency (0.0 - 1.0)")]
                    public float UIOpacity {
                        get;
                        set;
                    }
                }
                public class ZoneOptions {
                    [JsonProperty(PropertyName = "Disable building and deployable placement within the set radius of the box")]
                    public bool DisableBuilding {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Radius of the event zone")]
                    public float ZoneRadius {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Create a temporary zone around the box when it spawns using ZoneManager")]
                    public bool TempZone {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "The amount of time the Zone Manager zone will remain active after the event is over (seconds)")]
                    public int ActiveTime {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Flags to be applied to the temporary Zone Manager zone")]
                    public string[] Flags {
                        get;
                        set;
                    }
                }
                public class BotOptions {
                    [JsonProperty(PropertyName = "Spawn NPCs at the box location")]
                    public bool Enabled {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Amount of NPCs to spawn")]
                    public int Amount {
                        get;
                        set;
                    }
                    [JsonProperty
// ... [Code preview truncated due to length. Full source in attached file] ...

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