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

FREE Backpacks : 2.1.6 2.1.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using System.Linq;
using Oxide.Core;
using System;

// Changes:
// - Saving dataint for keys
// - Fixed error with NPC deaths

namespace Oxide.Plugins
{
    [Info("Backpacks", "LaserHydra", "2.1.6", ResourceId = 1408)]
    [Description("Allows players to have a Backpack which provides them extra inventory space.")]
    internal class Backpacks : RustPlugin
    {
        private const string BackpackPrefab = "assets/prefabs/misc/item drop/item_drop_backpack.prefab";
        private const string BackBone = "spine3";

	    private static Backpacks _instance;
        private static Dictionary<ulong, Backpack> _backpacks = new Dictionary<ulong, Backpack>();

        [PluginReference]
        private RustPlugin EventManager;

        #region Classes

        private static class Configuration
        {
            public static StorageSize BackpackSize = StorageSize.Medium;

            public static int BackpackSizeInt
            {
                get { return (int)BackpackSize; }
                set { BackpackSize = (StorageSize)value; }
            }

            public static bool ShowOnBack = true;
            public static bool HideOnBackIfEmpty = true;
            public static bool DropOnDeath = true;
            public static bool EraseOnDeath = false;

            public static bool UseBlacklist = false;

            public static List<object> BlacklistedItems = new List<object>
            {
                "rocket.launcher",
                "lmg.m249"
            };
        }

        private class StorageCloser : MonoBehaviour
        {
            private Action _callback;

            public static void Attach(BaseEntity entity, Action callback)
                => entity.gameObject.AddComponent<StorageCloser>()._callback = callback;

            private void PlayerStoppedLooting(BasePlayer player) => _callback.Invoke();
        }

        private class VisualBackpack : MonoBehaviour
        {
            public Backpack Backpack { get; set; }
        }

        private class Backpack
        {
            public BackpackInventory Inventory = new BackpackInventory();
            public ulong ownerID;

            private BaseEntity _boxEntity;
            private BaseEntity _visualEntity;
            private BasePlayer _looter;

            [JsonIgnore] public bool IsOpen => _boxEntity != null;
            [JsonIgnore] public StorageContainer Container => _boxEntity?.GetComponent<StorageContainer>();

            public StorageSize Size =>
                _instance.permission.UserHasPermission(ownerID.ToString(), "backpacks.use.large") ? StorageSize.Large :
                    (_instance.permission.UserHasPermission(ownerID.ToString(), "backpacks.use.medium") ? StorageSize.Medium :
                        (_instance.permission.UserHasPermission(ownerID.ToString(), "backpacks.use.medium") ? StorageSize.Small : Configuration.BackpackSize));

            public Backpack(ulong id)
            {
                ownerID = id;
            }

            public void Drop(Vector3 position)
            {
                if (Inventory.Items.Count > 0)
                {
                    BaseEntity entity = GameManager.server.CreateEntity(BackpackPrefab, position, Quaternion.identity);
                    DroppedItemContainer container = entity as DroppedItemContainer;

                    container.inventory = new ItemContainer();
                    container.inventory.ServerInitialize(null, Inventory.Items.Count);
                    container.inventory.GiveUID();
                    container.inventory.entityOwner = container;
                    container.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);

                    foreach (Item item in Inventory.Items.Select(i => i.ToItem()))
                    {
                        if (!item.MoveToContainer(container.inventory))
                            item.Remove();
                    }

                    container.ResetRemovalTime();

                    container.Spawn();

                    container.playerName = "Backpack";
                    container.playerSteamID = ownerID;

                    entity.name = "droppedbackpack";
                }

                EraseContents();
            }

            public void EraseContents()
            {
                RemoveVisual();
                Inventory.Items.Clear();
                SaveData(this, $"{_instance.DataFileName}/{ownerID}");
            }

            public void Open(BasePlayer looter)
            {
                if (IsOpen)
                {
                    _instance.PrintToChat(looter, _instance.lang.GetMessage("Backpack Already Open", _instance, looter.UserIDString));
                    return;
                }

                if (_instance.EventManager?.Call<bool>("isPlaying", looter) ?? false)
                {
                    _instance.PrintToChat(looter, _instance.lang.GetMessage("May Not Open Backpack In Event", _instance, looter.UserIDString));
                    return;
                }

                _boxEntity = SpawnContainer(Size, looter.transform.position - new Vector3(0, UnityEngine.Random.Range(100, 5000), 0));

                foreach (var backpackItem in Inventory.Items)
                {
                    var item = backpackItem.ToItem();
                    item?.MoveToContainer(Container.inventory, item.position);
                }

                _looter = looter;

                PlayerLootContainer(looter, Container);
                StorageCloser.Attach(_boxEntity, Close);
            }

            private void Close()
            {
                if (_boxEntity != null)
                {
                    Inventory.Items = Container.inventory.itemList.Select(BackpackInventory.BackpackItem.FromItem).ToList();

                    _boxEntity.Kill();
                    _boxEntity = null;
                }

                if (_looter != null)
                {
                    if (_looter.userID != ownerID)
                    {
                        BasePlayer ownerPlayer = BasePlayer.FindByID(ownerID);

                        if (ownerPlayer != null)
                        {
                            if (Inventory.Items.Count == 0 && Configuration.HideOnBackIfEmpty)
                                RemoveVisual();
                            else if (_visualEntity == null)
                                SpawnVisual(ownerPlayer);
                        }
                    }
                    else
                    {
                        if (Inventory.Items.Count == 0 && Configuration.HideOnBackIfEmpty)
                            RemoveVisual();
                        else if (_visualEntity == null)
                            SpawnVisual(_looter);
                    }
                }

                _looter = null;

                SaveData(this, $"{_instance.DataFileName}/{ownerID}");
            }

            public void ForceClose() => Close();

            public void SpawnVisual(BasePlayer player)
            {
                if (_visualEntity != null || !Configuration.ShowOnBack)
                    return;

                BaseEntity entity = GameManager.server.CreateEntity(BackpackPrefab, new Vector3(0, -0.1f, 0), Quaternion.Euler(-5, -90, 180));
                DroppedItemContainer container = entity as DroppedItemContainer;
                container.inventory = new ItemContainer();
                container.inventory.ServerInitialize(null, 0);
                container.inventory.GiveUID();
                container.inventory.entityOwner = container;
                container.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
                container.CancelInvoke(container.RemoveMe);
                
                var visualBackpack = entity.gameObject.AddComponent<VisualBackpack>();
                visualBackpack.Backpack = this;

                entity.limitNetworking = true;

                entity.SetParent(player, StringPool.Get(BackBone));
                entity.SetFlag(BaseEntity.Flags.Locked, true);
                entity.Spawn();
                entity.name = "backpack";

                _visualEntity = entity;

                _instance.PrintWarning(entity.limitNetworking.ToString());
            }

            public void RemoveVisual()
            {
                if (_visualEntity != null)
                {
                    _visualEntity.Kill();
                    _visualEntity = null;
                }
            }

            public static Backpack LoadOrCreate(ulong id)
            {
                if (_backpacks.ContainsKey(id))
                    return _backpacks[id];

                Backpack backpack = null;

                if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{_instance.DataFileName}/{id}"))
                    LoadData(ref backpack, $"{_instance.DataFileName}/{id}");
                else
                {
                    backpack = new Backpack(id);
                    SaveData(backpack, $"{_instance.DataFileName}/{id}");
                }

                _backpacks.Add(id, backpack);

                return backpack;
            }
        }

        private class BackpackInventory
        {
            public List<BackpackItem> Items = new List<BackpackItem>();

            public class BackpackItem
            {
                public int ID;
                public int Position = -1;
                public int Amount;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public ulong Skin;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public float Fuel;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public int FlameFuel;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public float Condition;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public float MaxCondition = -1;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public int Ammo;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public int AmmoType;

                [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
                public int DataInt;

                public bool IsBlueprint;
                public int BlueprintTarget;

                [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
                public List<BackpackItem> Contents = new List<BackpackItem>();

                public Item ToItem()
                {
                    if (Amount == 0)
                        return null;

                    Item item = ItemManager.CreateByItemID(ID, Amount, Skin);

                    item.position = Position;

                    if (IsBlueprint)
                    {
                        item.blueprintTarget = BlueprintTarget;
                        return item;
                    }

                    BaseProjectile.Magazine magazine = item.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine;
                    FlameThrower flameThrower = item.GetHeldEntity()?.GetComponent<FlameThrower>();

                    item.fuel = Fuel;
                    item.condition = Condition;

                    if (MaxCondition != -1)
                        item.maxCondition = MaxCondition;

                    if (Contents != null)
                        foreach (var contentItem in Contents)
                            contentItem.ToItem().MoveToContainer(item.contents);
                    else
                        item.contents = null;

                    if (magazine != null)
                    {
                        magazine.contents = Ammo;
                        magazine.ammoType = ItemManager.FindItemDefinition(AmmoType);
                    }

                    if (flameThrower != null)
                        flameThrower.ammo = FlameFuel;

                    if (item.instanceData != null)
                        item.instanceData.dataInt = DataInt;

                    return item;
                }

                public static BackpackItem FromItem(Item item) => new BackpackItem
                {
                    ID = item.info.itemid,
                    Position = item.position,
                    Ammo = item.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine?.contents ?? 0,
                    AmmoType = item.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine?.ammoType?.itemid ?? 0,
                    Amount = item.amount,
                    Condition = item.condition,
                    MaxCondition = item.maxCondition,
                    Fuel = item.fuel,
                    Skin = item.skin,
                    Contents = item.contents?.itemList?.Select(FromItem).ToList(),
                    FlameFuel = item.GetHeldEntity()?.GetComponent<FlameThrower>()?.ammo ?? 0,
                    IsBlueprint = item.IsBlueprint(),
                    BlueprintTarget = item.blueprintTarget,
                    DataInt = item.instanceData?.dataInt ?? 0
                };
            }
        }

        public enum StorageSize
        {
            Large = 3,
            Medium = 2,
            Small = 1
        }

        #endregion

        #region Container Related

        public static string GetContainerPrefab(StorageSize size)
        {
            switch (size)
            {
                case StorageSize.Large:
                    return "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab";
                case StorageSize.Medium:
                    return "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab";
                case StorageSize.Small:
                    return "assets/prefabs/deployable/small stash/small_stash_deployed.prefab";
            }

            return null;
        }

        private static BaseEntity SpawnContainer(StorageSize size = StorageSize.Medium, Vector3 position = default(Vector3))
        {
            var ent = GameManager.server.CreateEntity(GetContainerPrefab(size), position);

            ent.UpdateNetworkGroup();
            ent.SendNetworkUpdateImmediate();

            ent.globalBroadcast = true;

            ent.Spawn();

            return ent;
        }

        private static void PlayerLootContainer(BasePlayer player, StorageContainer container)
        {
            container.SetFlag(BaseEntity.Flags.Open, true);
            player.inventory.loot.StartLootingEntity(container, false);
            player.inventory.loot.AddContainer(container.inventory);
            player.inventory.loot.SendImmediate();
            player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", container.panelName);
            container.DecayTouch();
            container.SendNetworkUpdate();
        }

        #endregion

        #region Loading

        private void LoadMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["No Permission"] = "You don't have permission to use this command.",
                ["Backpack Already Open"] = "Somebody already has this backpack open!",
                ["May Not Open Backpack In Event"] = "You may not open a backpack while participating in an event!"
            }, this);
        }

        private new void LoadConfig()
        {
            Configuration.BackpackSizeInt = GetConfig(Configuration.BackpackSizeInt, "Backpack Size (1-3)");

            GetConfig(ref Configuration.DropOnDeath, "Drop On Death");
            GetConfig(ref Configuration.EraseOnDeath, "Erase On Death");

            GetConfig(ref Configuration.ShowOnBack, "Show On Back");
            GetConfig(ref Configuration.HideOnBackIfEmpty, "Hide On Back If Empty");

            GetConfig(ref Configuration.UseBlacklist, "Use Blacklist");
            GetConfig(ref Configuration.BlacklistedItems, "Blacklisted Items (Item Shortnames)");

            SaveConfig();
        }

        protected override void LoadDefaultConfig() => PrintWarning("Generating new configuration file...");

        #endregion

        #region Hooks

        private void Loaded()
        {
            _instance = this;

            LoadConfig();
            LoadMessages();

            permission.RegisterPermission("backpacks.use", this);
            permission.RegisterPermission("backpacks.use.small", this);
            permission.RegisterPermission("backpacks.use.medium", this);
            permission.RegisterPermission("backpacks.use.large", this);
            permission.RegisterPermission("backpacks.admin", this);

            foreach (var basePlayer in BasePlayer.activePlayerList)
            {
                try
                {
                    OnPlayerInit(basePlayer);
                }
                catch (Exception)
                {
                }
            }
        }

        private void Unload()
        {
            foreach (var backpack in _backpacks.Values)
            {
                if (backpack.IsOpen)
                    backpack.ForceClose();

                backpack.RemoveVisual();
            }

            foreach (var basePlayer in BasePlayer.activePlayerList)
                OnPlayerDisconnected(basePlayer);
        }

        private void OnPlayerInit(BasePlayer player)
        {
	        if (player is NPCPlayer)
		        return;

            var backpack = Backpack.LoadOrCreate(player.userID);

            if (permission.UserHasPermission(player.UserIDString, "backpacks.use") && Configuration.ShowOnBack)
            {
                if (backpack.Inventory.Items.Count == 0 && Configuration.HideOnBackIfEmpty)
                    return;

                backpack.SpawnVisual(player);
            }
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            if (_backpacks.ContainsKey(player.userID))
                _backpacks.Remove(player.userID);
        }

        private object CanAcceptItem(ItemContainer container, Item item)
        {
            if (!Configuration.UseBlacklist)
                return null;

            // Is the Item blacklisted and the target container is a backpack?
            if (Configuration.BlacklistedItems.Any(i => i.ToString() == item.info.shortname) &&
                _backpacks.Values.Any(b => b.Container != null && b.Container.inventory == container))
                return ItemContainer.CanAcceptResult.CannotAccept;

            return null;
        }

        private void OnUserPermissionGranted(string id, string perm)
        {
            if (perm == "backpacks.use" && Configuration.ShowOnBack)
            {
                var player = BasePlayer.Find(id);
                var backpack = Backpack.LoadOrCreate(player.userID);

                if (backpack.Inventory.Items.Count == 0 && Configuration.HideOnBackIfEmpty)
                    return;

                backpack.SpawnVisual(player);
            }
        }

        private void OnEntityDeath(BaseCombatEntity victim, HitInfo info)
        {
            if (victim is BasePlayer && !(victim is NPCPlayer))
            {
                var player = (BasePlayer)victim;
                var backpack = Backpack.LoadOrCreate(player.userID);

                backpack.ForceClose();

                if (Configuration.EraseOnDeath)
                    backpack.EraseContents();
                else if (Configuration.DropOnDeath)
                    backpack.Drop(player.transform.position);
            }
        }

		/* Work in progress
        private object CanBaseEntityNetworkTo(BaseEntity entity, BasePlayer target)
        {
            return null;

            var backpack = entity.GetComponent<VisualBackpack>();

            if (backpack?.Backpack?.ownerID == target.userID)
                return false;

            return null;
        }
		*/

        #endregion

        #region Commands

        [ChatCommand("backpack")]
        private void OpenBackpackChatCommand(BasePlayer player, string cmd, string[] args)
        {
            if (permission.UserHasPermission(player.UserIDString, "backpacks.use"))
                timer.Once(0.1f, () => Backpack.LoadOrCreate(player.userID).Open(player));
            else
                PrintToChat(player, lang.GetMessage("No Permission", this, player.UserIDString));
        }

        [ConsoleCommand("backpack.open")]
        private void OpenBackpackConsoleCommand(ConsoleSystem.Arg arg)
        {
            if (arg.Player() == null)
                return;

            BasePlayer player = arg.Player();

            if (permission.UserHasPermission(player.UserIDString, "backpacks.use"))
                Backpack.LoadOrCreate(player.userID).Open(player);
        }

        [ChatCommand("viewbackpack")]
        private void ViewBackpack(BasePlayer player, string cmd, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "backpacks.admin"))
            {
                PrintToChat(player, lang.GetMessage("No Permission", this, player.UserIDString));
                return;
            }

            if (args.Length != 1)
            {
                PrintToChat(player, "Syntax: /viewbackpack <steamid>");
                return;
            }

            ulong id;

            if (!ulong.TryParse(args[0], out id) || !args[0].StartsWith("7656119") || args[0].Length != 17)
            {
                PrintToChat(player, $"{args[0]} is not a valid SteamID (64)!");
                return;
            }

            Backpack backpack = Backpack.LoadOrCreate(id);

            if (backpack.IsOpen)
            {
                PrintToChat(player, lang.GetMessage("Backpack Already Open", this, player.UserIDString));
                return;
            }

            timer.Once(0.5f, () => backpack.Open(player));
        }

        #endregion

        #region Data & Config Helper

        private static void GetConfig<T>(ref T variable, params string[] path) => variable = GetConfig(variable, path);

        private static T GetConfig<T>(T defaultValue, params string[] path)
        {
            if (path.Length == 0)
                return defaultValue;

            if (_instance.Config.Get(path) == null)
            {
                _instance.Config.Set(path.Concat(new object[] { defaultValue }).ToArray());
                _instance.PrintWarning($"Added field to config: {string.Join("/", path)}");
            }

            return (T)Convert.ChangeType(_instance.Config.Get(path), typeof(T));
        }

        private string DataFileName => Title.Replace(" ", "");

        private static void LoadData<T>(ref T data, string filename = null) => data = Core.Interface.Oxide.DataFileSystem.ReadObject<T>(filename ?? _instance.DataFileName);

        private static void SaveData<T>(T data, string filename = null) => Core.Interface.Oxide.DataFileSystem.WriteObject(filename ?? _instance.DataFileName, data);

        #endregion
    }
}

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