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

FREE Kits : 4.0.12 4.0.12

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using Oxide.Plugins;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Kits", "k1lly0u", "4.0.12"), Description("Create kits containing items that players can redeem")]
    class Kits : RustPlugin
    {
        #region Fields
        [PluginReference]
        private Plugin CopyPaste, ImageLibrary, ServerRewards, Economics;

        private DateTime _deprecatedHookTime = new DateTime(2021, 12, 31);

        private Hash<ulong, KitData.Kit> _kitCreators = new Hash<ulong, KitData.Kit>();

        private const string ADMIN_PERMISSION = "kits.admin";

        private const string BLUEPRINT_BASE = "blueprintbase";
        #endregion

        #region Oxide Hooks
        private void Loaded()
        {
            LoadData();

            permission.RegisterPermission(ADMIN_PERMISSION, this);
            kitData.RegisterPermissions(permission, this);

            _costType = ParseType<CostType>(Configuration.Currency);

            cmd.AddChatCommand(Configuration.Command, this, cmdKit);
            cmd.AddConsoleCommand(Configuration.Command, this, "ccmdKit");
        }

        protected override void LoadDefaultMessages() => lang.RegisterMessages(Messages, this);

        private void OnServerInitialized()
        {
            kitData.RegisterImages(ImageLibrary);

            if (Configuration.AutoKits.Count == 0)
                Unsubscribe(nameof(OnPlayerRespawned));
        }

        private void OnNewSave(string filename)
        {
            if (Configuration.WipeData)
                playerData.Wipe();
        }

        private void OnServerSave() => SavePlayerData();

        private void OnPlayerRespawned(BasePlayer player)
        {
            if (player == null)
                return;

            if ((Interface.Oxide.CallDeprecatedHook("canRedeemKit", "CanRedeemKit", _deprecatedHookTime, player) ?? Interface.Oxide.CallHook("CanRedeemKit", player)) != null)
                return;

            if (Configuration.AllowAutoToggle && !playerData[player.userID].ClaimAutoKits)
            {
                player.ChatMessage(Message("Error.AutoKitDisabled", player.userID));
                return;
            }

            for (int i = 0; i < Configuration.AutoKits.Count; i++)
            {
                KitData.Kit kit;
                if (!kitData.Find(Configuration.AutoKits[i], out kit))
                    continue;

                object success = CanClaimKit(player, kit, true);
                if (success != null)
                    continue;

                player.inventory.Strip();

                success = GiveKit(player, kit);
                if (success is string)
                    continue;

                OnKitReceived(player, kit);
                return;
            }
        }

        private object OnServerCommand(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Player();
            if (player == null)
                return null;

            if (_kitCreators.ContainsKey(player.userID) && !arg.cmd.FullName.StartsWith("kits."))
                return false;

            return null;
        }

        private object OnPlayerCommand(BasePlayer player, string s, string[] args) => _kitCreators.ContainsKey(player.userID) ? (object)false : null;

        private void Unload()
        {
            if (!Interface.Oxide.IsShuttingDown)
                SavePlayerData();

            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, UI_MENU);
                CuiHelper.DestroyUi(player, UI_POPUP);
            }

            Configuration = null;
        }
        #endregion

        #region Kit Claiming
        private bool TryClaimKit(BasePlayer player, string name, bool usingUI)
        {
            if (string.IsNullOrEmpty(name))
            {
                if (usingUI)
                    CreateMenuPopup(player, Message("Error.EmptyKitName", player.userID));
                else player.ChatMessage(Message("Error.EmptyKitName", player.userID));
                return false;
            }

            KitData.Kit kit;
            if (!kitData.Find(name, out kit))
            {
                if (usingUI)
                    CreateMenuPopup(player, Message("Error.InvalidKitName", player.userID));
                else player.ChatMessage(Message("Error.InvalidKitName", player.userID));
                return false;
            }

            object success = CanClaimKit(player, kit) ?? GiveKit(player, kit);
            if (success is string)
            {
                if (usingUI)
                    CreateMenuPopup(player, (string)success);
                else player.ChatMessage((string)success);
                return false;
            }

            OnKitReceived(player, kit);
            return true;
        }

        private object CanClaimKit(BasePlayer player, KitData.Kit kit, bool ignoreAuthCost = false)
        {
            object success = Interface.Oxide.CallDeprecatedHook("canRedeemKit", "CanRedeemKit", _deprecatedHookTime, player) ?? Interface.Oxide.CallHook("CanRedeemKit", player);
            if (success != null)
            {
                if (success is string)
                    return (string)success;
                return Message("Error.CantClaimNow", player.userID);
            }

            if (!ignoreAuthCost && kit.RequiredAuth > 0 && player.net.connection.authLevel < kit.RequiredAuth)
                return Message("Error.CanClaim.Auth", player.userID);

            if (Configuration.AdminIgnoreRestrictions && IsAdmin(player))
            {
                if (!kit.HasSpaceForItems(player))
                    return Message("Error.CanClaim.InventorySpace", player.userID);

                return null;
            }
            
            if (!string.IsNullOrEmpty(kit.RequiredPermission) && !permission.UserHasPermission(player.UserIDString, kit.RequiredPermission))
                return Message("Error.CanClaim.Permission", player.userID);

            int wipeCooldownTime;
            if (Configuration.WipeCooldowns.TryGetValue(kit.Name, out wipeCooldownTime))
            {
                if (kitData.IsOnWipeCooldown(wipeCooldownTime, out wipeCooldownTime))
                    return string.Format(Message("Error.CanClaim.WipeCooldown", player.userID), FormatTime(wipeCooldownTime));
            }

            PlayerData.PlayerUsageData playerUsageData;
            if (playerData.Find(player.userID, out playerUsageData))
            {
                if (kit.Cooldown > 0)
                {
                    double cooldownRemaining = playerUsageData.GetCooldownRemaining(kit.Name);
                    if (cooldownRemaining > 0)
                        return string.Format(Message("Error.CanClaim.Cooldown", player.userID), FormatTime(cooldownRemaining));
                }

                if (kit.MaximumUses > 0)
                {
                    int currentUses = playerUsageData.GetKitUses(kit.Name);
                    if (currentUses >= kit.MaximumUses)
                        return Message("Error.CanClaim.MaxUses", player.userID);
                }
            }

            if (!kit.HasSpaceForItems(player))
                return Message("Error.CanClaim.InventorySpace", player.userID);

            if (!ignoreAuthCost && kit.Cost > 0)
            {
                if (!ChargePlayer(player, kit.Cost))
                    return string.Format(Message("Error.CanClaim.InsufficientFunds", player.userID), kit.Cost, Message($"Cost.{_costType}", player.userID));
            }

            return null;
        }

        private object GiveKit(BasePlayer player, KitData.Kit kit)
        {
            if (!string.IsNullOrEmpty(kit.CopyPasteFile))
            {
                object success = CopyPaste?.CallHook("TryPasteFromSteamId", player.userID, kit.CopyPasteFile, Configuration.CopyPasteParams, null);
                if (success != null)
                    return success;
            }

            kit.GiveItemsTo(player);

            return true;
        }

        private void OnKitReceived(BasePlayer player, KitData.Kit kit)
        {
            playerData[player.userID].OnKitClaimed(kit);

            Interface.CallHook("OnKitRedeemed", player, kit.Name);

            if (Configuration.LogKitsGiven)
                LogToFile("Kits_Received", $"{player.displayName} ({player.userID}) - Received {kit.Name}", this);
        }
        #endregion

        #region Purchase Costs     
        private CostType _costType;

        private enum CostType { Scrap, ServerRewards, Economics }

        private const int SCRAP_ITEM_ID = -932201673;

        private bool ChargePlayer(BasePlayer player, int amount)
        {
            if (amount == 0)
                return true;

            switch (_costType)
            {
                case CostType.Scrap:
                    if (amount <= player.inventory.GetAmount(SCRAP_ITEM_ID))
                    {
                        player.inventory.Take(null, SCRAP_ITEM_ID, amount);
                        return true;
                    }
                    return false;
                case CostType.ServerRewards:
                    return (bool)ServerRewards?.Call("TakePoints", player.userID, amount);
                case CostType.Economics:
                    return (bool)Economics?.Call("Withdraw", player.UserIDString, (double)amount);
            }
            return false;
        }
        #endregion

        #region Helpers
        private T ParseType<T>(string type)
        {
            try
            {
                return (T)Enum.Parse(typeof(T), type, true);
            }
            catch
            {
                return default(T);
            }
        }

        private string FormatTime(double time)
        {
            TimeSpan dateDifference = TimeSpan.FromSeconds(time);
            int days = dateDifference.Days;
            int hours = dateDifference.Hours;
            int mins = dateDifference.Minutes;
            int secs = dateDifference.Seconds;

            if (days > 0)
                return string.Format("~{0:00}d:{1:00}h", days, hours);
            else if (hours > 0)
                return string.Format("~{0:00}h:{1:00}m", hours, mins, secs);
            else if (mins > 0)
                return string.Format("{0:00}m:{1:00}s", mins, secs);
            else return string.Format("{0}s", secs);
        }

        private void GetUserValidKits(BasePlayer player, List<KitData.Kit> list, ulong npcId = 0UL)
        {
            bool isAdmin = IsAdmin(player);
            bool viewPermissionKits = Configuration.ShowPermissionKits;

            if (npcId != 0UL)
            {
                ConfigData.NPCKit npcKit;
                if (Configuration.NPCKitMenu.TryGetValue(npcId, out npcKit))
                {
                    npcKit.Kits.ForEach((string kitName) =>
                    {
                        KitData.Kit kit;
                        if (kitData.Find(kitName, out kit))
                        {
                            if (!viewPermissionKits && !string.IsNullOrEmpty(kit.RequiredPermission) && !permission.UserHasPermission(player.UserIDString, kit.RequiredPermission) && !isAdmin)
                                return;

                            if (player.net.connection.authLevel < kit.RequiredAuth)
                                return;

                            list.Add(kit);
                        }
                    });
                }
            }
            else
            {
                kitData.ForEach((KitData.Kit kit) =>
                {
                    if (kit.IsHidden && !isAdmin)
                        return;

                    if (!viewPermissionKits && !string.IsNullOrEmpty(kit.RequiredPermission) && !permission.UserHasPermission(player.UserIDString, kit.RequiredPermission) && !isAdmin)
                        return;

                    if (player.net.connection.authLevel < kit.RequiredAuth)
                        return;

                    list.Add(kit);
                });
            }
        }

        private bool IsAdmin(BasePlayer player) => permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION);

        private BasePlayer FindPlayer(string partialNameOrID) => BasePlayer.allPlayerList.FirstOrDefault<BasePlayer>((BasePlayer x) => x.UserIDString.Equals(partialNameOrID) ||            
                                                                                                    x.displayName.Equals(partialNameOrID, StringComparison.OrdinalIgnoreCase) ||
                                                                                                    x.displayName.Contains(partialNameOrID, CompareOptions.OrdinalIgnoreCase));

        private BasePlayer RaycastPlayer(BasePlayer player)
        {
            RaycastHit raycastHit;
            if (!Physics.Raycast(new Ray(player.eyes.position, Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward), out raycastHit, 5f))
                return null;

            return raycastHit.collider.GetComponentInParent<BasePlayer>();            
        }

        private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0);

        private static double CurrentTime => DateTime.UtcNow.Subtract(Epoch).TotalSeconds;

        private static double LastWipeTime => SaveRestore.SaveCreatedTime.Subtract(Epoch).TotalSeconds;
        #endregion

        #region ImageLibrary        
        private void RegisterImage(string name, string url) => ImageLibrary?.Call("AddImage", url, name.Replace(" ", ""), 0UL, null);

        private string GetImage(string name, ulong skinId = 0UL) => ImageLibrary?.Call<string>("GetImage", name.Replace(" ", ""), skinId, false);
        #endregion

        #region HumanNPC
        private void OnUseNPC(BasePlayer npcPlayer, BasePlayer player)
        {
            if (Configuration.NPCKitMenu.ContainsKey(npcPlayer.userID))            
                OpenKitGrid(player, 0, npcPlayer.userID);            
        }
        #endregion

        #region Deprecated API 
        [HookMethod("isKit")]
        public bool isKit(string name) => IsKit(name);

        [HookMethod("GetAllKits")]
        public string[] GetAllKits() => kitData.Keys.ToArray();

        [HookMethod("KitImage")]
        public string KitImage(string name) => GetKitImage(name);

        [HookMethod("KitDescription")]
        public string KitDescription(string name) => GetKitDescription(name);

        [HookMethod("KitMax")]
        public int KitMax(string name) => GetKitMaxUses(name);

        [HookMethod("KitCooldown")]
        public double KitCooldown(string name) => (double)GetKitCooldown(name);

        [HookMethod("PlayerKitMax")]
        public int PlayerKitMax(ulong playerId, string name) => GetPlayerKitUses(playerId, name);

        [HookMethod("PlayerKitCooldown")]
        public double PlayerKitCooldown(ulong playerId, string name) => GetPlayerKitCooldown(playerId, name);

        [HookMethod("GetKitContents")]
        public string[] GetKitContents(string name)
        {
            KitData.Kit kit;
            if (kitData.Find(name, out kit))
            {
                List<string> items = Facepunch.Pool.GetList<string>();
                for (int i1 = 0; i1 < kit.BeltItems.Length; i1++)
                {
                    ItemData itemData = kit.BeltItems[i1];
                    string itemstring = $"{itemData.ItemID}_{itemData.Amount}";

                    for (int i2 = 0; i2 < itemData.Contents?.Length; i2++)
                        itemstring = itemstring + $"_{itemData.Contents[i2].ItemID}";

                    items.Add(itemstring);
                }

                for (int i1 = 0; i1 < kit.WearItems.Length; i1++)
                {
                    ItemData itemData = kit.WearItems[i1];
                    string itemstring = $"{itemData.ItemID}_{itemData.Amount}";

                    for (int i2 = 0; i2 < itemData.Contents?.Length; i2++)
                        itemstring = itemstring + $"_{itemData.Contents[i2].ItemID}";

                    items.Add(itemstring);
                }

                for (int i1 = 0; i1 < kit.MainItems.Length; i1++)
                {
                    ItemData itemData = kit.MainItems[i1];
                    string itemstring = $"{itemData.ItemID}_{itemData.Amount}";

                    for (int i2 = 0; i2 < itemData.Contents?.Length; i2++)
                        itemstring = itemstring + $"_{itemData.Contents[i2].ItemID}";

                    items.Add(itemstring);
                }

                string[] array = items.ToArray();
                Facepunch.Pool.FreeList(ref items);

                return array;
            }

            return null;
        }

        [HookMethod("GetKitInfo")]
        public object GetKitInfo(string name)
        {
            KitData.Kit kit;
            if (kitData.Find(name, out kit))
            {
                JObject obj = new JObject
                {
                    ["name"] = kit.Name,
                    ["permission"] = kit.RequiredPermission,
                    ["max"] = kit.MaximumUses,
                    ["image"] = kit.KitImage,
                    ["hide"] = kit.IsHidden,
                    ["description"] = kit.Description,
                    ["cooldown"] = kit.Cooldown,
                    ["building"] = kit.CopyPasteFile,
                    ["authlevel"] = kit.RequiredAuth
                };

                JArray array = new JArray();
                GetItemObject_Old(ref array, kit.BeltItems, "belt");
                GetItemObject_Old(ref array, kit.MainItems, "main");
                GetItemObject_Old(ref array, kit.WearItems, "wear");

                obj["items"] = array;
                return obj;
            }

            return null;
        }

        private void GetItemObject_Old(ref JArray array, ItemData[] items, string container)
        {
            for (int i = 0; i < items.Length; i++)
            {
                ItemData itemData = items[i];
                JObject item = new JObject
                {
                    ["amount"] = itemData.Amount,
                    ["container"] = container,
                    ["itemid"] = itemData.ItemID,
                    ["skinid"] = itemData.Skin,
                    ["weapon"] = !string.IsNullOrEmpty(itemData.Ammotype),
                    ["blueprint"] = itemData.BlueprintItemID
                };

                item["mods"] = new JArray();
                for (int i1 = 0; i1 < itemData.Contents?.Length; i1++)
                    (item["mods"] as JArray).Add(itemData.Contents[i1].ItemID);

                array.Add(item);
            }
        }
        #endregion

        #region API
        [HookMethod("GiveKit")]
        public object GiveKit(BasePlayer player, string name)
        {
            if (player == null)
                return null;

            if (string.IsNullOrEmpty(name))
                return Message("Error.EmptyKitName", player.userID);

            KitData.Kit kit;
            if (!kitData.Find(name, out kit))
                return Message("Error.InvalidKitName", player.userID);

            return GiveKit(player, kit);
        }

        [HookMethod("IsKit")]
        public bool IsKit(string name) => !string.IsNullOrEmpty(name) ? kitData.Exists(name) : false;

        [HookMethod("GetKitNames")]
        public void GetKitNames(List<string> list) => list.AddRange(kitData.Keys);

        [HookMethod("GetKitImage")]
        public string GetKitImage(string name) => kitData[name]?.KitImage ?? string.Empty;

        [HookMethod("GetKitDescription")]
        public string GetKitDescription(string name) => kitData[name]?.Description ?? string.Empty;

        [HookMethod("GetKitMaxUses")]
        public int GetKitMaxUses(string name) => kitData[name]?.MaximumUses ?? 0;

        [HookMethod("GetKitCooldown")]
        public int GetKitCooldown(string name) => kitData[name]?.Cooldown ?? 0;

        [HookMethod("GetPlayerKitUses")]
        public int GetPlayerKitUses(ulong playerId, string name) => playerData.Exists(playerId) ? playerData[playerId].GetKitUses(name) : 0;

        [HookMethod("GetPlayerKitCooldown")]
        public double GetPlayerKitCooldown(ulong playerId, string name) => playerData.Exists(playerId) ? playerData[playerId].GetCooldownRemaining(name) : 0; 

        [HookMethod("GetKitObject")]
        public JObject GetKitObject(string name)
        {
            KitData.Kit kit;
            if (!kitData.Find(name, out kit))
                return null;

            return kit.ToJObject;
        }
        #endregion

        #region UI
        private const string UI_MENU = "kits.menu";
        private const string UI_POPUP = "kits.popup";

        private const string DEFAULT_ICON = "kits.defaultkiticon";
        private const string MAGNIFY_ICON = "kits.magnifyicon";

        #region Kit Grid View
        private void OpenKitGrid(BasePlayer player, int page = 0, ulong npcId = 0UL)
        {
            CuiElementContainer container = UI.BlurContainer(UI_MENU, new UI4(0.2f, 0.15f, 0.8f, 0.85f));

            UI.Panel(container, UI_MENU, Configuration.Menu.Panel.Get, new UI4(0.005f, 0.93f, 0.995f, 0.99f));

            UI.Label(container, UI_MENU, Message("UI.Title", player.userID), 20, new UI4(0.015f, 0.93f, 0.99f, 0.99f), TextAnchor.MiddleLeft);

            UI.Button(container, UI_MENU, Configuration.Menu.Color3.Get, "<b>×</b>", 20, new UI4(0.9575f, 0.9375f, 0.99f, 0.9825f), "kits.close");

            if (IsAdmin(player) && npcId == 0UL)            
                UI.Button(container, UI_MENU, Configuration.Menu.Color2.Get, Message("UI.CreateNew", player.userID), 14, new UI4(0.85f, 0.9375f, 0.9525f, 0.9825f), "kits.create");
            
            CreateGridView(player, container, page, npcId);

            CuiHelper.DestroyUi(player, UI_MENU);
            CuiHelper.AddUi(player, container);
        }

        private void CreateGridView(BasePlayer player, CuiElementContainer container, int page = 0, ulong npcId = 0UL)
        {
            List<KitData.Kit> list = Facepunch.Pool.GetList<KitData.Kit>();

            GetUserValidKits(player, list, npcId);

            if (list.Count == 0)
            {
                UI.Label(container, UI_MENU, Message("UI.NoKitsAvailable", player.userID), 14, new UI4(0.015f, 0.88f, 0.99f, 0.92f), TextAnchor.MiddleLeft);
                return;
            }

            PlayerData.PlayerUsageData playerUsageData = playerData[player.userID];

            int max = Mathf.Min(list.Count, (page + 1) * 8);
            int count = 0;
            for (int i = page * 8; i < max; i++)                
            {
                CreateKitEntry(player, playerUsageData, container, list[i], count, page, npcId);                
                count += 1;
            }

            if (page > 0)
                UI.Button(container, UI_MENU, Configuration.Menu.Color1.Get, "◀\n\n◀\n\n◀", 16, new UI4(0.005f, 0.35f, 0.03f, 0.58f), $"kits.gridview page {page - 1} {npcId}");
            if (max < list.Count)
                UI.Button(container, UI_MENU, Configuration.Menu.Color1.Get, "▶\n\n▶\n\n▶", 16, new UI4(0.97f, 0.35f, 0.995f, 0.58f), $"kits.gridview page {page + 1} {npcId}");

            Facepunch.Pool.FreeList(ref list);
        }

        private void CreateKitEntry(BasePlayer player, PlayerData.PlayerUsageData playerUsageData, CuiElementContainer container, KitData.Kit kit, int index, int page, ulong npcId)
        {            
            UI4 position = KitAlign.Get(index);

            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(position.xMin, position.yMax, position.xMax, position.yMax + 0.04f));
            UI.Label(container, UI_MENU, kit.Name, 14, new UI4(position.xMin, position.yMax, position.xMax, position.yMax + 0.04f));

            UI.Panel(container, UI_MENU, Configuration.Menu.Panel.Get, position);

            string imageId = string.IsNullOrEmpty(kit.KitImage) ? GetImage(DEFAULT_ICON) : GetImage(kit.Name);
            UI.Image(container, UI_MENU, imageId, new UI4(position.xMin + 0.005f, position.yMax - 0.3f, position.xMax - 0.005f, position.yMax - 0.0075f));
            
            UI.Button(container, UI_MENU, "0 0 0 0", string.Empty, 0, new UI4(position.xMin + 0.005f, position.yMax - 0.3f, position.xMax - 0.005f, position.yMax - 0.0075f), $"kits.gridview inspect {CommandSafe(kit.Name)} {page} {npcId}");

            string buttonText;
            string buttonCommand = string.Empty;
            string buttonColor;

            double cooldown = playerUsageData.GetCooldownRemaining(kit.Name);
            int currentUses = playerUsageData.GetKitUses(kit.Name);

            if (Configuration.AdminIgnoreRestrictions && IsAdmin(player))
            {
                buttonText = Message("UI.Redeem", player.userID);
                buttonColor = Configuration.Menu.Color2.Get;
                buttonCommand = $"kits.gridview redeem {CommandSafe(kit.Name)} {page} {npcId}";
            }
            else
            {
                if (!string.IsNullOrEmpty(kit.RequiredPermission) && !permission.UserHasPermission(player.UserIDString, kit.RequiredPermission))
                {
                    buttonText = Message("UI.NeedsPermission", player.userID);
                    buttonColor = Configuration.Menu.Disabled.Get;
                }
                else if (kit.Cooldown > 0 && cooldown > 0)
                {
                    UI.Label(container, UI_MENU, string.Format(Message("UI.Cooldown", player.userID), FormatTime(cooldown)), 12,
                        new UI4(position.xMin + 0.005f, position.yMin + 0.0475f, position.xMax - 0.005f, position.yMax - 0.3f), TextAnchor.MiddleLeft);

                    buttonText = Message("UI.OnCooldown", player.userID);
                    buttonColor = Configuration.Menu.Disabled.Get;
                }
                else if (kit.MaximumUses > 0 && currentUses >= kit.MaximumUses)
                {
                    buttonText = Message("UI.MaximumUses", player.userID);
                    buttonColor = Configuration.Menu.Disabled.Get;
                }
                else if (kit.Cost > 0)
                {
                    UI.Label(container, UI_MENU, string.Format(Message("UI.Cost", player.userID), kit.Cost, Message($"Cost.{_costType}", player.userID)), 12,
                        new UI4(position.xMin + 0.005f, position.yMin + 0.0475f, position.xMax - 0.005f, position.yMax - 0.3f), TextAnchor.MiddleLeft);

                    buttonText = Message("UI.Purchase", player.userID);
                    buttonColor = Configuration.Menu.Color2.Get;
                    buttonCommand = $"kits.gridview redeem {CommandSafe(kit.Name)} {page} {npcId}";
                }
                else
                {
                    buttonText = Message("UI.Redeem", player.userID);
                    buttonColor = Configuration.Menu.Color2.Get;
                    buttonCommand = $"kits.gridview redeem {CommandSafe(kit.Name)} {page} {npcId}";
                }
            }

            UI.Button(container, UI_MENU, buttonColor, buttonText, 14, 
                new UI4(position.xMin + 0.038f, position.yMin + 0.0075f, position.xMax - 0.005f, position.yMin + 0.0475f), buttonCommand);

            UI.ImageButton(container, UI_MENU, ICON_BACKGROUND_COLOR, GetImage(MAGNIFY_ICON), 
                new UI4(position.xMin + 0.005f, position.yMin + 0.0075f, position.xMin + 0.033f, position.yMin + 0.0475f), $"kits.gridview inspect {CommandSafe(kit.Name)} {page} {npcId}");
        }
        #endregion

        #region Kit View       
        private void OpenKitView(BasePlayer player, string name, int page, ulong npcId)
        {
            KitData.Kit kit;
            if (!kitData.Find(name, out kit))
            {
                OpenKitGrid(player);
                return;
            }

            CuiElementContainer container = UI.BlurContainer(UI_MENU, new UI4(0.2f, 0.15f, 0.8f, 0.85f));

            UI.Panel(container, UI_MENU, Configuration.Menu.Panel.Get, new UI4(0.005f, 0.93f, 0.995f, 0.99f));

            UI.Label(container, UI_MENU, $"{Message("UI.Title", player.userID)} - {name}", 20, new UI4(0.015f, 0.93f, 0.99f, 0.99f), TextAnchor.MiddleLeft);

            UI.Button(container, UI_MENU, Configuration.Menu.Color3.Get, "<b>×</b>", 20, new UI4(0.9575f, 0.9375f, 0.99f, 0.9825f), $"kits.gridview page 0 {npcId}");

            bool isAdmin;
            if (isAdmin = IsAdmin(player))
            {
                UI.Button(container, UI_MENU, Configuration.Menu.Color2.Get, Message("UI.EditKit", player.userID), 14, new UI4(0.7525f, 0.9375f, 0.845f, 0.9825f), $"kits.edit {CommandSafe(name)}");
                UI.Button(container, UI_MENU, Configuration.Menu.Color2.Get, Message("UI.CreateNew", player.userID), 14, new UI4(0.85f, 0.9375f, 0.9525f, 0.9825f), "kits.create");
            }

            PlayerData.PlayerUsageData playerUsageData = playerData[player.userID];

            int i = -1;

            if (!string.IsNullOrEmpty(kit.KitImage))
            {
                UI.Image(container, UI_MENU, GetImage(kit.Name), new UI4(0.15f, 0.62f, 0.35f, 0.92f));
                i = 6;
            }

            AddTitleSperator(container, i += 1, Message("UI.Details", player.userID));
            AddLabelField(container, i += 1, Message("UI.Name", player.userID), kit.Name);

            if (!string.IsNullOrEmpty(kit.Description)) 
            {
                int descriptionSlots = Mathf.Min(Mathf.CeilToInt(((float)kit.Description.Length / 38f) / 1.25f), 4);
                AddLabelField(container, i += 1, Message("UI.Description", player.userID), kit.Description, descriptionSlots - 1);
                i += descriptionSlots - 1;
            }

            string buttonText = string.Empty;
            string buttonCommand = string.Empty;
            string buttonColor = string.Empty;
            
            if (kit.Cooldown != 0 || kit.MaximumUses != 0 || kit.Cost != 0)
            {
                AddTitleSperator(container, i += 1, Message("UI.Usage", player.userID));

                if (kit.MaximumUses != 0)
                {
                    int playerUses = playerUsageData.GetKitUses(kit.Name);

                    AddLabelField(container, i += 1, Message("UI.MaxUses", player.userID), kit.MaximumUses.ToString());
                    AddLabelField(container, i += 1, Message("UI.YourUses", player.userID), playerUses.ToString());

                    if (playerUses >= kit.MaximumUses)
                    {
                        buttonText = Message("UI.MaximumUses", player.userID);
                        buttonColor = Configuration.Menu.Disabled.Get;
                    }
                }
                if (kit.Cooldown != 0)
                {
                    double cooldownRemaining = playerUsageData.GetCooldownRemaining(kit.Name);

                    AddLabelField(container, i += 1, Message("UI.CooldownTime", player.userID), FormatTime(kit.Cooldown));
                    AddLabelField(container, i += 1, Message("UI.CooldownRemaining", player.userID), cooldownRemaining == 0 ? Message("UI.None", player.userID) : 
                                                                                                     FormatTime(cooldownRemaining));

                    if (string.IsNullOrEmpty(buttonText) && cooldownRemaining > 0)
                    {
                        buttonText = Message("UI.OnCooldown", player.userID);
                        buttonColor = Configuration.Menu.Disabled.Get;
                    }
                }
                if (kit.Cost != 0)
                {
                    AddLabelField(container, i += 1, Message("UI.PurchaseCost", player.userID), $"{kit.Cost} {(Message($"Cost.{_costType}", player.userID))}");

                    if (string.IsNullOrEmpty(buttonText))
                    {
                        buttonText = Message("UI.Purchase", player.userID);
                        buttonColor = Configuration.Menu.Color2.Get;
                        buttonCommand = $"kits.gridview redeem {CommandSafe(kit.Name)} {page} {npcId}";
                    }
                }
            }

            if (!string.IsNullOrEmpty(kit.RequiredPermission) && !permission.UserHasPermission(player.UserIDString, kit.RequiredPermission))
            {
                buttonText = Message("UI.NeedsPermission", player.userID);
                buttonColor = Configuration.Menu.Disabled.Get;
            }
            
            if (i <= 16 && !string.IsNullOrEmpty(kit.CopyPasteFile))
            {
                AddTitleSperator(container, i += 1, Message("UI.CopyPaste", player.userID));
                AddLabelField(container, i += 1, Message("UI.FileName", player.userID), kit.CopyPasteFile);
            }

            if ((Configuration.AdminIgnoreRestrictions && isAdmin) || string.IsNullOrEmpty(buttonText))
            {
                buttonText = Message("UI.Redeem", player.userID);
                buttonCommand = $"kits.gridview redeem {CommandSafe(kit.Name)} {page} {npcId}";
                buttonColor = Configuration.Menu.Color2.Get;
            }

            CreateKitLayout(player, container, kit);

            UI.Button(container, UI_MENU, buttonColor, buttonText, 14, new UI4(0.005f, 0.005f, 0.495f, 0.045f), buttonCommand);

            CuiHelper.DestroyUi(player, UI_MENU);
            CuiHelper.AddUi(player, container);
        }
        #endregion

        #region Kit Layout
        private const string ICON_BACKGROUND_COLOR = "1 1 1 0.15";

        private void CreateKitLayout(BasePlayer player, CuiElementContainer container, KitData.Kit kit)
        {
            UI.Panel(container, UI_MENU, Configuration.Menu.Color1.Get, new UI4(0.505f, 0.88f, 0.995f, 0.92f));
            UI.Label(container, UI_MENU, Message("UI.KitItems", player.userID), 14, new UI4(0.51f, 0.88f, 0.995f, 0.92f), TextAnchor.MiddleLeft);

            // Main Items
            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.505f, 0.835f, 0.995f, 0.875f));
            UI.Label(container, UI_MENU, Message("UI.MainItems", player.userID), 14, new UI4(0.51f, 0.835f, 0.995f, 0.875f), TextAnchor.MiddleLeft);
            CreateInventoryItems(container, MainAlign, kit.MainItems, 24);
            
            // Wear Items
            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.505f, 0.365f, 0.995f, 0.405f));
            UI.Label(container, UI_MENU, Message("UI.WearItems", player.userID), 14, new UI4(0.51f, 0.365f, 0.995f, 0.405f), TextAnchor.MiddleLeft);
            CreateInventoryItems(container, WearAlign, kit.WearItems, 7);
            
            // Belt Items
            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.505f, 0.21f, 0.995f, 0.25f));
            UI.Label(container, UI_MENU, Message("UI.BeltItems", player.userID), 14, new UI4(0.51f, 0.21f, 0.995f, 0.25f), TextAnchor.MiddleLeft);
            CreateInventoryItems(container, BeltAlign, kit.BeltItems, 6);            
        }

        #region Item Layout Helpers
        private void CreateInventoryItems(CuiElementContainer container, GridAlignment alignment, ItemData[] items, int capacity)
        {
            for (int i = 0; i < capacity; i++)
                UI.Panel(container, UI_MENU, ICON_BACKGROUND_COLOR, alignment.Get(i));

            for (int i = 0; i < items.Length; i++)
            {
                ItemData itemData = items[i];
                if (itemData.Position > capacity - 1)
                    continue;

                UI4 position = alignment.Get(itemData.Position);

                UI.Image(container, UI_MENU, GetImage(itemData.Shortname, itemData.Skin), position);

                if (itemData.IsBlueprint && !string.IsNullOrEmpty(itemData.BlueprintShortname))
                    UI.Image(container, UI_MENU, GetImage(itemData.BlueprintShortname, 0UL), position);

                if (itemData.Amount > 1)
                    UI.Label(container, UI_MENU, $"x{itemData.Amount}", 10, position, TextAnchor.LowerRight);
            }
        }
        #endregion
        #endregion

        #region Kit Editor
        private void OpenKitsEditor(BasePlayer player, bool overwrite = false)
        {
            KitData.Kit kit;
            if (!_kitCreators.TryGetValue(player.userID, out kit))
                return;

            CuiElementContainer container = UI.BlurContainer(UI_MENU, new UI4(0.2f, 0.15f, 0.8f, 0.85f));

            UI.Panel(container, UI_MENU, Configuration.Menu.Panel.Get, new UI4(0.005f, 0.93f, 0.995f, 0.99f));

            UI.Label(container, UI_MENU, Message("UI.Title.Editor", player.userID), 20, new UI4(0.015f, 0.93f, 0.99f, 0.99f), TextAnchor.MiddleLeft);

            UI.Button(container, UI_MENU, Configuration.Menu.Color3.Get, "<b>×</b>", 20, new UI4(0.9575f, 0.9375f, 0.99f, 0.9825f), "kits.close");

            // Kit Options
            AddTitleSperator(container, 0, Message("UI.Details", player.userID));
            AddInputField(container, 1, Message("UI.Name", player.userID), "name", kit.Name);
            AddInputField(container, 2, Message("UI.Description", player.userID), "description", kit.Description, 3);
            AddInputField(container, 6, Message("UI.IconURL", player.userID), "image", kit.KitImage);

            AddTitleSperator(container, 7, Message("UI.UsageAuthority", player.userID));
            AddInputField(container, 8, Message("UI.Permission", player.userID), "permission", kit.RequiredPermission);
            AddInputField(container, 9, Message("UI.AuthLevel", player.userID), "authLevel", kit.RequiredAuth);
            AddToggleField(container, 10, Message("UI.IsHidden", player.userID), "isHidden", kit.IsHidden);

            AddTitleSperator(container, 11, Message("UI.Usage", player.userID));
            AddInputField(container, 12, Message("UI.MaxUses", player.userID), "maximumUses", kit.MaximumUses);
            AddInputField(container, 13, Message("UI.CooldownSeconds", player.userID), "cooldown", kit.Cooldown);
            AddInputField(container, 14, Message("UI.PurchaseCost", player.userID), "cost", kit.Cost);

            AddTitleSperator(container, 15, Message("UI.CopyPaste", player.userID));
            AddInputField(container, 16, Message("UI.FileName", player.userID), "copyPaste", kit.CopyPasteFile);

            // Kit Items
            CreateKitLayout(player, container, kit);

            // Kit Saving            
            UI.Button(container, UI_MENU, Configuration.Menu.Color2.Get, Message("UI.SaveKit", player.userID), 14, new UI4(0.005f, 0.005f, 0.2475f, 0.045f), $"kits.savekit {overwrite}");
            UI.Toggle(container, UI_MENU, ICON_BACKGROUND_COLOR, 14, new UI4(0.2525f, 0.005f, 0.2825f, 0.045f), $"kits.toggleoverwrite {overwrite}", overwrite);
            UI.Label(container, UI_MENU, Message("UI.Overwrite", player.userID), 14, new UI4(0.2875f, 0.005f, 0.495f, 0.045f), TextAnchor.MiddleLeft);

            // Item Management            
            UI.Button(container, UI_MENU, Configuration.Menu.Color3.Get, Message("UI.ClearItems", player.userID), 14, new UI4(0.505f, 0.005f, 0.7475f, 0.045f), $"kits.clearitems {overwrite}");
            UI.Button(container, UI_MENU, Configuration.Menu.Color2.Get, Message("UI.CopyInv", player.userID), 14, new UI4(0.7525f, 0.005f, 0.995f, 0.045f), $"kits.copyinv {overwrite}");

            CuiHelper.DestroyUi(player, UI_MENU);
            CuiHelper.AddUi(player, container);
        }

        #region Editor Helpers
        private const float EDITOR_ELEMENT_HEIGHT = 0.04f;

        private void AddInputField(CuiElementContainer container, int index, string title, string fieldName, object currentValue, int additionalHeight = 0)
        {
            float yMin = GetVerticalPos(index, 0.88f);
            float yMax = yMin + EDITOR_ELEMENT_HEIGHT;

            if (additionalHeight != 0)
                yMin = GetVerticalPos(index + additionalHeight, 0.88f);

            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.005f, yMin, 0.175f, yMax));
            UI.Label(container, UI_MENU, title, 12, new UI4(0.01f, yMin, 0.175f, yMax - 0.0075f), TextAnchor.UpperLeft);

            UI.Panel(container, UI_MENU, ICON_BACKGROUND_COLOR, new UI4(0.175f, yMin, 0.495f, yMax));

            string label = GetInputLabel(currentValue);
            if (!string.IsNullOrEmpty(label))
            {
                UI.Label(container, UI_MENU, label, 12, new UI4(0.18f, yMin, 0.47f, yMax - 0.0075f), TextAnchor.UpperLeft);
                UI.Button(container, UI_MENU, Configuration.Menu.Color3.Get, "X", 14, new UI4(0.47f, yMax - EDITOR_ELEMENT_HEIGHT, 0.495f, yMax), $"kits.clear {fieldName}");
            }
            else UI.Input(container, UI_MENU, string.Empty, 12, $"kits.creator {fieldName}", new UI4(0.18f, yMin, 0.495f, yMax - 0.0075f), TextAnchor.UpperLeft);
        }

        private void AddTitleSperator(CuiElementContainer container, int index, string title)
        {
            float yMin = GetVerticalPos(index, 0.88f);
            float yMax = yMin + EDITOR_ELEMENT_HEIGHT;

            UI.Panel(container, UI_MENU, Configuration.Menu.Color1.Get, new UI4(0.005f, yMin, 0.495f, yMax));
            UI.Label(container, UI_MENU, title, 14, new UI4(0.01f, yMin, 0.495f, yMax), TextAnchor.MiddleLeft);
        }

        private void AddLabelField(CuiElementContainer container, int index, string title, string value, int additionalHeight = 0)
        {
            float yMin = GetVerticalPos(index, 0.88f);
            float yMax = yMin + EDITOR_ELEMENT_HEIGHT;

            if (additionalHeight != 0)
                yMin = GetVerticalPos(index + additionalHeight, 0.88f);

            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.005f, yMin, 0.175f, yMax));
            UI.Label(container, UI_MENU, title, 12, new UI4(0.01f, yMin, 0.175f, yMax - 0.0075f), TextAnchor.UpperLeft);

            UI.Panel(container, UI_MENU, ICON_BACKGROUND_COLOR, new UI4(0.175f, yMin, 0.495f, yMax));
            UI.Label(container, UI_MENU, value, 12, new UI4(0.18f, yMin, 0.495f, yMax - 0.0075f), TextAnchor.UpperLeft);
        }

        private void AddToggleField(CuiElementContainer container, int index, string title, string fieldName, bool currentValue)
        {
            float yMin = GetVerticalPos(index, 0.88f);
            float yMax = yMin + EDITOR_ELEMENT_HEIGHT;

            UI.Panel(container, UI_MENU, Configuration.Menu.Color4.Get, new UI4(0.005f, yMin, 0.175f, yMax));
            UI.Label(container, UI_MENU, title, 14, new UI4(0.01f, yMin, 0.175f, yMax), TextAnchor.MiddleLeft);
            UI.Toggle(container, UI_MENU, ICON_BACKGROUND_COLOR, 14, new UI4(0.175f, yMin, 0.205f, yMax), $"kits.creator {fieldName} {!currentValue}", currentValue);
        }

        private string GetInputLabel(object obj)
        {
            if (obj is string)
                return string.IsNullOrEmpty(obj as string) ? null : obj.ToString();
            else if (obj is int)
                return (int)obj <= 0 ? null : obj.ToString();
            else if (obj is float)
                return (float)obj <= 0 ? null : obj.ToString();
            return null;
        }

        private float GetVerticalPos(int i, float start = 0.9f) => start - (i * (EDITOR_ELEMENT_HEIGHT + 0.005f));
        #endregion
        #endregion

        #region Popup Messages
        private void CreateMenuPopup(BasePlayer player, string text, float duration = 5f)
        {
            CuiElementContainer container = UI.Container(UI_POPUP, Configuration.Menu.Color4.Get, new UI4(0.2f, 0.11f, 0.8f, 0.15f));
            UI.Label(container, UI_POPUP, text, 14, UI4.Full);

            CuiHelper.DestroyUi(player, UI_POPUP);
            CuiHelper.AddUi(player, container);

            player.Invoke(() => CuiHelper.DestroyUi(player, UI_POPUP), duration);
        }
        #endregion

        #region UI Grid Helper
        private readonly GridAlignment KitAlign = new GridAlignment(4, 0.04f, 0.2f, 0.04f, 0.87f, 0.39f, 0.06f);

        private readonly GridAlignment MainAlign = new GridAlignment(6, 0.545f, 0.065f, 0.0035f, 0.8275f, 0.1f, 0.005f);
        private readonly GridAlignment WearAlign = new GridAlignment(7, 0.51f, 0.065f, 0.0035f, 0.3575f, 0.1f, 0.005f);
        private readonly GridAlignment BeltAlign = new GridAlignment(6, 0.545f, 0.065f, 0.0035f, 0.2025f, 0.1f, 0.005f);

        private class GridAlignment
        {
            internal int Columns { get; set; }
            internal float XOffset { get; set; }
            internal float Width { get; set; }
            internal float XSpacing { get; set; }
            internal float YOffset { get; set; }
            internal float Height { get; set; }
            internal float YSpacing { get; set; }

            internal GridAlignment(int columns, float xOffset, float width, float xSpacing, float yOffset, float height, float ySpacing)
            {
                Columns = columns;
                XOffset = xOffset;
                Width = width;
                XSpacing = xSpacing;
                YOffset = yOffset;
                Height = height;
                YSpacing = ySpacing;
            }

            internal UI4 Get(int index)
            {
                int rowNumber = index == 0 ? 0 : Mathf.FloorToInt(index / Columns);
                int columnNumber = index - (rowNumber * Columns);

                float offsetX = XOffset + (Width * columnNumber) + (XSpacing * columnNumber);

                float offsetY = (YOffset - (rowNumber * Height) - (YSpacing * rowNumber));

                return new UI4(offsetX, offsetY - Height, offsetX + Width, offsetY);
            }
        }
        #endregion
        #endregion

        #region UI Commands
        #region View Commands
        [ConsoleCommand("kits.close")]
        private void ccmdKitsClose(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Connection.player as BasePlayer;
            if (player == null)
                return;

            _kitCreators.Remove(player.userID);

            CuiHelper.DestroyUi(player, UI_MENU);
            CuiHelper.DestroyUi(player, UI_POPUP);
        }

        [ConsoleCommand("kits.gridview")]
        private void ccmdKitsGridView(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Connection.player as BasePlayer;
   
// ... [Code preview truncated due to length. Full source in attached file] ...

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