C#:
using System.Linq;
using System.Collections.Generic;
using Oxide.Core.Plugins;
using Oxide.Core;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using System;
using HarmonyLib;
namespace Oxide.Plugins {
// Id management improvements.
// Gingerbread npc error fix.
// Fix for June wipe
[Info("NPCKits", "Steenamaroo", "1.3.0", ResourceId = 29)]
[Description("Give custom Kits to all default Rust npc types.")]
public class NPCKits : RustPlugin {
[PluginReference]
Plugin Kits;
public static NPCKits nk;
bool loaded;
public int Increment = 10;
public enum FStein {
None, Light, Medium, Heavy
}
public System.Random random = new System.Random();
Dictionary<ulong, string> Copy = new Dictionary<ulong, string>();
public Dictionary<ulong, Info> BotInfo = new Dictionary<ulong, Info>();
public Dictionary<ulong, int> CorpseSteamIDs = new Dictionary<ulong, int>();
public Dictionary<int, int> CorpseInstanceIDs = new Dictionary<int, int>();
public Dictionary<ulong, Settings> LiveNpcs = new Dictionary<ulong, Settings>();
public class Info {
public NPCPlayer npc;
public string profilename;
public List<InvContents>[] inventory = {
new List<InvContents>(), new List<InvContents>(), new List<InvContents>()
}
;
}
public class InvContents {
public int ID;
public int amount;
public ulong skinID;
}
#region Hooks
void Init() => permission.RegisterPermission(permAllowed, this);
void Unload() {
harmony.UnpatchAll("NPCKits");
foreach (BasePlayer player in BasePlayer.activePlayerList) DestroyMenu(player, true);
if (configData != null && configData.SaveUIOnReload) SaveConfig(configData);
}
List<NPCPlayer> AllNPCs = new List<NPCPlayer>();
void OnServerInitialized() {
nk = this;
if (!LoadConfigVariables()) {
Puts("Config file issue detected. Please delete file, or check syntax and fix.");
Interface.Oxide.UnloadPlugin(Name);
return;
}
configData.CorpseTypes = configData.CorpseTypes.Where(x => new ConfigData().CorpseTypes.ContainsKey(x.Key)).ToDictionary(pair => pair.Key, pair => pair.Value);
if (Kits == null) PrintWarning("Kits plugin is not installed.");
CheckKits();
loaded = true;
harmony.UnpatchAll("NPCKits");
ApplyPatches();
AllNPCs = BaseNetworkable.serverEntities.OfType<NPCPlayer>().ToList();
foreach (var npc in AllNPCs) AddToBotList(npc, false);
}
void Reload(string profile) {
foreach (var inv in BotInfo.Where(x => x.Value.npc != null && x.Value.profilename == profile).ToList()) AddToBotList(inv.Value.npc, true);
}
#endregion
#region BotHandling
void EnsureNoRecord(ulong ID) {
CorpseSteamIDs.Remove(ID);
LiveNpcs.Remove(ID);
BotInfo.Remove(ID);
AllNPCs.RemoveAll(x => x != null && x.userID == ID);
}
void OnEntitySpawned(BaseEntity entity) {
if (!loaded || entity == null) return;
var npc = entity as NPCPlayer;
if (npc != null) {
EnsureNoRecord(npc.userID);
AllNPCs.Add(npc);
timer.Once(0.3f, () => {
if (npc != null && !npc.IsDestroyed) AddToBotList(npc, false);
}
);
return;
}
var corpse = entity as LootableCorpse;
if (corpse != null && LiveNpcs.ContainsKey(corpse.playerSteamID) && BotInfo.ContainsKey(corpse.playerSteamID)) {
Info botInv = BotInfo[corpse.playerSteamID];
Settings record = LiveNpcs[corpse.playerSteamID];
if (CorpseSteamIDs.ContainsKey(corpse.playerSteamID)) {
CorpseInstanceIDs[corpse.gameObject.GetInstanceID()] = CorpseSteamIDs[corpse.playerSteamID];
CorpseSteamIDs.Remove(corpse.playerSteamID);
}
LiveNpcs.Remove(corpse.playerSteamID);
BotInfo.Remove(corpse.playerSteamID);
timer.Once(0.3f, () => {
if (corpse == null || corpse.containers == null || corpse.containers.Length == 0) return;
corpse.enableSaving = false;
BaseEntity.saveList.RemoveWhere(p => p == corpse);
var ARL = record.Default_Rust_Loot_Percent >= random.Next(1, 101);
var WM = record.Wipe_Main_Inventory_Percent >= random.Next(1, 101);
var WC = record.Wipe_Clothing_Percent >= random.Next(1, 101);
var WB = record.Wipe_Belt_Percent >= random.Next(1, 101);
if (!ARL) corpse.containers[0].Clear();
if (corpse.containers.Count() == 1) corpse.containers = new ItemContainer[] {
corpse.containers[0], new ItemContainer(), new ItemContainer()
}
;
// Gingerbread npc only has one container - CopyInventoryToCorpse is false
for (int i = 0; i < botInv.inventory.Length; i++) {
if (i == 0 && WM || i == 1 || i == 2 && WB) continue;
foreach (var item in botInv.inventory[i]) {
var giveItem = ItemManager.CreateByItemID(item.ID, item.amount, item.skinID);
giveItem.MoveToContainer(corpse.containers[i], -1, true);
}
}
if (WC) corpse.containers[1].Clear();
corpse._playerName = record.DisplayName;
corpse.lootPanelName = record.DisplayName;
corpse.containers = new ItemContainer[] {
corpse.containers[0], new ItemContainer(), new ItemContainer(), corpse.containers[1], corpse.containers[2]
}
;
foreach (var item in corpse.containers[3].itemList.ToList()) {
if (item.info.shortname.Contains("frankensteins.")) {
corpse.containers[0].capacity += 1;
item.MoveToContainer(corpse.containers[0], corpse.containers[0].capacity - 1);
}
}
timer.Once(record.Corpse_Minutes * 60, () => {
if (corpse != null && !corpse.IsDestroyed) corpse?.Kill();
}
);
timer.Once(2, () => {
corpse?.ResetRemovalTime(record.Corpse_Minutes * 60);
}
);
}
);
}
}
float GetPercent(int min, int max, float weapMax) {
min = Mathf.Max(1, min);
max = Mathf.Max(1, max);
if (min >= max) return weapMax / 100f * max;
return weapMax / 100f * random.Next(min, max);
}
void OnPlayerDeath(BasePlayer player, HitInfo info) => OnEntityKill(player, info);
void OnEntityKill(BaseNetworkable entity, HitInfo info) {
NPCPlayer npc = entity as NPCPlayer;
if (npc != null && AllNPCs.Contains(npc)) {
AllNPCs.Remove(npc);
if (npc?.userID != null && LiveNpcs.ContainsKey(npc.userID)) {
if (info?.InitiatorPlayer != null) {
Item activeItem = npc.GetActiveItem();
var record = LiveNpcs[npc.userID];
int chance = random.Next(1, 101);
CorpseSteamIDs[npc.userID] = record.Backpack_Minutes * 60;
if (record.Weapon_Drop_Percent >= chance && activeItem != null) {
activeItem.condition = GetPercent(record.Min_Weapon_Drop_Condition_Percent, record.Max_Weapon_Drop_Condition_Percent, activeItem.info.condition.max);
var held = activeItem.GetHeldEntity();
if (held != null) {
BaseProjectile gun = held as BaseProjectile;
if (gun != null) {
bool wipeAmmo = record.Dropped_Weapon_Has_Ammo_Percent_Chance < random.Next(1, 101);
gun.primaryMagazine.contents = wipeAmmo ? 0 : gun.primaryMagazine.capacity;
gun.SendNetworkUpdateImmediate();
}
if (gun != null || held is BaseMelee) {
activeItem.Drop(npc.eyes.position, new Vector3(), new Quaternion());
npc.svActiveItemID = new ItemId();
npc.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
}
}
}
}
ItemContainer[] source = {
npc.inventory.containerMain, npc.inventory.containerWear, npc.inventory.containerBelt
}
;
Info botInv;
if (!BotInfo.TryGetValue(npc.userID, out botInv)) return;
for (int i = 0; i < source.Length; i++) {
foreach (var item in source[i].itemList) {
if (item.info.shortname.Contains("frankensteins.")) continue;
botInv.inventory[i].Add(new InvContents {
ID = item.info.itemid, amount = item.amount, skinID = item.skin,
}
);
}
}
}
}
}
void AddToBotList(NPCPlayer player, bool reload) {
if (player == null || player.Categorize() == "Zombie") return;
if (Interface.CallHook("OnNpcKits", player.userID.Get()) != null || Interface.CallHook("OnNpcKits", player) != null) return;
var instance = player?.GetComponent<SpawnPointInstance>()?.parentSpawnPoint;
if (instance != null) {
var name = instance?.GetComponentInParent<PrefabParameters>()?.ToString();
if (name != null) {
foreach (var n in names) if (name.Contains(n.Key)) {
ProcessNpc(player, n.Value, reload);
return;
}
}
}
foreach (var entry in names) if (player.ShortPrefabName == entry.Key) {
ProcessNpc(player, entry.Value, reload);
return;
}
foreach (var entry in names) if (player.ShortPrefabName.Contains(entry.Key)) {
ProcessNpc(player, entry.Value, reload);
return;
}
//Puts($"Prefab name {player.PrefabName}");
//foreach (var p in BasePlayer.activePlayerList)
// p.SendConsoleCommand("ddraw.line", 30f, Color.blue, player.transform.position, player.transform.position + new Vector3(0, 100, 0));
}
Dictionary<string, string> names = new Dictionary<string, string>() {
{
"oilrig", "OilRig"
}
, {
"excavator", "Excavator"
}
, {
"peacekeeper", "CompoundScientist"
}
, {
"bandit_guard", "BanditTown"
}
, {
"_ch47_gunner", "MountedScientist"
}
, {
"junkpile", "JunkPileScientist"
}
, {
"scarecrow_dungeon", "DungeonScarecrow"
}
, {
"scarecrow", "ScareCrow"
}
, {
"military_tunnel", "MilitaryTunnelScientist"
}
, {
"scientist_full", "MilitaryTunnelScientist"
}
, {
"scientist_turret", "CargoShip"
}
, {
"scientistnpc_cargo", "CargoShip"
}
, {
"scientist_astar", "CargoShip"
}
, {
"scientistnpc_bradley", "APCScientist"
}
, {
"scientistnpc_bradley_heavy", "APCScientistHeavy"
}
, {
"scientistnpc_heavy", "HeavyScientist"
}
, {
"scientistnpc_outbreak", "JungleScientist"
}
, {
"tunneldweller", "TunnelDweller"
}
, {
"underwaterdweller" , "UnderwaterDweller"
}
, {
"trainyard" , "Trainyard"
}
, {
"airfield" , "Airfield"
}
, {
"scientistnpc_roamtethered", "DesertScientist"
}
, {
"arctic_research_base", "ArcticResearchBase"
}
, {
"launch_site", "LaunchSite"
}
, {
"nuclear_missile_silo", "NuclearMissileSilo"
}
, {
"gingerbread", "Gingerbread"
}
, {
"missionprovider_fishing", "MissionProviderOutpost"
}
, {
"missionprovider_outpost", "MissionProviderFishing"
}
, {
"missionprovider_stables", "MissionProviderStables"
}
, {
"missionprovider_bandit", "MissionProviderBandit"
}
, {
"boat_shopkeeper", "BoatShopkeeper"
}
, {
"bandit_shopkeeper", "BanditShopkeeper"
}
,
}
;
object GetKitInfo(string name) => Kits?.Call("GetKitInfo", name, true);
object GiveKit(NPCPlayer npc, string name) => Kits?.Call($"GiveKit", npc, name, true);
bool HasFStein(Settings r) => r.FrankenStein_Head != FStein.None || r.FrankenStein_Torso != FStein.None || r.FrankenStein_Legs != FStein.None;
void GiveFStein(NPCPlayer npc, Settings r) {
if (r.FrankenStein_Head != FStein.None) {
npc.inventory.containerWear.capacity += 1;
Item newItem = ItemManager.CreateByName($"frankensteins.monster.0{Convert.ToInt16(r.FrankenStein_Head)}.head", 1);
if (newItem != null) {
SetOccupation(newItem, false, 0, 0);
if (!newItem.MoveToContainer(npc.inventory.containerWear)) newItem.Remove(0f);
}
}
if (r.FrankenStein_Torso != FStein.None) {
Item newItem = ItemManager.CreateByName($"frankensteins.monster.0{Convert.ToInt16(r.FrankenStein_Torso)}.torso", 1);
if (newItem != null) {
SetOccupation(newItem, true, 504, 0);
if (!newItem.MoveToContainer(npc.inventory.containerWear)) newItem.Remove(0f);
}
}
if (r.FrankenStein_Legs != FStein.None) {
Item newItem = ItemManager.CreateByName($"frankensteins.monster.0{Convert.ToInt16(r.FrankenStein_Legs)}.legs", 1);
if (newItem != null) {
SetOccupation(newItem, true, 129024, 0);
if (!newItem.MoveToContainer(npc.inventory.containerWear)) newItem.Remove(0f);
}
}
}
void SetOccupation(Item item, bool set, int under, int over) {
var comp = item.info.GetComponent<ItemModWearable>();
if (comp != null) {
comp.protectionProperties = null;
if (set) {
comp.targetWearable.occupationUnder = (Wearable.OccupationSlots)under;
comp.targetWearable.occupationOver = (Wearable.OccupationSlots)over;
}
}
}
public Dictionary<ulong, string> DisplayNames = new Dictionary<ulong, string>();
void ProcessNpc(NPCPlayer npc, string NPCType, bool reload) {
var record = configData.CorpseTypes[NPCType];
if (record == null || !record.enabled) return;
if (!reload && LiveNpcs.ContainsKey(npc.userID)) return;
LiveNpcs[npc.userID] = record;
if (record.Health > 0) {
npc._maxHealth = record.Health;
npc.startHealth = npc._maxHealth;
npc.InitializeHealth(record.Health, record.Health);
}
if (record.DisplayName != string.Empty) DisplayNames[npc.userID] = record.DisplayName;
else DisplayNames[npc.userID] = NPCType;
npc.displayName = DisplayNames[npc.userID];
if (reload) npc.inventory.Strip();
if (record.Kits != null && record.Kits.Count != 0) {
int kitRnd = random.Next(record.Kits.Count);
if (record.Kits[kitRnd] != null) {
object checkKit = GetKitInfo(record.Kits[kitRnd]);
if (checkKit == null) {
if (Kits != null) PrintWarning($"Kit {record.Kits[kitRnd]} does not exist.");
}
else {
if (record.Wipe_Default_Clothing) {
npc.inventory.containerWear.Clear();
ItemManager.DoRemoves();
}
if (record.Wipe_Default_Weapons) {
npc.inventory.containerBelt.Clear();
ItemManager.DoRemoves();
}
if (HasFStein(record)) npc.inventory.containerWear.Clear();
GiveKit(npc, record.Kits[kitRnd]);
GiveFStein(npc, record);
npc.EquipWeapon();
}
}
}
Info botInv = new Info() {
profilename = NPCType, npc = npc
}
;
BotInfo[npc.userID] = botInv;
}
Timer PatchTimer;
private Harmony harmony = new Harmony("NPCKits");
private void OnPluginUnloaded(Plugin plugin) => OnPluginLoaded(plugin);
private void OnPluginLoaded(Plugin plugin) {
if (nk?.harmony == null) return;
PatchTimer?.Destroy();
PatchTimer = timer.Once(2f, () => ApplyPatches());
}
void ApplyPatches() {
if (!Harmony.HasAnyPatches("NPCKits")) {
var SciName = typeof(ScientistNPC).GetMethod("get_displayName");
var SciNamePatch = typeof(ScientistNPCDisplayNames).GetMethod("ScientistNPCFix");
harmony.Patch(SciName, new HarmonyMethod(SciNamePatch));
var TunnelName = typeof(TunnelDweller).GetMethod("get_displayName");
var TunnelNamePatch = typeof(TunnelDwellerDisplayNames).GetMethod("TunnelDwellerNPCFix");
harmony.Patch(TunnelName, new HarmonyMethod(TunnelNamePatch));
var UnderwaterName = typeof(UnderwaterDweller).GetMethod("get_displayName");
var UnderwaterNamePatch = typeof(UnderwaterDwellerDisplayNames).GetMethod("UnderwaterDwellerNPCFix");
harmony.Patch(UnderwaterName, new HarmonyMethod(UnderwaterNamePatch));
var DropItems = typeof(LootableCorpse).GetMethod("DropItems");
var DropItemsPatch = typeof(NKDropItem).GetMethod("NKDropItemPatch");
harmony.Patch(DropItems, new HarmonyMethod(DropItemsPatch));
}
}
public static class ScientistNPCDisplayNames {
[HarmonyPrefix]
public static bool ScientistNPCFix(ref string __result, ScientistNPC __instance) {
if (__instance != null && nk != null && nk.DisplayNames.ContainsKey(__instance.userID)) {
__result = nk.DisplayNames[__instance.userID];
return false;
}
return true;
}
}
public static class TunnelDwellerDisplayNames {
[HarmonyPrefix]
public static bool TunnelDwellerNPCFix(ref string __result, TunnelDweller __instance) {
if (__instance != null && nk != null && nk.DisplayNames.ContainsKey(__instance.userID)) {
__result = nk.DisplayNames[__instance.userID];
return false;
}
return true;
}
}
public static class UnderwaterDwellerDisplayNames {
[HarmonyPrefix]
public static bool UnderwaterDwellerNPCFix(ref string __result, UnderwaterDweller __instance) {
if (__instance != null && nk != null && nk.DisplayNames.ContainsKey(__instance.userID)) {
__result = nk.DisplayNames[__instance.userID];
return false;
}
return true;
}
}
public static class NKDropItem {
[HarmonyPrefix]
public static bool NKDropItemPatch(LootableCorpse __instance) {
if (nk == null || __instance?.gameObject == null) return true;
if (ConVar.Global.disableBagDropping) {
return false;
}
if (__instance.containers != null) {
int minutes = -1;
if (nk.CorpseInstanceIDs.ContainsKey(__instance.gameObject.GetInstanceID())) {
minutes = nk.CorpseInstanceIDs[__instance.gameObject.GetInstanceID()];
if (minutes == 0) {
nk.CorpseInstanceIDs.Remove(__instance.gameObject.GetInstanceID());
return false;
}
DroppedItemContainer droppedItemContainer = ItemContainer.Drop("assets/prefabs/misc/item drop/item_drop_backpack.prefab", __instance.transform.position, Quaternion.identity, __instance.containers);
if (droppedItemContainer != null) {
droppedItemContainer.enableSaving = false;
BaseEntity.saveList.RemoveWhere(p => p == droppedItemContainer);
droppedItemContainer.playerName = __instance.playerName;
droppedItemContainer.playerSteamID = __instance.playerSteamID;
droppedItemContainer.CancelInvoke(droppedItemContainer.RemoveMe);
nk.timer.Once(minutes, () => {
if (droppedItemContainer != null && !droppedItemContainer.IsDestroyed) droppedItemContainer?.Kill();
}
);
nk.CorpseInstanceIDs.Remove(__instance.gameObject.GetInstanceID());
}
return false;
}
}
return true;
}
}
#endregion
#region UI
const string Font = "robotocondensed-regular.ttf";
const string permAllowed = "NPCKits.allowed";
public List<string> ValidKits = new List<string>();
bool HasPermission(string id, string perm) => permission.UserHasPermission(id, perm);
void OnPlayerDisconnected(BasePlayer player) => DestroyMenu(player, true);
[ChatCommand("npckits")]
void npckits(BasePlayer player, string command, string[] args) {
if (!HasPermission(player.UserIDString, permAllowed) && !player.IsAdmin) return;
if (args == null || args.Length == 0) {
CheckKits();
NPCKitsBGUI(player);
NPCKitsMainUI(player, "");
return;
}
}
void CheckKits() {
ValidKits.Clear();
Kits?.Call("GetKitNames", new object[] {
ValidKits
}
);
var names = Kits?.Call("GetAllKits");
if (names != null) ValidKits.AddRange((string[])names);
ValidKits = ValidKits.Distinct().ToList();
ValidKits = ValidKits.OrderBy(x => x.ToString()).ToList();
}
void DestroyMenu(BasePlayer player, bool all) {
if (all) {
if (Copy.ContainsKey(player.userID)) Copy.Remove(player.userID);
CuiHelper.DestroyUi(player, "NPCKitsBGUI");
}
CuiHelper.DestroyUi(player, "NPCKitsKitsUI");
CuiHelper.DestroyUi(player, "NPCKitsMainUI");
CuiHelper.DestroyUi(player, "NPCKitsDocs");
}
void NPCKitsBGUI(BasePlayer player) {
if (player == null || configData == null) return;
DestroyMenu(player, true);
string guiString = string.Format("0.1 0.1 0.1 0.94");
var elements = new CuiElementContainer();
var mainName = elements.Add(new CuiPanel {
Image = {
Color = guiString
}
, RectTransform = {
AnchorMin = "0.1 0.05", AnchorMax = "0.9 0.95"
}
, CursorEnabled = true
}
, "Overlay", "NPCKitsBGUI");
elements.Add(new CuiButton {
Button = {
Color = "0 0 0 1"
}
, RectTransform = {
AnchorMin = $"0 0.95", AnchorMax = $"0.999 1"
}
, Text = {
Text = string.Empty
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Color = "0 0 0 1"
}
, RectTransform = {
AnchorMin = $"0 0", AnchorMax = $"0.999 0.05"
}
, Text = {
Text = string.Empty
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = "CloseNPCKits", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = "0.955 0.96", AnchorMax = "0.99 0.99"
}
, Text = {
Text = "X", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiLabel {
Text = {
Text = "NPCKits", FontSize = 20, Font = Font, Align = TextAnchor.MiddleCenter
}
, RectTransform = {
AnchorMin = "0.2 0.95", AnchorMax = "0.8 1"
}
}
, mainName);
CuiHelper.AddUi(player, elements);
}
void NPCKitsMainUI(BasePlayer player, string profile) {
DestroyMenu(player, false);
var elements = new CuiElementContainer();
var mainName = elements.Add(new CuiPanel {
Image = {
Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = "0.1 0", AnchorMax = "0.9 0.9"
}
, CursorEnabled = true
}
, "Overlay", "NPCKitsMainUI");
elements.Add(new CuiElement {
Parent = "NPCKitsMainUI", Components = {
new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
}
);
float top = 0.875f, bottom = 0.9f;
bool odd = true;
if (string.IsNullOrEmpty(profile)) {
elements.Add(new CuiButton {
Button = {
Command = "", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0 0.95", AnchorMax = $"0.999 0.99"
}
, Text = {
Text = "NPC Types", FontSize = 18, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
var data = configData.CorpseTypes;
foreach (var entry in data) {
if (odd) elements.Add(new CuiPanel {
Image = {
Color = $"0 0 0 0.8"
}
, RectTransform = {
AnchorMin = $"0 {top}", AnchorMax = $"0.999 {bottom}"
}
, CursorEnabled = true
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsUI {RS(entry.Key)} 0 0", Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = $"0 {top}", AnchorMax = $"1 {bottom}"
}
, Text = {
Text = $"{entry.Key}", Color = entry.Value.enabled ? "0 1 0 1" : "1 1 1 1", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
top -= 0.025f;
bottom -= 0.025f;
odd = !odd;
}
}
else {
elements.Add(new CuiButton {
Button = {
Command = "", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0 0.95", AnchorMax = $"0.999 0.99"
}
, Text = {
Text = profile, FontSize = 18, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
foreach (var setting in typeof(Settings).GetFields()) {
if (setting.Name == "Kits" || setting.Name == "DisplayName") continue;
top -= 0.025f;
bottom -= 0.025f;
if (odd) elements.Add(new CuiPanel {
Image = {
Color = $"0 0 0 0.8"
}
, RectTransform = {
AnchorMin = $"0 {top}", AnchorMax = $"0.999 {bottom}"
}
, CursorEnabled = true
}
, mainName);
if (setting.FieldType == typeof(int)) {
elements.Add(new CuiLabel {
Text = {
Text = $"{TidyName(setting.Name)}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.55 {bottom}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsDocs {RS(setting.Name)}", Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.55 {bottom}"
}
, Text = {
Text = "", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeNum {RS(profile)} {RS(setting.Name)} false", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.55 {top + 0.003}", AnchorMax = $"0.57 {bottom - 0.003}"
}
, Text = {
Text = "<", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiLabel {
Text = {
Text = $"{setting.GetValue(configData.CorpseTypes[profile])}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
, RectTransform = {
AnchorMin = $"0.575 {top + 0.003}", AnchorMax = $"0.625 {bottom - 0.003}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeNum {RS(profile)} {RS(setting.Name)} true", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.63 {top + 0.003}", AnchorMax = $"0.65 {bottom - 0.003}"
}
, Text = {
Text = ">", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
}
else if (setting.FieldType == typeof(bool)) {
elements.Add(new CuiLabel {
Text = {
Text = $"{TidyName(setting.Name)}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.45 {bottom}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsDocs {RS(setting.Name)}", Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.45 {bottom}"
}
, Text = {
Text = "", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeBool {RS(profile)} {RS(setting.Name)}", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.55 {top + 0.003}", AnchorMax = $"0.65 {bottom - 0.003}"
}
, Text = {
Text = $"{setting.GetValue(configData.CorpseTypes[profile])}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
}
else if (setting.FieldType == typeof(FStein)) {
elements.Add(new CuiLabel {
Text = {
Text = $"{TidyName(setting.Name)}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.55 {bottom}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsDocs {RS(setting.Name)}", Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = $"0.31 {top}", AnchorMax = $"0.55 {bottom}"
}
, Text = {
Text = "", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeEnum {RS(profile)} {RS(setting.Name)} {Enum.GetNames(setting.FieldType).Length} false", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.55 {top + 0.003}", AnchorMax = $"0.57 {bottom - 0.003}"
}
, Text = {
Text = "<", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiLabel {
Text = {
Text = $"{setting.GetValue(configData.CorpseTypes[profile])}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
, RectTransform = {
AnchorMin = $"0.575 {top + 0.003}", AnchorMax = $"0.625 {bottom - 0.003}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeEnum {RS(profile)} {RS(setting.Name)} {Enum.GetNames(setting.FieldType).Length} true", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.63 {top + 0.003}", AnchorMax = $"0.65 {bottom - 0.003}"
}
, Text = {
Text = ">", FontSize = 11, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
}
odd = !odd;
}
elements.Add(new CuiLabel {
Text = {
Text = $"Set Adjustment Increment", FontSize = 13, Font = Font, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = $"0.31 0.175", AnchorMax = $"0.45 0.2"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsSetIncrement {RS(profile)} 1", Color = Increment == 1 ? configData.UI.ButtonColour2 : configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.55 0.175", AnchorMax = $"0.59 0.2"
}
, Text = {
Text = "1", FontSize = 13, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsSetIncrement {RS(profile)} 5", Color = Increment == 5 ? configData.UI.ButtonColour2 : configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.6 0.175", AnchorMax = $"0.64 0.2"
}
, Text = {
Text = "5", FontSize = 13, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsSetIncrement {RS(profile)} 10", Color = Increment == 10 ? configData.UI.ButtonColour2 : configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.65 0.175", AnchorMax = $"0.69 0.2"
}
, Text = {
Text = "10", FontSize = 13, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsCopy {RS(profile)}", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.88 0.14", AnchorMax = $"0.99 0.16"
}
, Text = {
Text = "Copy profile", FontSize = 12, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
if (Copy.ContainsKey(player.userID)) elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsPaste {RS(profile)}", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.88 0.11", AnchorMax = $"0.99 0.13"
}
, Text = {
Text = $"Paste", FontSize = 12, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsReloadProfile {RS(profile)}", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.25 0.065", AnchorMax = $"0.35 0.095"
}
, Text = {
Text = "Reload Profile", FontSize = 16, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsUIEditKits {RS(profile)} 0", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.45 0.065", AnchorMax = $"0.55 0.095"
}
, Text = {
Text = "Edit Kits", FontSize = 16, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsUI", Color = configData.UI.ButtonColour
}
, RectTransform = {
AnchorMin = $"0.65 0.065", AnchorMax = $"0.75 0.095"
}
, Text = {
Text = "Back", FontSize = 16, Font = Font, Align = TextAnchor.MiddleCenter
}
}
, mainName);
}
CuiHelper.AddUi(player, elements);
}
string TidyName(string name) => name.Replace("_", " ").Replace("Percent", " %").Replace("Change", "");
void NPCKitsKitsUI(BasePlayer player, string profile = "", int page = 0) {
DestroyMenu(player, false);
var elements = new CuiElementContainer();
var mainName = elements.Add(new CuiPanel {
Image = {
Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = "0.1 0", AnchorMax = "0.9 0.9"
}
, CursorEnabled = true
}
, "Overlay", "NPCKitsKitsUI");
elements.Add(new CuiElement {
Parent = "NPCKitsKitsUI", Components = {
new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
}
);
elements.Add(new CuiLabel {
Text = {
Text = $"Kits for {profile}", FontSize = 16, Font = Font, Align = TextAnchor.MiddleCenter
}
, RectTransform = {
AnchorMin = $"0 0.9", AnchorMax = $"1 1"
}
}
, mainName);
float top = 0.925f, bottom = 0.95f;
double left = 0;
int num = 0;
int from = page * 105;
int to = ((page + 1) * 105) - 1;
for (int i = from; i <= to; i++) {
if (i >= ValidKits.Count) break;
if (i > from && (i - from) % 35 == 0) {
top = 0.925f;
bottom = 0.95f;
left += 0.33;
}
if (i - from > 104) break;
top -= 0.023f;
bottom -= 0.023f;
num = configData.CorpseTypes[profile].Kits.Where(x => x == ValidKits[i]).Count();
elements.Add(new CuiLabel {
Text = {
Text = $"{ValidKits[i]}", FontSize = 11, Font = Font, Align = TextAnchor.MiddleLeft
}
, RectTransform = {
AnchorMin = $"{left + 0.05} {top}", AnchorMax = $"{left + 0.15} {bottom}"
}
}
, mainName);
elements.Add(new CuiButton {
Button = {
Command = $"NPCKitsChangeKit {RS(profile)} {i} {page} false", Color = num > 0
// ... [Code preview truncated due to length. Full source in attached file] ...