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

FREE LootManager : 1.1.1 1.1.1

Нет прав для скачивания
C#:
using Random = UnityEngine.Random;
using Newtonsoft.Json.Linq;
using UnityEngine.Networking;
using Oxide.Core;
using UnityEngine.UI;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using System.IO;
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using WebSocketSharp;
using System;
using Oxide.Plugins.LootManagerExtensionMethods;
using Facepunch.Extend;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
    [Info("LootManager", "Adem", "1.1.1")]
    public class LootManager : RustPlugin {
        private static string GetStringFromArgs(string[] args, int startIndex) {
            string result = "";
            for (int i = startIndex; i < args.Length; i++) {
                if (i > startIndex) result += " ";
                string word = args[i];
                result += word;
            }
            return result;
        }
        [ConsoleCommand("EditTableRight_NewElementButton_LootManager")]
        private void EditTableRightNewElementButtonCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission(player)) return;
            if (arg.Args == null || arg.Args.Length < 2) return;
            string lootTablePreset = arg.Args[0];
            bool isPrefab = arg.Args[1].ToBool();
            ChooseElementPanelGui.Draw(player, lootTablePreset, isPrefab);
        }
        private static class LootController {
            public static void UpdateFridge(Fridge fridge, LootTableData lootTableData) {
                fridge.OnlyAcceptCategory = ItemCategory.All;
                FillContainer(fridge.inventory, lootTableData);
            }
            public static void FillContainer(ItemContainer container, LootTableData lootTableData) {
                if (lootTableData.ClearDefaultItems) ClearContainer(container);
                if (lootTableData.UseItemList) {
                    if (lootTableData.UseMinMaxForItems) {
                        int itemsAmount = Random.Range(lootTableData.MinItemsAmount, lootTableData.MaxItemsAmount + 1);
                        HashSet<ItemData> itemsForSpawn = GetElementsForSpawn(lootTableData.Items, itemsAmount);
                        if (itemsForSpawn.Count > 0) ItemListController.FillContainer(container, itemsForSpawn);
                    }
                    else if (lootTableData.Items.Count > 0) {
                        ItemListController.FillContainerWithoutMinMax(container, lootTableData.Items);
                    }
                }
                if (lootTableData.UsePrefabList) {
                    int prefabsAmount = Random.Range(lootTableData.MinPrefabsAmount, lootTableData.MaxPrefabsAmount + 1);
                    HashSet<PrefabData> prefabsForSpawn = GetElementsForSpawn(lootTableData.Prefabs, prefabsAmount);
                    PrefabController.FillContainer(container, prefabsForSpawn);
                }
                if (!string.IsNullOrEmpty(lootTableData.AlphaLootPreset)) {
                    if (_ins.plugins.Exists("AlphaLoot") && (bool)_ins.AlphaLoot.Call("ProfileExists", lootTableData.AlphaLootPreset)) {
                        _ins.AlphaLoot.Call("PopulateLoot", container, lootTableData.AlphaLootPreset);
                    }
                }
                if (!string.IsNullOrEmpty(lootTableData.CustomLootPreset)) {
                    if (!_ins.plugins.Exists("CustomLoot")) return;
                    List<Item> items = (List<Item>)_ins.CustomLoot?.Call("MakeLoot", lootTableData.CustomLootPreset);
                    if (items != null) foreach (Item item in items) if (item == null || !item.MoveToContainer(container)) item.Remove();
                }
                if (!string.IsNullOrEmpty(lootTableData.LootTablePluginLootPreset)) {
                    if (!_ins.plugins.Exists("Loottable")) return;
                    List<Item> items = _ins.Loottable.Call<List<Item>>("MakeLoot", lootTableData.LootTablePluginLootPreset);
                    if (items != null) {
                        foreach (Item item in items) if (item == null || !item.MoveToContainer(container)) item.Remove();
                        Facepunch.Pool.FreeUnmanaged(ref items);
                    }
                }
            }
            private static HashSet<T> GetElementsForSpawn<T>(List<T> elements, int targetAmount) where T : LootElementChance {
                HashSet<T> result = new HashSet<T>();
                if (elements.Count == 0 || targetAmount <= 0) return result;
                HashSet<int> includedIndexes = new HashSet<int>();
                int counter = 200;
                while (result.Count < targetAmount && counter-- > 0) {
                    if (_ins._config.EnhancedRandomizer) {
                        float sumChance = 0f;
                        for (int i = 0; i < elements.Count; i++) {
                            if (includedIndexes.Contains(i)) continue;
                            sumChance += elements[i].Chance;
                        }
                        float random = Random.Range(0f, sumChance);
                        for (int i = 0; i < elements.Count; i++) {
                            if (includedIndexes.Contains(i)) continue;
                            T lootElement = elements[i];
                            random -= lootElement.Chance;
                            if (random <= 0f) {
                                includedIndexes.Add(i);
                                result.Add(lootElement);
                                break;
                            }
                        }
                    }
                    else {
                        for (int i = 0; i < elements.Count; i++) {
                            if (includedIndexes.Contains(i)) continue;
                            T lootElement = elements[i];
                            float chance = elements[i].Chance;
                            float roll = Random.Range(0f, 100f);
                            if (roll >= chance) continue;
                            includedIndexes.Add(i);
                            result.Add(lootElement);
                            if (result.Count >= targetAmount) break;
                        }
                    }
                }
                return result;
            }
            private static void ClearContainer(ItemContainer container) {
                for (int i = container.itemList.Count - 1; i >= 0; i--) {
                    Item item = container.itemList[i];
                    item.RemoveFromContainer();
                    item.Remove();
                }
            }
            public static void UpdateNpc(NPCPlayerCorpse corpse, string lootTableName) {
                if (!_ins._lootTables.TryGetValue(lootTableName, out LootTableData lootTableData)) return;
                if (corpse.containers.IsNullOrEmpty()) return;
                corpse.Invoke(() => {
                    ItemContainer container = corpse.containers[0];
                    if (container != null) FillContainer(container, lootTableData);
                }
                , 0.05f);
            }
            public static void UpdateLootContainer(LootContainer lootContainer, LootTableData lootTableData) {
                lootContainer.Invoke(() => {
                    FillContainer(lootContainer.inventory, lootTableData);
                }
                , 2f);
            }
        }
        private readonly HashSet<PrefabInfo> _prefabInfos = new HashSet<PrefabInfo> {
            new ("assets/bundled/prefabs/autospawn/resource/loot/loot-barrel-1.prefab", "loot-barrel-1", "Yellow Loot Barrel"), new ("assets/bundled/prefabs/autospawn/resource/loot/loot-barrel-2.prefab", "loot-barrel-2", "Blue Loot Barrel"), new ("assets/bundled/prefabs/radtown/oil_barrel.prefab", "oil_barrel", "Oil Barrel"), new ("assets/bundled/prefabs/radtown/crate_basic.prefab", "crate_basic", "Basic Crate"), new ("assets/bundled/prefabs/radtown/crate_basic_jungle.prefab", "crate_basic_jungle", "Crate Basic Jungle"), new ("assets/bundled/prefabs/radtown/crate_elite.prefab", "crate_elite", "Elite Crate"), new ("assets/prefabs/npc/m2bradley/bradley_crate.prefab", "crate_elite", "Elite Crate - Bradley"), new ("assets/prefabs/npc/patrol helicopter/heli_crate.prefab", "crate_elite", "Elite Crate - Heli"), new ("assets/prefabs/misc/food cache/food_cache_001.prefab", "food_cache_001", "Food Cache"), new ("assets/bundled/prefabs/radtown/foodbox.prefab", "foodbox", "Foodbox"), new ("assets/prefabs/deployable/chinooklockedcrate/codelockedhackablecrate.prefab", "codelockedhackablecrate", "Locked Crate"), new ("assets/prefabs/deployable/chinooklockedcrate/codelockedhackablecrate_oilrig.prefab", "codelockedhackablecrate", "Locked Crate - Oilrig"), new ("assets/bundled/prefabs/radtown/crate_normal.prefab", "crate_normal", "Military Crate"), new ("assets/bundled/prefabs/radtown/crate_normal_2.prefab", "crate_normal_2", "Normal Crate"), new ("assets/bundled/prefabs/radtown/crate_mine.prefab", "crate_normal_2", "Normal Crate - Cave"), new ("assets/bundled/prefabs/radtown/crate_normal_2_food.prefab", "crate_normal_2_food", "Normal Crate - Food"), new ("assets/bundled/prefabs/radtown/crate_normal_2_medical.prefab", "crate_normal_2_medical", "Normal Crate - Medical"), new ("assets/prefabs/misc/supply drop/supply_drop.prefab", "supply_drop", "Supply Drop"), new ("assets/bundled/prefabs/radtown/crate_tools.prefab", "crate_tools", "Tools Crate"), new ("assets/bundled/prefabs/radtown/crate_underwater_advanced.prefab", "crate_underwater_advanced", "Underwater Advanced Crate"), new ("assets/bundled/prefabs/radtown/crate_underwater_basic.prefab", "crate_basic", "Underwater Basic Crate"), new ("assets/bundled/prefabs/radtown/underwater_labs/crate_ammunition.prefab", "crate_ammunition", "Underwater Lab - Ammunition Crate"), new ("assets/bundled/prefabs/radtown/underwater_labs/crate_food_1.prefab", "crate_food_1", "Underwater Lab - Food Crate"), new ("assets/bundled/prefabs/radtown/underwater_labs/crate_fuel.prefab", "crate_fuel", "Underwater Lab - Fuel Crate"), new ("assets/bundled/prefabs/radtown/underwater_labs/crate_medical.prefab", "crate_medical", "Underwater Lab - Medical Crate"), new ("assets/bundled/prefabs/radtown/underwater_labs/tech_parts_1.prefab", "tech_parts_1", "Underwater Lab - Tier 2 Components"), new ("assets/bundled/prefabs/radtown/underwater_labs/tech_parts_2.prefab", "tech_parts_2", "Underwater Lab - Tier 3 Components"), new ("assets/bundled/prefabs/radtown/underwater_labs/vehicle_parts.prefab", "vehicle_parts", "Vehicle Parts"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_bradley.prefab", "scientistnpc", "Bradley Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_bradley_heavy.prefab", "scientistnpc_heavy", "Bradley Heavy Scientist"), new (new HashSet<string> {
                "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_cargo.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_cargo_turret_any.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_cargo_turret_lr300.prefab",
            }
            , "scientistnpc", "Cargo Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_excavator.prefab", "scientistnpc", "Excavator Scientist"), new (new HashSet<string> {
                "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_mp5.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_lr300.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_pistol.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_shotgun.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_any.prefab",
            }
            , "scientistnpc", "Military Tunnel Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_heavy.prefab", "scientistnpc_heavy", "Heavy Scientist"), new (new HashSet<string> {
                "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_junkpile_pistol.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_outbreak.prefab"
            }
            , "scientistnpc", "Road Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_oilrig.prefab", "scientistnpc", "Oilrig Scientist"), new (new HashSet<string> {
                "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_patrol.prefab", "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_patrol_arctic.prefab"
            }
            , "scientistnpc", "Patrol Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_roam.prefab", "scientistnpc", "Roam Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_roam_nvg_variant.prefab", "scientistnpc_tunnel", "Missile Silo Scientist"), new ("assets/rust.ai/agents/npcplayer/humannpc/tunneldweller/npc_tunneldweller.prefab", "npc_tunneldweller", "Tunnel/ Underwater Dweller"), new ("assets/prefabs/npc/gingerbread/gingerbread_dungeon.prefab", "gingerbread_dungeon", "Gingerbread"), new ("assets/prefabs/npc/scarecrow/scarecrow_dungeon.prefab", "scarecrow_dungeon", "Scarecrow"),
        }
        ;
        [ConsoleCommand("EditTableRight_FindElement_LootManager")]
        private void EditTableRightFindElementCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission(player)) return;
            if (arg.Args == null || arg.Args.Length < 3) return;
            string lootTablePreset = arg.Args[0];
            bool isPrefabSetting = arg.Args[1].ToBool();
            int page = arg.Args[2].ToInt();
            const int startInputArgIndex = 3;
            if (arg.Args.Length < startInputArgIndex + 1) {
                EditPanelGui.RightPanel.DrawElements(player, lootTablePreset, isPrefabSetting, page, string.Empty);
                return;
            }
            string filter = GetStringFromArgs(arg.Args, startInputArgIndex);
            EditPanelGui.RightPanel.DrawElements(player, lootTablePreset, isPrefabSetting, page, filter);
        }
        [ChatCommand("lm")]
        private void OpenChatCommand(BasePlayer player, string command, string[] arg) {
            if (!IsPlayerHavePermission(player)) {
                PrintToChat(player, $"[{Name}] You don’t have permission!");
                return;
            }
            CreateGui(player);
        }
        private void Unsubscribes() {
            foreach (string hook in _subscribeMethods) Unsubscribe(hook);
        }
        [ConsoleCommand("ChooseElementPanel_ChooseCategory_LootManager")]
        private void ChooseElementPanelChangeCategoryCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission(player)) return;
            if (arg.Args == null || arg.Args.Length < 3) return;
            if (!_ins._playerGuiInfos.TryGetValue(player.userID, out PlayerGuiInfo playerGuiInfo)) {
                playerGuiInfo = new PlayerGuiInfo();
                _ins._playerGuiInfos[player.userID] = playerGuiInfo;
            }
            string lootTablePreset = arg.Args[0];
            string categoryName = arg.Args[1];
            int.TryParse(arg.Args[2], out int page);
            ItemCategory itemCategory = (ItemCategory)Enum.Parse(typeof(ItemCategory), categoryName, true);
            playerGuiInfo.ItemCategorySelected = itemCategory;
            ChooseElementPanelGui.DrawItemList(player, lootTablePreset, string.Empty, playerGuiInfo);
            ChooseElementPanelGui.DrawCategoryPanel(player, lootTablePreset, page, playerGuiInfo);
        }
        private void AddNpc(ulong netId, string lootTableName) {
            if (string.IsNullOrEmpty(lootTableName) || !_lootTables.ContainsKey(lootTableName)) return;
            _npcs.TryAdd(netId, lootTableName);
        }
        private void Init() {
            Unsubscribes();
        }
        private readonly Dictionary<string, PrefabLootInfo> _prefabLootTables = new Dictionary<string, PrefabLootInfo>();
        private static LootTableData LoadLootTable(string fileName) {
            string path = $"{_ins.Name}/LootTables/{fileName}";
            LootTableData lootTableData = Interface.Oxide.DataFileSystem.ReadObject<LootTableData>(path);
            return lootTableData;
        }
        private void OnEntityKill(ScientistNPC npc) {
            if (npc == null || npc.net == null) return;
            _npcs.Remove(npc.net.ID.Value);
        }
        public class PrefabData : LootElementChance {
            public string PrefabName;
            public string ShortPrefabName;
            private PrefabData() {
            }
            public PrefabData(string prefabName, string shortPrefabName) {
                PrefabName = prefabName;
                ShortPrefabName = shortPrefabName;
                MinAmount = 1;
                MaxAmount = 1;
                Chance = 10f;
            }
            public bool DeepEquals(PrefabData other) {
                if (other == null) return false;
                return PrefabName == other.PrefabName && MinAmount == other.MinAmount && MaxAmount == other.MaxAmount && Math.Abs(Chance - other.Chance) < 0.0001f;
            }
            public void CheckAndUpdateValues() {
                if (MinAmount > MaxAmount) MinAmount = MaxAmount;
                if (MaxAmount < MinAmount) MaxAmount = MinAmount;
                Chance = Mathf.Clamp(Chance, 0, 100);
                if (string.IsNullOrEmpty(ShortPrefabName)) ShortPrefabName = PrefabName.Split('/').Last().Replace(".prefab", string.Empty);
            }
            public PrefabData Clone() {
                return new PrefabData() {
                    PrefabName = PrefabName, ShortPrefabName = ShortPrefabName, MinAmount = MinAmount, MaxAmount = MaxAmount, Chance = Chance
                }
                ;
            }
        }
        [ConsoleCommand("EditTableLeft_ChangeCategory_LootManager")]
        private void EditPanelGuiChangeCategory(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission(player)) return;
            if (arg.Args == null || arg.Args.Length < 2) return;
            string lootTablePreset = arg.Args[0];
            string categoryShortName = arg.Args[1];
            EditPanelGui.LeftPanel.Draw(player, lootTablePreset, categoryShortName);
            if (categoryShortName == "items") EditPanelGui.RightPanel.DrawElements(player, lootTablePreset, false, 0, string.Empty);
            else if (categoryShortName == "prefabs") EditPanelGui.RightPanel.DrawElements(player, lootTablePreset, true, 0, string.Empty);
            else if (categoryShortName == "main") EditPanelGui.RightPanel.DrawInstruction(player, 0);
            else EditPanelGui.RightPanel.DrawInstruction(player, 1);
        }
        private static class ChooseElementPanelGui {
            public static void Close(BasePlayer player) {
                CuiHelper.DestroyUi(player, "ItemCategory_Background");
                CuiHelper.DestroyUi(player, "ElementChooser_Background");
                CuiHelper.DestroyUi(player, "ItemChooser_Background");
                CuiHelper.DestroyUi(player, "ItemList_SearchPanel");
            }
            public static void Draw(BasePlayer player, string lootTableName, bool isPrefab) {
                if (!_ins._playerGuiInfos.TryGetValue(player.userID, out PlayerGuiInfo playerGuiInfo)) {
                    playerGuiInfo = new PlayerGuiInfo();
                    _ins._playerGuiInfos[player.userID] = playerGuiInfo;
                }
                DrawBackground(player, lootTableName, isPrefab);
                if (isPrefab) DrawPrefabList(player, lootTableName, string.Empty);
                else {
                    DrawItemList(player, lootTableName, string.Empty, playerGuiInfo);
                    DrawCategoryPanel(player, lootTableName, 0, playerGuiInfo);
                }
            }
            private static void DrawBackground(BasePlayer player, string lootTableName, bool isPrefab) {
                CuiElementContainer container = new CuiElementContainer();
                container.AddRect("ElementChooser_Background", BackgroundName, "0 0 0 0.9", "0 0", "1 1", "0 0", "0 0");
                container.AddButton(string.Empty, "ElementChooser_Background", "0 0", "1 1", string.Empty, string.Empty, $"ChooseElementPanel_Close_LootManager {lootTableName} {isPrefab}");
                container.AddRect(string.Empty, "ElementChooser_Background", "0.1 0.1 0.1 1", "0.5 0.5", "0.5 0.5", "-336 -251", $"336 251");
                CuiHelper.AddUi(player, container);
            }
            public static void DrawPrefabList(BasePlayer player, string lootTableName, string filter) {
                HashSet<ElementInfo> elements = new HashSet<ElementInfo>();
                HashSet<PrefabInfo> cratesForDisplay;
                if (string.IsNullOrEmpty(filter)) cratesForDisplay = _ins._prefabInfos;
                else cratesForDisplay = _ins._prefabInfos.Where(x => x.ShortPrefabName.Contains(filter));
                foreach (PrefabInfo crateInfo in cratesForDisplay) {
                    ElementInfo elementInfo = new ElementInfo(crateInfo.Name, $"ChooseElementPanel_ChoosePrefab_LootManager {lootTableName} {crateInfo.ShortPrefabName}", 0, _ins._imageIDs[crateInfo.ImageName]);
                    elements.Add(elementInfo);
                }
                DrawElements(player, lootTableName, filter, true, elements);
            }
            public static void DrawItemList(BasePlayer player, string lootTableName, string filter, PlayerGuiInfo playerGuiInfo) {
                HashSet<ItemDefinition> itemsForDisplay;
                if (string.IsNullOrEmpty(filter)) itemsForDisplay = ItemManager.itemList.Where(x => (_ins._config.IsHiddenItems || !x.hidden) && x.category == playerGuiInfo.ItemCategorySelected);
                else itemsForDisplay = ItemManager.itemList.Where(x => (_ins._config.IsHiddenItems || !x.hidden) && (x.shortname.Contains(filter) || x.displayName.english.Contains(filter)));
                HashSet<ElementInfo> elements = new HashSet<ElementInfo>();
                foreach (ItemDefinition itemDefinition in itemsForDisplay) {
                    ElementInfo elementInfo = new ElementInfo(itemDefinition.displayName.english, $"ChooseElementPanel_ChooseItem_LootManager {lootTableName} {itemDefinition.shortname}", itemDefinition.itemid, string.Empty);
                    elements.Add(elementInfo);
                }
                DrawElements(player, lootTableName, filter, false, elements);
            }
            public static void DrawCategoryPanel(BasePlayer player, string lootTableName, int startPage, PlayerGuiInfo playerGuiInfo) {
                List<ItemCategory> itemCategories = new List<ItemCategory> {
                    ItemCategory.Weapon, ItemCategory.Construction, ItemCategory.Items, ItemCategory.Resources, ItemCategory.Attire, ItemCategory.Tool, ItemCategory.Medical, ItemCategory.Food, ItemCategory.Ammunition, ItemCategory.Traps, ItemCategory.Misc, ItemCategory.Component, ItemCategory.Electrical, ItemCategory.Fun
                }
                ;
                startPage = Mathf.Clamp(startPage, 0, 8);
                CuiHelper.DestroyUi(player, "ItemCategory_Background");
                CuiElementContainer container = new CuiElementContainer();
                container.AddRect("ItemCategory_Background", BackgroundName, "0.15 0.15 0.15 1", "0.5 0.5", "0.5 0.5", "-300 251", "300 283");
                DrawPageButton(ref container, lootTableName, true, $"ChooseElementPanel_ChangeCategoryPage_LootManager {lootTableName} {(startPage - 1).ToString()}");
                DrawPageButton(ref container, lootTableName, false, $"ChooseElementPanel_ChangeCategoryPage_LootManager {lootTableName} {(startPage + 1).ToString()}");
                int xMin = 0;
                int xMax = 100;
                for (int i = startPage; i < itemCategories.Count; i++) {
                    ItemCategory category = itemCategories[i];
                    bool isActiveButton = playerGuiInfo.ItemCategorySelected == category;
                    string categoryName = category.ToString();
                    string buttonName = $"CategoryButton_{categoryName}";
                    container.AddRect(buttonName, "ItemCategory_Background", isActiveButton ? "0.2 0.2 0.2 1" : "0 0 0 0", "0 0", "0 1", $"{xMin} 0", $"{xMax} 0");
                    container.AddText(string.Empty, buttonName, "0.53 0.53 0.53 1", categoryName, TextAnchor.MiddleCenter, 16, "bold", "0 0", "1 1", "0 0", "0 0");
                    container.AddButton(string.Empty, buttonName, "0 0", "1 1", string.Empty, string.Empty, $"ChooseElementPanel_ChooseCategory_LootManager {lootTableName} {categoryName} {startPage}");
                    xMin = xMax;
                    xMax += 100;
                    if (xMax > 600) break;
                }
                CuiHelper.AddUi(player, container);
            }
            private static void DrawPageButton(ref CuiElementContainer container, string lootTableName, bool isLeft, string command) {
                int xMin = isLeft ? -336 : 304;
                int xMax = xMin + 32;
                string buttonText = isLeft ? "<" : ">";
                container.AddRect("ItemCategoryPageButton", "ItemCategory_Background", "0.25 0.25 0.25 1", "0.5 0", "0.5 0", $"{xMin} 0", $"{xMax} 32");
                container.AddText(string.Empty, "ItemCategoryPageButton", "0.53 0.53 0.53 1", buttonText, TextAnchor.MiddleCenter, 18, "bold", "0 0", "1 1", "0 0", "0 0");
                container.AddButton(string.Empty, "ItemCategoryPageButton", "0 0", "1 1", string.Empty, string.Empty, command);
            }
            private static void DrawElements(BasePlayer player, string lootTableName, string filter, bool isPrefab, HashSet<ElementInfo> elements) {
                CuiHelper.DestroyUi(player, "ItemChooser_Background");
                CuiElementContainer container = new CuiElementContainer();
                container.AddRect("ItemChooser_Background", BackgroundName, "0 0 0 0", "0.5 0.5", "0.5 0.5", "-336 -251", $"336 251");
                int yMinSearchPanel = isPrefab ? 251 : 296;
                if (!isPrefab) {
                    container.AddRect("ItemList_SearchPanel", "ElementChooser_Background", "0.1 0.1 0.1 1", "1 0.5", "1 0.5", $"-554 {yMinSearchPanel}", $"-304 {yMinSearchPanel + 30}");
                    container.AddImage(string.Empty, "ItemList_SearchPanel", _ins._imageIDs["Search_Icon"], filter, "0 0.5", "0 0.5", "5 -8", "21 8");
                    container.AddInputField(string.Empty, "ItemList_SearchPanel", "0.44 0.44 0.44 1", filter, TextAnchor.MiddleLeft, 16, "bold", "0 0", "1 1", "26 0", "0 0", $"ChooseElementPanel_SearchElement_LootManager {lootTableName} {false}");
                }
                int size = 83;
                int borderDelta = 10;
                int delta = 8;
                int totalRow = elements.Count == 0 ? 1 : (int)Math.Ceiling((double)elements.Count / 7);
                int scrollHeigh = borderDelta + totalRow * (size + delta);
                int scrollBackgroundHeigh = totalRow <= 5 ? scrollHeigh + delta : 482;
                container.AddRect("ItemList_ScrollBackground", "ItemChooser_Background", "0 0 0 0", "0 1", "0 1", $"10 -{scrollBackgroundHeigh}", "662 -10");
                CuiScrollViewComponent cuiScrollViewComponent = new CuiScrollViewComponent {
                    ContentTransform = new CuiRectTransformComponent {
                        AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = $"-336 -{scrollHeigh}", OffsetMax = "336 -10"
                    }
                    , Elasticity = float.MinValue, Horizontal = false, MovementType = ScrollRect.MovementType.Clamped, ScrollSensitivity = 5f, Vertical = true, VerticalScrollbar = new CuiScrollbar() {
                        AutoHide = false, HandleColor = "0.57 0.18 0.12 1", HighlightColor = "0.89 0.85 0.82 1", Invert = false, PressedColor = "0.89 0.85 0.82 1", Size = 6f, TrackColor = "0 0 0 0"
                    }
                }
                ;
                container.Add(new CuiElement {
                    Name = "ItemList_Scroll", Parent = "ItemList_ScrollBackground", Components = {
                        cuiScrollViewComponent
                    }
                }
                );
                int column = 0;
                int row = 0;
                foreach (ElementInfo elementInfo in elements) {
                    int xMin = borderDelta + column * (delta + size);
                    int yMax = -borderDelta - row * (delta + size);
                    int yMin = yMax - size;
                    int xMax = xMin + size;
                    string itemPanelName = $"ItemPanel_{elementInfo.Name}";
                    container.AddRect(itemPanelName, "ItemList_Scroll", "0.18 0.18 0.18 1", "0 1", "0 1", $"{xMin} {yMin}", $"{xMax} {yMax}");
                    if (elementInfo.ItemId != 0) container.AddItemIcon(string.Empty, itemPanelName, elementInfo.ItemId, 0, "0.5 0.5", "0.5 0.5", "-34 -34", "34 34");
                    else {
                        container.AddImage(string.Empty, itemPanelName, elementInfo.ImageId, string.Empty, "0.5 0.5", "0.5 0.5", "-34 -34", "34 34");
                    }
                    container.AddText(string.Empty, itemPanelName, "0.89 0.87 0.82 1", elementInfo.Name, TextAnchor.LowerCenter, 10, "regular", "0 0", "0 0", "5 3", "79 50");
                    container.AddButton(string.Empty, itemPanelName, "0 0", "1 1", string.Empty, string.Empty, elementInfo.Command);
                    column++;
                    if (column > 6) {
                        column = 0;
                        row++;
                    }
                }
                CuiHelper.AddUi(player, container);
            }
            private class ElementInfo {
                public readonly string Name;
                public readonly string Command;
                public readonly int ItemId;
                public readonly string ImageId;
                public ElementInfo(string name, string command, int itemId, string imageId) {
                    Name = name;
                    Command = command;
                    ItemId = itemId;
                    ImageId = imageId;
                }
            }
        }
        private static void Debug(params object[] arg) {
            string result = "";
            foreach (object obj in arg) result += obj.ToString() + " ";
            _ins.Puts(result);
        }
        private readonly Dictionary<string, LootTableUsageInfo> _pluginUsages = new Dictionary<string, LootTableUsageInfo>();
        private PluginConfig _config;
        private static bool IsRuLang(string userIdString) {
            return _ins.lang.GetLanguage(userIdString) == "ru";
        }
        private readonly Dictionary<string, LocalizeMessage> _localizeMessages = new Dictionary<string, LocalizeMessage> {
            ["PRESET_ALREADY_EXISTS"]
            = new LocalizeMessage {
                EnMessage = "A preset with this name already exists", RuMessage = "Пресет с таким именем уже существует",
            }
            , ["INVALID_PRESET_NAME_MULTIPLE_WORDS"] = new LocalizeMessage {
                EnMessage = "Preset name must be a single word (e.g., 'LootTable_1')", RuMessage = "Название пресета должно быть одним словом (пример: 'LootTable_1')"
            }
            , ["CLEAR_DEFAULT_CONFLICTS_WITH_EXTERNAL_LOOT"] = new LocalizeMessage {
                EnMessage = "Clear Default Contents + external loot without override → empty container. Disable clear or set override.", RuMessage = "Очистить контейнер + Лут из другого плагина без указанной лутовой таблицы → пустой контейнер"
            }
            , ["GUI_LOOT_TABLES"] = new LocalizeMessage {
                EnMessage = "LOOT TABLES", RuMessage = "СПИСОК ЛУТОВЫХ ТАБЛИЦ"
            }
            , ["GUI_CREATE_NEW_PRESET"] = new LocalizeMessage {
                EnMessage = "CREATE NEW PRESET", RuMessage = "СОЗДАТЬ НОВЫЙ ПРЕСЕТ"
            }
            , ["GUI_GENERAL"] = new LocalizeMessage {
                EnMessage = "GENERAL", RuMessage = "ОСНОВНОЕ"
            }
            , ["GUI_PRESET_NAME"] = new LocalizeMessage {
                EnMessage = "<b>PRESET</b> <color=#707070>NAME</color>", RuMessage = "<b>ИМЯ</b> <color=#707070>ПРЕСЕТА</color>"
            }
            , ["GUI_DESCRIPTION"] = new LocalizeMessage {
                EnMessage = "<b>DESCRIPTION</b>", RuMessage = "<b>ОПИСАНИЕ</b>"
            }
            , ["GUI_CLEAR_DEFAULT_ITEMS"] = new LocalizeMessage {
                EnMessage = "<b>CLEAR</b> <color=#707070>DEFAULT CONTENTS</color>", RuMessage = "<b>ОЧИСТИТЬ</b> <color=#707070>КОНТЕЙНЕР</color>"
            }
            , ["GUI_CLEAR_DEFAULT_ITEMS_SUBNAME"] = new LocalizeMessage {
                EnMessage = "DELETE ITEMS BEFORE ADDING", RuMessage = "УДАЛИТЬ ПРЕДМЕТЫ ПЕРЕД ДОБАВЛЕНИЕМ"
            }
            , ["GUI_ITEM_TABLE"] = new LocalizeMessage {
                EnMessage = "ITEM TABLE", RuMessage = "ТАБЛИЦА ПРЕДМЕТОВ"
            }
            , ["GUI_ADD_ITEMS"] = new LocalizeMessage {
                EnMessage = "<b>ADD ITEMS</b> <color=#707070>FROM LIST</color>", RuMessage = "<b>ДОБАВИТЬ ПРЕДМЕТЫ</b> <color=#707070>ИЗ СПИСКА</color>"
            }
            , ["GUI_USE_SETTINGS_BELOW"] = new LocalizeMessage {
                EnMessage = "<b>USE SETTINGS BELOW</b> <color=#707070> </color>", RuMessage = "<b>ИСПОЛЬЗОВАТЬ ПАРАМЕТРЫ НИЖЕ</b> <color=#707070> </color>"
            }
            , ["GUI_USE_SETTINGS_BELOW_SUBNAME"] = new LocalizeMessage {
                EnMessage = "EXACT MIN/MAX VALUES", RuMessage = "ТОЧНЫЕ ЗНАЧЕНИЯ МИН/МАКС"
            }
            , ["GUI_MIN_ITEMS"] = new LocalizeMessage {
                EnMessage = "<b>MIN</b> <color=#707070>ITEMS</color>", RuMessage = "<b>МИН КОЛ-ВО</b> <color=#707070>ПРЕДМЕТОВ</color>"
            }
            , ["GUI_MAX_ITEMS"] = new LocalizeMessage {
                EnMessage = "<b>MAX</b> <color=#707070>ITEMS</color>", RuMessage = "<b>МАКС КОЛ-ВО</b> <color=#707070>ПРЕДМЕТОВ</color>"
            }
            , ["GUI_PREFAB_TABLE"] = new LocalizeMessage {
                EnMessage = "PREFAB TABLE", RuMessage = "ТАБЛИЦА ПРЕФАБОВ"
            }
            , ["GUI_ADD_PREFABS"] = new LocalizeMessage {
                EnMessage = "<b>ADD PREFABS</b> <color=#707070>FROM LIST</color>", RuMessage = "<b>ДОБАВИТЬ ПРЕФАБЫ</b> <color=#707070>ИЗ СПИСКА</color>"
            }
            , ["GUI_ADD_PREFABS_SUBNAME"] = new LocalizeMessage {
                EnMessage = "DEFAULT LOOT FROM ENTITIES", RuMessage = "СТАНДАРТНЫЙ ЛУТ ИЗ СУЩНОСТЕЙ"
            }
            , ["GUI_MIN_PREFABS"] = new LocalizeMessage {
                EnMessage = "<b>MIN</b> <color=#707070>PREFABS</color>", RuMessage = "<b>МИН КОЛ-ВО</b> <color=#707070>ПРЕФАБОВ</color>"
            }
            , ["GUI_MAX_PREFABS"] = new LocalizeMessage {
                EnMessage = "<b>MAX</b> <color=#707070>PREFABS</color>", RuMessage = "<b>МАКС КОЛ-ВО</b> <color=#707070>ПРЕФАБОВ</color>"
            }
            , ["GUI_ALLOW_PLUGIN_SPAWN_LOOT"] = new LocalizeMessage {
                EnMessage = "<b>ALLOW PLUGIN</b> <color=#707070>TO SPAWN LOOT</color>", RuMessage = "<b>РАЗРЕШИТЬ</b> <color=#707070>СПАВНИТЬ ЛУТ</color>"
            }
            , ["GUI_ALLOW_PLUGIN_SPAWN_LOOT_SUBNAME_ALPHALOOT"] = new LocalizeMessage {
                EnMessage = "ALPHALOOT MAY CHANGE LOOT", RuMessage = "ALPHALOOT СМОЖЕТ ИЗМЕНЯТЬ ЛУТ"
            }
            , ["GUI_ALLOW_PLUGIN_SPAWN_LOOT_SUBNAME_CUSTOMLOOT"] = new LocalizeMessage {
                EnMessage = "CUSTOMLOOT MAY CHANGE LOOT", RuMessage = "CUSTOMLOOT СМОЖЕТ ИЗМЕНЯТЬ ЛУТ"
            }
            , ["GUI_ALLOW_PLUGIN_SPAWN_LOOT_SUBNAME_LOOTTABLE"] = new LocalizeMessage {
                EnMessage = "LOOT TABLE PLUGIN MAY CHANGE LOOT", RuMessage = "LOOT TABLE СМОЖЕТ ИЗМЕНЯТЬ ЛУТ"
            }
            , ["GUI_OVERRIDE_LOOT_TABLE"] = new LocalizeMessage {
                EnMessage = "<b>OVERRIDE</b> <color=#707070>LOOT TABLE</color>", RuMessage = "<b>ПЕРЕОПРЕДЕЛИТЬ</b> <color=#707070>ЛУТ-ТАБЛИЦУ</color>"
            }
            , ["GUI_PREFABS_INCLUDED"] = new LocalizeMessage {
                EnMessage = "PREFABS INCLUDED IN THE LOOT TABLE", RuMessage = "ПРЕФАБЫ В ЭТОЙ ЛУТОВОЙ ТАБЛИЦЕ"
            }
            , ["GUI_ITEMS_INCLUDED"] = new LocalizeMessage {
                EnMessage = "ITEMS INCLUDED IN THE LOOT TABLE", RuMessage = "ПРЕДМЕТЫ В ЭТОЙ ЛУТОВОЙ ТАБЛИЦЕ"
            }
            , ["GUI_ELEMENTS"] = new LocalizeMessage {
                EnMessage = "ELEMENTS: ", RuMessage = "КОЛИЧЕСТВО ЭЛЕМЕНТОВ: "
            }
            , ["GUI_NAME"] = new LocalizeMessage {
                EnMessage = "<b>NAME</b>", RuMessage = "<b>ИМЯ</b>"
            }
            , ["GUI_OWNER_NAME"] = new LocalizeMessage {
                EnMessage = "<b>OWNER NAME</b>", RuMessage = "<b>ИМЯ ВЛАДЕЛЬЦА</b>"
            }
            , ["GUI_CHANCE"] = new LocalizeMessage {
                EnMessage = "<b>CHANCE</b> <size=16><color=#707070>0.0-100.0</color></size>", RuMessage = "<b>ШАНС</b> <size=16><color=#707070>0.0–100.0</color></size>"
            }
            , ["GUI_AMOUNT"] = new LocalizeMessage {
                EnMessage = "<b>AMOUNT</b> <size=16><color=#707070>MIN–MAX</color></size>", RuMessage = "<b>КОЛИЧЕСТВО</b> <size=16><color=#707070>МИН–МАКС</color></size>"
            }
            , ["GUI_GENOMES"] = new LocalizeMessage {
                EnMessage = "<b>GENOMES</b> <size=16><color=#707070>(E.G. GGGYYY, HHHWWW)</color></size>", RuMessage = "<b>ГЕНОМЫ</b> <size=16><color=#707070>(НАПР.: GGGYYY, HHHWWW)</color></size>"
            }
            , ["GUI_IS_BLUEPRINT"] = new LocalizeMessage {
                EnMessage = "<b>IS BLUEPRINT</b>", RuMessage = "<b>ЭТО ЧЕРТЕЖ</b>"
            }
            , ["GUI_CANCEL"] = new LocalizeMessage {
                EnMessage = "CANCEL", RuMessage = "ОТМЕНИТЬ"
            }
            , ["GUI_SAVE"] = new LocalizeMessage {
                EnMessage = "SAVE", RuMessage = "СОХРАНИТЬ"
            }
            , ["GUI_DELETE"] = new LocalizeMessage {
                EnMessage = "DELETE", RuMessage = "УДАЛИТЬ"
            }
            , ["GUI_BACK"] = new LocalizeMessage {
                EnMessage = "BACK", RuMessage = "НАЗАД"
            }
            , ["GUI_INSTRUCTION_HEADER"] = new LocalizeMessage {
                EnMessage = "MANUAL", RuMessage = "ИНСТРУКЦИЯ"
            }
            , ["GUI_INSTRUCTION_ABOUT_PLUGIN_HEADER"] = new LocalizeMessage {
                EnMessage = "ABOUT LOOTMANAGER PLUGIN", RuMessage = "О ПЛАГИНЕ LOOTMANAGER"
            }
            , ["GUI_INSTRUCTION_ABOUT_PLUGIN_TEXT"] = new LocalizeMessage {
                EnMessage = "LootManager is a unified loot-table system for MadMappers events and plugins. It stores and allows you to edit loot tables, then fills NPCs and containers of other plugins with them\n<size=8>\n</size>" + "To apply a loot table to a specific object, enter its name in the config of that object in the “LootManager Preset” field of the plugin that spawns it. Works only with plugins marked as compatible on the plugin page", RuMessage = "LootManager — единая система лут-таблиц для событий и плагинов MadMappers.Он хранит и позволяет редактировать лутовые таблицы, а затем наполняет ими NPC и ящики сторонних плагинов\n<size=8>\n</size>" + "Чтобы применить лут-таблицу к конкретному объекту, впишите её имя в конфиг этого объекта в поле “LootManager Preset” в плагине, который спавнит объект.Работает только с плагинами, заявленными как совместимые на странице плагина"
            }
            , ["GUI_INSTRUCTION_GENERAL_HEADER"] = new LocalizeMessage {
                EnMessage = "GENERAL SECTION", RuMessage = "РАЗДЕЛ ОСНОВНОЕ"
            }
            , ["GUI_INSTRUCTION_GENERAL_TEXT"] = new LocalizeMessage {
                EnMessage = "Clear container — delete items from the container before adding loot from the Items and Prefabs sections. Useful if you want to completely replace the default loot", RuMessage = "Очистить контейнер — удалить предеметы из контейнара перед добавлением лута из разделов Items и Prefabs. Полезно, если хотите полностью заменить стандартный лут"
            }
            , ["GUI_INSTRUCTION_ITEMS_HEADER"] = new LocalizeMessage {
                EnMessage = "ITEM TABLE", RuMessage = "ТАБЛИЦА ПРЕДМЕТОВ"
            }
            , ["GUI_INSTRUCTION_ITEMS_TEXT"] = new LocalizeMessage {
                EnMessage = "- Add any items, including custom ones (skins/blueprints/genomes)\n<size=8>\n</size>" + "- Specify quantity ranges and chance for each item\n<size=8>\n</size>" + "- You can set the exact number of items that will appear in the container", RuMessage = "- Добавляйте любые предметы, включая кастомные (скины/чертежи/геномы)\n<size=8>\n</size>" + "- Указывайте диапазоны количества и шанс для каждого предмета\n<size=8>\n</size>" + "- Можно задать точное число предметов, которое попадёт в контейнер"
            }
            , ["GUI_INSTRUCTION_PREFABS_HEADER"] = new LocalizeMessage {
                EnMessage = "PREFAB TABLE", RuMessage = "ТАБЛИЦА ПРЕФАБОВ"
            }
            , ["GUI_INSTRUCTION_PREFABS_TEXT"] = new LocalizeMessage {
                EnMessage = "- Mix in standard game loot from prefabs (crates, barrels, NPCs, etc.)\n<size=8>\n</size>" + "- Flexibly control the amount: for example, “1 military crate + 2 barrels” in one table", RuMessage = "- Подмешивайте стандартный игровой лут из префабов (ящики, бочки, NPC и т.д.)\n<size=8>\n</size>" + "- Гибко регулируйте объём: например, «1 военный ящик + 2 бочки» в одну таблицу"
            }
            , ["GUI_INSTRUCTION_INTEGRATION_HEADER"] = new LocalizeMessage {
                EnMessage = "INTEGRATIONS: ALPHALOOT / CUSTOMLOOT / LOOTTABLE", RuMessage = "ИНТЕГРАЦИИ: ALPHALOOT / CUSTOMLOOT / LOOTTABLE"
            }
            , ["GUI_INSTRUCTION_INTEGRATION_TEXT"] = new LocalizeMessage {
                EnMessage = "- Sections for third-party plugins\n<size=8>\n</size>" + "- If these plugins are not installed — just ignore these settings\n<size=8>\n</size>" + "- When integrations are enabled, you can allow external plugins to modify or add loot according to your rules", RuMessage = "- Разделы для сторонних плагинов\n<size=8>\n</size>" + "- Если эти плагины у вас не установлены — просто игнорируйте эти настройки\n<size=8>\n</size>" + "- При включении интеграций можно разрешать внешним плагинам менять/дополнять лут по вашим правилам"
            }
            , ["GUI_FILTERS"] = new LocalizeMessage {
                EnMessage = "FILTERS", RuMessage = "ФИЛЬТРЫ"
            }
            , ["GUI_ALL"] = new LocalizeMessage {
                EnMessage = "All", RuMessage = "Все"
            }
            , ["GUI_UNUSED"] = new LocalizeMessage {
                RuMessage = "Неиспользуемые", EnMessage = "Unused"
            }
            , ["GUI_ENTER_NAME"] = new LocalizeMessage {
                EnMessage = "ENTER THE NAME", RuMessage = "ВВЕДИТЕ НАЗВАНИЕ"
            }
        }
        ;
        private static object HandleOtherPluginPopulate(ulong netId, Dictionary<ulong, string> targetDictionary, Func<LootTableData, bool> cancelFunction) {
            if (!targetDictionary.TryGetValue(netId, out string presetName)) return null;
            if (!_ins._lootTables.TryGetValue(presetName, out LootTableData lootTableData)) return null;
            return cancelFunction(lootTableData) ? true : null;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            _config = Config.ReadObject<PluginConfig>();
            Config.WriteObject(_config, true);
        }
        [ConsoleCommand("EditTableLeft_Switch_LootManager")]
        private void EditPanelGuiSwitchCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission(player)) return;
            if (arg.Args == null || arg.Args.Length < 3) return;
            bool ru = IsRuLang(player.UserIDString);
            string lootTablePreset = arg.Args[0];
            string sectionShortName = arg.Args[1];
            string fieldName = arg.Args[2];
            if (!_ins._lootTables.TryGetValue(lootTablePreset, out LootTableData lootTableData)) return;
            if (fieldName == "clearItems") {
                lootTableData.ClearDefaultItems = !lootTableData.ClearDefaultItems;
            }
            else if (fieldName == "isManual") {
                lootTableData.UseItemList = !lootTableData.UseItemList;
            }
            else if (fieldName == "isRandomNumber") {
                lootTableData.UseMinMaxForItems = !lootTableData.UseMinMaxForItems;
            }
            else if (fieldName == "isPrefab") {
                lootTableData.UsePrefabList = !lootTableData.UsePrefabList;
                PrefabController.CachePrefabs();
            }
            else if (fieldName == "isAlphaLoot") {
                if (lootTableData.ClearDefaultItems && !lootTableData.IsAlphaLoot && string.IsNullOrEmpty(lootTableData.AlphaLootPreset)) {
                    string message = GetMessage("CLEAR_DEFAULT_CONFLICTS_WITH_EXTERNAL_LOOT", ru);
                    ErrorDisplayer.ShowError(player, message);
                    return;
                }
                lootTableData.IsAlphaLoot = !lootTableData.IsAlphaLoot;
            }
            else if (fieldName == "isCustomLoot") {
                if (lootTableData.ClearDefaultItems && !lootTableData.IsCustomLoot && string.IsNullOrEmpty(lootTableData.CustomLootPreset)) {
                    string message = GetMessage("CLEAR_DEFAULT_CONFLICTS_WITH_EXTERNAL_LOOT", ru);
                    ErrorDisplayer.ShowError(player, message);
                    return;
                }
                lootTableData.IsCustomLoot = !lootTableData.IsCustomLoot;
            }
            else if (fieldName == "isLoottable") {
                if (lootTableData.ClearDefaultItems && !lootTableData.IsLootTablePlugin && string.IsNullOrEmpty(lootTableData.LootTablePluginLootPreset)) {
                    string message = GetMessage("CLEAR_DEFAULT_CONFLICTS_WITH_EXTERNAL_LOOT", ru);
                    ErrorDisplayer.ShowError(player, message);
                    return;
                }
                lootTableData.IsLootTablePlugin = !lootTableData.IsLootTablePlugin;
            }
            SaveLootTable(lootTablePreset, lootTableData);
            EditPanelGui.LeftPanel.Draw(player, lootTablePreset, sectionShortName);
        }
        [ConsoleCommand("EditTableRight_SetPageInstruction_LootManager")]
        private void EditTableRightSetPageInstructionCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || !IsPlayerHavePermission
// ... [Code preview truncated due to length. Full source in attached file] ...

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