C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Text;
using System;
using ConVar;
using Newtonsoft.Json;
using System.Collections.Generic;
using Network;
using System.Collections;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
[Info("IQBackpack", "Sempai#3239", "1.0.15")]
[Description("Просто твой любимый рюкзачок :)")]
class IQBackpack : RustPlugin {
void ReadData() => Backpacks = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<UInt64, BackpackInfo>>("IQBackpack/Backpacks");
private class BackpackBehaviour : FacepunchBehaviour {
public Item Backpack = null;
private BasePlayer Player = null;
public StorageContainer Container = null;
public UInt64 BackpackID = 0;
private Dictionary<Item, Item.Flag> SaveFlags = new Dictionary<Item, Item.Flag>();
private void Awake() {
Player = GetComponent<BasePlayer>();
BackpackID = _.GetBackpackID(Player);
}
private void BlackListAction(Boolean State) {
List<Item> Itemlist = _.GetItemBlacklist(Player);
if (Itemlist == null) return;
foreach (Item item in Itemlist) {
if (State) if (!SaveFlags.ContainsKey(item)) SaveFlags.Add(item, item.flags);
item.SetFlag(global : : Item.Flag.IsLocked, State);
}
if(!State) foreach(KeyValuePair<Item, Item.Flag> Items in SaveFlags) Items.Key.SetFlag(Items.Value, true);
Player.SendNetworkUpdate();
}
public void Open() {
Container = CreateContainer(Player);
PushItems();
LockSlot(true);
_.timer.Once(0.1f, () => PlayerLootContainer(Player, Container));
BlackListAction(true);
if (!_.PlayerUseBackpacks.Contains(Player)) _.PlayerUseBackpacks.Add(Player);
}
public void LockSlot(bool state) {
if (Backpack == null) return;
Backpack.LockUnlock(state);
foreach (var item in Player.inventory.AllItems()) if (item.skin == Backpack.skin) item.LockUnlock(state);
}
public void Close() {
LockSlot(false);
_.Backpacks[BackpackID].Items = SaveItems(Container.inventory.itemList);
Container.inventory.Clear();
Container.Kill();
Container = null;
Destroy(false);
BlackListAction(false);
if (_.PlayerUseBackpacks.Contains(Player)) _.PlayerUseBackpacks.Remove(Player);
}
private void PushItems() {
//_.Unsubscribe("OnItemAddedToContainer");
var items = RestoreItems(_.Backpacks[BackpackID].Items);
for (int i = items.Count - 1; i >= 0; i--) items[i].MoveToContainer(Container.inventory, items[i].position);
// _.Subscribe("OnItemAddedToContainer");
}
public void Destroy(bool isClose = true) {
if (isClose) Close();
UnityEngine.Object.Destroy(this);
}
}
private void ClearData() {
if (!config.TurnedsSetting.WipeCleaning) return;
foreach (KeyValuePair<UInt64, BackpackInfo> Backpack in Backpacks) Backpack.Value.Items.Clear();
WriteData();
}
private class NoRagdollCollision : FacepunchBehaviour {
private Collider _collider;
private void Awake() {
_collider = GetComponent<Collider>();
}
private void OnCollisionEnter(Collision collision) {
if (collision.collider.IsOnLayer(Rust.Layer.Ragdoll)) {
UnityEngine.Physics.IgnoreCollision(_collider, collision.collider);
}
}
}
public static StringBuilder sb = new StringBuilder();
public static IQBackpack _ = null;
private void DrawUI_Backpack_Slots_Locked(BasePlayer player) {
if (_interface == null) return;
if (!config.TurnedsSetting.UseCrafting || config.TurnedsSetting.Types == TypeBackpack.OnlyPermission) return;
Int32 AvailableSlots = GetAvailableSlots(player);
Int32 LockedSlots = 42 - AvailableSlots;
for (Int32 LockSlots = LockedSlots; LockSlots > 0; LockSlots--) {
String Interface = InterfaceBuilder.GetInterface("UI_Backpack_Slots_Lock");
if (Interface == null) return;
Interface = Interface.Replace("%INDEX%", $"{42 - LockSlots}");
CuiHelper.AddUi(player, Interface);
}
}
private List<BasePlayer> PlayerUseBackpacks = new List<BasePlayer>();
private void DropBackpack(BasePlayer player, TypeDropBackpack typeDropBackpack) {
if (!PlayerBackpack.ContainsKey(player)) return;
if (PlayerBackpack[player] != null) PlayerBackpack[player].Close();
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_Backpack_Visual);
BackpackRemoveSpine(player);
UInt64 ID = GetBackpackID(player);
Item Backpack = GetBackpack(player);
List<BackpackInfo.SavedItem> SavedList = GetSavedList(ID);
if (SavedList == null || SavedList.Count == 0) return;
switch (typeDropBackpack) {
case TypeDropBackpack.DropItems : {
foreach(BackpackInfo.SavedItem sItem in SavedList) {
Item BuildedItem = BuildItem(sItem);
BuildedItem.DropAndTossUpwards(player.transform.position, Oxide.Core.Random.Range(2, 6));
}
break;
}
case TypeDropBackpack.DropBackpack : {
String Prefab = "assets/prefabs/misc/item drop/item_drop_backpack.prefab";
DroppedItemContainer BackpackDrop = (BaseEntity)GameManager.server.CreateEntity(Prefab, player.transform.position + new Vector3(Oxide.Core.Random.Range(-1f, 1f), 0f, 0f)) as DroppedItemContainer;
BackpackDrop.gameObject.AddComponent<NoRagdollCollision>();
BackpackDrop.lootPanelName = "generic_resizable";
BackpackDrop.playerName = $"{player.displayName ?? "Somebody"}'s Backpack";
BackpackDrop.playerSteamID = player.userID;
BackpackDrop.inventory = new ItemContainer();
BackpackDrop.inventory.ServerInitialize(null, GetSlotsBackpack(player));
BackpackDrop.inventory.GiveUID();
BackpackDrop.inventory.entityOwner = BackpackDrop;
BackpackDrop.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
foreach (BackpackInfo.SavedItem sItem in SavedList) {
Item BuildedItem = BuildItem(sItem);
BuildedItem.MoveToContainer(BackpackDrop.inventory, sItem.TargetSlot);
}
BackpackDrop.SendNetworkUpdate();
BackpackDrop.Spawn();
BackpackDrop.ResetRemovalTime(Math.Max(config.TurnedsSetting.RemoveBackpack, BackpackDrop.CalculateRemovalTime()));
break;
}
default : break;
}
SavedList.Clear();
if (Backpack != null) Backpack.Remove();
if (config.TurnedsSetting.Types == TypeBackpack.Wear) Backpacks.Remove(ID);
}
public string GetLang(string LangKey, string userID = null, params object[] args) {
sb.Clear();
if (args != null) {
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
return lang.GetMessage(LangKey, this, userID);
}
object OnLootNetworkUpdate(PlayerLoot loot) {
if (loot == null) return null;
BasePlayer player = loot.GetComponent<BasePlayer>();
if (player == null) return null;
if (loot.entitySource == null || loot.entitySource.net == null) return null;
UInt64 NetID = loot.entitySource.net.ID;
NetworkIDGetSet(NetID, true, player);
return null;
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
private void BackpackSpawnSpine(BasePlayer player) {
if (!config.TurnedsSetting.UseSpineBackpack) return;
if (SpinesBackpacks.ContainsKey(player) && SpinesBackpacks[player] != null) return;
BackpackSpine backpackSpine = player.gameObject.AddComponent<BackpackSpine>();
SpinesBackpacks.Add(player, backpackSpine);
}
void CanLootEntity(BasePlayer player, StorageContainer container) {
if (container == null || player == null || !(Boolean)(container is Workbench)) return;
DrawUI_Backpack_Upgrade_Workbench(player);
return;
}
private String GetImage(Configuration.Backpack.BackpackCraft.ItemCraft CItem) {
String PNG = CItem.SkinID == 0 ? GetImage($"{CItem.Shortname}_128px") : GetImage($"{CItem.Shortname}_128px_{CItem.SkinID}", CItem.SkinID);
return PNG;
}
private new void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["CRAFT_BTN"]
= "CRAFT", ["SLOT_AVALIBLE_TITLE"] = "<b>YOUR AVAILABLE NUMBER OF SLOTS</b>", ["TITLE_PLUGIN_CRAFT_MENU"] = "CREATING BACKPACK", ["TITLE_STORE_INFORMATION"] = "YOU CAN EXPAND THE NUMBER OF SLOTS IN OUR STORE - VK.COM/MERCURYDEV", ["TITLE_HAVE_ITEMS"] = "<b>REQUIRED ITEMS FOR CRAFTING A BACKPACK</b>", ["TITLE_HAVE_ITEMS_DESCRIPTION"] = "In this section, the items that are required to create this backpack are displayed, you need to collect all the items and press the 'CRAFT' button, if you have the right amount collected, the indicator will change color to green under the item", ["CRAFTING_BACKPACK_NO_ITEMS"] = "You don't have enough items to create a backpack", ["BACKPACK_TITLE"] = "BACKPACK {0} SLOT(S)", ["BACKPACK_IS_OPENED"] = "Do you already have your backpack open!", ["BACKPACK_NO_WEARING"] = "In order to use a backpack, you need to put it on!", ["BACKPACK_NO_INITIALIZE"] = "The plugin is loading, expect you will be able to open crafting soon!", ["BACKPACK_UPGRADE_TITLE"] = "<b>Manual</b>", ["BACKPACK_UPGRADE_DESCRIPTION"] = "You need to collect these items and put them in the slot together with the backpack, in exchange you will receive an improved rucksack with an additional number of slots", ["BACKPACK_UPGRADE_WORKBENCH_TITLE"] = "<b>UPGRADE BACKPACK</b>", ["BACKPACK_UPGRADE_WORKBENCH_DESCRIPTION"] = "You can upgrade the backpack and increase the slots in it, to go to the upgrade menu, press the green button!\nThe maximum number of improvements to {0} slot(s)", ["BACKPACK_UPGRADE_WORKBENCH_BUTTON"] = "<b>UPGRADE BACKPACK</b>", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_SLOTS"] = "By upgrading the backpack to this level, you will receive: +{0} slot(s)", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE"] = "<b>UPGRADE BACKPACK</b>", ["BACKPACK_UPGRADE_WORKBENCH_BUTTON_MAXIMUM"] = "<b>MAX UPGRADE</b>", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE_FALSE_RESOURCE"] = "<b>INSUFFICIENT RESOURCES</b>", ["BACKPACK_GRANT"] = "You have successfully received a backpack, the number of slots has been increased to : {0}", ["BACKPACK_REVOKE"] = "Your extra slots privilege expired, slots reduced to : {0}", ["BACKPACK_NULL"] = "You don't have a backpack available",
}
, this);
lang.RegisterMessages(new Dictionary<string, string> {
["CRAFT_BTN"]
= "СКРАФТИТЬ", ["SLOT_AVALIBLE_TITLE"] = "<b>ВАШЕ ДОСТУПНОЕ КОЛИЧЕСТВО СЛОТОВ</b>", ["TITLE_PLUGIN_CRAFT_MENU"] = "СОЗДАНИЕ РЮКЗАКА", ["TITLE_STORE_INFORMATION"] = "РАСШИРИТЬ КОЛИЧЕСТВО СЛОТОВ МОЖНО У НАС В МАГАЗИНЕ - VK.COM/MERCURYDEV", ["TITLE_HAVE_ITEMS"] = "<b>ТРЕБУЕМЫЕ ПРЕДМЕТЫ ДЛЯ КРАФТА РЮКЗАКА</b>", ["TITLE_HAVE_ITEMS_DESCRIPTION"] = "В этой секции отображаются предметы, которые требуются для создания данного рюкзака, вам нужно собрать все элементы и нажать кнопку 'СКРАФТИТЬ', если у вас будет собрано нужное количество, под предметом индикатор изменит цвет на зеленый", ["CRAFTING_BACKPACK_NO_ITEMS"] = "У вас недостаточно предметов для создания рюкзака", ["BACKPACK_TITLE"] = "РЮКЗАК {0} СЛОТА(ОВ)", ["BACKPACK_IS_OPENED"] = "У вас уже открыт рюкзак!", ["BACKPACK_NO_WEARING"] = "Для того, чтобы использовать рюкзак, необходимо его надеть!", ["BACKPACK_NO_INITIALIZE"] = "Плагин загружается, ожидайте, вскоре вы сможете открыть крафт!", ["BACKPACK_UPGRADE_TITLE"] = "<b>Инструкция</b>", ["BACKPACK_UPGRADE_DESCRIPTION"] = "Вам нужно собрать указанные предметы и переложить в слот вместе с рюкзаком, в обмен вы получите улучшенный рюкзак с дополнительным количеством слотов", ["BACKPACK_UPGRADE_WORKBENCH_TITLE"] = "<b>УЛУЧШЕНИЕ РЮКЗАКА</b>", ["BACKPACK_UPGRADE_WORKBENCH_BUTTON"] = "<b>УЛУЧШИТЬ РЮК.</b>", ["BACKPACK_UPGRADE_WORKBENCH_BUTTON_MAXIMUM"] = "<b>МАКСИМУМ УЛ.</b>", ["BACKPACK_UPGRADE_WORKBENCH_DESCRIPTION"] = "Вы можете улучшать рюкзак и увеличивать слоты в нем, для перехода в меню улучшения нажмите зеленую кнопку!\nМаксимальное количество улучшений до - {0} слот(а/ов)", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_SLOTS"] = "Улучшив рюкзак до данного уровня вы получите : +{0} слот(а/ов)", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE"] = "<b>УЛУЧШИТЬ РЮКЗАК</b>", ["BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE_FALSE_RESOURCE"] = "<b>НЕДОСТАТОЧНО РЕСУРСОВ</b>", ["BACKPACK_GRANT"] = "Вы успешно получили рюкзак, количество слотов увеличено до : {0}", ["BACKPACK_REVOKE"] = "У вас истекла привилегия с дополнительными слотами, слоты уменьшились до : {0}", ["BACKPACK_NULL"] = "У вас нет доступного рюкзака",
}
, this, "ru");
}
private static void PlayerLootContainer(BasePlayer player, ShopFront shopFront, List<Configuration.Backpack.BackpackCraft.ItemCraft> ItemList) {
shopFront.SetFlag(BaseEntity.Flags.Open, true, false);
shopFront.vendorInventory.capacity = 12;
shopFront.customerInventory.capacity = 12;
shopFront.customerPlayer = player;
shopFront.customerInventory.playerOwner = player;
shopFront.customerInventory.uid = (UInt32)player.userID;
foreach (Configuration.Backpack.BackpackCraft.ItemCraft UpgradeItems in ItemList) {
Item item = ItemManager.CreateByName(UpgradeItems.Shortname, UpgradeItems.Amount, UpgradeItems.SkinID);
item.MoveToContainer(shopFront.vendorInventory);
}
player.inventory.loot.StartLootingEntity(shopFront, false);
player.inventory.loot.AddContainer(shopFront.vendorInventory);
player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "shopfront");
player.inventory.loot.AddContainer(shopFront.customerInventory);
player.inventory.loot.SendImmediate();
shopFront.UpdatePlayers();
shopFront.DecayTouch();
shopFront.SendNetworkUpdate();
}
private void DrawUI_Backpack_Main(BasePlayer player) {
if (!config.TurnedsSetting.UseCrafting || config.TurnedsSetting.Types == TypeBackpack.OnlyPermission) return;
String Interface = InterfaceBuilder.GetInterface("UI_Backpack_Main");
if (Interface == null) return;
Interface = Interface.Replace("%CRAFT_BTN%", GetLang("CRAFT_BTN", player.UserIDString));
Interface = Interface.Replace("%SLOT_AVALIBLE_TITLE%", GetLang("SLOT_AVALIBLE_TITLE", player.UserIDString));
Interface = Interface.Replace("%TITLE_PLUGIN_CRAFT_MENU%", GetLang("TITLE_PLUGIN_CRAFT_MENU", player.UserIDString));
Interface = Interface.Replace("%TITLE_STORE_INFORMATION%", GetLang("TITLE_STORE_INFORMATION", player.UserIDString));
Interface = Interface.Replace("%TITLE_HAVE_ITEMS%", GetLang("TITLE_HAVE_ITEMS", player.UserIDString));
Interface = Interface.Replace("%TITLE_HAVE_ITEMS_DESCRIPTION%", GetLang("TITLE_HAVE_ITEMS_DESCRIPTION", player.UserIDString));
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_Backpack);
CuiHelper.AddUi(player, Interface);
DrawUI_Backpack_Slots(player);
DrawUI_Backpack_ItemCrafts(player);
}
private class Configuration {
public static Configuration GetNewConfiguration() {
return new Configuration {
BackpackItem = new Backpack {
Shortname = "burlap.gloves", SkinID = 2726640855, UrlBackpack = "https://i.imgur.com/rPeKd9R.png", BackpacOption = new List<Backpack.BackpackCraft> {
new Backpack.BackpackCraft {
AmountSlot = 7, Permissions = "iqbackpack.7slot", BlackListItems = new List<String> {
}
, CraftItems = new List<Backpack.BackpackCraft.ItemCraft> {
}
, UpgradeList = new List<Backpack.BackpackCraft.UpgradeBackpack> {
}
,
}
, new Backpack.BackpackCraft {
AmountSlot = 15, Permissions = "iqbackpack.15slot", BlackListItems = new List<String> {
"rocket.launcher", "ammo.rocket.basic", "explosive.satchel", "supply.signal", "explosive.timed",
}
, CraftItems = new List<Backpack.BackpackCraft.ItemCraft> {
new Backpack.BackpackCraft.ItemCraft {
Shortname = "leather", Amount = 50, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "cloth", Amount = 200, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "sewingkit", Amount = 10, SkinID = 0
}
,
}
, UpgradeList = new List<Backpack.BackpackCraft.UpgradeBackpack> {
new Backpack.BackpackCraft.UpgradeBackpack {
SlotUpgrade = 3, CraftItems = new List<Backpack.BackpackCraft.ItemCraft> {
new Backpack.BackpackCraft.ItemCraft {
Shortname = "burlap.gloves", Amount = 1, SkinID = 2726640855
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "leather", Amount = 150, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "cloth", Amount = 300, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "sewingkit", Amount = 5, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "metal.fragments", Amount = 1000, SkinID = 0
}
,
}
}
, new Backpack.BackpackCraft.UpgradeBackpack {
SlotUpgrade = 10, CraftItems = new List<Backpack.BackpackCraft.ItemCraft> {
new Backpack.BackpackCraft.ItemCraft {
Shortname = "burlap.gloves", Amount = 1, SkinID = 2726640855
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "leather", Amount = 500, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "cloth", Amount = 1000, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "sewingkit", Amount = 25, SkinID = 0
}
, new Backpack.BackpackCraft.ItemCraft {
Shortname = "metal.fragments", Amount = 15000, SkinID = 0
}
,
}
}
,
}
}
}
}
, TurnedsSetting = new Turneds {
Types = TypeBackpack.Wear, WipeCleaning = false, UseCrafting = true, UseUpgradeBackpack = true, ClosePressedAgain = true, UseSpineBackpack = false, TypeDropBackpack = TypeDropBackpack.DropBackpack, RemoveBackpack = 200f, VisualBackpackSlots = new Turneds.VisualBackpackSlot {
UseVisual = true, UseSlots = true, UseIsFulled = true, UseButton = true, ColorProgressBar = new Turneds.VisualBackpackSlot.ColorProgress {
ColorMinimal = "0.44 0.53 0.26 1.00", ColorAverage = "0.98 0.53 0.26 1.00", ColorMaximum = "0.98 0.20 0.28 1.00",
}
, PositionSlotVisual = new Turneds.VisualBackpackSlot.Position {
AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-264.276 17.943", OffsetMax = "-203.724 78.087"
}
, PositionUpgrade = new Turneds.VisualBackpackSlot.Position {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "194.836 -36.769", OffsetMax = "575.164 36.785"
}
}
,
}
, References = new Reference {
IQChatSetting = new Reference.IQChat {
CustomAvatar = "0", CustomPrefix = "[IQBackpack] ", UIAlertUse = false,
}
}
}
;
}
[JsonProperty("Дополнительная настройка")]
public Turneds TurnedsSetting = new Turneds();
internal class Reference {
[JsonProperty("Настройка IQChat")]
public IQChat IQChatSetting = new IQChat();
internal class IQChat {
[JsonProperty("IQChat : Кастомный префикс в чате")]
public String CustomPrefix = "[IQBackpack]";
[JsonProperty("IQChat : Кастомный аватар в чате(Если требуется)")]
public String CustomAvatar = "0";
[JsonProperty("IQChat : Использовать UI уведомления")]
public Boolean UIAlertUse = false;
}
}
internal class Backpack {
[JsonProperty("Shortname для рюкзака (нужен предмет, который является одеждой)")]
public String Shortname = "burlap.gloves";
[JsonProperty("SkinID рюкзака")]
public UInt64 SkinID = 2726640855;
[JsonProperty("Ссылка на картинку для отображения рюкзака")]
public String UrlBackpack = "https://i.imgur.com/rPeKd9R.png";
[JsonProperty("Вариации рюкзаков по привилегиям (Дается доступный набор игроку, который выше других)")]
public List<BackpackCraft> BackpacOption = new List<BackpackCraft>();
internal class BackpackCraft {
[JsonProperty("Права для возможности крафтить и носить данный рюкзак(не оставляйте это поле пустым, иначе оно не будет учитываться)")]
public String Permissions = "iqbackpack.7slot";
[JsonProperty("Количество слотов у данного рюкзака")]
public Int32 AmountSlot = 7;
[JsonProperty("Черный список предметов для данного рюкзака")]
public List<String> BlackListItems = new List<String>();
[JsonProperty("Предметы для крафта рюкзака")]
public List<ItemCraft> CraftItems = new List<ItemCraft>();
[JsonProperty("Настройка улучшений рюкзака (Улучшение будет постепенное в зависимости от листа, сверху -> вниз (максимальное количество слотов - 42))")]
public List<UpgradeBackpack> UpgradeList = new List<UpgradeBackpack>();
internal class UpgradeBackpack {
[JsonProperty("Предметы для улучшения на этот уровень")]
public List<ItemCraft> CraftItems = new List<ItemCraft>();
[JsonProperty("Сколько слотов добавлять за это улучшение")]
public Int32 SlotUpgrade;
}
internal class ItemCraft {
public String Shortname;
public UInt64 SkinID;
[JsonProperty("Количество")]
public Int32 Amount;
}
}
}
[JsonProperty("Настройка рюкзака")]
public Backpack BackpackItem = new Backpack();
internal class Turneds {
[JsonProperty("Использовать возможность улучшать рюкзаки и увеличивать в нем слоты (true - да/false - нет) [Дополнительно настраивается в каждом рюкзаке, учтите - это общий параметр, детальная настройка в вариациях рюкзаков]")]
public Boolean UseUpgradeBackpack = true;
[JsonProperty("Тип выпадения рюкзака : 0 - Не выпадает при смерти, 1 - Выбрасывает предметы вокруг трупа, 2 - Выбрасывает рюкзак с предметами")]
public TypeDropBackpack TypeDropBackpack = TypeDropBackpack.DropBackpack;
[JsonProperty("Закрывать рюкзак при повторном нажатии на UI/использовании бинда, если он открыт")]
public Boolean ClosePressedAgain = true;
[JsonProperty("Отображать рюкзак за спиной игрока(модельку рюкзака, работает на всех поворотах и изгибах игрока) [ВНИМАНИЕ, ИСПОЛЬЗУЙТЕ ЭТО НА PVE СЕРВЕРЕ, ИЗ-ЗА ОСОБЕННОСТЕЙ ИГРЫ В ТАКОЙ РЮКЗАК НА СПИНЕ НЕ БУДЕТ ПРОХОДИТЬ УРОН]")]
public Boolean UseSpineBackpack = false;
[JsonProperty("Время удаления рюкзака при выпадении (Работает с : 2 - Выбрасывает рюкзак с предметами)")]
public Single RemoveBackpack = 200f;
[JsonProperty("Использовать возможность скрафтить рюкзак (true - да/false - нет)")]
public Boolean UseCrafting = true;
[JsonProperty("Автоматически очищать инвентарь рюкзаков игроков после вайпа (true - да/false - нет)")]
public Boolean WipeCleaning = false;
[JsonProperty("Настройка интерфейса")]
public VisualBackpackSlot VisualBackpackSlots = new VisualBackpackSlot();
internal class VisualBackpackSlot {
[JsonProperty("Отображать количество слотов в рюкзаке на UI (true - да/false - нет)")]
public Boolean UseSlots = true;
[JsonProperty("Настройка позиции UI слота с рюкзаком")]
public Position PositionSlotVisual = new Position();
[JsonProperty("Отображать полосу заполненности рюкзака на UI (true - да/false - нет)")]
public Boolean UseIsFulled = true;
[JsonProperty("Настройка цветов полосы заполненности")]
public ColorProgress ColorProgressBar = new ColorProgress();
[JsonProperty("Разрешить открывать рюкзак нажава на UI интерфейс (true - да/false - нет)")]
public Boolean UseButton = true;
internal class ColorProgress {
[JsonProperty("Цвет полосы заполненности, когда рюкзак заполнен на >80%")]
public String ColorMaximum = "0.98 0.20 0.28 1.00";
[JsonProperty("Цвет полосы заполненности, когда рюкзак заполнен на >60%")]
public String ColorAverage = "0.98 0.53 0.26 1.00";
[JsonProperty("Цвет полосы заполненности, когда рюкзак заполнен на >30%")]
public String ColorMinimal = "0.44 0.53 0.26 1.00";
}
[JsonProperty("Использовать отображение UI рюкзака возле слотов (true - да/false - нет)")]
public Boolean UseVisual = true;
internal class Position {
public String AnchorMin;
public String AnchorMax;
public String OffsetMin;
public String OffsetMax;
}
[JsonProperty("Настройка позиции UI для улучшения рюкзака")]
public Position PositionUpgrade = new Position();
}
[JsonProperty("Тип работы рюкзака : 0 - требуется надеть его, чтобы пользоватья, 1 - требуются лишь права(из вариаций рюкзаков)")]
public TypeBackpack Types = TypeBackpack.Wear;
}
[JsonProperty("Настройка поддерживающих плагинов")]
public Reference References = new Reference();
}
private void DrawUI_Backpack_Visual(BasePlayer player) {
if (!config.TurnedsSetting.VisualBackpackSlots.UseVisual || _interface == null) return;
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_Backpack_Visual);
String Interface = InterfaceBuilder.GetInterface("UI_Backpack_Visual_Backpack_Slot");
if (Interface == null) return;
Single BusySlots = (Single)GetBusySlotsBackpack(player);
Single Slots = (Single)GetSlotsBackpack(player);
if (Slots == 0) return;
Single Y_Progress = (Single)((Single)BusySlots / (Single)Slots);
String Y_Progress_Color = BusySlots >= GetSlotsPercent(80.0f, Slots) ? config.TurnedsSetting.VisualBackpackSlots.ColorProgressBar.ColorMaximum : BusySlots >= GetSlotsPercent(60.0f, Slots) ? config.TurnedsSetting.VisualBackpackSlots.ColorProgressBar.ColorAverage : config.TurnedsSetting.VisualBackpackSlots.ColorProgressBar.ColorMinimal;
Interface = Interface.Replace("%CRAFT_BTN%", GetLang("CRAFT_BTN", player.UserIDString));
Interface = Interface.Replace("%SLOTS_INFO%", $"<b>{BusySlots}/{Slots}</b>");
Interface = Interface.Replace("%Y_PROGRESS%", $"{Y_Progress}");
Interface = Interface.Replace("%Y_PROGRESS_COLOR%", $"{Y_Progress_Color}");
CuiHelper.AddUi(player, Interface);
}
private void UpdatePermissions(String ID, String Permissions, Boolean IsGranted) {
UInt64 UserID = UInt64.Parse(ID);
BasePlayer player = BasePlayer.FindByID(UserID);
if(player == null) return;
if (config.BackpackItem.BackpacOption.Find(x => x.Permissions.Equals(Permissions)) == null) return;
UInt64 IDBackpack = GetBackpackID(player);
if (!Backpacks.ContainsKey(IDBackpack)) return;
player.EndLooting();
Int32 AvailableSlots = GetAvailableSlots(player);
if (AvailableSlots < GetBusySlotsBackpack(player)) {
Int32 Count = Backpacks[IDBackpack].Items.Count - 1;
foreach (BackpackInfo.SavedItem Sitem in Backpacks[IDBackpack].Items.Take((Backpacks[IDBackpack].Items.Count - AvailableSlots))) {
NextTick(() => {
Item itemDrop = BuildItem(Sitem);
itemDrop.DropAndTossUpwards(player.transform.position, 2f);
Backpacks[IDBackpack].Items.RemoveAt(Count);
Count--;
}
);
}
}
Backpacks[IDBackpack].AmountSlot = AvailableSlots;
NextTick(() => {
DrawUI_Backpack_Visual(player);
SendChat(GetLang((IsGranted ? "BACKPACK_GRANT" : "BACKPACK_REVOKE"), player.UserIDString, AvailableSlots), player);
}
);
}
private Dictionary<BasePlayer, ShopFrontBehavior> PlayerUpgrades = new Dictionary<BasePlayer, ShopFrontBehavior>();
private void OpenUpgradeMenu(BasePlayer player) {
if (!config.TurnedsSetting.UseUpgradeBackpack) return;
if (player == null) return;
ShopFrontBehavior upgradeHandler = null;
if (PlayerBackpack.ContainsKey(player)) {
if (PlayerBackpack[player] != null) upgradeHandler = PlayerUpgrades[player];
}
else PlayerBackpack.Add(player, null);
if (upgradeHandler == null) {
upgradeHandler = player.gameObject.AddComponent<ShopFrontBehavior>();
PlayerUpgrades[player] = upgradeHandler;
}
if (upgradeHandler.Container != null) return;
upgradeHandler.Open();
}
private Configuration.Backpack.BackpackCraft GetBackpackOption(BasePlayer player) {
Configuration.Backpack.BackpackCraft BCraft = config.BackpackItem.BackpacOption.FirstOrDefault(x => permission.UserHasPermission(player.UserIDString, x.Permissions));
return BCraft;
}
internal class BackpackInfo {
public Int32 AmountSlot = 0;
public Int32 IndexUpgrade = -1;
public List<SavedItem> Items = new List<SavedItem>();
internal class SavedItem {
public Int32 TargetSlot;
public String Shortname;
public Int32 Itemid;
public Single Condition;
public Single Maxcondition;
public Int32 Amount;
public Int32 Ammoamount;
public String Ammotype;
public Int32 Flamefuel;
public UInt64 Skinid;
public String Name;
public Boolean Weapon;
public Int32 Blueprint;
public Single BusyTime;
public Boolean OnFire;
public List<SavedItem> Mods;
}
}
void OnItemDropped(Item item, BaseEntity entity) {
if (item == null || entity == null) return;
BasePlayer player = item.GetOwnerPlayer();
if (player == null || player is ScientistNPC || player is HumanNPC || player is NPCPlayer) return;
if (config.TurnedsSetting.Types == TypeBackpack.Wear) if (item.skin == config.BackpackItem.SkinID) {
NextTick(() => {
if (GetBackpack(player) == null) {
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_Backpack_Visual);
BackpackRemoveSpine(player);
}
}
);
return;
}
if (config.TurnedsSetting.UseUpgradeBackpack) {
if ((Boolean)(item?.GetRootContainer()?.entityOwner is ShopFront)) {
if (PlayerUpgrades.ContainsKey(player)) {
NextTick(() => {
if (PlayerUpgrades[player] != null && PlayerUpgrades[player].Container.vendorInventory != null && PlayerUpgrades[player].Container.customerInventory != null) PlayerUpgrades[player].VendorLock(true);
DrawUI_Backpack_Upgrade_Info_Controller(player);
}
);
}
return;
}
if (player?.inventory?.loot?.entitySource is Workbench) {
NextTick(() => {
DrawUI_Backpack_Upgrade_Workbench(player);
}
);
return;
}
}
}
void OnPlayerDeath(BasePlayer player, HitInfo info) {
if (player == null) return;
DropBackpack(player, config.TurnedsSetting.TypeDropBackpack);
return;
}
private Int32 GetBusySlotsBackpack(BasePlayer player) {
if (config.TurnedsSetting.Types == TypeBackpack.Wear) {
Item item = GetBackpack(player);
if (item != null) if (Backpacks.ContainsKey(item.uid)) {
return Backpacks[item.uid].Items.Count;
}
}
else {
if (Backpacks.ContainsKey(player.userID)) return Backpacks[player.userID].Items.Count;
}
return 0;
}
private void DrawUI_Backpack_Upgrade_Info_Controller(BasePlayer player) {
if (!config.TurnedsSetting.UseUpgradeBackpack || _interface == null) return;
if (!PlayerUpgrades.ContainsKey(player)) return;
if (PlayerUpgrades[player] == null) return;
String Interface = InterfaceBuilder.GetInterface("UI_Backpack_Upgrade_Info_Controller");
if (Interface == null) return;
Boolean IsUpgrade = HaveAllItem(player, PlayerUpgrades[player].ItemList, PlayerUpgrades[player].Container.customerInventory);
Interface = Interface.Replace("%BACKPACK_UPGRADE_WORKBENCH_INFORMATION_SLOTS%", GetLang("BACKPACK_UPGRADE_WORKBENCH_INFORMATION_SLOTS", player.UserIDString, PlayerUpgrades[player].UpgradeSlotsUp));
Interface = Interface.Replace("%BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE%", GetLang((IsUpgrade ? "BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE" : "BACKPACK_UPGRADE_WORKBENCH_INFORMATION_BUTTON_TILE_FALSE_RESOURCE"), player.UserIDString));
Interface = Interface.Replace("%BUTTON_COLOR%", (IsUpgrade ? "0.4431373 0.5450981 0.2627451 1" : "0.7568628 0.2273419 0.2078431 1"));
CuiHelper.DestroyUi(player, "BackpackStatusUpgrade");
CuiHelper.AddUi(player, Interface);
}
private UInt64 GetBackpackID(BasePlayer player) {
UInt64 ID = 0;
if (config.TurnedsSetting.Types == TypeBackpack.Wear) {
Item Backpack = GetBackpack(player);
if (Backpack == null) return ID;
ID = Backpack.uid;
}
else ID = player.userID;
return ID;
}
private void DrawUI_Backpack_ItemCrafts(BasePlayer player) {
if (_interface == null) return;
if (!config.TurnedsSetting.UseCrafting || config.TurnedsSetting.Types == TypeBackpack.OnlyPermission) return;
Configuration.Backpack.BackpackCraft BCraft = GetBackpackOption(player);
if (BCraft == null || BCraft.CraftItems == null) return;
Int32 ItemCount = 0;
Single itemMinPosition = 219f;
Single itemWidth = 0.15f;
/// Ширина
Single itemMargin = 0.062f;
/// Расстояние между
Int32 itemCount = BCraft.CraftItems.Count;
Single itemMinHeight = 0.84f;
// Сдвиг по вертикали
Single itemHeight = 0.16f;
/// Высота
Int32 ItemTarget = 5;
if (itemCount > ItemTarget) {
itemMinPosition = 0.5f - ItemTarget / 2f * itemWidth - (ItemTarget - 1) / 2f * itemMargin;
itemCount -= ItemTarget;
}
else itemMinPosition = 0.5f - itemCount / 2f * itemWidth - (itemCount - 1) / 2f * itemMargin;
foreach (Configuration.Backpack.BackpackCraft.ItemCraft item in BCraft.CraftItems) {
String Interface = InterfaceBuilder.GetInterface("UI_Backpack_Craft_Item");
if (Interface == null) return;
Interface = Interface.Replace("%ANCHOR_MIN%", $"{itemMinPosition} {itemMinHeight}");
Interface = Interface.Replace("%ANCHOR_MAX%", $"{itemMinPosition + itemWidth} {itemMinHeight + itemHeight}");
Interface = Interface.Replace("%AMOUNT%", $"{item.Amount}");
Interface = Interface.Replace("%PNG_ITEM%", GetImage(item));
Interface = Interface.Replace("%COLOR_PANEL%", HaveItem(player, item.Shortname, item.Amount, item.SkinID) ? "0.57 1.00 0.65 1.00" : "0.98 0.13 0.18 1.00");
CuiHelper.AddUi(player, Interface);
ItemCount++;
itemMinPosition += (itemWidth + itemMargin);
if (ItemCount % ItemTarget == 0) {
itemMinHeight -= (itemHeight + (itemMargin * 0.5f));
if (itemCount > ItemTarget) {
itemMinPosition = 0.5f - ItemTarget / 2f * itemWidth - (ItemTarget - 1) / 2f * itemMargin;
itemCount -= ItemTarget;
}
else itemMinPosition = 0.5f - itemCount / 2f * itemWidth - (itemCount - 1) / 2f * itemMargin;
}
}
}
private class InterfaceBuilder {
public static InterfaceBuilder Instance;
public const String UI_Backpack = "UI_BACKPACK";
public const String UI_Backpack_Visual = "UI_BACKPACK_VISUAL";
public const String UI_Backpack_Upgrade_Info = "UI_BACKPACK_UPGRATE_INFO";
public const String UI_Backpack_Upgrade_Workbench = "UI_BACKPACK_UPGRATE_WORKBENCH";
public Dictionary<String, String> Interfaces;
public InterfaceBuilder() {
Instance = this;
Interfaces = new Dictionary<String, String>();
BuildingBackpack_Main();
BuildingBackpack_Slots();
BuildingBackpack_Slots_Lock();
BuildingBackpack_Craft();
BuildingBackpack_UpgradeBackpack_Workbench();
BuildingBackpack_UpgradeBackpack_Info();
BuildingBackpack_UpgradeBackpack_Info_Controller();
if (config.TurnedsSetting.VisualBackpackSlots.UseVisual) BuildingBackpack_Visual_Backpack_Slot();
}
public static void AddInterface(String name, String json) {
if (Instance.Interfaces.ContainsKey(name)) {
_.PrintError($"Error! Tried to add existing cui elements! -> {name}");
return;
}
Instance.Interfaces.Add(name, json);
}
public static string GetInterface(String name) {
string json = string.Empty;
if (Instance.Interfaces.TryGetValue(name, out json) == false) {
_.PrintWarning($"Warning! UI elements not found by name! -> {name}");
}
return json;
}
public static void DestroyAll() {
for (var i = 0; i < BasePlayer.activePlayerList.Count; i++) {
var player = BasePlayer.activePlayerList[i];
CuiHelper.DestroyUi(player, UI_Backpack);
CuiHelper.DestroyUi(player, UI_Backpack_Visual);
CuiHelper.DestroyUi(player, UI_Backpack_Upgrade_Info);
CuiHelper.DestroyUi(player, UI_Backpack_Upgrade_Workbench);
}
}
private void BuildingBackpack_Main() {
if (!config.TurnedsSetting.UseCrafting || config.TurnedsSetting.Types == TypeBackpack.OnlyPermission) return;
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel {
CursorEnabled = true, Image = {
Color = "0 0 0 0.8", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
, "Overlay", UI_Backpack);
container.Add(new CuiElement {
Name = "BackpackImage", Parent = UI_Backpack, Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = _.GetImage(config.BackpackItem.UrlBackpack)
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-605 -104", OffsetMax = "-349 152"
}
}
}
);
container.Add(new CuiButton {
Button = {
Color = "0 0 0 0", Command = "backpack.crafting"
}
, Text = {
Text = "%CRAFT_BTN%", Font = "robotocondensed-regular.ttf", FontSize = 40, Align = TextAnchor.MiddleCenter, Color = "0.91 0.87 0.83 1"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-605 -160.464", OffsetMax = "-349 -103.995"
}
}
, UI_Backpack, "TitleCraft");
container.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "0 0 0 0"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "205.779 -360", OffsetMax = "628.221 360"
}
}
, UI_Backpack, "SlotPanels");
container.Add(new CuiElement {
Name = "TitleSlot", Parent = "SlotPanels", Components = {
new CuiTextComponent {
Text = "%SLOT_AVALIBLE_TITLE%", Font = "robotocondensed-regular.ttf", Font
// ... [Code preview truncated due to length. Full source in attached file] ...