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

FREE ChestModifier : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("ChestModifier", "M&B-Studios", "1.0.0")]
    class ChestModifier : RustPlugin
    {
        #region Classes
        internal class ItemData
        {
            [JsonProperty(Order = 0)]
            public string Shortname;
            [JsonProperty("Skin id", Order = 1)]
            public ulong SkinId;
        }
        internal class Chest
        {
            [JsonProperty(Order = 0)]
            public string Shortname;
            
            [JsonProperty("Skin id", Order = 1)]
            public ulong SkinId;

            [JsonProperty("Item name", Order = 2)] 
            public string displayName;
            
            [JsonProperty(Order = 3)]
            public int Capacity;
            
            [JsonProperty("Blacklisted items", Order = 4)]
            public List<ItemData> BlacklistedItems;
            
            [JsonProperty("Allowed categories (still empty if allowed all)", Order = 5)]
            public List<string> AllowedCategories;
            
            [JsonProperty("Spawn chances", Order = 6)]
            public Dictionary<string, float> SpawnChances;


            public Item Get(int amount = 1)
            {
                var item = ItemManager.CreateByName(Shortname, amount, SkinId);
                if (!string.IsNullOrEmpty(displayName))
                    item.name = displayName;
                return item;
            }
        }
        #endregion

        #region Fields
        private const string Layer = "ui.ChestModifier.bg";
        private const string PERM_GIVE = "chestmodifier.give";
        private const string PERM_HELPMENU = "chestmodifier.helpmenu";
        private readonly List<string> AllCategories = new();

        private readonly Dictionary<string, string> CategoryToSprite = new()
        {
            ["Attire"] = "assets/icons/clothing.png",
            ["Misc"] = "assets/icons/menu_dots.png",
            ["Items"] = "assets/icons/extinguish.png",
            ["Component"] = "assets/icons/loot.png",
            ["Ammunition"] = "assets/icons/ammunition.png",
            ["Construction"] = "assets/icons/construction.png",
            ["Traps"] = "assets/icons/traps.png",
            ["Electrical"] = "assets/icons/electric.png",
            ["Fun"] = "assets/icons/fun.png",
            ["Food"] = "assets/icons/meat.png",
            ["Weapon"] = "assets/icons/weapon.png",
            ["Resources"] = "assets/icons/resource.png",
            ["Tool"] = "assets/icons/tools.png",
            ["Medical"] = "assets/icons/medical.png"
        };
        #endregion

        #region Hooks
        private void OnLootEntity(BasePlayer player, BaseEntity entity)
        {
            if (entity == null || player == null || !player.userID.IsSteamId())
                return;
            
            if (!player.IPlayer.HasPermission(PERM_HELPMENU))
                return;
            
            if (entity.skinID == 0)
                return;

            var storage = entity as StorageContainer;
            if (storage == null)
                return;
            
            var chest = cfg.Chests.FirstOrDefault(x => x.Value.SkinId == entity.skinID);
            if (chest.Key == null)
                return;

            UI_DrawHelpButton(player, storage.inventory.capacity, chest.Key);
        }

        private void OnLootEntityEnd(BasePlayer player, BaseEntity entity)
        {
            CuiHelper.DestroyUi(player, Layer);
            CuiHelper.DestroyUi(player, Layer + ".btn");
        }

        private void OnEntitySpawned(BaseEntity entity)
        {
            timer.Once(0.2f, () =>
            {
                if (entity == null)
                    return;
                if (entity.TryGetComponent<LootableCorpse>(out var corpse))
                {
                    foreach (var x in cfg.Chests.Where(x => x.Value.SpawnChances.ContainsKey(entity.PrefabName)))
                    {
                        foreach (var y in x.Value.SpawnChances.Where(z => z.Key == entity.PrefabName))
                        {
                            var rndm = UnityEngine.Random.Range(0f, 100.1f);
                            if (y.Value > rndm)
                            {
                                corpse.containers[0].capacity++;
                                x.Value.Get().MoveToContainer(corpse.containers[0]);
                            }
                        }
                    }
                }
                else if (entity.TryGetComponent<StorageContainer>(out var comp))
                {
                    var chest = cfg.Chests.FirstOrDefault(x => x.Value.SkinId == entity.skinID);
                    if (chest.Key == null)
                        return;
                    comp.inventory.capacity = chest.Value.Capacity;
                    comp.SendNetworkUpdate();
                }
            });
        }

        private void OnLootSpawn(LootContainer container)
        {
            if (container == null)
                return;
            
            foreach (var x in cfg.Chests.Where(x => x.Value.SpawnChances.ContainsKey(container.PrefabName)))
            {
                foreach (var y in x.Value.SpawnChances.Where(z => z.Key == container.PrefabName))
                {
                    var rndm = UnityEngine.Random.Range(0f, 100.1f);
                    if (y.Value > rndm)
                    {
                        container.inventory.capacity++;
                        container.inventory.GiveItem(x.Value.Get());
                    }
                }
            }
            
            return;
        }
        
        private void OnServerInitialized()
        {
            PrintWarning(
                $"Support M&B Studios\n Contact Discord: mbstudios");

            permission.RegisterPermission(PERM_GIVE, this);
            permission.RegisterPermission(PERM_HELPMENU, this);

            var categories = new List<string>();
            foreach (var x in ItemManager.itemList)
                if (!categories.Contains(x.category.ToString()))
                    categories.Add(x.category.ToString());

            foreach (var x in cfg.Chests)
            {
                foreach (var y in x.Value.AllowedCategories)
                    if (!categories.Contains(y))
                        PrintError($"Unknown category '{y}' in '{x.Key}'");
            }
        }

        private void Unload()
        {
            foreach (var x in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(x, Layer);
                CuiHelper.DestroyUi(x, Layer + ".btn");
            }
        }
        
        private ItemContainer.CanAcceptResult? CanAcceptItem(ItemContainer container, Item item, int targetPos)
        {
            if (container == null || item == null)
                return null;
            
            var entity = container.GetEntityOwner();
            if (entity == null)
                return null;
        
            var chest = cfg.Chests.FirstOrDefault(x => x.Value.SkinId == entity.skinID);
        
            if (chest.Key == null)
                return null;
            
            if (!IsAllowedForChest(chest.Key, item))
                return ItemContainer.CanAcceptResult.CannotAccept;
            
            return null;
        }
        #endregion

        #region Methods

        private void SendMessage(BasePlayer player, string message)
        {
            if (player == null)
                PrintWarning(message);
            else
                player.ChatMessage(message);
        }

        private bool IsAllowedForChest(string key, Item item)
        {
            if (!cfg.Chests.TryGetValue(key, out var chest))
                return true;
            
            if (!chest.AllowedCategories.IsNullOrEmpty())
                if (!chest.AllowedCategories.Contains(item.info.category.ToString()))
                    return false;

            if (chest.BlacklistedItems.Any(x => x.SkinId == item.skin && x.Shortname == item.info.shortname))
                return false;

            return true;
        }
        private string ConcatArgs(string[] args, int start)
        {
            StringBuilder sb = new StringBuilder();
            
            for (int i = start; i < args.Length; i++)
            {
                if (i == start)
                    sb.Append(args[i]);
                else
                    sb.Append(" " + args[i]);
            }

            return sb.ToString();
        }
        #endregion

        #region UI

        private void UI_DrawMain(BasePlayer player, string key, int slots)
        {
            var chest = cfg.Chests[key];
            if (chest == null)
                return;

            CuiHelper.DestroyUi(player, Layer);
            var container = new CuiElementContainer();
            container.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "0.317 0.317 0.317 0.5490196", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat" },
                RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "192.26 109.4", OffsetMax = "573.589 367.201" }
            }, "Overlay", Layer);
            
            
            container.Add(new CuiElement
            {
                Name = Layer + ".label",
                Parent = Layer,
                Components = {
                    new CuiTextComponent { Text = chest.displayName.ToUpper(), Font = "robotocondensed-bold.ttf", FontSize = 17, Align = TextAnchor.MiddleCenter, Color = "0.8078431 0.7803922 0.7411765 1" },
                    new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-190.658 95.74", OffsetMax = "190.662 128.9" }
                }
            });

            container.Add(new CuiButton
            {
                Button = { Color = "0.4078432 0.3372549 0.3019608 1", Close = Layer },
                Text = { Text = "✖", Font = "robotocondensed-bold.ttf", FontSize = 16, Align = TextAnchor.MiddleCenter, Color = "0.8156863 0.5568628 0.4745098 1" },
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "161.617 99.907", OffsetMax = "186.383 124.733" }
            }, Layer, Layer + ".close");
            
            container.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "1 1 1 0" },
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-190.658 48.727", OffsetMax = "190.662 95.74" }
            }, Layer, Layer + ".categories");
            
            container.Add(new CuiElement
            {
                Name = Layer + ".categories" + ".label",
                Parent = Layer + ".categories",
                Components = {
                    new CuiTextComponent { Text = "ALLOWED CATEGORIES", Font = "robotocondensed-bold.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "0.8078431 0.7803922 0.7411765 1" },
                    new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-185.532 0.058", OffsetMax = "190.66 23.506" }
                }
            });
            
            float minx = -183.1622f;
            float maxx = -159.4378f;  
            float miny = -23.7244f;
            float maxy = 0f;
            
            var categories = chest.AllowedCategories.IsNullOrEmpty() ? AllCategories : chest.AllowedCategories;
            foreach (var x in chest.AllowedCategories)
            {
                
                container.Add(new CuiButton
                {
                    Button = { Color = "0.5254902 0.5019608 0.4666667 1", Sprite = CategoryToSprite[x] },
                    Text = { Text = "", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0 0 0 1" },
                    RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{minx} {miny}", OffsetMax =  $"{maxx} {maxy}" }
                }, Layer + ".categories", Layer + $".cat.{x}");
                
                minx += 25.3f;
                maxx += 25.3f;
            }
            
            container.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "1 1 1 0" },
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-190.665 -82.066", OffsetMax = "190.655 48.726" }
            }, Layer, Layer + ".blacklistedItems");
            container.Add(new CuiElement
            {
                Name = Layer + ".blacklistedItems" + ".label",
                Parent = Layer + ".blacklistedItems",
                Components = {
                    new CuiTextComponent { Text = "BLACKLISTED ITEMS", Font = "robotocondensed-bold.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "0.8078431 0.7803922 0.7411765 1" },
                    new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-185.532 41.948", OffsetMax = "190.66 65.396" }
                }
            });
            minx = -181.5822f;
            maxx = -157.8578f;
            miny = 15.7378f;
            maxy = 39.4622f;
            int i = 0;
            foreach (var x in chest.BlacklistedItems)
            {
                var item = ItemManager.FindItemDefinition(x.Shortname);
                if (item == null)
                    continue;
                if (i != 0 && i % 14 == 0)
                {
                    minx = -181.5822f;
                    maxx = -157.8578f;
                }

                
                container.Add(new CuiElement()
                {
                    Name = Layer + ".blacklistedItems" + $".item.{x.Shortname}.{x.SkinId}",
                    Parent = Layer + ".blacklistedItems",
                    Components =
                    {
                        new CuiImageComponent() { ItemId = item.itemid, SkinId = x.SkinId },
                        new CuiRectTransformComponent() { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{minx} {miny}", OffsetMax =  $"{maxx} {maxy}" }
                    }
                });
                
                minx += 25.32f;
                maxx += 25.32f;
                i++;
            }
            container.Add(new CuiPanel
            {
                CursorEnabled = false,
                Image = { Color = "1 1 1 0" },
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-190.658 -128.905", OffsetMax = "190.662 -82.075" }
            }, Layer, Layer + ".description");

            container.Add(new CuiElement
            {
                Name = Layer + ".description" + ".capacity",
                Parent = Layer + ".description",
                Components = {
                    new CuiTextComponent { Text = $"CAPACITY: {slots}", Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.LowerRight, Color = "0.8078431 0.7803922 0.7411765 1" },
                    new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "32.022 -23.416", OffsetMax = "186.978 0" }
                }
            });
            
            CuiHelper.AddUi(player, container);
        }
        private void UI_DrawHelpButton(BasePlayer player, int slots, string key)
        {
            CuiHelper.DestroyUi(player, Layer);
            var container = new CuiElementContainer();
            
            container.Add(new CuiButton
            {
                Button = { Color = "0.3882353 0.3960785 0.3098039 1", Command = $"cm.openmenu {slots} {key}" },
                Text = { Text = "?", Font = "robotocondensed-bold.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8078431 0.8431373 0.5490196 1" },
                RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = $"551.218 {176.688 + ((slots / 6) * 61.73)}", OffsetMax = $"571.382 {196.852  + ((slots / 6) * 61.73)}" }
            }, "Overlay", Layer + ".btn");
            
            CuiHelper.AddUi(player, container);
        }
        #endregion

        #region Commands

        [ConsoleCommand("cm.openmenu")]
        private void cmdOpenMenu(ConsoleSystem.Arg arg)
        {
            if (arg.Player() == null || arg.Args.IsNullOrEmpty())
                return;
            
            if (!arg.Player().IPlayer.HasPermission(PERM_HELPMENU))
                return;
            
            if (!int.TryParse(arg.Args[0], out var slots))
                return;

            var key = ConcatArgs(arg.Args, 1);
            if (!cfg.Chests.ContainsKey(key))
                return;
            UI_DrawMain(arg.Player(), key, slots);
        }
        
        [ChatCommand("cm.give")]
        private void cmdGive(BasePlayer player, string command, string[] args)
        {
            if (player != null)
                if (!player.IsAdmin && !player.IPlayer.HasPermission(PERM_GIVE))
                    return;

            if (args.IsNullOrEmpty())
            {
                SendMessage(player, "Usage: /cm.give 'chest key' 'player'");
                return;
            }

            if (!cfg.Chests.TryGetValue(args[0], out var chest))
            {
                SendMessage(player, $"Chest '{args[0]}' not found in config");
                return;
            }

            var arg = ConcatArgs(args, 1);

            if (string.IsNullOrEmpty(arg))
            {
                player.GiveItem(chest.Get());
                return;
            }
            
            var target = BasePlayer.activePlayerList.FirstOrDefault(x =>
                x.UserIDString == arg || x.displayName.Contains(arg, CompareOptions.IgnoreCase));
            if (target == null)
            {
                SendMessage(player, $"Player '{arg}' not found");
                return;
            }
            
            target.GiveItem(chest.Get());
        }
        #endregion
        
        #region Config

        private ConfigData cfg;

        public class ConfigData
        {
            [JsonProperty("Chests")] 
            public Dictionary<string, Chest> Chests;
        }

        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData()
            {
                Chests = new()
                {
                    ["test"] = new Chest
                    {
                        displayName = "Large test box",
                        Shortname = "box.wooden.large",
                        SkinId = 5,
                        Capacity = 3,
                        BlacklistedItems = new()
                        {
                            new()
                            {
                                Shortname = "rifle.ak",
                                SkinId = 0
                            },
                            new()
                            {
                                Shortname = "sulfur.ore",
                                SkinId = 0
                            },
                        },
                        AllowedCategories = new()
                        {
                            "Attire",
                            "Misc",
                            "Items",
                            "Component",
                            "Ammunition",
                            "Construction",
                            "Traps",
                            "Electrical",
                            "Fun",
                            "Food",
                            "Weapon",
                            "Resources",
                            "Tool",
                            "Medical"
                        },
                        SpawnChances = new()
                        {
                            ["assets/bundled/prefabs/radtown/crate_basic.prefab"] = 5,
                            ["assets/bundled/prefabs/radtown/crate_elite.prefab"] = 100,
                            ["assets/prefabs/npc/scientist/scientist_corpse.prefab"] = 100
                        }
                    },
                    ["test1"] = new Chest
                    {
                        displayName = "Small test box",
                        Shortname = "box.wooden",
                        SkinId = 6,
                        Capacity = 35,
                        BlacklistedItems = new()
                        {
                            new()
                            {
                                Shortname = "rifle.lr300",
                                SkinId = 0
                            },
                            new()
                            {
                                Shortname = "metal.ore",
                                SkinId = 0
                            },
                        },
                        AllowedCategories = new()
                        {
                            "Attire",
                            "Misc",
                            "Items",
                            "Component",
                            "Ammunition",
                            "Construction",
                            "Traps",
                            "Weapon",
                            "Resources",
                            "Tool",
                            "Medical"
                        },
                        SpawnChances = new()
                        {
                            ["assets/bundled/prefabs/radtown/crate_basic.prefab"] = 100,
                            ["assets/bundled/prefabs/radtown/crate_elite.prefab"] = 5,
                            ["assets/prefabs/npc/scientist/scientist_corpse.prefab"] = 50
                        }
                    }
                }
            };
            SaveConfig(config);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            cfg = Config.ReadObject<ConfigData>();
            SaveConfig(cfg);
        }

        private void SaveConfig(object config)
        {
            Config.WriteObject(config, true);
        }
        #endregion
    }
}

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