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

FREE Juggernaut : 0.2.43 0.2.43

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Rust;
using UnityEngine;
using System.Linq;
namespace Oxide.Plugins {
    [Info("Juggernaut", "k1lly0u", "0.2.43", ResourceId = 0)]
    internal class Juggernaut : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Clans, Friends, LustyMap, EventManager, ServerRewards, Economics;
        private static Juggernaut ins;
        private StoredData storedData;
        private RestoreData restoreData;
        private DynamicConfigFile data, restorationData;
        private BasePlayer juggernaut = null;
        private BaseEntity[] finalSphere = null;
        private Vector3 endPos = Vector3.zero;
        private Timer nextMatch;
        private Timer startMatch;
        private Timer eventTimer;
        private Timer broadcastTimer;
        private Timer openMessage;
        private Timer uiTimer;
        private double eventEnd;
        private double nextTrigger;
        private string juggernautIcon;
        private bool isOpen;
        private bool hasStarted;
        private bool initialized;
        private bool hasDestinations;
        private static bool isUnloading;
        private List<ulong> optedIn = new List<ulong>();
        private Dictionary<ulong, Destinations> destinationCreator = new Dictionary<ulong, Destinations>();
        private const string sphereEnt = "assets/prefabs/visualization/sphere.prefab";
#endregion
#region Oxide Hooks
        private void Loaded() {
            permission.RegisterPermission("juggernaut.canbe", this);
            lang.RegisterMessages(Messages, this);
            data = Interface.Oxide.DataFileSystem.GetFile("juggernaut_data");
            restorationData = Interface.Oxide.DataFileSystem.GetFile("juggernaut_restoration_data");
            isUnloading = false;
        }
        private void OnServerInitialized() {
            ins = this;
            LoadData();
            if (storedData.destinations.Count > 0) {
                hasDestinations = true;
                StartEventTimer();
            }
            else PrintWarning("No destinations have been set! Unable to start the event");
            RemoveMapMarker(msg("juggernaut"), false);
            RemoveMapMarker(msg("possibleDest"), true);
            RemoveMapMarker(msg("destination"), false);
            Unsubscribe(nameof(CanNetworkTo));
            initialized = true;
        }
        private void OnServerSave() => SaveRestoreData();
        private void Unload() {
            isUnloading = true;
            if (eventTimer != null) eventTimer.Destroy();
            if (nextMatch != null) nextMatch.Destroy();
            if (startMatch != null) startMatch.Destroy();
            if (openMessage != null) openMessage.Destroy();
            if (uiTimer != null) uiTimer.Destroy();
            if (broadcastTimer != null) broadcastTimer.Destroy();
            foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Main);
            CuiHelper.DestroyUi(juggernaut, Compass);
            if (juggernaut != null && hasStarted) {
                UnlockInventory(juggernaut);
                StripInventory(juggernaut);
                DestroyEvent();
            }
            SaveRestoreData();
        }
        private void OnPlayerInit(BasePlayer player) {
            if (player.IsSleeping() || player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                timer.In(1, () => OnPlayerInit(player));
                return;
            }
            if (restoreData.HasRestoreData(player.userID)) restoreData.RestorePlayer(player);
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            if (optedIn.Contains(player.userID)) optedIn.Remove(player.userID);
            if (player == juggernaut && hasStarted) {
                UnlockInventory(player);
                StripInventory(player);
                DestroyEvent();
            }
        }
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
            if (entity == null || info == null) return;
            var victim = entity.ToPlayer();
            var attacker = info.InitiatorPlayer;
            if (victim != null && victim == juggernaut) {
                if (info.Initiator != null && info.Initiator.ShortPrefabName.Equals("beartrap") && configData.Juggernaut.NoBeartrapDamage) {
                    info.damageTypes.ScaleAll(0);
                    return;
                }
                if (info.WeaponPrefab != null && info.WeaponPrefab.ShortPrefabName.Equals("landmine") && configData.Juggernaut.NoLandmineDamage) {
                    info.damageTypes.ScaleAll(0);
                    return;
                }
                if (info.damageTypes.GetMajorityDamageType() == DamageType.Fall && configData.Juggernaut.NoFallDamage) {
                    info.damageTypes.ScaleAll(0);
                    return;
                }
                if (attacker != null) {
                    if (IsFriend(victim.userID, attacker.userID)) {
                        info.damageTypes.ScaleAll(0);
                        SendReply(attacker, msg("ff1", attacker.UserIDString));
                        return;
                    }
                    if (IsClanmate(victim.userID, attacker.userID)) {
                        info.damageTypes.ScaleAll(0);
                        SendReply(attacker, msg("ff2", attacker.UserIDString));
                        return;
                    }
                }
                info.damageTypes.ScaleAll(configData.Juggernaut.DefenseMod);
                return;
            }
            if (attacker == null) return;
            if (attacker == juggernaut) {
                if (!configData.Juggernaut.DamageStructures && (entity is BuildingBlock || entity is SimpleBuildingBlock)) {
                    info.damageTypes.ScaleAll(0);
                    return;
                }
                info.damageTypes.ScaleAll(configData.Juggernaut.AttackMod);
            }
        }
        private void OnEntitySpawned(BaseNetworkable entity) {
            if (!initialized || entity == null) return;
            var player = entity as BasePlayer;
            if (player != null) {
                TryRestorePlayer(player);
            }
        }
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            if (entity == null || info == null) return;
            var victim = entity.ToPlayer();
            if (victim == null) return;
            if (victim == juggernaut) {
                if (!configData.Prizes.Inventory) StripInventory(victim);
                var attacker = info.InitiatorPlayer;
                if (attacker != null) {
                    if (victim == info.InitiatorPlayer) {
                        StripInventory(victim);
                        PrintToChat(msg("juggerSuicide"));
                    }
                    else if (!IsFriend(victim.userID, attacker.userID) && !IsClanmate(victim.userID, attacker.userID)) {
                        PrintToChat(msg("juggerDead"));
                        if (configData.Prizes.Amount > 0) {
                            if (configData.Prizes.Economics) Economics?.Call("Deposit", attacker.userID, (double)configData.Prizes.Amount);
                            if (configData.Prizes.ServerRewards) ServerRewards?.Call("AddPoints", attacker.userID, configData.Prizes.Amount);
                        }
                    }
                }
                else PrintToChat(msg("juggerDead"));
                UnlockInventory(victim);
                DestroyEvent();
            }
        }
        private object CanNetworkTo(BaseEntity entity, BasePlayer target) {
            if (entity == null || finalSphere == null || juggernaut == null || target == null) return null;
            if (finalSphere.Contains(entity)) {
                if (target != juggernaut) return false;
            }
            return null;
        }
        private object OnRunCommand(ConsoleSystem.Arg arg) {
            if (!hasStarted || arg.Connection == null || arg.Connection.player == null || arg.cmd.Name != "kill") return null;
            var player = arg.Connection.player as BasePlayer;
            if (player == null) return null;
            if (player == juggernaut) {
                SendReply(player, msg("noSuicide", player.UserIDString));
                return true;
            }
            return null;
        }
        private object OnPlayerCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player != null && juggernaut != null && player == juggernaut) {
                string text = arg.GetString(0, "text").ToLower();
                if (text.Length > 0 && text[0] == '/' && arg.cmd.FullName == "chat.say") {
                    if (configData.Game.CommandBlacklist.Any(entry => entry.StartsWith("/") ? text.StartsWith(entry) : text.Substring(1).StartsWith(entry))) {
                        SendReply(player, msg("blacklistcmd", player.UserIDString));
                        return false;
                    }
                }
            }
            return null;
        }
#endregion
#region Functions
        private void LockInventory(BasePlayer player) {
            if (!player.inventory.containerMain.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerMain.SetFlag(ItemContainer.Flag.IsLocked, true);
            if (!player.inventory.containerBelt.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerBelt.SetFlag(ItemContainer.Flag.IsLocked, true);
            if (!player.inventory.containerWear.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerWear.SetFlag(ItemContainer.Flag.IsLocked, true);
            player.inventory.SendSnapshot();
        }
        private void UnlockInventory(BasePlayer player) {
            if (player.inventory.containerMain.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerMain.SetFlag(ItemContainer.Flag.IsLocked, false);
            if (player.inventory.containerBelt.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerBelt.SetFlag(ItemContainer.Flag.IsLocked, false);
            if (player.inventory.containerWear.HasFlag(ItemContainer.Flag.IsLocked)) player.inventory.containerWear.SetFlag(ItemContainer.Flag.IsLocked, false);
            player.inventory.SendSnapshot();
        }
        private void StartEventTimer() {
            optedIn.Clear();
            UnsubscribeHooks();
            nextMatch = timer.Once(configData.Timers.Interval, CheckConditions);
            nextTrigger = GrabCurrentTime() + configData.Timers.Interval;
        }
        private void CheckConditions() {
            if (BasePlayer.activePlayerList.Count >= configData.Conditions.OpenMin) OpenEvent();
        }
        private void OpenEvent() {
            if (string.IsNullOrEmpty(juggernautIcon) && configData.UI.ShowUITimer && !string.IsNullOrEmpty(configData.UI.IconUrl)) Add(configData.UI.IconUrl);
            isOpen = true;
            startMatch = timer.Once(configData.Timers.Open, StartEvent);
            openMessage = timer.Repeat(45, 0, () => PrintToChat(msg("eventOpen")));
            nextTrigger = configData.Timers.Open + GrabCurrentTime();
            PrintToChat(msg("eventOpen"));
        }
        private void StartEvent() {
            isOpen = false;
            if (openMessage != null) openMessage.Destroy();
            if (optedIn.Count == 0) {
                PrintToChat(msg("noEntrants"));
                StartEventTimer();
                return;
            }
            var minEntrants = (int)Math.Round(BasePlayer.activePlayerList.Count * configData.Conditions.Percentage, 0);
            if (optedIn.Count < minEntrants) {
                PrintToChat(string.Format(msg("notEnoughEntrants"), $"{configData.Conditions.Percentage * 100}%"));
                StartEventTimer();
                return;
            }
            SubscribeHooks();
            var player = GetRandomPlayer();
            if (player == null) {
                StartEventTimer();
                return;
            }
            Destinations destinations = storedData.destinations.GetRandom();
            endPos = new Vector3(destinations.x2, destinations.y2, destinations.z2);
            restoreData.AddData(player);
            StripInventory(player);
            MovePosition(player, new Vector3(destinations.x1, destinations.y1, destinations.z1));
            PrepareJuggernaut(player);
            Subscribe(nameof(CanNetworkTo));
            CreateSphere();
            eventEnd = configData.Timers.Completion + GrabCurrentTime();
            nextTrigger = configData.Timers.Completion + GrabCurrentTime();
            hasStarted = true;
        }
        private BasePlayer GetRandomPlayer(int tries = 0) {
            if (tries > 4) return null;
            ulong playerId = optedIn.GetRandom();
            BasePlayer player = BasePlayer.activePlayerList.FirstOrDefault(x => x.userID == playerId);
            if (player == null || player.IsSleeping() || player.IsDead()) {
                optedIn.Remove(playerId);
                if (optedIn.Count == 0) return null;
                return GetRandomPlayer(++tries);
            }
            return player;
        }
        private void PrepareJuggernaut(BasePlayer player) {
            if (player.IsSleeping() || player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                timer.In(1, () => PrepareJuggernaut(player));
                return;
            }
            juggernaut = player;
            if (configData.Juggernaut.ResetMetabolism) {
                player.metabolism.Reset();
                player.health = player.MaxHealth();
                player.metabolism.hydration.value = player.metabolism.hydration.max;
                player.metabolism.calories.value = player.metabolism.calories.max;
                player.metabolism.SendChangesToClient();
            }
            GiveJuggernautGear();
            PrintToChat(string.Format(msg("eventStart"), $"X:{Math.Round(endPos.x, 1)}, Z:{Math.Round(endPos.z, 1)}"));
            SendReply(player, string.Format(msg("juggerStart", player.UserIDString), $"X:{Math.Round(endPos.x, 1)}, Z:{Math.Round(endPos.z, 1)}"));
            eventTimer = timer.In(configData.Timers.Completion, EventCancel);
            if (configData.UI.ShowUITimer) RefreshAllUI();
            if (configData.Lusty.Enabled) {
                if (configData.Lusty.DestinationAmount > 1 && storedData.destinations.Count >= configData.Lusty.DestinationAmount) {
                    List<Destinations> destinations = new List<Destinations>(storedData.destinations);
                    int randomNumber = UnityEngine.Random.Range(1, configData.Lusty.DestinationAmount);
                    for (int i = 0; i < configData.Lusty.DestinationAmount; i++) {
                        if (i == randomNumber) {
                            AddMapMarker(endPos.x, endPos.z, $"{msg("possibleDest")} {i + 1}");
                        }
                        else {
                            Destinations destination = destinations.GetRandom();
                            destinations.Remove(destination);
                            AddMapMarker(destination.x2, destination.z2, $"{msg("possibleDest")} {i + 1}");
                        }
                    }
                }
                else AddMapMarker(endPos.x, endPos.z, msg("destination"));
            }
            if (configData.Game.BroadcastEvery > 0) MapIconUpdater();
        }
        private void MapIconUpdater() {
            broadcastTimer = timer.Repeat(configData.Game.BroadcastEvery, 0, () => {
                if (juggernaut != null) {
                    if (configData.Game.BroadcastEveryLM) {
                        AddMapMarker(juggernaut.transform.position.x, juggernaut.transform.position.z, msg("juggernaut"));
                        timer.In(configData.Game.BroadcastLMSeconds, () => RemoveMapMarker(msg("juggernaut"), false));
                    }
                    else PrintToChat(string.Format(msg("positionBroadcast"), Math.Round(juggernaut.transform.position.x, 1), Math.Round(juggernaut.transform.position.z, 1)));
                }
            }
            );
        }
        private void EventCancel() {
            PrintToChat(msg("eventCancel"));
            TryRestorePlayer(juggernaut);
            DestroyEvent();
        }
        private void EventWin() {
            PrintToChat(msg("juggerWin"));
            if (configData.Prizes.Inventory) {
                var remainingItems = new List<RestoreData.ItemData>();
                remainingItems.AddRange(GetItems(juggernaut.inventory.containerBelt));
                remainingItems.AddRange(GetItems(juggernaut.inventory.containerMain));
                remainingItems.AddRange(GetItems(juggernaut.inventory.containerWear));
                if (!storedData.winnerRewards.ContainsKey(juggernaut.userID)) storedData.winnerRewards.Add(juggernaut.userID, remainingItems);
                else storedData.winnerRewards[juggernaut.userID] = remainingItems;
            }
            if (configData.Prizes.ServerRewards || configData.Prizes.Economics) {
                if (!storedData.winnerMoney.ContainsKey(juggernaut.userID)) storedData.winnerMoney.Add(juggernaut.userID, new List<Points>());
                storedData.winnerMoney[juggernaut.userID].Add(new Points {
                    isRp = configData.Prizes.ServerRewards, amount = configData.Prizes.Amount
                }
                );
            }
            TryRestorePlayer(juggernaut);
            DestroyEvent();
        }
        private void DestroyEvent() {
            hasStarted = false;
            if (eventTimer != null) eventTimer.Destroy();
            if (uiTimer != null) uiTimer.Destroy();
            if (broadcastTimer != null) broadcastTimer.Destroy();
            foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Main);
            CuiHelper.DestroyUi(juggernaut, Compass);
            juggernaut = null;
            if (finalSphere != null) {
                if (finalSphere[0].GetComponent<FinalSphere>()) UnityEngine.Object.Destroy(finalSphere[0].GetComponent<FinalSphere>());
                for (int i = 0; i < finalSphere.Length; i++) finalSphere[i].KillMessage();
            }
            Unsubscribe(nameof(CanNetworkTo));
            SaveData();
            RemoveMapMarker(msg("juggernaut"), false);
            RemoveMapMarker(msg("possibleDest"), true);
            RemoveMapMarker(msg("destination"), false);
            StartEventTimer();
        }
        private void TryRestorePlayer(BasePlayer player) {
            if (player == null) return;
            if (player.IsSleeping() || player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                timer.In(1, () => TryRestorePlayer(player));
                return;
            }
            UnlockInventory(player);
            if (restoreData.HasRestoreData(player.userID)) restoreData.RestorePlayer(player);
        }
        private void GiveJuggernautGear() {
            foreach (var entry in configData.Juggernaut.Inventory) {
                Item item = null;
                if (entry.IsBP) {
                    item = ItemManager.CreateByItemID(-1887162396, entry.Amount, entry.SkinID);
                    item.blueprintTarget = ItemManager.itemList.Find(x => x.shortname == entry.Shortname)?.itemid ?? 0;
                }
                else item = ItemManager.CreateByName(entry.Shortname, entry.Amount, entry.SkinID);
                if (item == null) PrintError($"Error creating item: {entry.Shortname}.Check this is a correct shortname!");
                else item.MoveToContainer(entry.Container == "wear" ? juggernaut.inventory.containerWear : entry.Container == "belt" ? juggernaut.inventory.containerBelt : juggernaut.inventory.containerMain);
            }
            LockInventory(juggernaut);
        }
        private void UnsubscribeHooks() {
            Unsubscribe(nameof(OnEntityTakeDamage));
            Unsubscribe(nameof(OnEntityDeath));
            Unsubscribe(nameof(CanNetworkTo));
        }
        private void SubscribeHooks() {
            Subscribe(nameof(OnEntityTakeDamage));
            Subscribe(nameof(OnEntityDeath));
            Subscribe(nameof(CanNetworkTo));
        }
        private double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private string GetGridString(Vector3 position) {
            Vector2 adjPosition = new Vector2((World.Size / 2) + position.x, (World.Size / 2) - position.z);
            return $"{NumberToString((int)(adjPosition.x / 145))}{((int)(adjPosition.y / 145)) - 1}";
        }
        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 Teleportation Management
        private void MovePosition(BasePlayer player, Vector3 destination) {
            if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "StartLoading");
            StartSleeping(player);
            player.MovePosition(destination);
            if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "ForcePositionTo", destination);
            if (player.net?.connection != null) player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
            player.UpdateNetworkGroup();
            player.SendNetworkUpdateImmediate(false);
            if (player.net?.connection == null) return;
            try {
                player.ClearEntityQueue(null);
            }
            catch {
            }
            player.SendFullSnapshot();
        }
        private void StartSleeping(BasePlayer player) {
            if (player.IsSleeping()) return;
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Sleeping, true);
            if (!BasePlayer.sleepingPlayerList.Contains(player)) BasePlayer.sleepingPlayerList.Add(player);
            player.CancelInvoke("InventoryUpdate");
        }
#endregion
#region Player Saving and Restoration
        public static void StripInventory(BasePlayer player) {
            Item[] allItems = player.inventory.AllItems();
            for (int i = allItems.Length - 1; i >= 0; i--) {
                Item item = allItems[i];
                item.RemoveFromContainer();
                item.Remove();
            }
        }
        private IEnumerable<RestoreData.ItemData> GetItems(ItemContainer container) {
            return container.itemList.Select(item => new RestoreData.ItemData {
                itemid = item.info.itemid, amount = item.amount, ammo = item.GetHeldEntity() is BaseProjectile ? (item.GetHeldEntity() as BaseProjectile).primaryMagazine.contents : item.GetHeldEntity() is FlameThrower ? (item.GetHeldEntity() as FlameThrower).ammo : 0, ammotype = (item.GetHeldEntity() as BaseProjectile)?.primaryMagazine.ammoType.shortname ?? null, position = item.position, skin = item.skin, condition = item.condition, maxCondition = item.maxCondition, instanceData = new RestoreData.ItemData.InstanceData(item), contents = item.contents?.itemList.Select(item1 => new RestoreData.ItemData {
                    itemid = item1.info.itemid, amount = item1.amount, condition = item1.condition
                }
                ).ToArray()
            }
            );
        }
        public class RestoreData {
            public Hash<ulong, PlayerData> restoreData = new Hash<ulong, PlayerData>();
            public void AddData(BasePlayer player) {
                restoreData[player.userID] = new PlayerData(player);
            }
            public void RemoveData(ulong playerId) {
                if (HasRestoreData(playerId)) restoreData.Remove(playerId);
            }
            public bool HasRestoreData(ulong playerId) => restoreData.ContainsKey(playerId);
            public void RestorePlayer(BasePlayer player) {
                if (isUnloading) {
                    player.Die();
                    player.ChatMessage("<color=#ce422b>The plugin has been unloaded!</color> We are unable to restore you at this time, when the plugin has been reloaded you will be restored to your previous state");
                    return;
                }
                PlayerData playerData;
                if (restoreData.TryGetValue(player.userID, out playerData)) {
                    StripInventory(player);
                    ins.UnlockInventory(player);
                    if (player.IsSleeping() || player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
                        ins.timer.Once(1, () => RestorePlayer(player));
                        return;
                    }
                    ins.NextTick(() => {
                        if (player == null || playerData == null) return;
                        playerData.SetStats(player);
                        ins.MovePosition(player, playerData.GetPosition());
                        RestoreAllItems(player, playerData);
                    }
                    );
                }
            }
            private void RestoreAllItems(BasePlayer player, PlayerData playerData) {
                if (player == null || !player.IsConnected) return;
                if (RestoreItems(player, playerData.containerBelt, "belt") && RestoreItems(player, playerData.containerWear, "wear") && RestoreItems(player, playerData.containerMain, "main")) RemoveData(player.userID);
            }
            private bool RestoreItems(BasePlayer player, ItemData[] itemData, string type) {
                ItemContainer container = type == "belt" ? player.inventory.containerBelt : type == "wear" ? player.inventory.containerWear : player.inventory.containerMain;
                for (int i = 0; i < itemData.Length; i++) {
                    Item item = CreateItem(itemData[i]);
                    item.position = itemData[i].position;
                    item.SetParent(container);
                }
                return true;
            }
            public Item CreateItem(ItemData itemData) {
                Item item = ItemManager.CreateByItemID(itemData.itemid, itemData.amount, itemData.skin);
                item.condition = itemData.condition;
                if (itemData.instanceData != null) itemData.instanceData.Restore(item);
                BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
                if (weapon != null) {
                    if (!string.IsNullOrEmpty(itemData.ammotype)) weapon.primaryMagazine.ammoType = ItemManager.FindItemDefinition(itemData.ammotype);
                    weapon.primaryMagazine.contents = itemData.ammo;
                }
                FlameThrower flameThrower = item.GetHeldEntity() as FlameThrower;
                if (flameThrower != null) flameThrower.ammo = itemData.ammo;
                if (itemData.contents != null) {
                    foreach (ItemData contentData in itemData.contents) {
                        Item newContent = ItemManager.CreateByItemID(contentData.itemid, contentData.amount);
                        if (newContent != null) {
                            newContent.condition = contentData.condition;
                            newContent.MoveToContainer(item.contents);
                        }
                    }
                }
                return item;
            }
            public class PlayerData {
                public float[] stats;
                public float[] position;
                public ItemData[] containerMain;
                public ItemData[] containerWear;
                public ItemData[] containerBelt;
                public PlayerData() {
                }
                public PlayerData(BasePlayer player) {
                    stats = GetStats(player);
                    position = GetPosition(player.transform.position);
                    containerBelt = ins.GetItems(player.inventory.containerBelt).ToArray();
                    containerMain = ins.GetItems(player.inventory.containerMain).ToArray();
                    containerWear = ins.GetItems(player.inventory.containerWear).ToArray();
                }
                private float[] GetStats(BasePlayer player) => new float[] {
                    player.health, player.metabolism.hydration.value, player.metabolism.calories.value
                }
                ;
                public void SetStats(BasePlayer player) {
                    player.health = stats[0];
                    player.metabolism.hydration.value = stats[1];
                    player.metabolism.calories.value = stats[2];
                    player.metabolism.SendChangesToClient();
                }
                private float[] GetPosition(Vector3 position) => new float[] {
                    position.x, position.y, position.z
                }
                ;
                public Vector3 GetPosition() => new Vector3(position[0], position[1], position[2]);
            }
            public class ItemData {
                public int itemid;
                public ulong skin;
                public int amount;
                public float condition;
                public float maxCondition;
                public int ammo;
                public string ammotype;
                public int position;
                public InstanceData instanceData;
                public ItemData[] contents;
                public class InstanceData {
                    public int dataInt;
                    public int blueprintTarget;
                    public int blueprintAmount;
                    public InstanceData() {
                    }
                    public InstanceData(Item item) {
                        if (item.instanceData == null) return;
                        dataInt = item.instanceData.dataInt;
                        blueprintAmount = item.instanceData.blueprintAmount;
                        blueprintTarget = item.instanceData.blueprintTarget;
                    }
                    public void Restore(Item item) {
                        item.instanceData = new ProtoBuf.Item.InstanceData();
                        item.instanceData.blueprintAmount = blueprintAmount;
                        item.instanceData.blueprintTarget = blueprintTarget;
                        item.instanceData.dataInt = dataInt;
                    }
                }
            }
        }
#endregion
#region Sphere Creation
        private void CreateSphere() {
            finalSphere = new SphereEntity[configData.Game.SphereDarkness];
            for (int i = 0; i < configData.Game.SphereDarkness; i++) {
                var sphere = (SphereEntity)GameManager.server.CreateEntity(sphereEnt, endPos, new Quaternion(), true);
                sphere.currentRadius = 5;
                sphere.lerpSpeed = 0;
                sphere.enableSaving = false;
                sphere.Spawn();
                finalSphere[i] = sphere;
            }
            finalSphere[0].gameObject.AddComponent<FinalSphere>();
        }
        class FinalSphere : MonoBehaviour {
            public BaseEntity entity;
            void Awake() {
                entity = GetComponent<BaseEntity>();
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = $"Juggernaut Final Zone";
                enabled = false;
                var collider = entity.gameObject.AddComponent<SphereCollider>();
                collider.isTrigger = true;
                collider.radius = 0.5f;
            }
            void OnDestroy() {
                if (!entity.IsDestroyed) entity.Kill();
            }
            void OnTriggerEnter(Collider obj) {
                if (obj.gameObject.layer == (int)Layer.Player_Server) {
                    var player = obj?.GetComponentInParent<BasePlayer>();
                    if (player != null) {
                        if (player == ins.juggernaut) {
                            ins.EventWin();
                        }
                    }
                }
            }
        }
#endregion
#region Hooks
#region Internal Checks
        private bool IsClanmate(ulong playerId, ulong friendId) {
            if (!Clans) return false;
            object playerTag = Clans?.Call("GetClanOf", playerId);
            object friendTag = Clans?.Call("GetClanOf", friendId);
            if (playerTag is string && friendTag is string) if (playerTag == friendTag) return true;
            return false;
        }
        private bool IsFriend(ulong playerID, ulong friendID) {
            if (!Friends) return false;
            return (bool)Friends?.Call("IsFriend", playerID, friendID);
        }
        private bool IsPlaying(BasePlayer player) {
            if (!EventManager) return false;
            return (bool)EventManager.Call("isPlaying", player);
        }
        private void JoinedEvent(BasePlayer player) {
            if (optedIn.Contains(player.userID)) optedIn.Remove(player.userID);
        }
        private void AddMapMarker(float x, float z, string markerName) => LustyMap?.Call("AddTemporaryMarker", x, z, markerName, configData.UI.IconUrl);
        private void RemoveMapMarker(string markerName, bool startsWith) {
            if (!startsWith) LustyMap?.Call("RemoveTemporaryMarker", markerName);
            else LustyMap?.Call("RemoveTemporaryMarkerStartsWith", markerName);
        }
#endregion
#region External Checks
        object CanTrade(BasePlayer player) {
            if (player == juggernaut) return msg("tryTrading", player.UserIDString);
            return null;
        }
        object canRemove(BasePlayer player) {
            if (player == juggernaut) return msg("tryRemove", player.UserIDString);
            return null;
        }
        object CanTeleport(BasePlayer player) {
            if (player == juggernaut) return msg("tryTP", player.UserIDString);
            return null;
        }
        object canShop(BasePlayer player) {
            if (player == juggernaut) return msg("tryShop", player.UserIDString);
            return null;
        }
#endregion
#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 = "JuggernautMain";
        private const string Compass = "JuggernautCompass";
        private void CreateTimerUI(BasePlayer player) {
            var MainCont = UI.CreateElementContainer(Main, UI.Color(configData.UI.UIBackgroundColor, configData.UI.UIOpacity), $"{configData.UI.TimerPosition.XPosition} {configData.UI.TimerPosition.YPosition}", $"{configData.UI.TimerPosition.XPosition + configData.UI.TimerPosition.XDimension} {configData.UI.TimerPosition.YPosition + configData.UI.TimerPosition.YDimension}");
            if (!string.IsNullOrEmpty(juggernautIcon)) UI.AddImage(ref MainCont, Main, juggernautIcon, "0.01 0.05", "0.425 0.95");
            UI.CreateLabel(ref MainCont, Main, "", GetFormatTime(eventEnd), 15, "0.5 0", "1 1", TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(player, Main);
            CuiHelper.AddUi(player, MainCont);
        }
        private string GetFormatTime(double timeLeft) {
            var time = timeLeft - 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)(eventEnd - GrabCurrentTime()) - 1, () => {
                foreach (var player in BasePlayer.activePlayerList) CreateTimerUI(player);
                if (configData.UI.ShowCoordsToJuggernaut) ShowCompass();
            }
            );
        }
        private void ShowCompass() {
            var MainCont = UI.CreateElementContainer(Compass, UI.Color(configData.UI.UIBackgroundColor, configData.UI.UIOpacity), $"{configData.UI.CompassPosition.XPosition} {configData.UI.CompassPosition.YPosition}", $"{configData.UI.CompassPosition.XPosition + configData.UI.CompassPosition.XDimension} {configData.UI.CompassPosition.YPosition + configData.UI.CompassPosition.YDimension}");
            UI.CreateLabel(ref MainCont, Compass, "", string.Format(msg("target1", juggernaut.UserIDString), GetGridString(endPos)), 10, "0.05 0.5", "0.95 0.95", TextAnchor.MiddleLeft);
            UI.CreateLabel(ref MainCont, Compass, "", string.Format(msg("target2", juggernaut.UserIDString), Math.Round(Vector3.Distance(juggernaut.transform.position, endPos), 2)), 10, "0.05 0.05", "0.95 0.5", TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(juggernaut, Compass);
            CuiHelper.AddUi(juggernaut, MainCont);
        }
#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 Juggernaut icon! Error: {0}", info.error));
                return;
            }
            else juggernautIcon = FileStorage.server.Store(info.bytes, FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
        }
#endregion
#region Commands
        [ChatCommand("jug")]
        void cmdJuggernaut(BasePlayer player, string command, string[] args) {
            if (args.Length == 0) {
                SendReply(player, $"<color=#ce422b>{Title}</color><color=#939393>  v{Version}  -</color> <color=#ce422b>{Author} @ www.chaoscode.io</color>");
                SendReply(player, msg("help0", player.UserIDString));
                SendReply(player, msg("help1", player.UserIDString));
                SendReply(player, msg("help2", player.UserIDString));
                SendReply(player, msg("help3", player.UserIDString));
                SendReply(player, msg("help4", player.UserIDString));
                if (player.IsAdmin) {
                    SendReply(player, msg("help5", player.UserIDString));
                    SendReply(player, msg("help6", player.UserIDString));
                    SendReply(player, msg("help7", player.UserIDString));
                    SendReply(player, msg("help8", player.UserIDString));
                }
                return;
            }
            switch (args[0].ToLower()) {
                case "info" : string time = GetFormatTime(nextTrigger);
                if (hasStarted) SendReply(player, string.Format(msg("endsIn", player.UserIDString), time));
                else if (isOpen) SendReply(player, string.Format(msg("startsIn", player.UserIDString), time));
                else SendReply(player, string.Format(msg("nextEvent", player.UserIDString), time));
                return;
                case "join" : if (!permission.UserHasPermission(player.UserIDString, "juggernaut.canbe")) {
                    SendReply(player, msg("noPerms", player.UserIDString));
                    return;
                }
                if (!isOpen) {
                    SendReply(player, msg("notOpen", player.UserIDString));
                    return;
                }
                if (IsPlaying(player)) {
                    SendReply(player, msg("playingEM", player.UserIDString));
                    return;
                }
                if (!optedIn.Contains(player.userID)) {
                    optedIn.Add(player.userID);
                    SendReply(player, msg("enteredDraw", player.UserIDString));
                    PrintToChat(string.Format(msg("candidate"), player.displayName, optedIn.Count));
                }
                return;
                case "leave" : if (!isOpen) {
                    SendReply(player, msg("notOpen", player.UserIDString));
                    return;
                }
                if (optedIn.Contains(player.userID)) optedIn.Remove(player.userID);
                SendReply(player, msg("removedDraw", player.UserIDString));
                return;
                case "claim" : if (storedData.winnerRewards.ContainsKey(player.userID)) {
                    foreach(var prize in storedData.winnerRewards[player.userID]) {
                        Item item = restoreData.CreateItem(prize);
                        if (item != null) player.GiveItem(item, BaseEntity.GiveItemReason.Generic);
                    }
                    SendReply(player, msg("claimSuccess", player.UserIDString));
                    storedData.winnerRewards.Remove(player.userID);
                    SaveData();
                }
                else if (storedData.winnerMoney.ContainsKey(player.userID)) {
                    foreach(var prize in storedData.winnerMoney[player.userID]) {
                        if (prize.isRp) ServerRewards?.Call("AddPoints", player.userID, prize.amount);
                        else Economics?.Call("Deposit", player.userID, (double)prize.amount);
                    }
                    SendReply(player, msg("claimSuccess", player.UserIDString));
                    storedData.winnerMoney.Remove(player.userID);
                    SaveData();
                }
                else SendReply(player, msg("noPrizes", player.UserIDString));
                return;
                case "restore" : if (player == juggernaut) {
                    SendReply(player, msg("cantRestore", player.UserIDString));
                    return;
                }
                if (restoreData.HasRestoreData(player.userID)) {
                    TryRestorePlayer(player);
                    return;
                }
                else SendReply(player, msg("noRestoreData", player.UserIDString));
                return;
                case "open" : if (player.IsAdmin) {
                    if (isOpen) {
                        SendReply(player, msg("alreadyOpen", player.UserIDString));
                        return;
                    }
                    if (!hasDestinations) {
                        SendReply(player, msg("noDestinations", player.UserIDString));
                        return;
                    }
                    if (hasStarted) {
                        SendReply(player, msg("alreadyStarted", player.UserIDString));
                        return;
                    }
                    if (nextMatch != null) nextMatch.Destroy();
                    OpenEvent();
                }
                return;
                case "start" : if (player.IsAdmin) {
                    if (!isOpen) {
                        SendReply(player, msg("isntOpen", player.UserIDString));
                        return;
                    }
                    if (hasStarted) {
                        SendReply(player, msg("alreadyStarted", player.UserIDString));
                        return;
                    }
                    if (startMatch != null) startMatch.Destroy();
                    if (openMessage != null) openMessage.Destroy();
                    StartEvent();
                }
                return;
                case "cancel" : if (player.IsAdmin) {
                    if (!isOpen && !hasStarted) {
                        SendReply(player, msg("notStarted", player.UserIDString));
                        return;
                    }
                    if (isOpen) {
                        if (startMatch != null) startMatch.Destroy();
                        if (openMessage != null) openMessage.Destroy();
                        isOpen = false;
                        PrintToChat(msg("adminCancel"));
                        StartEventTimer();
                        return;
                    }
                    if (hasStarted) {
                        PrintToChat(msg("adminCancel"));
                        TryRestorePlayer(juggernaut);
                        DestroyEvent();
                        return;
                    }
                }
                return;
                case "destination" : if (player.IsAdmin) {
                    if (!destinationCreator.ContainsKey(player.userID)) {
                        destinationCreator.Add(player
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху