Guest User

Kits.CS

a guest
Jul 29th, 2020
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 87.94 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. using Oxide.Core;
  7. using Oxide.Core.Plugins;
  8. using Oxide.Game.Rust.Cui;
  9. using UnityEngine;
  10.  
  11. namespace Oxide.Plugins
  12. {
  13.     [Info("Kits", "Reneb", "3.2.93", ResourceId = 668)]
  14.     class Kits : RustPlugin
  15.     {
  16.         readonly int playerLayer = LayerMask.GetMask("Player (Server)");
  17.  
  18.         //////////////////////////////////////////////////////////////////////////////////////////
  19.         ///// Plugin initialization
  20.         //////////////////////////////////////////////////////////////////////////////////////////
  21.         [PluginReference]
  22.         Plugin CopyPaste, ImageLibrary, EventManager;
  23.  
  24.         void Loaded()
  25.         {
  26.             LoadData();
  27.             try
  28.             {
  29.                 kitsData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, Dictionary<string, KitData>>>("Kits_Data");
  30.             }
  31.             catch
  32.             {
  33.                 kitsData = new Dictionary<ulong, Dictionary<string, KitData>>();
  34.             }
  35.             lang.RegisterMessages(messages, this);
  36.         }
  37.  
  38.         void OnServerInitialized()
  39.         {
  40.             InitializePermissions();
  41.             if (!string.IsNullOrEmpty(BackgroundURL))
  42.                 if (ImageLibrary)
  43.                     AddImage(BackgroundURL, "Background", (ulong)ResourceId);
  44.             foreach (var player in BasePlayer.activePlayerList)
  45.                 OnPlayerInit(player);
  46.         }
  47.  
  48.         void OnPlayerInit(BasePlayer player)
  49.         {
  50.             BindKeys(player);
  51.         }
  52.  
  53.         void InitializePermissions()
  54.         {
  55.             permission.RegisterPermission(this.Title + ".admin", this);
  56.             permission.RegisterPermission(this.Title + ".ConsoleGive", this);
  57.             foreach (var kit in storedData.Kits.Values)
  58.             {
  59.                 if (!string.IsNullOrEmpty(kit.permission) && !permission.PermissionExists(kit.permission))
  60.                     permission.RegisterPermission(kit.permission, this);
  61.                 if (ImageLibrary)
  62.                     AddImage(kit.image ?? "http://i.imgur.com/xxQnE1R.png", kit.name.Replace(" ", ""), (ulong)ResourceId);
  63.             }
  64.         }
  65.  
  66.         void BindKeys(BasePlayer player, bool unbind = false)
  67.         {
  68.             if (string.IsNullOrEmpty(UIKeyBinding)) return;
  69.             if (unbind)
  70.                 player.Command($"bind {UIKeyBinding} \"\"");
  71.             else
  72.                 player.Command($"bind {UIKeyBinding} \"UI_ToggleKitMenu\"");
  73.         }
  74.  
  75.         //////////////////////////////////////////////////////////////////////////////////////////
  76.         ///// Configuration
  77.         //////////////////////////////////////////////////////////////////////////////////////////
  78.  
  79.         Dictionary<ulong, GUIKit> GUIKits;
  80.         List<string> CopyPasteParameters = new List<string>();
  81.         string BackgroundURL;
  82.         string UIKeyBinding;
  83.         bool KitLogging;
  84.         bool ShowUnavailableKits;
  85.         public Dictionary<int, string> AutoKits = new Dictionary<int, string>();
  86.  
  87.         class GUIKit
  88.         {
  89.             public string description = string.Empty;
  90.             public List<string> kits = new List<string>();
  91.         }
  92.  
  93.         protected override void LoadDefaultConfig() { }
  94.  
  95.         void Init()
  96.         {
  97.             var config = Config.ReadObject<Dictionary<string, object>>();
  98.             if (!config.ContainsKey("NPC - GUI Kits"))
  99.             {
  100.                 config["NPC - GUI Kits"] = GetExampleGUIKits();
  101.                 Config.WriteObject(config);
  102.             }
  103.             if (!config.ContainsKey("CopyPaste - Parameters"))
  104.             {
  105.                 config["CopyPaste - Parameters"] = new List<string> { "deployables", "true", "inventories", "true" };
  106.                 Config.WriteObject(config);
  107.             }
  108.             if (!config.ContainsKey("Custom AutoKits"))
  109.             {
  110.                 config["Custom AutoKits"] = new Dictionary<int, string> {{0, "KitName" },{1, "KitName" },{2, "KitName" }};
  111.                 Config.WriteObject(config);
  112.             }
  113.             if (!config.ContainsKey("UI KeyBinding"))
  114.             {
  115.                 config["UI KeyBinding"] = string.Empty;
  116.                 Config.WriteObject(config);
  117.             }
  118.             if (!config.ContainsKey("Kit - Logging"))
  119.             {
  120.                 config["Kit - Logging"] = false;
  121.                 Config.WriteObject(config);
  122.             }
  123.             if (!config.ContainsKey("Show All Kits"))
  124.             {
  125.                 config["Show All Kits"] = false;
  126.                 Config.WriteObject(config);
  127.             }
  128.             if (!config.ContainsKey("Background - URL"))
  129.             {
  130.                 config["Background - URL"] = string.Empty;
  131.                 Config.WriteObject(config);
  132.             }
  133.             var keys = config.Keys.ToArray();
  134.             if (keys.Length > 1)
  135.             {
  136.                 foreach (var key in keys)
  137.                 {
  138.                     if (!key.Equals("NPC - GUI Kits") && !key.Equals("CopyPaste - Parameters") && !key.Equals("Custom AutoKits") && !key.Equals("UI KeyBinding") && !key.Equals("Background - URL") && !key.Equals("Kit - Logging") && !key.Equals("Show All Kits"))
  139.                         config.Remove(key);
  140.                 }
  141.                 Config.WriteObject(config);
  142.             }
  143.             CopyPasteParameters = JsonConvert.DeserializeObject<List<string>>(JsonConvert.SerializeObject(config["CopyPaste - Parameters"]));
  144.             GUIKits = JsonConvert.DeserializeObject<Dictionary<ulong, GUIKit>>(JsonConvert.SerializeObject(config["NPC - GUI Kits"]));
  145.             AutoKits = JsonConvert.DeserializeObject<Dictionary<int, string>>(JsonConvert.SerializeObject(config["Custom AutoKits"]));
  146.             UIKeyBinding = JsonConvert.DeserializeObject<string>(JsonConvert.SerializeObject(config["UI KeyBinding"]));
  147.             BackgroundURL = JsonConvert.DeserializeObject<string>(JsonConvert.SerializeObject(config["Background - URL"]));
  148.             KitLogging = JsonConvert.DeserializeObject<bool>(JsonConvert.SerializeObject(config["Kit - Logging"]));
  149.             ShowUnavailableKits = JsonConvert.DeserializeObject<bool>(JsonConvert.SerializeObject(config["Show All Kits"]));
  150.         }
  151.  
  152.         static Dictionary<ulong, GUIKit> GetExampleGUIKits()
  153.         {
  154.             return new Dictionary<ulong, GUIKit>
  155.             {
  156.                 {
  157.                     0, new GUIKit
  158.                     {
  159.                         kits = {"kit1", "kit2"},
  160.                         description = "Welcome to <color=orange>SPQR ROME 5X!</color> Here are your free kits! <color=green>Enjoy your stay!</color>"
  161.                     }
  162.                 },
  163. {
  164.                     1235439, new GUIKit
  165.                     {
  166.                         kits = {"kit1", "kit2"},
  167.                         description = "Welcome to <color=orange>SPQR ROME 5X!</color> Here are your free kits! <color=green>Enjoy your stay!</color>"
  168.                     }
  169.                 },
  170.                 {
  171.                     8753201223, new GUIKit
  172.                     {
  173.                         kits = {"kit1", "kit3"},
  174.                         description = "<color=red>VIPs Kits</color>"
  175.                     }
  176.                 }
  177.             };
  178.         }
  179.  
  180.         void OnPlayerRespawned(BasePlayer player)
  181.         {
  182.             var thereturn = Interface.Oxide.CallHook("canRedeemKit", player);
  183.             if (thereturn == null)
  184.             {
  185.                 if (storedData.Kits.ContainsKey("autokit"))
  186.                 {
  187.                     player.inventory.Strip();
  188.                     GiveKit(player, "autokit");
  189.                     return;
  190.                 }
  191.                 foreach (var entry in AutoKits.OrderBy(k=>k.Key))
  192.                     {
  193.                         var success = CanRedeemKit(player, entry.Value, true) as string;
  194.                         if (success != null) continue;
  195.                         player.inventory.Strip();
  196.                         success = GiveKit(player, entry.Value) as string;
  197.                         if (success != null) continue;
  198.                         proccessKitGiven(player, entry.Value);
  199.                         return;
  200.                     }
  201.             }
  202.         }
  203.  
  204.         //////////////////////////////////////////////////////////////////////////////////////////
  205.         ///// Language
  206.         //////////////////////////////////////////////////////////////////////////////////////////
  207.  
  208.         string GetMsg(string key, object steamid = null) { return lang.GetMessage(key, this, steamid == null ? null : steamid.ToString()); }
  209.  
  210.         Dictionary<string, string> messages = new Dictionary<string, string>()
  211.         {
  212.             {"title", "Kits: " },
  213.             {"Name", "Name" },
  214.             {"Description", "Description" },
  215.             {"Redeem", "Redeem" },
  216.             {"AddKit", "Add Kit" },
  217.             {"Close", "Close" },
  218.             {"NoKitsFound", "All Available Kits are already in this Menu!" },
  219.             {"AddKitToMenu", "Select a Kit to Add to this Menu" },
  220.             {"KitCooldown", "Cooldown: {0}" },
  221.             {"Unavailable", "Unavailable" },
  222.             {"Last", "Last" },
  223.             {"Next", "Next" },
  224.             {"Back", "Back" },
  225.             {"First", "First" },
  226.             {"RemoveKit", "Remove Kit?" },
  227.             {"KitUses", "Uses: {0}" },
  228.             {"NoInventorySpace", "You do not have enough inventory space for this Kit!" },
  229.             {"Unlimited", "Unlimited" },
  230.             {"None", "None" },
  231.             {"KitRedeemed", "Kit Redeemed" },
  232.             {"Emptykitname", "Empty Kit Name" },
  233.             {"KitExistError","This kit doesn't exist"},
  234.             {"CantRedeemNow","You are not allowed to redeem a kit at the moment"},
  235.             {"NoAuthToRedeem","You don't have the Auth Level to use this kit"},
  236.             {"NoPermKit","You don't have the permissions to use this kit"},
  237.             {"NoRemainingUses","You already redeemed all of these kits"},
  238.             {"CooldownMessage","You need to wait {0} seconds to use this kit"},
  239.             {"NPCError","You must find the NPC that gives this kit to redeem it."},
  240.             {"PastingError", "Something went wrong while pasting, is CopyPaste installed?"},
  241.             {"NoKitFound", "This kit doesn't exist" },
  242. };
  243.  
  244.         private readonly Dictionary<int, string> _itemIdShortnameConversions = new Dictionary<int, string>
  245.         {
  246.             [-1461508848] = "rifle.ak",
  247.             [2115555558] = "ammo.handmade.shell",
  248.             [-533875561] = "ammo.pistol",
  249.             [1621541165] = "ammo.pistol.fire",
  250.             [-422893115] = "ammo.pistol.hv",
  251.             [815896488] = "ammo.rifle",
  252.             [805088543] = "ammo.rifle.explosive",
  253.             [449771810] = "ammo.rifle.incendiary",
  254.             [1152393492] = "ammo.rifle.hv",
  255.             [1578894260] = "ammo.rocket.basic",
  256.             [1436532208] = "ammo.rocket.fire",
  257.             [542276424] = "ammo.rocket.hv",
  258.             [1594947829] = "ammo.rocket.smoke",
  259.             [-1035059994] = "ammo.shotgun",
  260.             [1818890814] = "ammo.shotgun.fire",
  261.             [1819281075] = "ammo.shotgun.slug",
  262.             [1685058759] = "antiradpills",
  263.             [93029210] = "apple",
  264.             [-1565095136] = "apple.spoiled",
  265.             [-1775362679] = "arrow.bone",
  266.             [-1775249157] = "arrow.fire",
  267.             [-1280058093] = "arrow.hv",
  268.             [-420273765] = "arrow.wooden",
  269.             [563023711] = "autoturret",
  270.             [790921853] = "axe.salvaged",
  271.             [-337261910] = "bandage",
  272.             [498312426] = "barricade.concrete",
  273.             [504904386] = "barricade.metal",
  274.             [-1221200300] = "barricade.sandbags",
  275.             [510887968] = "barricade.stone",
  276.             [-814689390] = "barricade.wood",
  277.             [1024486167] = "barricade.woodwire",
  278.             [2021568998] = "battery.small",
  279.             [97329] = "bbq",
  280.             [1046072789] = "trap.bear",
  281.             [97409] = "bed",
  282.             [-1480119738] = "tool.binoculars",
  283.             [1611480185] = "black.raspberries",
  284.             [-1386464949] = "bleach",
  285.             [93832698] = "blood",
  286.             [-1063412582] = "blueberries",
  287.             [-1887162396] = "blueprintbase",
  288.             [-55660037] = "rifle.bolt",
  289.             [919780768] = "bone.club",
  290.             [-365801095] = "bone.fragments",
  291.             [68998734] = "botabag",
  292.             [-853695669] = "bow.hunting",
  293.             [271534758] = "box.wooden.large",
  294.             [-770311783] = "box.wooden",
  295.             [-1192532973] = "bucket.water",
  296.             [-307490664] = "building.planner",
  297.             [707427396] = "burlap.shirt",
  298.             [707432758] = "burlap.shoes",
  299.             [-2079677721] = "cactusflesh",
  300.             [-1342405573] = "tool.camera",
  301.             [-139769801] = "campfire",
  302.             [-1043746011] = "can.beans",
  303.             [2080339268] = "can.beans.empty",
  304.             [-171664558] = "can.tuna",
  305.             [1050986417] = "can.tuna.empty",
  306.             [-1693683664] = "candycaneclub",
  307.             [523409530] = "candycane",
  308.             [1300054961] = "cctv.camera",
  309.             [-2095387015] = "ceilinglight",
  310.             [1428021640] = "chainsaw",
  311.             [94623429] = "chair",
  312.             [1436001773] = "charcoal",
  313.             [1711323399] = "chicken.burned",
  314.             [1734319168] = "chicken.cooked",
  315.             [-1658459025] = "chicken.raw",
  316.             [-726947205] = "chicken.spoiled",
  317.             [-341443994] = "chocholate",
  318.             [1540879296] = "xmasdoorwreath",
  319.             [94756378] = "cloth",
  320.             [3059095] = "coal",
  321.             [3059624] = "corn",
  322.             [2045107609] = "clone.corn",
  323.             [583366917] = "seed.corn",
  324.             [2123300234] = "crossbow",
  325.             [1983936587] = "crude.oil",
  326.             [1257201758] = "cupboard.tool",
  327.             [-1144743963] = "diving.fins",
  328.             [-1144542967] = "diving.mask",
  329.             [-1144334585] = "diving.tank",
  330.             [1066729526] = "diving.wetsuit",
  331.             [-1598790097] = "door.double.hinged.metal",
  332.             [-933236257] = "door.double.hinged.toptier",
  333.             [-1575287163] = "door.double.hinged.wood",
  334.             [-2104481870] = "door.hinged.metal",
  335.             [-1571725662] = "door.hinged.toptier",
  336.             [1456441506] = "door.hinged.wood",
  337.             [1200628767] = "door.key",
  338.             [-778796102] = "door.closer",
  339.             [1526866730] = "xmas.door.garland",
  340.             [1925723260] = "dropbox",
  341.             [1891056868] = "ducttape",
  342.             [1295154089] = "explosive.satchel",
  343.             [498591726] = "explosive.timed",
  344.             [1755466030] = "explosives",
  345.             [726730162] = "facialhair.style01",
  346.             [-1034048911] = "fat.animal",
  347.             [252529905] = "femalearmpithair.style01",
  348.             [471582113] = "femaleeyebrow.style01",
  349.             [-1138648591] = "femalepubichair.style01",
  350.             [305916740] = "female_hairstyle_01",
  351.             [305916742] = "female_hairstyle_03",
  352.             [305916744] = "female_hairstyle_05",
  353.             [1908328648] = "fireplace.stone",
  354.             [-2078972355] = "fish.cooked",
  355.             [-533484654] = "fish.raw",
  356.             [1571660245] = "fishingrod.handmade",
  357.             [1045869440] = "flamethrower",
  358.             [1985408483] = "flameturret",
  359.             [97513422] = "flare",
  360.             [1496470781] = "flashlight.held",
  361.             [1229879204] = "weapon.mod.flashlight",
  362.             [-1722829188] = "floor.grill",
  363.             [1849912854] = "floor.ladder.hatch",
  364.             [-1266285051] = "fridge",
  365.             [-1749787215] = "boots.frog",
  366.             [28178745] = "lowgradefuel",
  367.             [-505639592] = "furnace",
  368.             [1598149413] = "furnace.large",
  369.             [-1779401418] = "gates.external.high.stone",
  370.             [-57285700] = "gates.external.high.wood",
  371.             [98228420] = "gears",
  372.             [1422845239] = "geiger.counter",
  373.             [277631078] = "generator.wind.scrap",
  374.             [115739308] = "burlap.gloves",
  375.             [-522149009] = "gloweyes",
  376.             [3175989] = "glue",
  377.             [718197703] = "granolabar",
  378.             [384204160] = "grenade.beancan",
  379.             [-1308622549] = "grenade.f1",
  380.             [-217113639] = "fun.guitar",
  381.             [-1580059655] = "gunpowder",
  382.             [-1832205789] = "male_hairstyle_01",
  383.             [305916741] = "female_hairstyle_02",
  384.             [936777834] = "attire.hide.helterneck",
  385.             [-1224598842] = "hammer",
  386.             [-1976561211] = "hammer.salvaged",
  387.             [-1406876421] = "hat.beenie",
  388.             [-1397343301] = "hat.boonie",
  389.             [1260209393] = "bucket.helmet",
  390.             [-1035315940] = "burlap.headwrap",
  391.             [-1381682752] = "hat.candle",
  392.             [696727039] = "hat.cap",
  393.             [-2128719593] = "coffeecan.helmet",
  394.             [-1178289187] = "deer.skull.mask",
  395.             [1351172108] = "heavy.plate.helmet",
  396.             [-450738836] = "hat.miner",
  397.             [-966287254] = "attire.reindeer.headband",
  398.             [340009023] = "riot.helmet",
  399.             [124310981] = "hat.wolf",
  400.             [1501403549] = "wood.armor.helmet",
  401.             [698310895] = "hatchet",
  402.             [523855532] = "hazmatsuit",
  403.             [2045246801] = "clone.hemp",
  404.             [583506109] = "seed.hemp",
  405.             [-148163128] = "attire.hide.boots",
  406.             [-132588262] = "attire.hide.skirt",
  407.             [-1666761111] = "attire.hide.vest",
  408.             [-465236267] = "weapon.mod.holosight",
  409.             [-1211618504] = "hoodie",
  410.             [2133577942] = "hq.metal.ore",
  411.             [-1014825244] = "humanmeat.burned",
  412.             [-991829475] = "humanmeat.cooked",
  413.             [-642008142] = "humanmeat.raw",
  414.             [661790782] = "humanmeat.spoiled",
  415.             [-1440143841] = "icepick.salvaged",
  416.             [569119686] = "bone.armor.suit",
  417.             [1404466285] = "heavy.plate.jacket",
  418.             [-1616887133] = "jacket.snow",
  419.             [-1167640370] = "jacket",
  420.             [-1284735799] = "jackolantern.angry",
  421.             [-1278649848] = "jackolantern.happy",
  422.             [776005741] = "knife.bone",
  423.             [108061910] = "ladder.wooden.wall",
  424.             [255101535] = "trap.landmine",
  425.             [-51678842] = "lantern",
  426.             [-789202811] = "largemedkit",
  427.             [516382256] = "weapon.mod.lasersight",
  428.             [50834473] = "leather",
  429.             [-975723312] = "lock.code",
  430.             [1908195100] = "lock.key",
  431.             [-1097452776] = "locker",
  432.             [146685185] = "longsword",
  433.             [-1716193401] = "rifle.lr300",
  434.             [193190034] = "lmg.m249",
  435.             [371156815] = "pistol.m92",
  436.             [3343606] = "mace",
  437.             [825308669] = "machete",
  438.             [830965940] = "mailbox",
  439.             [1662628660] = "male.facialhair.style02",
  440.             [1662628661] = "male.facialhair.style03",
  441.             [1662628662] = "male.facialhair.style04",
  442.             [-1832205788] = "male_hairstyle_02",
  443.             [-1832205786] = "male_hairstyle_04",
  444.             [1625090418] = "malearmpithair.style01",
  445.             [-1269800768] = "maleeyebrow.style01",
  446.             [429648208] = "malepubichair.style01",
  447.             [-1832205787] = "male_hairstyle_03",
  448.             [-1832205785] = "male_hairstyle_05",
  449.             [107868] = "map",
  450.             [997973965] = "mask.balaclava",
  451.             [-46188931] = "mask.bandana",
  452.             [-46848560] = "metal.facemask",
  453.             [-2066726403] = "bearmeat.burned",
  454.             [-2043730634] = "bearmeat.cooked",
  455.             [1325935999] = "bearmeat",
  456.             [-225234813] = "deermeat.burned",
  457.             [-202239044] = "deermeat.cooked",
  458.             [-322501005] = "deermeat.raw",
  459.             [-1851058636] = "horsemeat.burned",
  460.             [-1828062867] = "horsemeat.cooked",
  461.             [-1966381470] = "horsemeat.raw",
  462.             [968732481] = "meat.pork.burned",
  463.             [991728250] = "meat.pork.cooked",
  464.             [-253819519] = "meat.boar",
  465.             [-1714986849] = "wolfmeat.burned",
  466.             [-1691991080] = "wolfmeat.cooked",
  467.             [179448791] = "wolfmeat.raw",
  468.             [431617507] = "wolfmeat.spoiled",
  469.             [688032252] = "metal.fragments",
  470.             [-1059362949] = "metal.ore",
  471.             [1265861812] = "metal.plate.torso",
  472.             [374890416] = "metal.refined",
  473.             [1567404401] = "metalblade",
  474.             [-1057402571] = "metalpipe",
  475.             [-758925787] = "mining.pumpjack",
  476.             [-1411620422] = "mining.quarry",
  477.             [88869913] = "fish.minnows",
  478.             [-2094080303] = "smg.mp5",
  479.             [843418712] = "mushroom",
  480.             [-1569356508] = "weapon.mod.muzzleboost",
  481.             [-1569280852] = "weapon.mod.muzzlebrake",
  482.             [449769971] = "pistol.nailgun",
  483.             [590532217] = "ammo.nailgun.nails",
  484.             [3387378] = "note",
  485.             [1767561705] = "burlap.trousers",
  486.             [106433500] = "pants",
  487.             [-1334615971] = "heavy.plate.pants",
  488.             [-135651869] = "attire.hide.pants",
  489.             [-1595790889] = "roadsign.kilt",
  490.             [-459156023] = "pants.shorts",
  491.             [106434956] = "paper",
  492.             [-578028723] = "pickaxe",
  493.             [-586116979] = "jar.pickle",
  494.             [-1379225193] = "pistol.eoka",
  495.             [-930579334] = "pistol.revolver",
  496.             [548699316] = "pistol.semiauto",
  497.             [142147109] = "planter.large",
  498.             [148953073] = "planter.small",
  499.             [102672084] = "attire.hide.poncho",
  500.             [640562379] = "pookie.bear",
  501.             [-1732316031] = "xmas.present.large",
  502.             [-2130280721] = "xmas.present.medium",
  503.             [-1725510067] = "xmas.present.small",
  504.             [1974032895] = "propanetank",
  505.             [-225085592] = "pumpkin",
  506.             [509654999] = "clone.pumpkin",
  507.             [466113771] = "seed.pumpkin",
  508.             [2033918259] = "pistol.python",
  509.             [2069925558] = "target.reactive",
  510.             [-1026117678] = "box.repair.bench",
  511.             [1987447227] = "research.table",
  512.             [540154065] = "researchpaper",
  513.             [1939428458] = "riflebody",
  514.             [-288010497] = "roadsign.jacket",
  515.             [-847065290] = "roadsigns",
  516.             [3506021] = "rock",
  517.             [649603450] = "rocket.launcher",
  518.             [3506418] = "rope",
  519.             [569935070] = "rug.bear",
  520.             [113284] = "rug",
  521.             [1916127949] = "water.salt",
  522.             [-1775234707] = "salvaged.cleaver",
  523.             [-388967316] = "salvaged.sword",
  524.             [2007564590] = "santahat",
  525.             [-1705696613] = "scarecrow",
  526.             [670655301] = "hazmatsuit_scientist",
  527.             [1148128486] = "hazmatsuit_scientist_peacekeeper",
  528.             [-141135377] = "weapon.mod.small.scope",
  529.             [109266897] = "scrap",
  530.             [-527558546] = "searchlight",
  531.             [-1745053053] = "rifle.semiauto",
  532.             [1223860752] = "semibody",
  533.             [-419069863] = "sewingkit",
  534.             [-1617374968] = "sheetmetal",
  535.             [2057749608] = "shelves",
  536.             [24576628] = "shirt.collared",
  537.             [-1659202509] = "shirt.tanktop",
  538.             [2107229499] = "shoes.boots",
  539.             [191795897] = "shotgun.double",
  540.             [-1009492144] = "shotgun.pump",
  541.             [2077983581] = "shotgun.waterpipe",
  542.             [378365037] = "guntrap",
  543.             [-529054135] = "shutter.metal.embrasure.a",
  544.             [-529054134] = "shutter.metal.embrasure.b",
  545.             [486166145] = "shutter.wood.a",
  546.             [1628490888] = "sign.hanging.banner.large",
  547.             [1498516223] = "sign.hanging",
  548.             [-632459882] = "sign.hanging.ornate",
  549.             [-626812403] = "sign.pictureframe.landscape",
  550.             [385802761] = "sign.pictureframe.portrait",
  551.             [2117976603] = "sign.pictureframe.tall",
  552.             [1338515426] = "sign.pictureframe.xl",
  553.             [-1455694274] = "sign.pictureframe.xxl",
  554.             [1579245182] = "sign.pole.banner.large",
  555.             [-587434450] = "sign.post.double",
  556.             [-163742043] = "sign.post.single",
  557.             [-1224714193] = "sign.post.town",
  558.             [644359987] = "sign.post.town.roof",
  559.             [-1962514734] = "sign.wooden.huge",
  560.             [-705305612] = "sign.wooden.large",
  561.             [-357728804] = "sign.wooden.medium",
  562.             [-698499648] = "sign.wooden.small",
  563.             [1213686767] = "weapon.mod.silencer",
  564.             [386382445] = "weapon.mod.simplesight",
  565.             [1859976884] = "skull_fire_pit",
  566.             [960793436] = "skull.human",
  567.             [1001265731] = "skull.wolf",
  568.             [1253290621] = "sleepingbag",
  569.             [470729623] = "small.oil.refinery",
  570.             [1051155022] = "stash.small",
  571.             [865679437] = "fish.troutsmall",
  572.             [927253046] = "smallwaterbottle",
  573.             [109552593] = "smg.2",
  574.             [-2092529553] = "smgbody",
  575.             [691633666] = "snowball",
  576.             [-2055888649] = "snowman",
  577.             [621575320] = "shotgun.spas12",
  578.             [-2118132208] = "spear.stone",
  579.             [-1127699509] = "spear.wooden",
  580.             [-685265909] = "spikes.floor",
  581.             [552706886] = "spinner.wheel",
  582.             [1835797460] = "metalspring",
  583.             [-892259869] = "sticks",
  584.             [-1623330855] = "stocking.large",
  585.             [-1616524891] = "stocking.small",
  586.             [789892804] = "stone.pickaxe",
  587.             [-1289478934] = "stonehatchet",
  588.             [-892070738] = "stones",
  589.             [-891243783] = "sulfur",
  590.             [889398893] = "sulfur.ore",
  591.             [-1625468793] = "supply.signal",
  592.             [1293049486] = "surveycharge",
  593.             [1369769822] = "fishtrap.small",
  594.             [586484018] = "syringe.medical",
  595.             [110115790] = "table",
  596.             [1490499512] = "targeting.computer",
  597.             [3552619] = "tarp",
  598.             [1471284746] = "techparts",
  599.             [456448245] = "smg.thompson",
  600.             [110547964] = "torch",
  601.             [1588977225] = "xmas.decoration.baubels",
  602.             [918540912] = "xmas.decoration.candycanes",
  603.             [-471874147] = "xmas.decoration.gingerbreadmen",
  604.             [205978836] = "xmas.decoration.lights",
  605.             [-1044400758] = "xmas.decoration.pinecone",
  606.             [-2073307447] = "xmas.decoration.star",
  607.             [435230680] = "xmas.decoration.tinsel",
  608.             [-864578046] = "tshirt",
  609.             [1660607208] = "tshirt.long",
  610.             [260214178] = "tunalight",
  611.             [-1847536522] = "vending.machine",
  612.             [-496055048] = "wall.external.high.stone",
  613.             [-1792066367] = "wall.external.high",
  614.             [562888306] = "wall.frame.cell.gate",
  615.             [-427925529] = "wall.frame.cell",
  616.             [995306285] = "wall.frame.fence.gate",
  617.             [-378017204] = "wall.frame.fence",
  618.             [447918618] = "wall.frame.garagedoor",
  619.             [313836902] = "wall.frame.netting",
  620.             [1175970190] = "wall.frame.shopfront",
  621.             [525244071] = "wall.frame.shopfront.metal",
  622.             [-1021702157] = "wall.window.bars.metal",
  623.             [-402507101] = "wall.window.bars.toptier",
  624.             [-1556671423] = "wall.window.bars.wood",
  625.             [61936445] = "wall.window.glass.reinforced",
  626.             [112903447] = "water",
  627.             [1817873886] = "water.catcher.large",
  628.             [1824679850] = "water.catcher.small",
  629.             [-1628526499] = "water.barrel",
  630.             [547302405] = "waterjug",
  631.             [1840561315] = "water.purifier",
  632.             [-460592212] = "xmas.window.garland",
  633.             [3655341] = "wood",
  634.             [1554697726] = "wood.armor.jacket",
  635.             [-1883959124] = "wood.armor.pants",
  636.             [-481416622] = "workbench1",
  637.             [-481416621] = "workbench2",
  638.             [-481416620] = "workbench3",
  639.             [-1151126752] = "xmas.lightstring",
  640.             [-1926458555] = "xmas.tree"
  641.         };
  642.  
  643.         //////////////////////////////////////////////////////////////////////////////////////////
  644.         ///// Kit Creator
  645.         //////////////////////////////////////////////////////////////////////////////////////////
  646.  
  647.         static List<KitItem> GetPlayerItems(BasePlayer player)
  648.         {
  649.             List<KitItem> kititems = new List<KitItem>();
  650.             foreach (Item item in player.inventory.containerWear.itemList)
  651.             {
  652.                 if (item != null)
  653.                 {
  654.                     var iteminfo = ProcessItem(item, "wear");
  655.                     kititems.Add(iteminfo);
  656.                 }
  657.             }
  658.             foreach (Item item in player.inventory.containerMain.itemList)
  659.             {
  660.                 if (item != null)
  661.                 {
  662.                     var iteminfo = ProcessItem(item, "main");
  663.                     kititems.Add(iteminfo);
  664.                 }
  665.             }
  666.             foreach (Item item in player.inventory.containerBelt.itemList)
  667.             {
  668.                 if (item != null)
  669.                 {
  670.                     var iteminfo = ProcessItem(item, "belt");
  671.                     kititems.Add(iteminfo);
  672.                 }
  673.             }
  674.             return kititems;
  675.         }
  676.         static private KitItem ProcessItem(Item item, string container)
  677.         {
  678.             KitItem iItem = new KitItem();
  679.             iItem.amount = item.amount;
  680.             iItem.mods = new List<int>();
  681.             iItem.container = container;
  682.             iItem.skinid = item.skin;
  683.             iItem.itemid = item.info.itemid;
  684.             iItem.weapon = false;
  685.             iItem.blueprintTarget = item.blueprintTarget;
  686.  
  687.             if (item.info.category.ToString() == "Weapon")
  688.             {
  689.                 BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
  690.                 if (weapon != null)
  691.                 {
  692.                     if (weapon.primaryMagazine != null)
  693.                     {
  694.                         iItem.weapon = true;
  695.                         if (item.contents != null)
  696.                             foreach (var mod in item.contents.itemList)
  697.                             {
  698.                                 if (mod.info.itemid != 0)
  699.                                     iItem.mods.Add(mod.info.itemid);
  700.                             }
  701.                     }
  702.                 }
  703.             }
  704.             return iItem;
  705.         }
  706.  
  707.         //////////////////////////////////////////////////////////////////////////////////////////
  708.         ///// Kit Redeemer
  709.         //////////////////////////////////////////////////////////////////////////////////////////
  710.  
  711.         void TryGiveKit(BasePlayer player, string kitname)
  712.         {
  713.             var success = CanRedeemKit(player, kitname) as string;
  714.             if (success != null)
  715.             {
  716.                 OnScreen(player, success);
  717.                 return;
  718.             }
  719.             success = GiveKit(player, kitname) as string;
  720.             if (success != null)
  721.             {
  722.                 OnScreen(player, success);
  723.                 return;
  724.             }
  725.             OnScreen(player, GetMsg("<size=44><color=yellow>KitRedeemed</color></size>",player.userID));
  726.             Interface.CallHook("OnKitRedeemed", player, kitname);
  727.             proccessKitGiven(player, kitname);
  728.         }
  729.         void proccessKitGiven(BasePlayer player, string kitname)
  730.         {
  731.             if (string.IsNullOrEmpty(kitname)) return;
  732.             kitname = kitname.ToLower();
  733.             Kit kit;
  734.             if (!storedData.Kits.TryGetValue(kitname, out kit)) return;
  735.  
  736.             var kitData = GetKitData(player.userID, kitname);
  737.             if (kit.max > 0)
  738.                 kitData.max += 1;
  739.  
  740.             if (kit.cooldown > 0)
  741.                 kitData.cooldown = CurrentTime() + kit.cooldown;
  742.             if (PlayerGUI.ContainsKey(player.userID) && PlayerGUI[player.userID].open)
  743.                 RefreshKitPanel(player, PlayerGUI[player.userID].guiid, PlayerGUI[player.userID].page);
  744.         }
  745.  
  746.         private object GiveKit(BasePlayer player, string kitname)
  747.         {
  748.             if (string.IsNullOrEmpty(kitname)) return GetMsg("Emptykitname", player.userID);
  749.             kitname = kitname.ToLower();
  750.             Kit kit;
  751.             if (!storedData.Kits.TryGetValue(kitname, out kit)) return GetMsg("NoKitFound",player.userID);
  752.  
  753.             foreach (var kitem in kit.items)
  754.             {
  755.                 GiveItem(player.inventory,
  756.                     kitem.weapon
  757.                         ? BuildWeapon(kitem.itemid, kitem.skinid, kitem.mods)
  758.                         : BuildItem(kitem.itemid, kitem.amount, kitem.skinid, kitem.blueprintTarget),
  759.                     kitem.container == "belt"
  760.                         ? player.inventory.containerBelt
  761.                         : kitem.container == "wear"
  762.                             ? player.inventory.containerWear
  763.                             : player.inventory.containerMain);
  764.             }
  765.             if (!string.IsNullOrEmpty(kit.building))
  766.             {
  767.                 var success = CopyPaste?.CallHook("TryPasteFromSteamID", player.userID, kit.building, CopyPasteParameters.ToArray());
  768.                 return success;
  769.             }
  770.  
  771.             if (KitLogging) LogToFile("received", $"{player.displayName}<{player.UserIDString}> - Received Kit: {kitname}", this);
  772.             return true;
  773.         }
  774.  
  775.         bool GiveItem(PlayerInventory inv, Item item, ItemContainer container = null)
  776.         {
  777.             if (item == null) { return false; }
  778.             int position = -1;
  779.             return (((container != null) && item.MoveToContainer(container, position, true)) || (item.MoveToContainer(inv.containerMain, -1, true) || item.MoveToContainer(inv.containerBelt, -1, true)));
  780.         }
  781.         private Item BuildItem(int itemid, int amount, ulong skin, int blueprintTarget)
  782.         {
  783.             if (amount < 1) amount = 1;
  784.             Item item = CreateByItemID(itemid, amount, skin);
  785.             if (blueprintTarget != 0)
  786.                 item.blueprintTarget = blueprintTarget;
  787.             return item;
  788.         }
  789.         private Item BuildWeapon(int id, ulong skin, List<int> mods)
  790.         {
  791.             Item item = CreateByItemID(id, 1, skin);
  792.             var weapon = item.GetHeldEntity() as BaseProjectile;
  793.             if (weapon != null)
  794.             {
  795.                 (item.GetHeldEntity() as BaseProjectile).primaryMagazine.contents = (item.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity;
  796.             }
  797.             if (mods != null)
  798.             {
  799.                 foreach (var mod in mods)
  800.                 {
  801.                     item.contents.AddItem(BuildItem(mod, 1, 0, 0).info, 1);
  802.                 }
  803.             }
  804.             return item;
  805.         }
  806.  
  807.         private Item CreateByItemID(int itemID, int amount = 1, ulong skin = 0)
  808.         {
  809.             string shortName = "";
  810.             if (_itemIdShortnameConversions.TryGetValue(itemID, out shortName))
  811.             {
  812.                 return ItemManager.CreateByName(shortName, amount, skin);
  813.             }
  814.             else
  815.             {
  816.                 return ItemManager.CreateByItemID(itemID, amount, skin);
  817.             }
  818.         }
  819.  
  820.         //////////////////////////////////////////////////////////////////////////////////////////
  821.         ///// Check Kits
  822.         //////////////////////////////////////////////////////////////////////////////////////////
  823.  
  824.         bool isKit(string kitname)
  825.         {
  826.             return !string.IsNullOrEmpty(kitname) && storedData.Kits.ContainsKey(kitname.ToLower());
  827.         }
  828.  
  829.         static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
  830.         static double CurrentTime() { return DateTime.UtcNow.Subtract(epoch).TotalSeconds; }
  831.  
  832.         bool CanSeeKit(BasePlayer player, string kitname, bool fromNPC, out string reason)
  833.         {
  834.             reason = string.Empty;
  835.             if (string.IsNullOrEmpty(kitname)) return false;
  836.             kitname = kitname.ToLower();
  837.             Kit kit;
  838.             if (!storedData.Kits.TryGetValue(kitname, out kit)) return false;
  839.             if (kit.hide)
  840.                 return false;
  841.             if (kit.authlevel > 0)
  842.                 if (player.net.connection.authLevel < kit.authlevel)
  843.                     return false;
  844.             if (!string.IsNullOrEmpty(kit.permission))
  845.                 if (player.net.connection.authLevel < 2 && !permission.UserHasPermission(player.UserIDString, kit.permission))
  846.                     return false;
  847.             if (kit.npconly && !fromNPC)
  848.                 return false;
  849.             if (kit.max > 0)
  850.             {
  851.                 int left = GetKitData(player.userID, kitname).max;
  852.                 if (left >= kit.max)
  853.                 {
  854.                     reason += "- 0 left";
  855.                     return false;
  856.                 }
  857.                 reason += $"- {(kit.max - left)} left";
  858.             }
  859.             if (kit.cooldown > 0)
  860.             {
  861.                 double cd = GetKitData(player.userID, kitname).cooldown;
  862.                 double ct = CurrentTime();
  863.                 if (cd > ct && cd != 0.0)
  864.                 {
  865.                     reason += $"- {Math.Abs(Math.Ceiling(cd - ct))} seconds";
  866.                     return false;
  867.                 }
  868.             }
  869.             return true;
  870.         }
  871.  
  872.         object CanRedeemKit(BasePlayer player, string kitname, bool skipAuth = false)
  873.         {
  874.             if (string.IsNullOrEmpty(kitname)) return GetMsg("Emptykitname", player.userID);
  875.             kitname = kitname.ToLower();
  876.             Kit kit;
  877.             if (!storedData.Kits.TryGetValue(kitname, out kit)) return GetMsg("KitExistError", player.userID);
  878.  
  879.             object thereturn = Interface.Oxide.CallHook("canRedeemKit", player);
  880.             if (thereturn != null)
  881.             {
  882.                 if (thereturn is string) return thereturn;
  883.                 return GetMsg("CantRedeemNow", player.userID);
  884.             }
  885.  
  886.             if (kit.authlevel > 0 && !skipAuth)
  887.                 if (player.net.connection.authLevel < kit.authlevel)
  888.                     return GetMsg("NoAuthToRedeem", player.userID);
  889.  
  890.             if (!string.IsNullOrEmpty(kit.permission))
  891.                 if (player.net.connection.authLevel < 2 && !permission.UserHasPermission(player.UserIDString, kit.permission))
  892.                     return GetMsg("NoPermKit", player.userID);
  893.  
  894.             var kitData = GetKitData(player.userID, kitname);
  895.             if (kit.max > 0)
  896.                 if (kitData.max >= kit.max)
  897.                     return GetMsg("NoRemainingUses", player.userID);
  898.  
  899.             if (kit.cooldown > 0)
  900.             {
  901.                 var ct = CurrentTime();
  902.                 if (kitData.cooldown > ct && kitData.cooldown != 0.0)
  903.                     return string.Format(GetMsg("CooldownMessage", player.userID), Math.Abs(Math.Ceiling(kitData.cooldown - ct)));
  904.             }
  905.  
  906.             if (kit.npconly)
  907.             {
  908.                 bool foundNPC = false;
  909.                 var neededNpc = new List<ulong>();
  910.                 foreach (var pair in GUIKits)
  911.                 {
  912.                     if (pair.Value.kits.Contains(kitname))
  913.                         neededNpc.Add(pair.Key);
  914.                 }
  915.                 foreach (var col in Physics.OverlapSphere(player.transform.position, 3f, playerLayer, QueryTriggerInteraction.Collide))
  916.                 {
  917.                     var targetplayer = col.GetComponentInParent<BasePlayer>();
  918.                     if (targetplayer == null) continue;
  919.  
  920.                     if (neededNpc.Contains(targetplayer.userID))
  921.                     {
  922.                         foundNPC = true;
  923.                         break;
  924.                     }
  925.                 }
  926.                 if (!foundNPC)
  927.                     return GetMsg("NPCError", player.userID);
  928.             }
  929.             int beltcount = kit.items.Where(k => k.container == "belt").Count();
  930.             int wearcount = kit.items.Where(k => k.container == "wear").Count();
  931.             int maincount = kit.items.Where(k => k.container == "main").Count();
  932.             int totalcount = beltcount + wearcount + maincount;
  933.             if ((player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count) < beltcount || (player.inventory.containerWear.capacity - player.inventory.containerWear.itemList.Count) < wearcount || (player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count) < maincount)
  934.                 if (totalcount > (player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count))
  935.                     return GetMsg("NoInventorySpace", player.userID);
  936.             return true;
  937.         }
  938.  
  939.  
  940.         //////////////////////////////////////////////////////////////////////////////////////
  941.         // Kit Class
  942.         //////////////////////////////////////////////////////////////////////////////////////
  943.         class KitItem
  944.         {
  945.             public int itemid;
  946.             public string container;
  947.             public int amount;
  948.             public ulong skinid;
  949.             public bool weapon;
  950.             public int blueprintTarget;
  951.             public List<int> mods = new List<int>();
  952.         }
  953.  
  954.         class Kit
  955.         {
  956.             public string name;
  957.             public string description;
  958.             public int max;
  959.             public double cooldown;
  960.             public int authlevel;
  961.             public bool hide;
  962.             public bool npconly;
  963.             public string permission;
  964.             public string image;
  965.             public string image2;
  966.             public string building;
  967.             public List<KitItem> items = new List<KitItem>();
  968.         }
  969.  
  970.         //////////////////////////////////////////////////////////////////////////////////////
  971.         // Data Manager
  972.         //////////////////////////////////////////////////////////////////////////////////////
  973.  
  974.         private void SaveKitsData()
  975.         {
  976.             if (kitsData == null) return;
  977.             Interface.Oxide.DataFileSystem.WriteObject("Kits_Data", kitsData);
  978.         }
  979.  
  980.  
  981.         private StoredData storedData;
  982.         private Dictionary<ulong, Dictionary<string, KitData>> kitsData;
  983.  
  984.         class StoredData
  985.         {
  986.             public Dictionary<string, Kit> Kits = new Dictionary<string, Kit>();
  987.         }
  988.         class KitData
  989.         {
  990.             public int max;
  991.             public double cooldown;
  992.         }
  993.         void ResetData()
  994.         {
  995.             kitsData.Clear();
  996.             SaveKitsData();
  997.         }
  998.  
  999.         void Unload()
  1000.         {
  1001.             SaveKitsData();
  1002.             foreach (var player in BasePlayer.activePlayerList)
  1003.             {
  1004.                 DestroyAllGUI(player);
  1005.             }
  1006.         }
  1007.         void OnServerSave()
  1008.         {
  1009.             SaveKitsData();
  1010.         }
  1011.  
  1012.         void SaveKits()
  1013.         {
  1014.             Interface.Oxide.DataFileSystem.WriteObject("Kits", storedData);
  1015.         }
  1016.  
  1017.         void LoadData()
  1018.         {
  1019.             var kits = Interface.Oxide.DataFileSystem.GetFile("Kits");
  1020.             try
  1021.             {
  1022.                 kits.Settings.NullValueHandling = NullValueHandling.Ignore;
  1023.                 storedData = kits.ReadObject<StoredData>();
  1024.                 var update = new List<string>();
  1025.                 foreach (var kit in storedData.Kits)
  1026.                 {
  1027.                     if (!kit.Key.Equals(kit.Key.ToLower()))
  1028.                         update.Add(kit.Key);
  1029.                 }
  1030.                 foreach (var key in update)
  1031.                 {
  1032.                     storedData.Kits[key.ToLower()] = storedData.Kits[key];
  1033.                     storedData.Kits.Remove(key);
  1034.                 }
  1035.             }
  1036.             catch
  1037.             {
  1038.                 storedData = new StoredData();
  1039.             }
  1040.             kits.Settings.NullValueHandling = NullValueHandling.Include;
  1041.         }
  1042.  
  1043.         KitData GetKitData(ulong userID, string kitname)
  1044.         {
  1045.             Dictionary<string, KitData> kitDatas;
  1046.             if (!kitsData.TryGetValue(userID, out kitDatas))
  1047.                 kitsData[userID] = kitDatas = new Dictionary<string, KitData>();
  1048.             KitData kitData;
  1049.             if (!kitDatas.TryGetValue(kitname, out kitData))
  1050.                 kitDatas[kitname] = kitData = new KitData();
  1051.             return kitData;
  1052.         }
  1053.  
  1054.         //////////////////////////////////////////////////////////////////////////////////////
  1055.         // Kit Editor
  1056.         //////////////////////////////////////////////////////////////////////////////////////
  1057.  
  1058.         readonly Dictionary<ulong, string> kitEditor = new Dictionary<ulong, string>();
  1059.  
  1060.         //////////////////////////////////////////////////////////////////////////////////////
  1061.         // ImageLibrary Hooks ---->> Absolut
  1062.         //////////////////////////////////////////////////////////////////////////////////////
  1063.  
  1064.         private string TryForImage(string shortname, ulong skin = 99)
  1065.         {
  1066.             if (shortname.Contains("http")) return shortname;
  1067.             if (skin == 99) skin = (ulong)ResourceId;
  1068.             return GetImage(shortname, skin, true);
  1069.         }
  1070.  
  1071.         public string GetImage(string shortname, ulong skin = 0, bool returnUrl = false) => (string)ImageLibrary.Call("GetImage", shortname.ToLower(), skin, returnUrl);
  1072.         public bool HasImage(string shortname, ulong skin = 0) => (bool)ImageLibrary.Call("HasImage", shortname.ToLower(), skin);
  1073.         public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname.ToLower(), skin);
  1074.         public List<ulong> GetImageList(string shortname) => (List<ulong>)ImageLibrary.Call("GetImageList", shortname.ToLower());
  1075.         public bool isReady() => (bool)ImageLibrary?.Call("IsReady");
  1076.  
  1077.         //////////////////////////////////////////////////////////////////////////////////////
  1078.         // GUI CREATION ---->> Absolut
  1079.         //////////////////////////////////////////////////////////////////////////////////////
  1080.  
  1081.         private string PanelOnScreen = "PanelOnScreen";
  1082.         private string PanelKits = "PanelKits";
  1083.         private string PanelBackground = "PanelBackground";
  1084.         public class UI
  1085.         {
  1086.             static public CuiElementContainer CreateElementContainer(string panelName, string color, string aMin, string aMax, bool cursor = false)
  1087.             {
  1088.                 var NewElement = new CuiElementContainer()
  1089.             {
  1090.                 {
  1091.                     new CuiPanel
  1092.                     {
  1093.                         Image = {Color = color},
  1094.                         RectTransform = {AnchorMin = aMin, AnchorMax = aMax},
  1095.                         CursorEnabled = cursor
  1096.                     },
  1097.                     new CuiElement().Parent,
  1098.                     panelName
  1099.                 }
  1100.             };
  1101.                 return NewElement;
  1102.             }
  1103.             static public CuiElementContainer CreateOverlayContainer(string panelName, string color, string aMin, string aMax, bool cursor = false)
  1104.             {
  1105.                 var NewElement = new CuiElementContainer()
  1106.             {
  1107.                 {
  1108.                     new CuiPanel
  1109.                     {
  1110.                         Image = {Color = color},
  1111.                         RectTransform = {AnchorMin = aMin, AnchorMax = aMax},
  1112.                         CursorEnabled = cursor
  1113.                     },
  1114.                     new CuiElement().Parent = "Overlay",
  1115.                     panelName
  1116.                 }
  1117.             };
  1118.                 return NewElement;
  1119.             }
  1120.  
  1121.             static public void CreatePanel(ref CuiElementContainer container, string panel, string color, string aMin, string aMax, bool cursor = false)
  1122.             {
  1123.                 container.Add(new CuiPanel
  1124.                 {
  1125.                     Image = { Color = color },
  1126.                     RectTransform = { AnchorMin = aMin, AnchorMax = aMax },
  1127.                     CursorEnabled = cursor
  1128.                 },
  1129.                 panel);
  1130.             }
  1131.             static public void CreateLabel(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter)
  1132.             {
  1133.                 container.Add(new CuiLabel
  1134.                 {
  1135.                     Text = { Color = color, FontSize = size, Align = align, FadeIn = 1.0f, Text = text },
  1136.                     RectTransform = { AnchorMin = aMin, AnchorMax = aMax }
  1137.                 },
  1138.                 panel);
  1139.             }
  1140.  
  1141.             static public void CreateButton(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, string command, TextAnchor align = TextAnchor.MiddleCenter)
  1142.             {
  1143.                 container.Add(new CuiButton
  1144.                 {
  1145.                     Button = { Color = color, Command = command, FadeIn = 1.0f },
  1146.                     RectTransform = { AnchorMin = aMin, AnchorMax = aMax },
  1147.                     Text = { Text = text, FontSize = size, Align = align }
  1148.                 },
  1149.                 panel);
  1150.             }
  1151.  
  1152.             static public void LoadImage(ref CuiElementContainer container, string panel, string img, string aMin, string aMax)
  1153.             {
  1154.                 if (img.StartsWith("http") || img.StartsWith("www"))
  1155.                 {
  1156.                     container.Add(new CuiElement
  1157.                     {
  1158.                         Parent = panel,
  1159.                         Components =
  1160.                     {
  1161.                         new CuiRawImageComponent {Url = img, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
  1162.                         new CuiRectTransformComponent {AnchorMin = aMin, AnchorMax = aMax }
  1163.                     }
  1164.                     });
  1165.                 }
  1166.                 else
  1167.                     container.Add(new CuiElement
  1168.                     {
  1169.                         Parent = panel,
  1170.                         Components =
  1171.                     {
  1172.                         new CuiRawImageComponent {Png = img, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
  1173.                         new CuiRectTransformComponent {AnchorMin = aMin, AnchorMax = aMax }
  1174.                     }
  1175.                     });
  1176.             }
  1177.  
  1178.             static public void CreateTextOutline(ref CuiElementContainer element, string panel, string colorText, string colorOutline, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter)
  1179.             {
  1180.                 element.Add(new CuiElement
  1181.                 {
  1182.                     Parent = panel,
  1183.                     Components =
  1184.                     {
  1185.                         new CuiTextComponent{Color = colorText, FontSize = size, Align = align, Text = text },
  1186.                         new CuiOutlineComponent {Distance = "1 1", Color = colorOutline},
  1187.                         new CuiRectTransformComponent {AnchorMax = aMax, AnchorMin = aMin }
  1188.                     }
  1189.                 });
  1190.             }
  1191.         }
  1192.  
  1193.         private Dictionary<string, string> UIColors = new Dictionary<string, string>
  1194.         {
  1195.             {"black", "0 0 0 1.0" },
  1196.             {"dark", "0.1 0.1 0.1 0.98" },
  1197.             {"header", "1 1 1 0.3" },
  1198.             {"light", ".564 .564 .564 1.0" },
  1199.             {"grey1", "0.6 0.6 0.6 1.0" },
  1200.             {"brown", "0.3 0.16 0.0 1.0" },
  1201.             {"yellow", "0.9 0.9 0.0 1.0" },
  1202.             {"orange", "1.0 0.65 0.0 1.0" },
  1203.             {"limegreen", "0.42 1.0 0 1.0" },
  1204.             {"blue", "0.2 0.6 1.0 1.0" },
  1205.             {"red", "1.0 0.1 0.1 1.0" },
  1206.             {"clear", "1.0 0.1 0.1 0.0" },
  1207.             {"white", "1 1 1 1" },
  1208.             {"green", "0.28 0.82 0.28 1.0" },
  1209.             {"grey", "0.8 0.8 0.8 0.8" },
  1210.             {"lightblue", "0.6 0.86 1.0 1.0" },
  1211.             {"buttonbg", "0.2 0.2 0.2 0.7" },
  1212.             {"buttongreen", "0.133 0.965 0.133 0.9" },
  1213.             {"buttonred", "0.964 0.133 0.133 0.9" },
  1214.             {"buttongrey", "0.8 0.8 0.8 0.9" },
  1215.         };
  1216.  
  1217.         //////////////////////////////////////////////////////////////////////////////////////
  1218.         // GUI
  1219.         //////////////////////////////////////////////////////////////////////////////////////
  1220.         private Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
  1221.  
  1222.         void OnScreen(BasePlayer player, string msg)
  1223.         {
  1224.             if (timers.ContainsKey(player.userID.ToString()))
  1225.             {
  1226.                 timers[player.userID.ToString()].Destroy();
  1227.                 timers.Remove(player.userID.ToString());
  1228.             }
  1229.             CuiHelper.DestroyUi(player, PanelOnScreen);
  1230.             var element = UI.CreateOverlayContainer(PanelOnScreen, "0.0 0.0 0.0 0.0", "0.05 0.65", "0.95 .85", false);
  1231.             UI.CreateTextOutline(ref element, PanelOnScreen, UIColors["black"], UIColors["white"], msg, 24, "0.0 0.0", "1.0 1.0");
  1232.             CuiHelper.AddUi(player, element);
  1233.             timers.Add(player.userID.ToString(), timer.Once(3, () => CuiHelper.DestroyUi(player, PanelOnScreen)));
  1234.         }
  1235.  
  1236.         void BackgroundPanel(BasePlayer player)
  1237.         {
  1238.             CuiHelper.DestroyUi(player, PanelBackground);
  1239.             var element = UI.CreateOverlayContainer(PanelBackground, "0.2 0.2 0.2 0.0",".05 .15", ".95 .95", true);  ///background size here
  1240.             UI.CreatePanel(ref element, PanelBackground, "0.5 0.5 0.5 0.9", "0 0", "1 1"); /////////////////////////////////////////////////////  r g b then transparency
  1241.             if (!string.IsNullOrEmpty(BackgroundURL))
  1242.             {
  1243.                 var image = BackgroundURL;
  1244.                 if (ImageLibrary)
  1245.                     image = TryForImage("Background");
  1246.                 UI.LoadImage(ref element, PanelBackground, image, "0 0", "1 1");
  1247.             }
  1248.             CuiHelper.AddUi(player, element);
  1249.         }
  1250.  
  1251.  
  1252.         readonly Dictionary<ulong, PLayerGUI> PlayerGUI = new Dictionary<ulong, PLayerGUI>();
  1253.  
  1254.         class PLayerGUI
  1255.         {
  1256.             public ulong guiid;
  1257.             public int page;
  1258.             public bool open;
  1259.         }
  1260.  
  1261.         [ConsoleCommand("UI_ToggleKitMenu")]
  1262.         private void cmdUI_ToggleKitMenu(ConsoleSystem.Arg arg)
  1263.         {
  1264.             var player = arg.Connection.player as BasePlayer;
  1265.             if (player == null || string.IsNullOrEmpty(UIKeyBinding)) return;
  1266.             if (PlayerGUI.ContainsKey(player.userID))
  1267.                 if (PlayerGUI[player.userID].open)
  1268.                 {
  1269.                     PlayerGUI[player.userID].open = false;
  1270.                     DestroyAllGUI(player);
  1271.                     return;
  1272.                 }
  1273.             NewKitPanel(player);
  1274.         }
  1275.  
  1276.         void NewKitPanel(BasePlayer player, ulong guiId = 0)
  1277.         {
  1278.             DestroyAllGUI(player);
  1279.             GUIKit kitpanel;
  1280.             if (!GUIKits.TryGetValue(guiId, out kitpanel)) return;
  1281.             BackgroundPanel(player);
  1282.             RefreshKitPanel(player, guiId);
  1283.         }
  1284.  
  1285.         void RefreshKitPanel(BasePlayer player, ulong guiId, int page = 0)
  1286.         {
  1287.             CuiHelper.DestroyUi(player, PanelKits);
  1288.             var element = UI.CreateOverlayContainer(PanelKits, "0 0 0 0", ".1 .15", ".9 .95"); //////////////////also the whole thing
  1289.             PLayerGUI playerGUI;
  1290.             if (!PlayerGUI.TryGetValue(player.userID, out playerGUI))
  1291.                 PlayerGUI[player.userID] = playerGUI = new PLayerGUI();
  1292.             playerGUI.guiid = guiId;
  1293.             playerGUI.page = page;
  1294.             PlayerGUI[player.userID].open = true;
  1295.             bool npcCheck = false;
  1296.             if (guiId != 0)
  1297.                 npcCheck = true;
  1298.             var kitpanel = GUIKits[guiId];
  1299.             List<string> Kits = new List<string>();
  1300.             if (ShowUnavailableKits)
  1301.                 Kits = kitpanel.kits.Where(k=> storedData.Kits.ContainsKey(k.ToLower())).ToList();
  1302.             else
  1303.             {
  1304.                 foreach (var entry in kitpanel.kits)
  1305.                 {
  1306.                     string reason;
  1307.                     var cansee = CanSeeKit(player, entry.ToLower(), npcCheck, out reason);
  1308.                     if (!cansee && string.IsNullOrEmpty(reason)) continue;
  1309.                     Kits.Add(entry);
  1310.                 }
  1311.             }
  1312.             int entriesallowed = 10;
  1313.             int remainingentries = Kits.Count - (page * entriesallowed);
  1314.             UI.CreateTextOutline(ref element, PanelKits, UIColors["white"], UIColors["black"], kitpanel.description, 20, "0.1 0.9", "0.9 1");
  1315.             var i = 0;
  1316.             var n = 0;
  1317.             int shownentries = page * entriesallowed;
  1318.             foreach (var entry in Kits)
  1319.             {
  1320.                 i++;
  1321.                 if (i < shownentries + 1) continue;
  1322.                 else if (i <= shownentries + entriesallowed)
  1323.                 {
  1324.                     var pos = KitSquarePos(n, remainingentries);
  1325.                     CreateKitEntry(player, ref element, PanelKits, pos, entry);
  1326.                     n++;
  1327.                     if (n == entriesallowed) break;
  1328.                 }
  1329.             }
  1330.             if (player.net.connection.authLevel == 2 || permission.UserHasPermission(player.UserIDString, this.Title + ".admin"))
  1331.                 UI.CreateButton(ref element, PanelKits, UIColors["buttongrey"], GetMsg("AddKit", player.userID), 14, $".02 .02", ".07 .06", $"UI_AddKit {0}");
  1332.             if (page >= 1)
  1333.             UI.CreateButton(ref element, PanelKits, UIColors["buttongrey"], "<<", 20, $".79 .02", ".84 .06", $"kit.show {page - 1}");
  1334.             if (remainingentries > entriesallowed)
  1335.             UI.CreateButton(ref element, PanelKits, UIColors["buttongrey"], ">>", 20, $".86 .02", ".91 .06", $"kit.show {page + 1}");
  1336.             UI.CreateButton(ref element, PanelKits, UIColors["buttonred"], GetMsg("Close", player.userID), 14, $".81 .03", ".86 .07", $"kit.close");  ////close button position
  1337.             CuiHelper.AddUi(player, element);
  1338.         }
  1339.  
  1340.         void CreateKitEntry(BasePlayer player, ref CuiElementContainer element, string panel, float[] pos, string entry) //////////////PANEL ENTRIES ******************
  1341.         {
  1342.             Kit kit = storedData.Kits[entry.ToLower()];
  1343.             var kitData = GetKitData(player.userID, entry.ToLower());
  1344.             var image = kit.image ?? "http://i.imgur.com/xxQnE1R.png";
  1345.             var image2 = kit.image2 ?? "https://i.ibb.co/vzMFYL8/Kits-UIRed-Flag-Panel-Frame-Pic.png";
  1346.            
  1347.             if (ImageLibrary)
  1348.                 image = TryForImage(kit.name.Replace(" ", ""));
  1349.             UI.CreatePanel(ref element, PanelKits, UIColors["clear"], $"{pos[0]} {pos[1]}", $"{pos[2]} {pos[3]}");   ////////////*****  0 0 0 0
  1350.             UI.LoadImage(ref element, PanelKits, image2, $"{pos[0]} {pos[1]}", $"{pos[2]} {pos[3]}");
  1351.             UI.LoadImage(ref element, PanelKits, image, $"{pos[0] + .03f} {pos[1] + 0.15f}", $"{pos[0] + .16f} {pos[1] + .3f}");
  1352.             UI.CreateLabel(ref element, PanelKits, UIColors["white"], kit.name, 16, $"{pos[0] + .005f} {pos[3] - .07f}", $"{pos[2] - .005f} {pos[3] - .01f}"); ///kit name margin?
  1353.             UI.CreateLabel(ref element, PanelKits, UIColors["white"], kit.description ?? string.Empty, 12, $"{pos[0] + .005f} {pos[3] - .18f}", $"{pos[2] - .005f} {pos[3] - .07f}", TextAnchor.UpperCenter);
  1354.             UI.CreateLabel(ref element, PanelKits, UIColors["white"], string.Format(GetMsg("KitCooldown", player.userID), kit.cooldown <= 0 ? GetMsg("None", player.userID) : CurrentTime() > kitData.cooldown ? MinuteFormat(kit.cooldown / 60).ToString() : "<color=red> -" + MinuteFormat((double)Math.Abs(Math.Ceiling(CurrentTime() - kitData.cooldown)) / 60) + "</color>"), 12, $"{pos[0] + .005f} {pos[3] - .3f}", $"{pos[2] - .005f} {pos[3] - .27f}", TextAnchor.MiddleCenter);
  1355.             UI.CreateLabel(ref element, PanelKits, UIColors["white"], string.Format(GetMsg("KitUses", player.userID), kit.max <= 0 ? GetMsg("Unlimited") : kit.max - kitData.max < kit.max ? $"<color=red>{kit.max - kitData.max }</color>/{kit.max}" : $"{kit.max - kitData.max }/{kit.max}"), 12, $"{pos[0] + .005f} {pos[3] - .33f}", $"{pos[2] - .005f} {pos[3] - .30f}", TextAnchor.MiddleCenter);
  1356.             if (player.net.connection.authLevel == 2 || permission.UserHasPermission(player.UserIDString, this.Title + ".admin"))
  1357.                 UI.CreateButton(ref element, PanelKits, UIColors["buttonred"], GetMsg("RemoveKit", player.userID), 14, $"{pos[0] + .005f} {pos[1] + 0.01f}", $"{pos[0] + .06f} {pos[1] + .07f}", $"UI_RemoveKit {entry.ToLower()}");
  1358.             if (!ShowUnavailableKits)
  1359.                 UI.CreateButton(ref element, PanelKits, UIColors["clear"], GetMsg("<color=yellow>REDEEM</color>"), 16, $"{pos[0] + .03f} {pos[1] + 0.15f}", $"{pos[0] + .16f} {pos[1] + .3f}", $"kit.gui {entry.ToLower()}");  ////redeem
  1360.             else
  1361.             {
  1362.                 string reason;
  1363.                 var cansee = CanSeeKit(player, entry.ToLower(), PlayerGUI[player.userID].guiid == 0 ? false : true, out reason);
  1364.                 if (!cansee && string.IsNullOrEmpty(reason))
  1365.                 {
  1366.                     UI.CreatePanel(ref element, PanelKits, UIColors["header"], $"{pos[0] + .005f} {pos[1] + 0.01f}", $"{pos[0] + .06f} {pos[1] + .07f}");
  1367.                     UI.CreateLabel(ref element, PanelKits, UIColors["white"],"<color=red>"+GetMsg("Unavailable", player.userID)+"</color>", 12, $"{pos[0] + .005f} {pos[1] + 0.01f}", $"{pos[0] + .06f} {pos[1] + .07f}");
  1368.                 }
  1369.                 else
  1370.                     UI.CreateButton(ref element, PanelKits, UIColors["clear"], GetMsg("<color=yellow>REDEEM/color>"), 16, $"{pos[0] + .03f} {pos[1] + 0.15f}", $"{pos[0] + .16f} {pos[1] + .3f}", $"kit.gui {entry.ToLower()}"); ////redeem
  1371.             }
  1372.         }
  1373.  
  1374.         private float[] KitSquarePos(int number, double count)
  1375.         {
  1376.             Vector2 position = new Vector2(0.015f, 0.5f);
  1377.             Vector2 dimensions = new Vector2(0.22f, 0.4f);
  1378.             float offsetY = 0;
  1379.             float offsetX = 0;
  1380.           if (count < 10)
  1381.             {
  1382.                 position.x = (float)(1 - (((dimensions.x + .005f) * (count > 1 ? (Math.Round((count / 2), MidpointRounding.AwayFromZero)) : 1)))) / 2;
  1383.             }
  1384.             if (number >= 0 && number < 2)
  1385.             {
  1386.                 offsetY = (-0.01f - dimensions.y) * number;
  1387.             }
  1388.             if (number > 1 && number < 4)
  1389.             {
  1390.                 offsetX = (.005f + dimensions.x) * 1;
  1391.                 offsetY = (-0.01f - dimensions.y) * (number - 2);
  1392.             }
  1393.             if (number > 3 && number < 6)
  1394.             {
  1395.                 offsetX = (.005f + dimensions.x) * 2;
  1396.                 offsetY = (-0.01f - dimensions.y) * (number - 4);
  1397.             }
  1398.             if (number > 5 && number < 8)
  1399.             {
  1400.                 offsetX = (.005f + dimensions.x) * 3;
  1401.                 offsetY = (-0.01f - dimensions.y) * (number - 6);
  1402.             }
  1403.             if (number > 7 && number < 10)
  1404.             {
  1405.                 offsetX = (.005f + dimensions.x) * 4;
  1406.                 offsetY = (-0.01f - dimensions.y) * (number - 8);
  1407.             }
  1408.             Vector2 offset = new Vector2(offsetX, offsetY);
  1409.             Vector2 posMin = position + offset;
  1410.             Vector2 posMax = posMin + dimensions;
  1411.             return new float[] { posMin.x, posMin.y, posMax.x, posMax.y };
  1412.         }
  1413.  
  1414.  
  1415.  
  1416.         [ConsoleCommand("UI_RemoveKit")]
  1417.         private void cmdUI_RemoveKit(ConsoleSystem.Arg arg)
  1418.         {
  1419.             var player = arg.Connection.player as BasePlayer;
  1420.             if (player == null || (player.net.connection.authLevel < 2 && !permission.UserHasPermission(player.UserIDString, this.Title + ".admin"))) return;
  1421.             CuiHelper.DestroyUi(player, PanelOnScreen);
  1422.             var kit = string.Join(" ", arg.Args);
  1423.             if (GUIKits[PlayerGUI[player.userID].guiid].kits.Contains(kit))
  1424.             {
  1425.                 GUIKits[PlayerGUI[player.userID].guiid].kits.Remove(kit);
  1426.                 var config = Config.ReadObject<Dictionary<string, object>>();
  1427.                 config["NPC - GUI Kits"] = GUIKits;
  1428.                 Config.WriteObject(config);
  1429.                 CuiHelper.DestroyUi(player, PanelOnScreen);
  1430.                 RefreshKitPanel(player, PlayerGUI[player.userID].guiid, PlayerGUI[player.userID].page);
  1431.             }
  1432.         }
  1433.  
  1434.         [ConsoleCommand("UI_AddKit")]
  1435.         private void cmdUI_AddKit(ConsoleSystem.Arg arg)
  1436.         {
  1437.             var player = arg.Connection.player as BasePlayer;
  1438.             if (player == null || (player.net.connection.authLevel < 2 && !permission.UserHasPermission(player.UserIDString, this.Title + ".admin"))) return;
  1439.             CuiHelper.DestroyUi(player, PanelOnScreen);
  1440.             int page;
  1441.             if (!int.TryParse(arg.Args[0], out page))
  1442.                 if (arg.Args[0] == "close")
  1443.                     return;
  1444.                 else
  1445.                 {
  1446.                     GUIKits[PlayerGUI[player.userID].guiid].kits.Add(string.Join(" ",arg.Args));
  1447.                     var config = Config.ReadObject<Dictionary<string, object>>();
  1448.                     config["NPC - GUI Kits"] = GUIKits;
  1449.                     Config.WriteObject(config);
  1450.                     CuiHelper.DestroyUi(player, PanelOnScreen);
  1451.                     RefreshKitPanel(player, PlayerGUI[player.userID].guiid, PlayerGUI[player.userID].page);
  1452.                     return;
  1453.                 }
  1454.             double count = GetAllKits().Count() - GUIKits[PlayerGUI[player.userID].guiid].kits.Where(k => storedData.Kits.ContainsKey(k.ToLower())).ToList().Count();
  1455.             if (count == 0)
  1456.             {
  1457.                 SendReply(player, GetMsg("NoKitsFound", player.userID));
  1458.                 return;
  1459.             }
  1460.             var element = UI.CreateOverlayContainer(PanelOnScreen, UIColors["dark"], ".1 .15", ".9 .95");
  1461.             UI.CreateTextOutline(ref element, PanelOnScreen, UIColors["white"], UIColors["black"], GetMsg("AddKitToMenu", player.userID), 20, "0.1 0.9", "0.9 .99", TextAnchor.UpperCenter);
  1462.             int entriesallowed = 30;
  1463.             double remainingentries = count - (page * (entriesallowed));
  1464.             double totalpages = (Math.Floor(count / (entriesallowed)));
  1465.             {
  1466.                 if (page < totalpages - 1)
  1467.                 {
  1468.                     UI.CreateButton(ref element, PanelOnScreen, UIColors["buttongrey"], GetMsg("Last", player.userID), 16, "0.8 0.02", "0.85 0.06", $"UI_AddKit {totalpages}");
  1469.                 }
  1470.                 if (remainingentries > entriesallowed)
  1471.                 {
  1472.                     UI.CreateButton(ref element, PanelOnScreen, UIColors["buttongrey"], GetMsg("Next", player.userID), 16, "0.74 0.02", "0.79 0.06", $"UI_AddKit {page + 1}");
  1473.                 }
  1474.                 if (page > 0)
  1475.                 {
  1476.                     UI.CreateButton(ref element, PanelOnScreen, UIColors["buttongrey"], GetMsg("Back", player.userID), 16, "0.68 0.02", "0.73 0.06", $"UI_AddKit {page - 1}");
  1477.                 }
  1478.                 if (page > 1)
  1479.                 {
  1480.                     UI.CreateButton(ref element, PanelOnScreen, UIColors["buttongrey"], GetMsg("First", player.userID), 16, "0.62 0.02", "0.67 0.06", $"UI_AddKit {0}");
  1481.                 }
  1482.             }
  1483.             var i = 0;
  1484.             int n = 0;
  1485.             double shownentries = page * entriesallowed;
  1486.             foreach (string kitname in GetAllKits().Where(k => !GUIKits[PlayerGUI[player.userID].guiid].kits.Contains(k)).OrderBy(k=>k))
  1487.             {
  1488.                 i++;
  1489.                 if (i < shownentries + 1) continue;
  1490.                 else if (i <= shownentries + entriesallowed)
  1491.                 {
  1492.                     CreateKitButton(ref element, PanelOnScreen, UIColors["header"], kitname, $"UI_AddKit {kitname}", n);
  1493.                     n++;
  1494.                 }
  1495.             }
  1496.             UI.CreateButton(ref element, PanelOnScreen, UIColors["buttonred"], GetMsg("Close", player.userID), 14, $".93 .02", ".98 .06", $"UI_AddKit close");
  1497.             CuiHelper.AddUi(player, element);
  1498.         }
  1499.  
  1500.         private void CreateKitButton(ref CuiElementContainer container, string panelName, string color, string name, string cmd, int num)
  1501.         {
  1502.             var pos = CalcKitButtonPos(num);
  1503.             UI.CreateButton(ref container, panelName, color, name, 14, $"{pos[0]} {pos[1]}", $"{pos[2]} {pos[3]}", cmd);
  1504.         }
  1505.  
  1506.         private float[] CalcKitButtonPos(int number)
  1507.         {
  1508.             Vector2 position = new Vector2(0.05f, 0.82f);
  1509.             Vector2 dimensions = new Vector2(0.125f, 0.125f);
  1510.             float offsetY = 0;
  1511.             float offsetX = 0;
  1512.             if (number >= 0 && number < 6)
  1513.             {
  1514.                 offsetX = (0.03f + dimensions.x) * number;
  1515.             }
  1516.             if (number > 5 && number < 12)
  1517.             {
  1518.                 offsetX = (0.03f + dimensions.x) * (number - 6);
  1519.                 offsetY = (-0.06f - dimensions.y) * 1;
  1520.             }
  1521.             if (number > 11 && number < 18)
  1522.             {
  1523.                 offsetX = (0.03f + dimensions.x) * (number - 12);
  1524.                 offsetY = (-0.06f - dimensions.y) * 2;
  1525.             }
  1526.             if (number > 17 && number < 24)
  1527.             {
  1528.                 offsetX = (0.03f + dimensions.x) * (number - 18);
  1529.                 offsetY = (-0.06f - dimensions.y) * 3;
  1530.             }
  1531.             if (number > 23 && number < 36)
  1532.             {
  1533.                 offsetX = (0.03f + dimensions.x) * (number - 24);
  1534.                 offsetY = (-0.06f - dimensions.y) * 4;
  1535.             }
  1536.             Vector2 offset = new Vector2(offsetX, offsetY);
  1537.             Vector2 posMin = position + offset;
  1538.             Vector2 posMax = posMin + dimensions;
  1539.             return new float[] { posMin.x, posMin.y, posMax.x, posMax.y };
  1540.         }
  1541.  
  1542.         private string MinuteFormat(double minutes)
  1543.         {
  1544.             TimeSpan dateDifference = TimeSpan.FromMinutes(minutes);
  1545.             var hours = dateDifference.Hours;
  1546.             hours += (dateDifference.Days * 24);
  1547.             return string.Format("{0:00}:{1:00}:{2:00}", hours, dateDifference.Minutes, dateDifference.Seconds);
  1548.         }
  1549.  
  1550.         void DestroyAllGUI(BasePlayer player) { CuiHelper.DestroyUi(player, "KitOverlay"); CuiHelper.DestroyUi(player, PanelOnScreen); CuiHelper.DestroyUi(player, PanelKits); CuiHelper.DestroyUi(player, PanelBackground); }
  1551.         void OnUseNPC(BasePlayer npc, BasePlayer player)
  1552.         {
  1553.             if (!GUIKits.ContainsKey(npc.userID)) return;
  1554.             NewKitPanel(player, npc.userID);
  1555.         }
  1556.  
  1557.         //////////////////////////////////////////////////////////////////////////////////////
  1558.         // External Hooks
  1559.         //////////////////////////////////////////////////////////////////////////////////////
  1560.         [HookMethod("GetAllKits")]
  1561.         public string[] GetAllKits() => storedData.Kits.Keys.ToArray();
  1562.  
  1563.         [HookMethod("GetKitInfo")]
  1564.         public object GetKitInfo(string kitname)
  1565.         {
  1566.             if (storedData.Kits.ContainsKey(kitname.ToLower()))
  1567.             {
  1568.                 var kit = storedData.Kits[kitname.ToLower()];
  1569.                 JObject obj = new JObject();
  1570.                 obj["name"] = kit.name;
  1571.                 obj["permission"] = kit.permission;
  1572.                 obj["npconly"] = kit.npconly;
  1573.                 obj["max"] = kit.max;
  1574.                 obj["image"] = kit.image;
  1575.                 //obj["image2"] = kit.image2;   ///////////////////////////where i was fucking around
  1576.                 obj["hide"] = kit.hide;
  1577.                 obj["description"] = kit.description;
  1578.                 obj["cooldown"] = kit.cooldown;
  1579.                 obj["building"] = kit.building;
  1580.                 obj["authlevel"] = kit.authlevel;
  1581.                 JArray items = new JArray();
  1582.                 foreach(var itemEntry in kit.items)
  1583.                 {
  1584.                     JObject item = new JObject();
  1585.                     item["amount"] = itemEntry.amount;
  1586.                     item["container"] = itemEntry.container;
  1587.                     item["itemid"] = itemEntry.itemid;
  1588.                     item["skinid"] = itemEntry.skinid;
  1589.                     item["weapon"] = itemEntry.weapon;
  1590.                     item["blueprint"] = itemEntry.blueprintTarget > 0;
  1591.                     JArray mods = new JArray();
  1592.                     foreach (var mod in itemEntry.mods)
  1593.                         mods.Add(mod);
  1594.                     item["mods"] = mods;
  1595.                     items.Add(item);
  1596.                 }
  1597.                 obj["items"] = items;
  1598.                 return obj;
  1599.             }
  1600.             return null;
  1601.         }
  1602.  
  1603.         [HookMethod("GetKitContents")]
  1604.         public string[] GetKitContents(string kitname)
  1605.         {
  1606.             if (storedData.Kits.ContainsKey(kitname.ToLower()))
  1607.             {
  1608.                 List<string> items = new List<string>();
  1609.                 foreach (var item in storedData.Kits[kitname.ToLower()].items)
  1610.                 {
  1611.                     var itemstring = $"{item.itemid}_{item.amount}";
  1612.                     if (item.mods.Count > 0)
  1613.                         foreach (var mod in item.mods)
  1614.                             itemstring = itemstring + $"_{mod}";
  1615.                     items.Add(itemstring);
  1616.                 }
  1617.                 if (items.Count > 0)
  1618.                     return items.ToArray();
  1619.             }
  1620.             return null;
  1621.         }
  1622.  
  1623.         [HookMethod("KitCooldown")]
  1624.         public double KitCooldown(string kitname) => storedData.Kits[kitname].cooldown;
  1625.  
  1626.         [HookMethod("PlayerKitCooldown")]
  1627.         public double PlayerKitCooldown(ulong ID, string kitname) => storedData.Kits[kitname].cooldown <= 0 ? 0 : CurrentTime() > GetKitData(ID, kitname).cooldown ? storedData.Kits[kitname].cooldown : CurrentTime() - GetKitData(ID, kitname).cooldown;
  1628.  
  1629.         [HookMethod("KitDescription")]
  1630.         public string KitDescription(string kitname) => storedData.Kits[kitname].description;
  1631.  
  1632.         [HookMethod("KitMax")]
  1633.         public int KitMax(string kitname) => storedData.Kits[kitname].max;
  1634.  
  1635.         [HookMethod("PlayerKitMax")]
  1636.         public double PlayerKitMax(ulong ID, string kitname) => storedData.Kits[kitname].max <= 0 ? 0 : storedData.Kits[kitname].max - GetKitData(ID, kitname).max < storedData.Kits[kitname].max ? storedData.Kits[kitname].max - GetKitData(ID, kitname).max : 0;
  1637.  
  1638.         [HookMethod("KitImage")]
  1639.         public string KitImage(string kitname) => storedData.Kits[kitname].image;
  1640.  
  1641.         //////////////////////////////////////////////////////////////////////////////////////
  1642.         // Console Command
  1643.         //////////////////////////////////////////////////////////////////////////////////////
  1644.         [ConsoleCommand("kit.gui")]
  1645.         void cmdConsoleKitGui(ConsoleSystem.Arg arg)
  1646.         {
  1647.             if (arg.Connection == null)
  1648.             {
  1649.                 SendReply(arg, "You can't use this command from the server console");
  1650.                 return;
  1651.             }
  1652.             if (!arg.HasArgs())
  1653.             {
  1654.                 SendReply(arg, "You are not allowed to use manually this command");
  1655.                 return;
  1656.             }
  1657.             var player = arg.Player();
  1658.             var kitname = arg.Args[0]/*.Substring(1, arg.Args[0].Length - 2)*/;
  1659.             TryGiveKit(player, kitname);
  1660.         }
  1661.  
  1662.         [ConsoleCommand("kit.close")]
  1663.         void cmdConsoleKitClose(ConsoleSystem.Arg arg)
  1664.         {
  1665.             if (arg.Connection == null)
  1666.             {
  1667.                 SendReply(arg, "You can't use this command from the server console");
  1668.                 return;
  1669.             }
  1670.             PlayerGUI[arg.Player().userID].open = false;
  1671.             DestroyAllGUI(arg.Player());
  1672.         }
  1673.  
  1674.         [ConsoleCommand("kit.show")]
  1675.         void cmdConsoleKitShow(ConsoleSystem.Arg arg)
  1676.         {
  1677.             if (arg.Connection == null)
  1678.             {
  1679.                 SendReply(arg, "You can't use this command from the server console");
  1680.                 return;
  1681.             }
  1682.             if (!arg.HasArgs())
  1683.             {
  1684.                 SendReply(arg, "You are not allowed to use manually this command");
  1685.                 return;
  1686.             }
  1687.  
  1688.             var player = arg.Player();
  1689.             PLayerGUI playerGUI;
  1690.             if (!PlayerGUI.TryGetValue(player.userID, out playerGUI)) return;
  1691.             RefreshKitPanel(player, playerGUI.guiid, arg.GetInt(0));
  1692.         }
  1693.  
  1694.         List<BasePlayer> FindPlayer(string arg)
  1695.         {
  1696.             var listPlayers = new List<BasePlayer>();
  1697.  
  1698.             ulong steamid;
  1699.             ulong.TryParse(arg, out steamid);
  1700.             string lowerarg = arg.ToLower();
  1701.  
  1702.             foreach (var player in BasePlayer.activePlayerList)
  1703.             {
  1704.                 if (steamid != 0L)
  1705.                     if (player.userID == steamid)
  1706.                     {
  1707.                         listPlayers.Clear();
  1708.                         listPlayers.Add(player);
  1709.                         return listPlayers;
  1710.                     }
  1711.                 string lowername = player.displayName.ToLower();
  1712.                 if (lowername.Contains(lowerarg))
  1713.                 {
  1714.                     listPlayers.Add(player);
  1715.                 }
  1716.             }
  1717.             return listPlayers;
  1718.         }
  1719.  
  1720.         //////////////////////////////////////////////////////////////////////////////////////
  1721.         // Chat Command
  1722.         //////////////////////////////////////////////////////////////////////////////////////
  1723.  
  1724.         bool hasAccess(BasePlayer player)
  1725.         {
  1726.             if (player?.net?.connection?.authLevel > 1 || permission.UserHasPermission(player.UserIDString, this.Title +".admin"))
  1727.                 return true;
  1728.             return false;
  1729.         }
  1730.         void SendListKitEdition(BasePlayer player)
  1731.         {
  1732.             SendReply(player, "authlevel XXX\r\nbuilding \"filename\" => buy a building to paste from\r\ncooldown XXX\r\ndescription \"description text here\" => set a description for this kit\r\nhide TRUE/FALSE => dont show this kit in lists (EVER)\r\nimage \"image http url\" => set an image for this kit (gui only)\r\nitems => set new items for your kit (will copy your inventory)\r\nmax XXX\r\nnpconly TRUE/FALSE => only get this kit out of a NPC\r\npermission \"permission name\" => set the permission needed to get this kit");
  1733.         }
  1734.         [ChatCommand("kit")]
  1735.         void cmdChatKit(BasePlayer player, string command, string[] args)
  1736.         {
  1737.             if (args.Length == 0)
  1738.             {
  1739.                 if (GUIKits.ContainsKey(0))
  1740.                     NewKitPanel(player, 0);
  1741.                 else
  1742.                 {
  1743.                     string reason = string.Empty;
  1744.                     foreach (var pair in storedData.Kits)
  1745.                     {
  1746.                         var cansee = CanSeeKit(player, pair.Key, false, out reason);
  1747.                         if (!cansee && string.IsNullOrEmpty(reason)) continue;
  1748.                         SendReply(player, $"{pair.Value.name} - {pair.Value.description} {reason}");
  1749.                     }
  1750.                 }
  1751.                 return;
  1752.             }
  1753.             if (args.Length == 1)
  1754.             {
  1755.                 switch (args[0])
  1756.                 {
  1757.                     case "help":
  1758.                         SendReply(player, "====== Player Commands ======");
  1759.                         SendReply(player, "/kit => to get the list of kits");
  1760.                         SendReply(player, "/kit KITNAME => to redeem the kit");
  1761.                         if (!hasAccess(player)) { return; }
  1762.                         SendReply(player, "====== Admin Commands ======");
  1763.                         SendReply(player, "/kit add KITNAME => add a kit");
  1764.                         SendReply(player, "/kit remove KITNAME => remove a kit");
  1765.                         SendReply(player, "/kit edit KITNAME => edit a kit");
  1766.                         SendReply(player, "/kit list => get a raw list of kits (the real full list)");
  1767.                         SendReply(player, "/kit give PLAYER/STEAMID KITNAME => give a kit to a player");
  1768.                         SendReply(player, "/kit resetkits => deletes all kits");
  1769.                         SendReply(player, "/kit resetdata => reset player data");
  1770.                         break;
  1771.                     case "add":
  1772.                     case "remove":
  1773.                     case "edit":
  1774.                         if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1775.                         SendReply(player, $"/kit {args[0]} KITNAME");
  1776.                         break;
  1777.                     case "give":
  1778.                         if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1779.                         SendReply(player, "/kit give PLAYER/STEAMID KITNAME");
  1780.                         break;
  1781.                     case "list":
  1782.                         if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1783.                         foreach (var kit in storedData.Kits.Values)
  1784.                         {
  1785.                             SendReply(player, $"{kit.name} - {kit.description}");
  1786.                         }
  1787.                         break;
  1788.                     case "items":
  1789.                         break;
  1790.                     case "resetkits":
  1791.                         if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1792.                         storedData.Kits.Clear();
  1793.                         kitEditor.Clear();
  1794.                         ResetData();
  1795.                         SaveKits();
  1796.                         SendReply(player, "Resetted all kits and player data");
  1797.                         break;
  1798.                     case "resetdata":
  1799.                         if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1800.                         ResetData();
  1801.                         SendReply(player, "Resetted all player data");
  1802.                         break;
  1803.                     default:
  1804.                         TryGiveKit(player, args[0].ToLower());
  1805.                         break;
  1806.                 }
  1807.                 if (args[0] != "items")
  1808.                     return;
  1809.  
  1810.             }
  1811.             if (!hasAccess(player)) { SendReply(player, "You don't have access to this command"); return; }
  1812.  
  1813.             string kitname;
  1814.             switch (args[0])
  1815.             {
  1816.                 case "add":
  1817.                     kitname = args[1].ToLower();
  1818.                     if (storedData.Kits.ContainsKey(kitname))
  1819.                     {
  1820.                         SendReply(player, "This kit already exists.");
  1821.                         return;
  1822.                     }
  1823.                     storedData.Kits[kitname] = new Kit { name = args[1] };
  1824.                     kitEditor[player.userID] = kitname;
  1825.                     SendReply(player, "You've created a new kit: " + args[1]);
  1826.                     SendListKitEdition(player);
  1827.                     break;
  1828.                 case "give":
  1829.                     if (args.Length < 3)
  1830.                     {
  1831.                         SendReply(player, "/kit give PLAYER/STEAMID KITNAME");
  1832.                         return;
  1833.                     }
  1834.                     kitname = args[2].ToLower();
  1835.                     if (!storedData.Kits.ContainsKey(kitname))
  1836.                     {
  1837.                         SendReply(player, "This kit doesn't seem to exist.");
  1838.                         return;
  1839.                     }
  1840.                     var findPlayers = FindPlayer(args[1]);
  1841.                     if (findPlayers.Count == 0)
  1842.                     {
  1843.                         SendReply(player, "No players found.");
  1844.                         return;
  1845.                     }
  1846.                     if (findPlayers.Count > 1)
  1847.                     {
  1848.                         SendReply(player, "Multiple players found.");
  1849.                         return;
  1850.                     }
  1851.                     GiveKit(findPlayers[0], kitname);
  1852.                     SendReply(player, $"You gave {findPlayers[0].displayName} the kit: {storedData.Kits[kitname].name}");
  1853.                     SendReply(findPlayers[0], string.Format("You've received the kit {1} from {0}", player.displayName, storedData.Kits[kitname].name));
  1854.                     break;
  1855.                 case "edit":
  1856.                     kitname = args[1].ToLower();
  1857.                     if (!storedData.Kits.ContainsKey(kitname))
  1858.                     {
  1859.                         SendReply(player, "This kit doesn't seem to exist");
  1860.                         return;
  1861.                     }
  1862.                     kitEditor[player.userID] = kitname;
  1863.                     SendReply(player, $"You are now editing the kit: {kitname}");
  1864.                     SendListKitEdition(player);
  1865.                     break;
  1866.                 case "remove":
  1867.                     kitname = args[1].ToLower();
  1868.                     if (!storedData.Kits.Remove(kitname))
  1869.                     {
  1870.                         SendReply(player, "This kit doesn't seem to exist");
  1871.                         return;
  1872.                     }
  1873.                     SendReply(player, $"{kitname} was removed");
  1874.                     if (kitEditor[player.userID] == kitname) kitEditor.Remove(player.userID);
  1875.                     break;
  1876.                 default:
  1877.                     if (!kitEditor.TryGetValue(player.userID, out kitname))
  1878.                     {
  1879.                         SendReply(player, "You are not creating or editing a kit");
  1880.                         return;
  1881.                     }
  1882.                     Kit kit;
  1883.                     if (!storedData.Kits.TryGetValue(kitname, out kit))
  1884.                     {
  1885.                         SendReply(player, "There was an error while getting this kit, was it changed while you were editing it?");
  1886.                         return;
  1887.                     }
  1888.                     for (var i = 0; i < args.Length; i++)
  1889.                     {
  1890.                         object editvalue;
  1891.                         var key = args[i].ToLower();
  1892.                         switch (key)
  1893.                         {
  1894.                             case "items":
  1895.                                 kit.items = GetPlayerItems(player);
  1896.                                 SendReply(player, "The items were copied from your inventory");
  1897.                                 continue;
  1898.                             case "building":
  1899.                                 var buildingvalue = args[++i];
  1900.                                 if (buildingvalue.ToLower() == "false")
  1901.                                     editvalue = kit.building = string.Empty;
  1902.                                 else
  1903.                                     editvalue = kit.building = buildingvalue;
  1904.                                 break;
  1905.                             case "name":
  1906.                                 continue;
  1907.                             case "description":
  1908.                                 editvalue = kit.description = args[++i];
  1909.                                 break;
  1910.                             case "max":
  1911.                                 editvalue = kit.max = int.Parse(args[++i]);
  1912.                                 break;
  1913.                             case "cooldown":
  1914.                                 editvalue = kit.cooldown = double.Parse(args[++i]);
  1915.                                 break;
  1916.                             case "authlevel":
  1917.                                 editvalue = kit.authlevel = int.Parse(args[++i]);
  1918.                                 break;
  1919.                             case "hide":
  1920.                                 editvalue = kit.hide = bool.Parse(args[++i]);
  1921.                                 break;
  1922.                             case "npconly":
  1923.                                 editvalue = kit.npconly = bool.Parse(args[++i]);
  1924.                                 break;
  1925.                             case "permission":
  1926.                                 editvalue = kit.permission = args[++i];
  1927.                                 if (!kit.permission.StartsWith("kits."))
  1928.                                     editvalue = kit.permission = $"kits.{kit.permission}";
  1929.                                 InitializePermissions();
  1930.                                 break;
  1931.                             case "image":
  1932.                                 editvalue = kit.image = args[++i];
  1933.                                 break;
  1934.                             default:
  1935.                                 SendReply(player, $"{args[i]} is not a valid argument");
  1936.                                 continue;
  1937.                         }
  1938.                         SendReply(player, $"{key} set to {editvalue ?? "null"}");
  1939.                     }
  1940.                     break;
  1941.             }
  1942.             SaveKits();
  1943.         }
  1944.     }
  1945. }
  1946.  
Advertisement
Add Comment
Please, Sign In to add comment