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

FREE Skins : 2.1.3 2.1.3

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

namespace Oxide.Plugins
{
    [Info("Skins", "TopPlugin.ru", "2.1.3")]
    [Description("Change workshop skins of items easily")]
    class Skins : RustPlugin
    {
        #region Variables

        private static Skins _ins;

        private List<ContainerController> _controllers = new List<ContainerController>();

        private const string PermissionUse = "skins.use";
        private const string PermissionAdmin = "skins.admin";
        
        #endregion

        #region Configuration

        private Configuration _config;

        private class Configuration
        {
            [JsonProperty(PropertyName = "Workshop", NullValueHandling = NullValueHandling.Ignore)]
            public Dictionary<string, List<ulong>> OldSkins = null;

            [JsonProperty(PropertyName = "Command")]
            public string Command = "skin";

            [JsonProperty(PropertyName = "Skins", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<SkinItem> Skins = new List<SkinItem> {new SkinItem()};

            [JsonProperty(PropertyName = "Container Panel Name")]
            public string Panel = "generic";

            [JsonProperty(PropertyName = "Container Capacity")]
            public int Capacity = 36;

            [JsonProperty(PropertyName = "UI")]
            public UIConfiguration UI = new UIConfiguration();

            [JsonProperty(PropertyName = "Debug")]
            public bool Debug = false;

            public class SkinItem
            {
                [JsonProperty(PropertyName = "Item Shortname")]
                // ReSharper disable once MemberCanBePrivate.Local
                public string Shortname = "shortname";

                [JsonProperty(PropertyName = "Skins", ObjectCreationHandling = ObjectCreationHandling.Replace)]
                public List<ulong> Skins = new List<ulong> {0};

                public static SkinItem Find(string shortname)
                {
                    for (var i = 0; i < _ins._config.Skins.Count; i++)
                    {
                        var item = _ins._config.Skins[i];
                        if (item.Shortname == shortname)
                            return item;
                    }

                    return null;
                }
            }

            public class UIConfiguration
            {
                [JsonProperty(PropertyName = "Background Color")]
                public string BackgroundColor = "0.18 0.28 0.36";

                [JsonProperty(PropertyName = "Background Anchors")]
                public Anchors BackgroundAnchors = new Anchors
                    {AnchorMinX = "1.0", AnchorMinY = "1.0", AnchorMaxX = "1.0", AnchorMaxY = "1.0"};

                [JsonProperty(PropertyName = "Background Offsets")]
                public Offsets BackgroundOffsets = new Offsets
                    {OffsetMinX = "-300", OffsetMinY = "-100", OffsetMaxX = "0", OffsetMaxY = "0"};
                
                [JsonProperty(PropertyName = "Left Button Text")]
                public string LeftText = "<size=36><</size>";
                
                [JsonProperty(PropertyName = "Left Button Color")]
                public string LeftColor = "0.11 0.51 0.83";

                [JsonProperty(PropertyName = "Left Button Anchors")]
                public Anchors LeftAnchors = new Anchors
                    {AnchorMinX = "0.025", AnchorMinY = "0.05", AnchorMaxX = "0.325", AnchorMaxY = "0.95"};
                
                [JsonProperty(PropertyName = "Center Button Text")]
                public string CenterText = "<size=36>Page: {page}</size>";
                
                [JsonProperty(PropertyName = "Center Button Color")]
                public string CenterColor = "0.11 0.51 0.83";

                [JsonProperty(PropertyName = "Center Button Anchors")]
                public Anchors CenterAnchors = new Anchors
                    {AnchorMinX = "0.350", AnchorMinY = "0.05", AnchorMaxX = "0.650", AnchorMaxY = "0.95"};
                
                [JsonProperty(PropertyName = "Right Button Text")]
                public string RightText = "<size=36>></size>";
                
                [JsonProperty(PropertyName = "Right Button Color")]
                public string RightColor = "0.11 0.51 0.83";

                [JsonProperty(PropertyName = "Right Button Anchors")]
                public Anchors RightAnchors = new Anchors
                    {AnchorMinX = "0.675", AnchorMinY = "0.05", AnchorMaxX = "0.975", AnchorMaxY = "0.95"};

                public class Anchors
                {
                    [JsonProperty(PropertyName = "Anchor Min X")]
                    public string AnchorMinX = "0.0";
                    
                    [JsonProperty(PropertyName = "Anchor Min Y")]
                    public string AnchorMinY = "0.0";
                    
                    [JsonProperty(PropertyName = "Anchor Max X")]
                    public string AnchorMaxX = "1.0";
                    
                    [JsonProperty(PropertyName = "Anchor Max Y")]
                    public string AnchorMaxY = "1.0";

                    [JsonIgnore]
                    public string AnchorMin => $"{AnchorMinX} {AnchorMinY}";

                    [JsonIgnore]
                    public string AnchorMax => $"{AnchorMaxX} {AnchorMaxY}";
                }

                public class Offsets
                {
                    [JsonProperty(PropertyName = "Offset Min X")]
                    public string OffsetMinX = "0";
                    
                    [JsonProperty(PropertyName = "Offset Min Y")]
                    public string OffsetMinY = "0";
                    
                    [JsonProperty(PropertyName = "Offset Max X")]
                    public string OffsetMaxX = "100";
                    
                    [JsonProperty(PropertyName = "Offset Max Y")]
                    public string OffsetMaxY = "100";

                    [JsonIgnore]
                    public string OffsetMin => $"{OffsetMinX} {OffsetMinY}";

                    [JsonIgnore]
                    public string OffsetMax => $"{OffsetMaxX} {OffsetMaxY}";
                }
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
                SaveConfig();
            }
            catch
            {
                PrintError("Your configuration file contains an error.Using default configuration values.");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig() => Config.WriteObject(_config);

        protected override void LoadDefaultConfig() => _config = new Configuration();
        
        #endregion

        #region Hooks

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                { "Not Allowed", "You don't have permission to use this command" },
                { "Cannot Use", "I'm sorry, you cannot use that right now" },
                { "Help", "Command usage:\n" +
                          "skin show - Show skins\n" +
                          "skin get - Get Skin ID of the item" },
                { "Admin Help", "Admin command usage:\n" +
                                "skin show - Show skins\n" +
                                "skin get - Get Skin ID of the item\n" +
                                "skin remove (Shortname) (Skin ID) - Remove a skin\n" +
                                "skin add (Shortname) (Skin ID) - Add a skin" },
                { "Skin Get Format", "{shortname}'s skin: {id}" },
                { "Skin Get No Item", "Please, hold the needed item" },
                { "Incorrect Skin", "You have entered an incorrect skin" },
                { "Skin Already Exists", "This skin already exists on this item" },
                { "Skin Does Not Exist", "This skin does not exist" },
                { "Skin Added", "Skin was successfully added" },
                { "Skin Removed", "Skin was removed" }
            }, this);
        }

        private void Init()
        {
            _ins = this;
            
            permission.RegisterPermission(PermissionUse, this);
            permission.RegisterPermission(PermissionAdmin, this);

            if (_config.OldSkins == null)
                return;
            
            foreach (var kvp in _config.OldSkins)
            {
                var skinItem = Configuration.SkinItem.Find(kvp.Key);
                if (skinItem == null)
                {
                    _config.Skins.Add(new Configuration.SkinItem {Shortname = kvp.Key, Skins = kvp.Value});
                    continue;
                }
                
                skinItem.Skins.AddRange(kvp.Value);
            }

            _config.OldSkins = null;
            SaveConfig();
        }

        private void OnServerInitialized()
        {
            for (var i = 0; i < BasePlayer.activePlayerList.Count; i++)
            {
                OnPlayerConnected(BasePlayer.activePlayerList[i]);
            }

            AddCovalenceCommand(_config.Command, nameof(CommandSkin));
        }

        private void Unload()
        {
            for (var i = 0; i < _controllers.Count; i++)
            {
                _controllers[i].Destroy();
            }

            _ins = null;
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (ContainerController.FindIndex(player) != -1)
                return;
            
            _controllers.Add(new ContainerController(player)); // lol
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            var index = ContainerController.FindIndex(player);
            if (index == -1)
                return;
            
            _controllers[index].Destroy();
            _controllers.RemoveAt(index);
        }

        #region Working With Containers

        private void OnItemSplit(Item item, int amount)
        {
            if (item.parentItem != null)
                return;

            var container = ContainerController.Find(item.parent);
            if (container == null)
                return;
            
            PrintDebug($"OnItemSplit: {item.info.shortname} ({item.amount}x, slot {item.position}); {amount}x");

            var main = container.Container.GetSlot(0);
            if (main == null)
            {
                PrintDebug("Main item is null");
                return;
            }

            NextFrame(() =>
            {
                if (main.uid != item.uid) // Ignore main item because it's amount will be changed
                    main.amount -= amount;
                
                container.UpdateContent(0);
            });
        }

        private void OnItemAddedToContainer(ItemContainer itemContainer, Item item)
        {
            if (item.parentItem != null)
                return;

            var player = itemContainer.GetOwnerPlayer();
            var container = ContainerController.Find(itemContainer);
            if (container == null || player != null)
                return;
            
            PrintDebug($"OnItemAddedToContainer: {item.info.shortname} (slot {item.position})");

            if (itemContainer.itemList.Count != 1)
            {
                item.position = -1;
                item.parent.itemList.Remove(item);
                item.parent = null;
                container.GiveItemBack();
                container.Clear();
                item.parent = container.Container;
                item.parent.itemList.Add(item);
            }

            item.position = 0;
            container.StoreContent(item);
            container.UpdateContent(0);
        }

        private void OnItemRemovedFromContainer(ItemContainer itemContainer, Item item)
        {
            if (item.parentItem != null)
                return;
            
            var container = ContainerController.Find(itemContainer);
            var player = itemContainer.entityOwner as BasePlayer;
            if (player == null || container == null)
            {
                return;
            }

            PrintDebug($"OnItemRemovedFromContainer: {item.info.shortname} (slot {item.position})");

            container.SetupContent(item);

            Interface.CallHook("OnItemSkinChanged", player, item);
            
            container.Clear();
        }

        private void OnPlayerLootEnd(PlayerLoot loot)
        {
            var player = loot.gameObject.GetComponent<BasePlayer>();
            if (player != loot.entitySource)
                return;
            
            PrintDebug("OnLootEntityEnd: Closing container");
            ContainerController.Find(player)?.Close();
        }

        private object CanLootPlayer(BasePlayer looter, Object target)
        {
            if (looter != target)
                return null;

            var container = ContainerController.Find(looter);
            if (container == null || !container.IsOpened)
                return null;

            return true;
        }

        private object CanMoveItem(Item item, PlayerInventory playerLoot, uint targetContainerId, int slot, int amount)
        {
            var containerFrom = ContainerController.Find(item.parent);
            var containerTo = ContainerController.Find(targetContainerId);
            if ((containerFrom ?? containerTo) == null)
                return null;
            
            PrintDebug($"CanMoveItem: {item.info.shortname} ({item.amount}) from {item.parent?.uid ?? 0} to {targetContainerId} in {slot} ({amount})");
            if (item.parent?.uid == targetContainerId)
            {
                PrintDebug("// CanMoveItem: Preventing same containers");
                return false;
            }
            
            return CanMoveItemTo(containerTo, item, slot, amount);
        }

        #region Minor helpers

        private object CanMoveItemTo(ContainerController controller, Item item, int slot, int amount)
        {
            var targetItem = controller?.Container?.GetSlot(slot);
            if (targetItem != null)
            {
                // Give target item back
                controller.GiveItemBack(targetItem);
                controller.Clear();
            }

            return null;
        }

        #endregion

        #endregion

        [HookMethod(nameof(SkinsClose))]
        private void SkinsClose(BasePlayer player)
        {
            if (player == null)
                return;
            
            ContainerController.Find(player)?.Close();
        }
        
        #endregion

        #region Commands

        private void CommandSkin(IPlayer player, string command, string[] args)
        {
            PrintDebug("Executed Skin command");
            
            if (!CanUse(player))
            {
                PrintDebug("Not allowed");
                player.Reply(GetMsg("Not Allowed", player.Id));
                return;
            }

            if (args.Length == 0)
                args = new[] {"show"}; // :P strange yeah

            var isAdmin = player.IsServer || CanUseAdmin(player);
            var basePlayer = player.Object as BasePlayer;
            var isPlayer = basePlayer != null;
            
            PrintDebug($"Arguments: {string.Join(" ", args)}");
            PrintDebug($"Is Admin: {isAdmin} : Is Player: {isPlayer}");
            
            switch (args[0].ToLower())
            {
                case "_tech-update":
                {
                    int page;
                    if (args.Length != 2 || !isPlayer || !int.TryParse(args[1], out page))
                        break;

                    ContainerController.Find(basePlayer)?.UpdateContent(page);
                    break;
                }
                    
                case "show":
                case "s":
                {
                    if (!isPlayer)
                    {
                        PrintDebug("Not a player");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    var container = ContainerController.Find(basePlayer);
                    if (container == null || !container.CanShow())
                    {
                        PrintDebug("Cannot show container or container not found");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    basePlayer.Invoke(container.Show, 0.5f);
                    break;
                }

                case "add":
                case "a":
                {
                    if (args.Length != 3)
                        goto default;

                    if (!isAdmin)
                    {
                        PrintDebug("Not an admin");
                        player.Reply(GetMsg("Not Allowed", player.Id));
                        break;
                    }

                    var shortname = args[1];
                    ulong skin;
                    if (!ulong.TryParse(args[2], out skin))
                    {
                        PrintDebug("Invalid skin");
                        player.Reply(GetMsg("Incorrect Skin", player.Id));
                        break;
                    }
                    
                    LoadConfig();

                    var skinData = Configuration.SkinItem.Find(shortname);
                    if (skinData == null)
                    {
                        skinData = new Configuration.SkinItem {Shortname = shortname};
                        _config.Skins.Add(skinData);
                    }

                    if (skinData.Skins.Contains(skin))
                    {
                        PrintDebug("Skin already exists");
                        player.Reply(GetMsg("Skin Already Exists", player.Id));
                        break;
                    }
                    
                    skinData.Skins.Add(skin);
                    player.Reply(GetMsg("Skin Added", player.Id));
                    
                    SaveConfig();
                    PrintDebug("Added skin");
                    break;
                }

                case "remove":
                case "delete":
                case "r":
                case "d":
                {
                    if (args.Length != 3)
                        goto default;

                    if (!isAdmin)
                    {
                        PrintDebug("Not an admin");
                        player.Reply(GetMsg("Not Allowed", player.Id));
                        break;
                    }

                    var shortname = args[1];
                    ulong skin;
                    if (!ulong.TryParse(args[2], out skin))
                    {
                        PrintDebug("Invalid skin");
                        player.Reply(GetMsg("Incorrect Skin", player.Id));
                        break;
                    }
                    
                    LoadConfig();

                    var skinData = Configuration.SkinItem.Find(shortname);
                    int index;
                    if (skinData == null || (index = skinData.Skins.IndexOf(skin)) == -1)
                    {
                        PrintDebug("Skin doesnt exist");
                        player.Reply(GetMsg("Skin Does Not Exist", player.Id));
                        break;
                    }
                    
                    skinData.Skins.RemoveAt(index);
                    player.Reply(GetMsg("Skin Removed", player.Id));
                    
                    SaveConfig();
                    PrintDebug("Removed skin");
                    break;
                }

                case "get":
                case "g":
                {
                    if (!isPlayer)
                    {
                        PrintDebug("Not a player");
                        player.Reply(GetMsg("Cannot Use", player.Id));
                        break;
                    }

                    var item = basePlayer.GetActiveItem();
                    if (item == null || !item.IsValid())
                    {
                        PrintDebug("Invalid item");
                        player.Reply(GetMsg("Skin Get No Item", player.Id));
                        break;
                    }

                    player.Reply(GetMsg("Skin Get Format", player.Id).Replace("{shortname}", item.info.shortname).Replace("{id}", item.skin.ToString()));
                    
                    break;
                }

                default: // and "help", and all other args
                {
                    PrintDebug("Unknown command");
                    player.Reply(GetMsg(isAdmin ? "Admin Help" : "Help", player.Id));
                    break;
                }
            }
        }

        #endregion
        
        #region Controller

        private class ContainerController
        {
            /*
             * Basic tips:
             * Item with slot 0: Player's skin item
             */
            
            public BasePlayer Owner;
            public ItemContainer Container;
            public bool IsOpened = false;

            private List<Item> _storedContent;
            private ProtoBuf.Magazine _storedMagazine;

            #region Search

            // ReSharper disable once SuggestBaseTypeForParameter
            public static int FindIndex(BasePlayer player)
            {
                if (!CanShow(player))
                    goto none;
                
                for (var i = 0; i < _ins._controllers.Count; i++)
                {
                    if (_ins._controllers[i].Owner == player)
                    {
                        return i;
                    }
                }

                none:
                return -1;
            }

            public static ContainerController Find(BasePlayer player)
            {
                var index = FindIndex(player);
                return index == -1 ? null : _ins._controllers[index];
            }

            // ReSharper disable once SuggestBaseTypeForParameter
            private static int FindIndex(ItemContainer container)
            {
                if (container == null)
                    goto none;
                
                for (var i = 0; i < _ins._controllers.Count; i++)
                {
                    if (_ins._controllers[i].Container == container)
                    {
                        return i;
                    }
                }

                none:
                return -1;
            }

            public static ContainerController Find(ItemContainer container)
            {
                var index = FindIndex(container);
                return index == -1 ? null : _ins._controllers[index];
            }

            // ReSharper disable once SuggestBaseTypeForParameter
            private static int FindIndex(uint id)
            {
                for (var i = 0; i < _ins._controllers.Count; i++)
                {
                    if (_ins._controllers[i].Container.uid == id)
                    {
                        return i;
                    }
                }

                return -1;
            }

            public static ContainerController Find(uint id)
            {
                var index = FindIndex(id);
                return index == -1 ? null : _ins._controllers[index];
            }
            
            #endregion

            public ContainerController(BasePlayer player)
            {
                Owner = player;
                _storedContent = new List<Item>();
                
                Container = new ItemContainer
                {
                    entityOwner = Owner,
                    capacity = _ins._config.Capacity,
                    isServer = true,
                    allowedContents = ItemContainer.ContentsType.Generic
                };
                
                Container.GiveUID();
            }
            
            #region UI

            private void DestroyUI()
            {
                PrintDebug("Destroying UI");
                CuiHelper.DestroyUi(Owner, "Skins.Background");
            }

            private void DrawUI(int page)
            {
                PrintDebug("Drawing UI");
                var elements = new CuiElementContainer();

                var background = new CuiElement
                {
                    Name = "Skins.Background",
                    Parent = "Overlay",
                    Components =
                    {
                        new CuiImageComponent
                        {
                            Color = _ins._config.UI.BackgroundColor
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = _ins._config.UI.BackgroundAnchors.AnchorMin,
                            AnchorMax = _ins._config.UI.BackgroundAnchors.AnchorMax,
                            OffsetMin = _ins._config.UI.BackgroundOffsets.OffsetMin,
                            OffsetMax = _ins._config.UI.BackgroundOffsets.OffsetMax
                        }
                    },
                    FadeOut = 0.5f
                };

                var left = new CuiElement
                {
                    Name = "Skins.Left",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiButtonComponent
                        {
                            Close = background.Name,
                            Command = $"{_ins._config.Command} _tech-update {page - 1}",
                            Color = _ins._config.UI.LeftColor
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = _ins._config.UI.LeftAnchors.AnchorMin,
                            AnchorMax = _ins._config.UI.LeftAnchors.AnchorMax
                        }
                    },
                    FadeOut = 0.5f
                };

                var leftText = new CuiElement
                {
                    Name = "Skins.Left.Text",
                    Parent = left.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = _ins._config.UI.LeftText,
                            Align = TextAnchor.MiddleCenter
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    },
                    FadeOut = 0.5f
                };

                var center = new CuiElement
                {
                    Name = "Skins.Center",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiImageComponent
                        {
                            Color = _ins._config.UI.CenterColor
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = _ins._config.UI.CenterAnchors.AnchorMin,
                            AnchorMax = _ins._config.UI.CenterAnchors.AnchorMax
                        }
                    },
                    FadeOut = 0.5f
                };

                var centerText = new CuiElement
                {
                    Name = "Skins.Center.Text",
                    Parent = center.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = _ins._config.UI.CenterText.Replace("{page}", $"{page + 1}"),
                            Align = TextAnchor.MiddleCenter
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    },
                    FadeOut = 0.5f
                };

                var right = new CuiElement
                {
                    Name = "Skins.Right",
                    Parent = background.Name,
                    Components =
                    {
                        new CuiButtonComponent
                        {
                            Close = background.Name,
                            Command = $"{_ins._config.Command} _tech-update {page + 1}",
                            Color = _ins._config.UI.RightColor
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = _ins._config.UI.RightAnchors.AnchorMin,
                            AnchorMax = _ins._config.UI.RightAnchors.AnchorMax
                        }
                    },
                    FadeOut = 0.5f
                };

                var rightText = new CuiElement
                {
                    Name = "Skins.Right.Text",
                    Parent = right.Name,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = _ins._config.UI.RightText,
                            Align = TextAnchor.MiddleCenter
                        },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        }
                    },
                    FadeOut = 0.5f
                };
                
                elements.Add(background);
                elements.Add(left);
                elements.Add(leftText);
                elements.Add(center);
                elements.Add(centerText);
                elements.Add(right);
                elements.Add(rightText);

                CuiHelper.AddUi(Owner, elements);
            }
            
            #endregion

            public void Close()
            {
                PrintDebug("Closing container");
                
                GiveItemBack();
                Clear();
                DestroyUI();
                
                IsOpened = false;
            }

            public void Show()
            {
                PrintDebug($"Showing container.UID: {Container.uid}");

                if (!CanUse())
                    return;
                
                IsOpened = true;
                UpdateContent(0);
                
                var loot = Owner.inventory.loot;
                
                loot.Clear();
                loot.PositionChecks = false;
                loot.entitySource = Owner;
                loot.itemSource = null;
                loot.AddContainer(Container);
                loot.SendImmediate();
                
                Owner.ClientRPCPlayer(null, Owner, "RPC_OpenLootPanel", _ins._config.Panel);
            }
            
            #region Can Show

            public bool CanShow()
            {
                return CanShow(Owner);
            }

            private static bool CanShow(BaseCombatEntity player)
            {
                return player != null && !player.IsDead();
            }
            
            #endregion

            public void GiveItemBack(Item itemOverride = null)
            {
                if (!IsValid())
                    return;
                
                PrintDebug("Trying to give item back..");

                var item = itemOverride ?? Container.GetSlot(0);
                if (item == null)
                {
                    PrintDebug("// Invalid item");
                    return;
                }

                MoveItem(item, Owner.inventory.containerMain);
                SetupContent(item);
            }

            public void SetupContent(Item destination)
            {
                PrintDebug("Setting up content for an item");
                if (destination == null)
                {
                    PrintDebug("Destination is null!");
                    return;
                }

                if (_storedMagazine != null)
                {
                    (destination.GetHeldEntity() as BaseProjectile)?.primaryMagazine?.Load(_storedMagazine);
                    _storedMagazine = null;
                }

                var contents = destination.contents?.itemList;
                if (contents == null)
                {
                    PrintDebug("// Contents null");
                    return;
                }
                
                for (var i = _storedContent.Count - 1; i >= 0; i--)
                {
                    var item = _storedContent[i];
                    item.parent = destination.contents;
                    item.RemoveFromWorld();
                    
                    _storedContent.RemoveAt(i);
                    contents.Add(item);
                    
                    item.MarkDirty();
                    foreach (var itemMod in item.info.itemMods)
                        itemMod.OnParentChanged(item);
                }

                _storedContent.Clear();
            }

            public void StoreContent(Item source)
            {
                PrintDebug("Removing content for an item");
                
                var contents = source.contents?.itemList;
                if (contents != null)
                {
                    for (var i = contents.Count - 1; i >= 0; i--)
                    {
                        var item = contents[i];
                        item.parent = null;
                        contents.RemoveAt(i);
                        _storedContent.Add(item);
                    }
                }

                var magazine = (source.GetHeldEntity() as BaseProjectile)?.primaryMagazine;
                _storedMagazine = magazine?.Save();

                if (magazine != null) // Just in case so they won't be able to take out the ammo
                    magazine.contents = 0;
            }

            public void Clear()
            {
                PrintDebug("Clearing container");
                
                for (var i = Container.itemList.Count - 1; i >= 0; i--)
                {
                    RemoveItem(Container.itemList[i]);
                }
                
                Container.itemList.Clear();
                Container.MarkDirty();
            }

            public void Destroy()
            {
                Close();
                Container.Kill();
            }

            public void UpdateContent(int page)
            {
                if (!IsValid())
                {
                    PrintDebug("// Invalid container");
                    return;
                }
                
                var source = Container.GetSlot(0);
                if (source == null)
                {
                    PrintDebug("// Source item is null");
                    return;
                }

                if (source.uid == 0 || !source.IsValid() || source.amount <= 0)
                {
                    PrintDebug("// Invalid item that was removed.Player may have tried to dupe something");
                    return;
                }

                var skins = new List<ulong>(Configuration.SkinItem.Find(source.info.shortname)?.Skins ??
                                            Enumerable.Empty<ulong>());
                
                var perPage = Container.capacity - 1;

                if (page < 0)
                    page = 0;

                Interface.CallHook("OnFetchSkins", Owner, source.info, skins);
                
                var offset = perPage * page;
                if (offset > skins.Count)
                {
                    page--;
                    offset -= perPage;
                }

                Container.itemList.Remove(source);
                for (var i = 0; i < source.info.itemMods.Length; i++)
                {
                    var itemMod = source.info.itemMods[i];
                    itemMod.OnParentChanged(source);
                }

                PrintDebug($"Updating content.Page: {page}");
                Clear();
                
                MoveItem(source, Container);
                DestroyUI();
                DrawUI(page);

                var slot = 1;
                for (var i = 0; i < skins.Count; i++)
                {
                    if (slot >= Container.capacity)
                        break;

                    if (offset > i)
                        continue;

                    var skin = skins[i];
                    var duplicate = GetDuplicateItem(source, skin);
                    
                    MoveItem(duplicate, Container, slot++);
                }
            }

            private bool IsValid() => Owner == null || Container?.itemList != null;

            private bool CanUse()
            {
                var result = Interface.CallHook("CanUseSkins", Owner.IPlayer.Id);
                if (!(result is bool))
                    return true;
                
                PrintDebug($"Hook result: {result}");
                return (bool) result;
            }
            
            #region Working with items

            private Item GetDuplicateItem(Item item, ulong skin)
            {
                var duplicate = ItemManager.Create(item.info, item.amount, skin);
                if (item.hasCondition)
                {
                    duplicate._maxCondition = item._maxCondition;
                    duplicate._condition = item._condition;
                }

                if (item.contents != null)
                {
                    duplicate.contents.capacity = item.contents.capacity;
                }
                
                var projectile = duplicate.GetHeldEntity() as BaseProjectile;
                if (projectile != null)
                    projectile.primaryMagazine.contents = 0;
                
                return duplicate;
            }

            private void MoveItem(Item item, ItemContainer container, int slot = 0)
            {
                while (container.SlotTaken(item, slot) && container.capacity > slot)
                    slot++;
                
                if (container.IsFull() || container.SlotTaken(item, slot))
                {
                    PrintDebug("Container is full, dropping item");
                    item.Drop(Owner.transform.position, Vector3.up);
                    return;
                }

                item.parent?.itemList?.Remove(item);

                item.RemoveFromWorld();

                item.position = slot;
                item.parent = container;

                container.itemList.Add(item);
                item.MarkDirty();

                for (var i = 0; i < item.info.itemMods.Length; i++)
                {
                    item.info.itemMods[i].OnParentChanged(item);
                }
            }

            private void RemoveItem(Item item)
            {
                if (item.uid > 0U && Network.Net.sv != null)
                {
                    Network.Net.sv.ReturnUID(item.uid);
                    item.uid = 0U;
                }
                
                if (item.contents != null)
                {
                    for (var i = item.contents.itemList.Count - 1; i >= 0; i--)
                    {
                        RemoveItem(item.contents.itemList[i]);
                    }

                    item.contents = null;
                }
                
                item.RemoveFromWorld();

                item.parent = null;
                
                var heldEntity = item.GetHeldEntity();
                if (heldEntity != null && heldEntity.IsValid() && !heldEntity.IsDestroyed)
                    heldEntity.Kill();
            }
            
            #endregion
        }
        
        #endregion
        
        #region Helpers

        private bool CanUse(IPlayer player) => player.HasPermission(PermissionUse);

        private bool CanUseAdmin(IPlayer player) => player.HasPermission(PermissionAdmin);

        private string GetMsg(string key, string userId = null) => lang.GetMessage(key, this, userId);

        private static void PrintDebug(string message)
        {
            if (_ins._config.Debug)
                Interface.Oxide.LogDebug(message);
        }

        #endregion
    }
}

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