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

FREE BankSystem : 1.3.18 1.3.18

Нет прав для скачивания
C#:
// #define TESTING

#if TESTING
using System.Diagnostics;
#endif

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.BankSystemExtensionMethods;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;

#if CARBON
using Carbon.Base;
using Carbon.Modules;
#endif

namespace Oxide.Plugins
{
	[Info("Bank System", "Mevent", "1.3.18")]
	public class BankSystem : RustPlugin
	{
		#region Fields

		[PluginReference] private Plugin
			ImageLibrary = null,
			Notify = null,
			UINotify = null,
			Economics = null, 
			LangAPI = null;

		private const string Layer = "UI.BankSystem";

		private static BankSystem _instance;

		private const bool LangRu = false;

		private readonly Dictionary<ulong, ATMData> _atmByPlayer = new Dictionary<ulong, ATMData>();

		private readonly List<VendingMachine> _vendingMachines = new List<VendingMachine>();

		private const string VendingMachinePrefab =
			"assets/prefabs/deployable/vendingmachine/vendingmachine.deployed.prefab";

		private enum Transaction
		{
			Deposit,
			Withdrawal,
			Transfer
		}

#if CARBON
        private ImageDatabaseModule imageDatabase;
#endif

		private bool _enabledImageLibrary;

		#endregion

		#region Config

		private static Configuration _config;

		private class Configuration
		{
			[JsonProperty(PropertyName = LangRu ? "Работать с LangAPI?" : "Work with LangAPI?")]
			public bool UseLangAPI = true;

			[JsonProperty(PropertyName = LangRu ? "Работать с Notify?" : "Work with Notify?")]
			public bool UseNotify = true;

            [JsonProperty(PropertyName = LangRu ? "Включить режим офлайн изображений?" : "Enable Offline Image Mode")]
            public bool EnableOfflineImageMode = false;

			[JsonProperty(PropertyName = LangRu ? "Команды" : "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public string[] Commands = {"bank"};

			[JsonProperty(PropertyName = LangRu ? "Разрешение (например: banksystemru.use)" : "Permission (example: banksystem.use)")]
			public string Permission = string.Empty;

			[JsonProperty(PropertyName = LangRu ? "Стартовый баланс" : "Starting balance")]
			public int StartingBalance = 100;

			[JsonProperty(PropertyName = LangRu ? "Изображение карты" : "Card Image")]
			public string CardImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/card.png";

			[JsonProperty(PropertyName = LangRu ? "Изображение пополнения" : "Transit Image")]
			public string DepositImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/deposit.png";

			[JsonProperty(PropertyName = LangRu ? "Изображение снятия" : "Withdraw Image")]
			public string WithdrawImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/withdraw.png";

			[JsonProperty(PropertyName = LangRu ? "Изображение перевода" : "Transfer Image")]
			public string TransferImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/transfer.png";

			[JsonProperty(PropertyName = LangRu ? "Изображение выхода" : "Exit Image")]
			public string ExitImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/exit.png";

			[JsonProperty(PropertyName = LangRu ? "Отключить кнопку закрытия в заголовке ATM" : "Disable the close button in the ATM header")]
			public bool AtmDisableCloser = false;

			[JsonProperty(PropertyName = LangRu ? "Настройки валюты" : "Currency Settings")]
			public CurrencySettings Currency = new CurrencySettings
			{
				ControlSplit = true,
				DisplayName = "RUSTNote",
				ShortName = "sticks",
				Skin = 2536195910
			};

			[JsonProperty(PropertyName = LangRu ? "Показывать всех игроков в Transfer (false - только онлайн)" : "Show all players in Transfer (false - online only)")]
			public bool TransferShowAllPlayers = false;

			[JsonProperty(PropertyName = LangRu ? "Автоматическое создание карты" : "Card auto-creation")]
			public bool CardAutoCreation = false;

			[JsonProperty(PropertyName = LangRu ? "Использовать срок действия карты?" : "Use card expiration date?")]
			public bool UseCardExpiry = true;

			[JsonProperty(PropertyName = LangRu ? "Срок действия карты (в днях)" : "Card expiry date (in days)")]
			public int CardExpiryDays = 7;

			[JsonProperty(PropertyName = LangRu ? "Настройки ATM" : "ATM Settings")]
			public ATMSettings Atm = new ATMSettings
			{
				MinWithdrawal = 1,
				MinDeposit = 1,
				EnableDepositFee = true,
				MinDepositFee = 0,
				MaxDepositFee = 10,
				StepDepositFee = 0.1f,
				MinWithdrawalFee = 0,
				MaxWithdrawalFee = 10,
				EnableBreakage = true,
				StepWithdrawalFee = 0.1f,
				DisplayName = "ATM",
				Skin = 2551771822,
				Repair = new RepairSettings
				{
					Items = new List<RepairItemConf>
					{
						new RepairItemConf
						{
							ShortName = "scrap",
							Amount = 2,
							Skin = 0,
							Title = string.Empty
						},
						new RepairItemConf
						{
							ShortName = "metalpipe",
							Amount = 1,
							Skin = 0,
							Title = string.Empty
						},
						new RepairItemConf
						{
							ShortName = "metal.fragments",
							Amount = 15,
							Skin = 0,
							Title = string.Empty
						}
					}
				},
				DefaultDepositFee = 1,
				EnableWithdrawalFee = true,
				DefaultWithdrawalFee = 1,
				DefaultBreakPercent = 1,
				BreakPercent = new Dictionary<string, float>
				{
					["banksystem.vip"] = 0.7f,
					["banksystem.premium"] = 0.5f
				},
				Spawn = new SpawnSettings
				{
					ConfAddons = new ATMConf
					{
						DisplayName = "ATM",
						DepositFee = 0,
						WithdrawFee = 0
					},
					Monuments = new Dictionary<string, ATMPosition>
					{
						["compound"] = new ATMPosition
						{
							Enabled = true,
							DisplayName = "ATM",
							Position = new Vector3(-3.5f,
								1.15f,
								2.7f),
							Rotation = -90,
							DepositFee = 0,
							WithdrawFee = 0
						},
						["bandit"] = new ATMPosition
						{
							Enabled = true,
							DisplayName = "ATM",
							Position = new Vector3(34.2f,
								2.35f,
								-24.7f),
							Rotation = 135,
							DepositFee = 0,
							WithdrawFee = 0
						}
					}
				},
				ShopName = "ATM #{id}",
				Commands = new[]
				{
					"secret.open.atm"
				},
				PermissionToOpenATMviaCommand = "banksystem.openatm",
				NotifyPlayerWhenNoPermissionInCommandATM = false
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки отслеживания" : "Tracking Settings")]
			public TrackingSettings Tracking = new TrackingSettings
			{
				InHand = false,
				CostTable = new Dictionary<string, float>
				{
					["sulfur.ore"] = 5f,
					["metal.ore"] = 5f,
					["hq.metal.ore"] = 5f,
					["stone.ore"] = 5f,
					["crate_elite"] = 10f,
					["crate_normal"] = 7f,
					["crate_normal_2"] = 4
				},
				CollectibleCostTable = new Dictionary<string, float>
				{
					["sulfur.ore"] = 0.5f,
					["metal.ore"] = 0.5f,
					["hq.metal.ore"] = 0.5f,
					["stones"] = 0.5f
				}
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки очистки" : "Wipe Settings")]
			public WipeSettings Wipe = new WipeSettings
			{
				Players = false,
				Logs = true,
				ATMs = true
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки NPC" : "NPC Settings")]
			public NPCSettings NPC = new NPCSettings
			{
				NPCs = new List<string>
				{
					"1234567",
					"7654321",
					"4644687478"
				}
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки экономики" : "Economy Settings")]
			public EconomySettings Economy = new EconomySettings
			{
				Self = true,
				AddHook = "Deposit",
				BalanceHook = "Balance",
				RemoveHook = "Withdraw",
				PluginName = "Economics"
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки дропа" : "Drop Settings", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<DropInfo> Drop = new List<DropInfo>
			{
				new DropInfo
				{
					Enabled = true,
					PrefabName = "assets/bundled/prefabs/radtown/crate_normal.prefab",
					DropChance = 50,
					MinAmount = 2,
					MaxAmount = 5
				},
				new DropInfo
				{
					Enabled = true,
					PrefabName = "assets/bundled/prefabs/radtown/loot_barrel_2.prefab",
					DropChance = 5,
					MinAmount = 2,
					MaxAmount = 5
				},
				new DropInfo
				{
					Enabled = true,
					PrefabName = "assets/bundled/prefabs/radtown/loot_barrel_1.prefab",
					DropChance = 5,
					MinAmount = 2,
					MaxAmount = 5
				}
			};

			[JsonProperty(PropertyName = LangRu ? "Цвета" : "Colors")]
			public Colors Colors = new Colors
			{
				Color1 = new IColor("#0E0E10"),
				Color2 = new IColor("#161617"),
				Color3 = new IColor("#4B68FF"),
				Color4 = new IColor("#74884A"),
				Color5 = new IColor("#FF6060"),
				Color6 = new IColor("#C4C4C4"),
				Color7 = new IColor("#CD4632"),
				Color8 = new IColor("#595651"),
				Color9 = new IColor("#4B68FF", 50),
				Color10 = new IColor("#4B68FF", 33),
				Color11 = new IColor("#FFFFFF", 20),
				Color12 = new IColor("#C4C4C4", 20),
				Color13 = new IColor("#FFFFFF"),
				Color14 = new IColor("#FFFFFF", 50),
				Color15 = new IColor("#FFFFFF", 40),
				Color16 = new IColor("#FFFFFF", 70),
				Color17 = new IColor("#FFFFFF", 10),
				Color18 = new IColor("#FFFFFF", 95),
				Color19 = new IColor("#FFFFFF", 30),
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки UI" : "UI Settings")]
			public UserInterface UI = new UserInterface
			{
				BankWidth = 900f,
				BankHeight = 595f,
				BankHeaderHeight = 70f,
				BankHeaderWidth = 850f,
				BankHeaderUpIndent = 65f,
				ShowTransactionsHistory = true,
				THFieldWidth = 190f,
				THButtonMargin = 5f,
				THButtonSize = 20f,
				ShowGatherHistory = true,
				GHFieldWidth = 190f,
				GHButtonMargin = 5f,
				GHButtonSize = 20f,
				ShowCard = true,
				CardWidth = 245f,
				CardLeftIndent = 25f,
				ShowTransfers = true,
				Transfers = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "25 -345",
					OffsetMax = "175 -325",
					Align = TextAnchor.MiddleLeft,
					Font = "robotocondensed-bold.ttf",
					FontSize = 16,
					Color = new IColor("#FFFFFF")
				},
				RecentTransfersTitle = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "25 -360",
					OffsetMax = "175 -345",
					Align = TextAnchor.MiddleLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = new IColor("#FFFFFF", 50)
				},
				NoTransactions = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "25 -490",
					OffsetMax = "405 -360",
					Align = TextAnchor.MiddleCenter,
					Font = "robotocondensed-bold.ttf",
					FontSize = 14,
					Color = new IColor("#FFFFFF", 10)
				},
				TransferCard = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "25 -515",
					OffsetMax = "175 -500",
					Align = TextAnchor.MiddleLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = new IColor("#FFFFFF", 50)
				},
				TransferCardNumber = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "25 -550",
					OffsetMax = "175 -520",
					Align = TextAnchor.MiddleLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = new IColor("#FFFFFF")
				},
				TransferCardAmount = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "185 -550",
					OffsetMax = "335 -520",
					FontSize = 10,
					Font = "robotocondensed-regular.ttf",
					Align = TextAnchor.MiddleLeft,
					Color = new IColor("#FFFFFF")
				},
				TransferCardButton = new LabelSettings
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "340 -550",
					OffsetMax = "400 -520",
					Align = TextAnchor.MiddleCenter,
					Font = "robotocondensed-bold.ttf",
					FontSize = 11,
					Color = new IColor("#FFFFFF")
				}
			};

			[JsonProperty(PropertyName = LangRu ? "Настройки логирования" : "Log Settings")]
			public LogInfo Logs = new LogInfo
			{
				CollectGatherLogs = true,
				CollectTransfersLogs = true
			};

			public VersionNumber Version;
		}

		private class LogInfo
		{
			[JsonProperty(PropertyName = LangRu ? "Собирать логи сбора?" : "Collect Gather logs?")]
			public bool CollectGatherLogs;

			[JsonProperty(PropertyName = LangRu ? "Собирать логи переводов?" : "Collect Transfers logs?")]
			public bool CollectTransfersLogs;
		}

		private class UserInterface
		{
			[JsonProperty(PropertyName = LangRu ? "Банк | Ширина" : "Bank | Width")]
			public float BankWidth;

			[JsonProperty(PropertyName = LangRu ? "Банк | Высота" : "Bank | Height")]
			public float BankHeight;

			[JsonProperty(PropertyName = LangRu ? "Банк | Ширина заголовка" : "Bank Header | Width")]
			public float BankHeaderWidth;

			[JsonProperty(PropertyName = LangRu ? "Банк | Высота заголовка" : "Bank Header | Height")]
			public float BankHeaderHeight;

			[JsonProperty(PropertyName = LangRu ? "Банк | Отступ сверху заголовка" : "Bank Header | Up Indent")]
			public float BankHeaderUpIndent;

			[JsonProperty(PropertyName = LangRu ? "Показывать историю транзакций?" : "Show Transactions history?")]
			public bool ShowTransactionsHistory;

			[JsonProperty(PropertyName = LangRu ? "История транзакций | Ширина поля" : "Transactions history | Field width")]
			public float THFieldWidth;

			[JsonProperty(PropertyName = LangRu ? "История транзакций | Отступ кнопки страницы" : "Transactions history | Page button margin")]
			public float THButtonMargin;

			[JsonProperty(PropertyName = LangRu ? "История транзакций | Размер кнопки страницы" : "Transactions history | Page button size")]
			public float THButtonSize;

			[JsonProperty(PropertyName = LangRu ? "Показывать историю сбора?" : "Show Gather history?")]
			public bool ShowGatherHistory;

			[JsonProperty(PropertyName = LangRu ? "История сбора | Ширина поля" : "Gather history | Field width")]
			public float GHFieldWidth;

			[JsonProperty(PropertyName = LangRu ? "История сбора | Отступ кнопки страницы" : "Gather history | Page button margin")]
			public float GHButtonMargin;

			[JsonProperty(PropertyName = LangRu ? "История сбора | Размер кнопки страницы" : "Gather history | Page button size")]
			public float GHButtonSize;

			[JsonProperty(PropertyName = LangRu ? "Показывать карту?" : "Show card?")]
			public bool ShowCard;

			[JsonProperty(PropertyName = LangRu ? "Карта | Ширина" : "Card | Width")]
			public float CardWidth;

			[JsonProperty(PropertyName = LangRu ? "Карта | Отступ слева" : "Card | Left indent")]
			public float CardLeftIndent;

			[JsonProperty(PropertyName = LangRu ? "Показывать переводы?" : "Show Transfers?")]
			public bool ShowTransfers;

			[JsonProperty(PropertyName = LangRu ? "Заголовок: Переводы" : "Title: Transfers")]
			public LabelSettings Transfers;

			[JsonProperty(PropertyName = LangRu ? "Заголовок: Последние переводы" : "Title: Recent Transfers")]
			public LabelSettings RecentTransfersTitle;

			[JsonProperty(PropertyName = LangRu ? "Заголовок: У игрока нет транзакций" : "Title: Player has no transactions Title")]
			public LabelSettings NoTransactions;

			[JsonProperty(PropertyName = LangRu ? "Заголовок: Перевод по карте" : "Title: Transfer by card")]
			public LabelSettings TransferCard;

			[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Номер карты" : "Transfer by card | Card number")]
			public LabelSettings TransferCardNumber;

			[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Сумма" : "Transfer by card | Amount")]
			public LabelSettings TransferCardAmount;

			[JsonProperty(PropertyName = LangRu ? "Перевод по карте | Кнопка перевода" : "Transfer by card | Transfer button")]
			public LabelSettings TransferCardButton;
		}

		private class LabelSettings : InterfacePosition
		{
			[JsonProperty(PropertyName = LangRu ? "Размер шрифта" : "FontSize")]
			public int FontSize;

			[JsonProperty(PropertyName = LangRu ? "Выравнивание" : "Align")] [JsonConverter(typeof(StringEnumConverter))]
			public TextAnchor Align;

			[JsonProperty(PropertyName = LangRu ? "Цвет" : "Color")] public IColor Color;

			[JsonProperty(PropertyName = LangRu ? "Шрифт" : "Font")] public string Font;
		}

		private class InterfacePosition
		{
			public string AnchorMin;

			public string AnchorMax;

			public string OffsetMin;

			public string OffsetMax;
		}

		private class IColor
		{
			[JsonProperty(PropertyName = LangRu ? "HEX" : "HEX")] public string Hex;

			[JsonProperty(PropertyName = LangRu ? "Непрозрачность (0 - 100)" : "Opacity (0 - 100)")]
			public float Alpha;

			[JsonIgnore] private string _color;

			[JsonIgnore]
			public string Get
			{
				get
				{
					if (string.IsNullOrEmpty(_color))
						_color = GetColor();

					return _color;
				}
			}

			private string GetColor()
			{
				if (string.IsNullOrEmpty(Hex)) Hex = "#FFFFFF";

				var str = Hex.Trim('#');
				if (str.Length != 6) throw new Exception(Hex);
				var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
				var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
				var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);

				return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
			}

			public IColor()
			{
			}

			public IColor(string hex, float alpha = 100)
			{
				Hex = hex;
				Alpha = alpha;
			}
		}

		private class Colors
		{
			[JsonProperty(PropertyName = LangRu ? "Первый цвет" : "First color")]
			public IColor Color1;

			[JsonProperty(PropertyName = LangRu ? "Второй цвет" : "Second color")]
			public IColor Color2;

			[JsonProperty(PropertyName = LangRu ? "Третий цвет" : "Third color")]
			public IColor Color3;

			[JsonProperty(PropertyName = LangRu ? "Четвертый цвет" : "Fourth color")]
			public IColor Color4;

			[JsonProperty(PropertyName = LangRu ? "Пятый цвет" : "Fifth color")]
			public IColor Color5;

			[JsonProperty(PropertyName = LangRu ? "Шестой цвет" : "Sixth color")]
			public IColor Color6;

			[JsonProperty(PropertyName = LangRu ? "Седьмой цвет" : "Seventh color")]
			public IColor Color7;

			[JsonProperty(PropertyName = LangRu ? "Восьмой цвет" : "Eighth color")]
			public IColor Color8;

			[JsonProperty(PropertyName = LangRu ? "Девятый цвет" : "Ninth color")]
			public IColor Color9;

			[JsonProperty(PropertyName = LangRu ? "Десятый цвет" : "Tenth color")]
			public IColor Color10;

			[JsonProperty(PropertyName = LangRu ? "Одиннадцатый цвет" : "Eleventh color")]
			public IColor Color11;

			[JsonProperty(PropertyName = LangRu ? "Двенадцатый цвет" : "Twelfth color")]
			public IColor Color12;

			[JsonProperty(PropertyName = LangRu ? "Тринадцатый цвет" : "Thirteenth color")]
			public IColor Color13;

			[JsonProperty(PropertyName = LangRu ? "Четырнадцатый цвет" : "Fourteenth color")]
			public IColor Color14;

			[JsonProperty(PropertyName = LangRu ? "Пятнадцатый цвет" : "Fifteenth color")]
			public IColor Color15;

			[JsonProperty(PropertyName = LangRu ? "Шестнадцатый цвет" : "Sixteenth color")]
			public IColor Color16;

			[JsonProperty(PropertyName = LangRu ? "Семнадцатый цвет" : "Seventeenth color")]
			public IColor Color17;

			[JsonProperty(PropertyName = LangRu ? "Восемнадцатый цвет" : "Eighteenth color")]
			public IColor Color18;

			[JsonProperty(PropertyName = LangRu ? "Девятнадцатый цвет" : "Nineteenth color")]
			public IColor Color19;
		}

		public class DropInfo
		{
			[JsonProperty(PropertyName = LangRu ? "Включено" : "Enabled")]
			public bool Enabled;

			[JsonProperty(PropertyName = LangRu ? "Префаб" : "Prefab")]
			public string PrefabName;

			[JsonProperty(PropertyName = LangRu ? "Шанс" : "Chance")]
			public int DropChance;

			[JsonProperty(PropertyName = LangRu ? "Минимальное количество" : "Min Amount")]
			public int MinAmount;

			[JsonProperty(PropertyName = LangRu ? "Максимальное количество" : "Max Amount")]
			public int MaxAmount;
		}

		private class EconomySettings
		{
			[JsonProperty(PropertyName = LangRu ? "Использовать собственную экономическую систему?" : "Use own economic system?")]
			public bool Self;

			[JsonProperty(PropertyName = LangRu ? "Название плагина" : "Plugin name")]
			public string PluginName;

			[JsonProperty(PropertyName = LangRu ? "Хук добавления баланса" : "Balance add hook")]
			public string AddHook;

			[JsonProperty(PropertyName = LangRu ? "Хук удаления баланса" : "Balance remove hook")]
			public string RemoveHook;

			[JsonProperty(PropertyName = LangRu ? "Хук показа баланса" : "Balance show hook")]
			public string BalanceHook;

			public double ShowBalance(BasePlayer player)
			{
				return ShowBalance(player.UserIDString);
			}

			public double ShowBalance(ulong player)
			{
				return ShowBalance(player.ToString());
			}

			private double ShowBalance(string player)
			{
				if (Self) return _instance.Balance(player);

				var plugin = _instance?.plugins?.Find(PluginName);
				if (plugin == null) return 0;

				return Convert.ToDouble(Math.Floor(Convert.ToDouble(plugin.Call(BalanceHook, player)))
					.ToString("0.00"));
			}

			public void AddBalance(BasePlayer player, int amount)
			{
				AddBalance(player.UserIDString, amount);
			}

			private void AddBalance(ulong player, int amount)
			{
				AddBalance(player.ToString(), amount);
			}

			private void AddBalance(string player, int amount)
			{
				if (Self)
				{
					_instance.Deposit(player, amount);
					return;
				}

				var plugin = _instance?.plugins.Find(PluginName);
				if (plugin == null) return;

				switch (PluginName)
				{
					case "Economics":
						plugin.Call(AddHook, player, (double) amount);
						break;
					default:
						plugin.Call(AddHook, player, amount);
						break;
				}
			}

			public bool RemoveBalance(BasePlayer player, int amount)
			{
				return RemoveBalance(player.UserIDString, amount);
			}

			private bool RemoveBalance(ulong player, int amount)
			{
				return RemoveBalance(player.ToString(), amount);
			}

			private bool RemoveBalance(string player, int amount)
			{
				if (ShowBalance(player) < amount) return false;

				if (Self) return _instance.Withdraw(player, amount);

				var plugin = _instance?.plugins.Find(PluginName);
				if (plugin == null) return false;

				switch (PluginName)
				{
					case "Economics":
						plugin.Call(RemoveHook, player, (double) amount);
						break;
					default:
						plugin.Call(RemoveHook, player, amount);
						break;
				}

				return true;
			}

			public bool Transfer(ulong member, ulong target, int amount)
			{
				if (!RemoveBalance(member, amount)) return false;

				AddBalance(target, amount);
				return true;
			}
		}

		private class NPCSettings
		{
			[JsonProperty(PropertyName = LangRu ? "NPCs" : "NPCs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<string> NPCs = new List<string>();
		}

		private class WipeSettings
		{
			[JsonProperty(PropertyName = LangRu ? "Очистить игроков?" : "Wipe Players?")]
			public bool Players;

			[JsonProperty(PropertyName = LangRu ? "Очистить логи?" : "Wipe Logs?")]
			public bool Logs;

			[JsonProperty(PropertyName = LangRu ? "Очистить ATM?" : "Wipe ATMs?")]
			public bool ATMs;
		}

		private class SpawnSettings
		{
			[JsonProperty(PropertyName = LangRu ? "Monuments" : "Monuments", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, ATMPosition> Monuments;

			[JsonProperty(PropertyName = LangRu ? "Настройки для ATM из MonumentAddons" : "Settings for ATMs from MonumentAddons")]
			public ATMConf ConfAddons;
		}

		private class ATMConf
		{
			[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
			public string DisplayName;

			[JsonProperty(PropertyName = LangRu ? "Комиссия за пополнение" : "Deposit Fee")]
			public float DepositFee;

			[JsonProperty(PropertyName = LangRu ? "Комиссия за снятие" : "Withdraw Fee")]
			public float WithdrawFee;
		}

		private class ATMPosition : ATMConf
		{
			[JsonProperty(PropertyName = LangRu ? "Включено" : "Enabled")]
			public bool Enabled;

			[JsonProperty(PropertyName = LangRu ? "Позиция" : "Position")]
			public Vector3 Position;

			[JsonProperty(PropertyName = LangRu ? "Поворот" : "Rotation")]
			public float Rotation;
		}

		private class TrackingSettings
		{
			[JsonProperty(PropertyName = LangRu ? "Выдавать награду?" : "Handing out an award?")]
			public bool InHand;

			[JsonProperty(PropertyName = LangRu ? "Таблица стоимости (shortname - cost)" : "Cost Table (shortname - cost)",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, float> CostTable;

			[JsonProperty(PropertyName = LangRu ? "Таблица стоимости предметов (shortname - cost)" : "Collectible Items Cost Table (shortname - cost)",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, float> CollectibleCostTable;
		}

		private class CurrencySettings
		{
			[JsonProperty(PropertyName = LangRu ? "Включить контроль разделения предметов? (если есть ошибки с плагинами стека - стоит выключить)" : "Enable item split control? (if there are errors with stack plugins - it is worth turning off)")]
			public bool ControlSplit;

			[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
			public string DisplayName;

			[JsonProperty(PropertyName = LangRu ? "Короткое название" : "Short Name")]
			public string ShortName;

			[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;

			public Item ToItem(int amount = 1)
			{
				var item = ItemManager.CreateByName(ShortName, amount, Skin);
				if (item == null)
				{
					Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
					return null;
				}

				if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
				return item;
			}
		}

		private class ATMSettings
		{
			#region Fields

			[JsonProperty(PropertyName = LangRu ? "Минимальный депозит (сумма)" : "Minimum deposit (amount)")]
			public float MinDeposit;

			[JsonProperty(PropertyName = LangRu ? "Минимальный вывод (сумма)" : "Minimum withdrawal (amount)")]
			public float MinWithdrawal;

			[JsonProperty(PropertyName = LangRu ? "Включить комиссию за пополнение?" : "Enable Deposit fee?")]
			public bool EnableDepositFee;

			[JsonProperty(PropertyName = LangRu ? "Минимальная комиссия за пополнение" : "Minimum deposit fee")]
			public float MinDepositFee;

			[JsonProperty(PropertyName = LangRu ? "Максимальная комиссия за пополнение" : "Maximum deposit fee")]
			public float MaxDepositFee;

			[JsonProperty(PropertyName = LangRu ? "По умолчанию комиссия за пополнение" : "Default deposit fee")]
			public float DefaultDepositFee;

			[JsonProperty(PropertyName = LangRu ? "Шаг комиссии за пополнение" : "Step deposit fee")]
			public float StepDepositFee;

			[JsonProperty(PropertyName = LangRu ? "Включить комиссию за вывод?" : "Enable Withdrawal fee?")]
			public bool EnableWithdrawalFee;

			[JsonProperty(PropertyName = LangRu ? "Минимальная комиссия за вывод" : "Minimum withdrawal fee")]
			public float MinWithdrawalFee;

			[JsonProperty(PropertyName = LangRu ? "Максимальная комиссия за вывод" : "Maximum withdrawal fee")]
			public float MaxWithdrawalFee;

			[JsonProperty(PropertyName = LangRu ? "По умолчанию комиссия за вывод" : "Default withdrawal fee")]
			public float DefaultWithdrawalFee;

			[JsonProperty(PropertyName = LangRu ? "Шаг комиссии за вывод" : "Step withdrawal fee")]
			public float StepWithdrawalFee;

			[JsonProperty(PropertyName = LangRu ? "Включить поломку?" : "Enable breakage?")]
			public bool EnableBreakage = true;

			[JsonProperty(PropertyName = LangRu ? "По умолчанию процент поломки во время операции" : "Default breakage percentage during operation")]
			public float DefaultBreakPercent;

			[JsonProperty(PropertyName = LangRu ? "Процент поломки во время операции" : "Breakage percentage during operation",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, float> BreakPercent = new Dictionary<string, float>();

			[JsonProperty(PropertyName = LangRu ? "Настройки ремонта" : "Repair Settings")]
			public RepairSettings Repair;

			[JsonProperty(PropertyName = LangRu ? "Название" : "Display Name")]
			public string DisplayName;

			[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;

			[JsonProperty(PropertyName = LangRu ? "Настройки спавна" : "Spawn Settings")]
			public SpawnSettings Spawn;

			[JsonProperty(PropertyName = LangRu ? "Название магазина ({id} {owner})" : "Shop Name ({id} {owner})")]
			public string ShopName;

			[JsonProperty(PropertyName = LangRu ? "Команды для открытия меню ATM" : "Commands to open ATM menu",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public string[] Commands = { };

			[JsonProperty(PropertyName = LangRu ? "Разрешение для открытия меню ATM через команду" : "Permission to open ATM menu via command")]
			public string PermissionToOpenATMviaCommand = string.Empty;

			[JsonProperty(PropertyName = LangRu ? "Уведомлять игрока, когда они не имеют разрешения при открытии меню ATM через команду?" :
				"Notify a player when they don't have permissions when opening the ATM menu via command?")]
			public bool NotifyPlayerWhenNoPermissionInCommandATM;

			#endregion

			public Item ToItem()
			{
				var item = ItemManager.CreateByName("vending.machine", 1, Skin);
				if (item == null)
					return null;

				if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;

				return item;
			}
		}

		private class RepairSettings
		{
			[JsonProperty(PropertyName = LangRu ? "Предметы (для 1%)" : "Items (for 1%)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<RepairItemConf> Items = new List<RepairItemConf>();
		}

		private class RepairItemConf
		{
			[JsonProperty(PropertyName = LangRu ? "Короткое название" : "Short Name")]
			public string ShortName;

			[JsonProperty(PropertyName = LangRu ? "Количество (для 1%)" : "Amount (for 1%)")]
			public float Amount;

			[JsonProperty(PropertyName = LangRu ? "Скин" : "Skin")] public ulong Skin;

			[JsonProperty(PropertyName = LangRu ? "Название (пустое - по умолчанию)" : "Title (empty - default)")]
			public string Title;

			[JsonIgnore] private string _publicTitle;

			[JsonIgnore]
			public string PublicTitle
			{
				get
				{
					if (string.IsNullOrEmpty(_publicTitle))
					{
						if (string.IsNullOrEmpty(Title))
							_publicTitle = ItemManager.FindItemDefinition(ShortName)?.displayName.translated ??
							               "UNKNOWN";
						else
							_publicTitle = Title;
					}

					return _publicTitle;
				}
			}
		}

		protected override void LoadConfig()
		{
			base.LoadConfig();
			try
			{
				_config = Config.ReadObject<Configuration>();
				if (_config == null) throw new Exception();

				if (_config.Version < Version)
					UpdateConfigValues();

				SaveConfig();
			}
			catch (Exception ex)
			{
				PrintError("Your configuration file contains an error. Using default configuration values.");
				Debug.LogError(ex.Message);
				LoadDefaultConfig();
			}
		}

		protected override void SaveConfig()
		{
			Config.WriteObject(_config);
		}

		protected override void LoadDefaultConfig()
		{
			_config = new Configuration();
		}

		private void UpdateConfigValues()
		{
			PrintWarning("Config update detected! Updating config values...");

			//var baseConfig = new Configuration();

			if (_config.Version != default(VersionNumber))
			{
				if (_config.Version < new VersionNumber(1, 3, 0))
				{
					ConvertPlayerData();

					ConvertPlayerLogs();
				}

				if (_config.Version < new VersionNumber(1, 3, 6))
				{
					var color1 = Config["Colors", "Color 1"].ToString();
					var color2 = Config["Colors", "Color 2"].ToString();
					var color3 = Config["Colors", "Color 3"].ToString();
					var color4 = Config["Colors", "Color 4"].ToString();
					var color5 = Config["Colors", "Color 5"].ToString();
					var color6 = Config["Colors", "Color 6"].ToString();
					var color7 = Config["Colors", "Color 7"].ToString();
					var color8 = Config["Colors", "Color 8"].ToString();

					_config.Colors.Color1 = new IColor(color1);
					_config.Colors.Color2 = new IColor(color2);
					_config.Colors.Color3 = new IColor(color3);
					_config.Colors.Color4 = new IColor(color4);
					_config.Colors.Color5 = new IColor(color5);
					_config.Colors.Color6 = new IColor(color6);
					_config.Colors.Color7 = new IColor(color7);
					_config.Colors.Color8 = new IColor(color8);
					_config.Colors.Color9 = new IColor(color3, 50);
					_config.Colors.Color10 = new IColor(color3, 33);
					_config.Colors.Color12 = new IColor(color6, 20);

					if (_config.CardImage.Equals("https://i.imgur.com/Br9z7Ou.png"))
						_config.CardImage = "https://i.ibb.co/ZMXtF1d/image.png";

					if (_config.DepositImage.Equals("https://i.imgur.com/h2bqMu4.png"))
						_config.DepositImage = "https://i.ibb.co/R2NT67x/image.png";

					if (_config.WithdrawImage.Equals("https://i.imgur.com/lwVwxm3.png"))
						_config.WithdrawImage = "https://i.ibb.co/qp6VLDm/image.png";

					if (_config.TransferImage.Equals("https://i.imgur.com/TBIxUnz.png"))
						_config.TransferImage = "https://i.ibb.co/T2ZNvFf/image.png";

					if (_config.ExitImage.Equals("https://i.imgur.com/OGoMu9N.png"))
						_config.ExitImage = "https://i.ibb.co/BgssZ0p/image.png";
				}
			
				if (_config.Version < new VersionNumber(1, 3, 16))
				{
					_config.EnableOfflineImageMode = false;

					if (_config.CardImage.Contains("https://i.ibb.co/ZMXtF1d/image.png")) _config.CardImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/card.png";
					if (_config.DepositImage.Contains("https://i.ibb.co/R2NT67x/image.png")) _config.DepositImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/deposit.png";
					if (_config.WithdrawImage.Contains("https://i.ibb.co/qp6VLDm/image.png")) _config.WithdrawImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/withdraw.png";
					if (_config.TransferImage.Contains("https://i.ibb.co/T2ZNvFf/image.png")) _config.TransferImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/transfer.png";
					if (_config.ExitImage.Contains("https://i.ibb.co/BgssZ0p/image.png")) _config.ExitImage = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/BankSystem/exit.png";
				}
			}

			_config.Version = Version;
			PrintWarning("Config update completed!");

			SaveConfig();
		}

		#endregion

		#region Data

		private ATMsData _atms;

		#region Save

		private void SaveATMs()
		{
			Interface.Oxide.DataFileSystem.WriteObject($"{Name}/ATMs", _atms);
		}

		#endregion

		#region Load

		private void LoadData()
		{
			LoadATMs();
		}

		private void LoadATMs()
		{
			try
			{
				_atms = Interface.Oxide.DataFileSystem.ReadObject<ATMsData>($"{Name}/ATMs");
			}
			catch (Exception e)
			{
				PrintError(e.ToString());
			}

			if (_atms == null) _atms = new ATMsData();
		}

		#endregion

		#region Wipe

		private void WipeData()
		{
			WipeATMs();
		}

		private void WipeATMs()
		{
			if (_atms == null)
				LoadATMs();

			_atms.ATMs?.Clear();
			_atms.LastATMID = 0;
			PrintWarning("ATMs wiped!");
		}

		#endregion

		#region Logs

		private class TransferData
		{
			[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
			public Transaction Type;

			[JsonProperty(PropertyName = "Amount")]
			public int Amount;

			[JsonProperty(PropertyName = "Sender ID")]
			public ulong SenderId;

			[JsonProperty(PropertyName = "Target ID")]
			public ulong TargetId;

			public void Get(BasePlayer player, ref CuiElementContainer container, string parent)
			{
				var color = string.Empty;
				var icon = string.Empty;
				var symbol = string.Empty;
				var title = string.Empty;
				var description = string.Empty;

				#region Icon

				switch (Type)
				{
					case Transaction.Deposit:
					{
						color = _config.Colors.Color3.Get;
						icon = _instance.Msg(player, DepositIconTitle);
						symbol = _instance.Msg(player, DepositSymbolTitle);
						title = _instance.Msg(player, DepositOperationTitle);
						description = _instance.Msg(player, DepositOperationDescription);
						break;
					}
					case Transaction.Withdrawal:
					{
						color = _config.Colors.Color5.Get;
						icon = _instance.Msg(player, WithdrawalIconTitle);
						symbol = _instance.Msg(player, WithdrawalSymbolTitle);
						title = _instance.Msg(player, WithdrawalOperationTitle);
						description = _instance.Msg(player, WithdrawalOperationDescription);
						break;
					}
					case Transaction.Transfer:
					{
						var self = TargetId == 0 && SenderId != 0;
						if (self)
						{
							color = _config.Colors.Color3.Get;
							icon = _instance.Msg(player, SelfTransferlIconTitle);
							symbol = _instance.Msg(player, SelfTransferSymbolTitle);
							description = _instance.Msg(player, SelfTransferOperationDescription,
								PlayerData.GetNotLoad(SenderId.ToString())?.DisplayName);
						}
						else
						{
							color = _config.Colors.Color5.Get;
							icon = _instance.Msg(player, TransferlIconTitle);
							symbol = _instance.Msg(player, TransferSymbolTitle);
							description = _instance.Msg(player, TransferOperationDescription,
								PlayerData.GetNotLoad(TargetId.ToString())?.DisplayName);
						}

						title = _instance.Msg(player, TransferOperationTitle);
						break;
					}
				}

				container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "0 0",
						OffsetMin = "5 5", OffsetMax = "30 30"
					},
					Image =
					{
						Color = color
					}
				}, parent, parent + ".Icon");

				container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 1"
					},
					Text =
					{
						Text = $"{icon}",
						Align = TextAnchor.MiddleCenter,
						Font = "robotocondensed-bold.ttf",
						FontSize = 20,
						Color = _config.Colors.Color13.Get
					}
				}, parent + ".Icon");

				#endregion

				#region Title

				container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0.5", AnchorMax = "1 1",
						OffsetMin = "35 0", OffsetMax = "-37.5 0"
					},
					Text =
					{
						Text = $"{title}",
						Align = TextAnchor.LowerLeft,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = _config.Colors.Color13.Get
					}
				}, parent);

				container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 0.5",
						OffsetMin = "35 0", OffsetMax = "-37.5 0"
					},
					Text =
					{
						Text = $"{description}",
						Align = TextAnchor.UpperLeft,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = _config.Colors.Color14.Get
					}
				}, parent);

				#endregion

				#region Value

				container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 1",
						OffsetMin = "0 0",
						OffsetMax = "-10 0"
					},
					Text =
					{
						Text = _instance.Msg(player, OperationsValueFormat, symbol, Amount),
						Align = TextAnchor.MiddleRight,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = color
					}
				}, parent);

				#endregion
			}
		}

		private enum GatherLogType
		{
			Gather,
			Loot,
			Collect,
			Kill
		}

		private class GatherLogData
		{
			[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
			public GatherLogType Type;

			[JsonProperty(PropertyName = "Short Name")]
			public string ShortName;

			[JsonProperty(PropertyName = "Amount")]
			public int Amount;
		}

		#endregion

		#region ATMs

		private class ATMsData
		{
			[JsonProperty(PropertyName = "Last ATM ID")]
			public int LastATMID;

			[JsonProperty(PropertyName = "ATMs", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<ATMData> ATMs = new List<ATMData>();
		}

		private class ATMData
		{
			[JsonProperty(PropertyName = "Enity ID")]
			public ulong EntityID;

			[JsonProperty(PropertyName = "ATM ID")]
			public int ID;

			[JsonProperty(PropertyName = "Owner Id")]
			public ulong OwnerId;

			[JsonProperty(PropertyName = "Withdrawal Fee")]
			public float WithdrawalFee;

			[JsonProperty(PropertyName = "Deposit Fee")]
			public float DepositFee;

			[JsonProperty(PropertyName = "Condition")]
			public float Condition;

			[JsonProperty(PropertyName = "Balance")]
			public float Balance;

			[JsonProperty(PropertyName = "Is Admin")]
			public bool IsAdmin;

			public bool IsOwner(BasePlayer player)
			{
				return IsOwner(player.userID);
			}

			public bool IsOwner(ulong userId)
			{
				return OwnerId == userId;
			}

			public void LoseCondition()
			{
				if (IsAdmin)
					return;

				Condition -= LoseConditionAmount();
			}

			private float LoseConditionAmount()
			{
				var result = _config.Atm.DefaultBreakPercent;

				_config.Atm.BreakPercent.Where(x => OwnerId.HasPermission(x.Key)).ForEach(check =>
				{
					if (result > check.Value) result = check.Value;
				});

				return result;
			}

			public bool CanOpen()
			{
				return Condition - LoseConditionAmount() > 0;
			}
		}

		#endregion

		#endregion

		#region Hooks

		private void Init()
		{
			_instance = this;

			LoadData();

			if (_config.Drop.Count == 0)
				Unsubscribe(nameof(OnLootSpawn));

#if TESTING
			StopwatchWrapper.OnComplete = DebugMessage;
#endif
		}

		private void OnServerInitialized(bool initial)
		{
			LoadImages();

			if (_config.Currency.ControlSplit == false)
				Unsubscribe(nameof(OnItemSplit));

			LoadEconomyHooks();
			
			RegisterPermissions();

			RegisterCommands();

			foreach (var player in BasePlayer.activePlayerList)
				OnPlayerConnected(player);

			RenameATMs();

			timer.In(20, SpawnATMs);
		}

		private void OnPlayerConnected(BasePlayer player)
		{
			if (player == null || !player.userID.IsSteamId()) return;

#if TESTING
			Debug.Log($"[OnPlayerConnected] called GetOrCreate with id={player.UserIDString}");
#endif
			var data = PlayerData.GetOrCreate(player.UserIDString);
			if (data == null) return;

			data.DisplayName = player.displayName;

			if (_config.UseCardExpiry)
				CheckCard(player.userID);

			if (_config.CardAutoCreation && !HasCard(player))
				CreateCard(player);
		}

		private void OnPlayerDisconnected(BasePlayer player)
		{
			UnloadAndSavePlayer(player.UserIDString);
		}

		private void OnServerSave()
		{
			timer.In(Random.Range(2, 7), ClearDataCache);
			timer.In(Random.Range(2, 7), SaveATMs);
		}

		private void Unload()
		{
			try
			{
				foreach (var player in BasePlayer.activePlayerList)
				{
					CuiHelper.DestroyUi(player, Layer);

					UnloadAndSavePlayer(player.UserIDString);
				}

				_vendingMachines.ForEach(entity =>
				{
					if (entity != null)
						entity.Kill();
				});

				SaveATMs();
			}
			finally
			{
				_instance = null;

				_config = null;
			}
		}

		#region Wipe

		private void OnNewSave(string filename)
		{
			if (_config.Wipe.ATMs) WipeATMs();
		}

		#endregion

		#region Loot

		private void OnLootSpawn(LootContainer container)
		{
			if (container == null || _config.Drop.Count <= 0) return;

#if TESTING
			SayDebug($"[OnLootSpawn.{container.net.ID}] called");
#endif
			
			var dropInfo = _config.Drop.Find(x => x.Enabled && x.PrefabName.Contains(container.PrefabName));
			if (dropInfo == null || Random.Range(0, 100) > dropInfo.DropChance)
			{
				
#if TESTING
				SayDebug($"[OnLootSpawn.{container.net.ID}] can't drop");
#endif

				return;
			}

			NextTick(() =>
			{
				if (container == null)
				{
					
#if TESTING
					SayDebug($"[OnLootSpawn.In.Tick] container is null");
#endif

					return;
				}

				var inventory = container.inventory;
				if (inventory == null)
				{
					
#if TESTING
					SayDebug($"[OnLootSpawn.{container.net.ID}] inventory is null");
#endif
					return;
				}

				if (inventory.capacity <= inventory.itemList.Count)
					inventory.capacity = inventory.itemList.Count + 1;

				var moveToContainer = _config.Currency.ToItem(Random.Range(dropInfo.MinAmount, dropInfo.MaxAmount))
					?.MoveToContainer(inventory);
				
#if TESTING
				SayDebug($"[OnLootSpawn.{container.net.ID}] moveToContainer={moveToContainer}");
#endif
			});
		}

		#endregion

		#region NPC

		private void OnUseNPC(BasePlayer npc, BasePlayer player)
		{
			if (player == null || npc == null || !_config.NPC.NPCs.Contains(npc.UserIDString)) return;

			if (!string.IsNullOrEmpty(_config.Permission) && !player.HasPermission(_config.Permission))
			{
				SendNotify(player, NoPermissions, 1);
				return;
			}

			MainUi(player, first: true);
		}

		#endregion

		#region ATM

		private void OnEntitySpawned(VendingMachine entity)
		{
			NextTick(() =>
			{
				if (entity == null ||
				    entity.skinID != _config.Atm.Skin ||
				    _atms.ATMs.Exists(x => x.EntityID == entity.net.ID.Value))
					return;

				var data = new ATMData
				{
					ID = ++_atms.LastATMID,
					EntityID = entity.net.ID.Value,
					OwnerId = 0,
					Balance = 0,
					Condition = 100,
					DepositFee = _config.Atm.Spawn.ConfAddons.DepositFee,
					WithdrawalFee = _config.Atm.Spawn.ConfAddons.WithdrawFee,
					IsAdmin = true
				};

				_atms.ATMs.Add(data);

				if (!string.IsNullOrEmpty(_config.Atm.ShopName))
				{
					entity.shopName = _config.Atm.ShopName
						.Replace("{id}", data.ID.ToString())
						.Replace("{owner}", _config.Atm.Spawn.ConfAddons.DisplayName);
					entity.UpdateMapMarker();
				}
			});
		}

		private void OnEntityBuilt(Planner plan, GameObject go)
		{
			if (plan == null || go == null) return;

			var entity = go.ToBaseEntity() as VendingMachine;
			if (entity == null) return;

			var player = plan.GetOwnerPlayer();
			if (player == null) return;

			var item = player.GetActiveItem();
			if (item == null || item.skin != _config.Atm.Skin) return;

			var data = new ATMData
			{
				ID = ++_atms.LastATMID,
				EntityID = entity.net.ID.Value,
				OwnerId = player.userID
// ... [Code preview truncated due to length. Full source in attached file] ...

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