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

FREE SkillTreeItems : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
	[Info("SkillTreeItems", "imthenewguy", "1.0.0")]
	[Description("Lootable items that give xp and skill points")]
	class SkillTreeItems : RustPlugin
	{
        #region Config       

        private Configuration config;
        public class Configuration
        {
            [JsonProperty("XP items")]
            public STItemInfo xp_items;

            [JsonProperty("Skill point items")]
            public STItemInfo sp_items;

            [JsonProperty("Manage item stacking? (set to false if using any sort of stacks plugin)")]
            public bool manage_stacks = true;

            public string ToJson() => JsonConvert.SerializeObject(this);

            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }

        protected override void LoadDefaultConfig()
        {
            config = new Configuration();
            config.xp_items = DefaultXPItems;
            config.sp_items = DefaultSPItems;
        }

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

                if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
                {
                    PrintToConsole("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch
            {
                PrintToConsole($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig()
        {
            PrintToConsole($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }

        #endregion

        #region Default Config

        Dictionary<string, float> DefaultLootContainersXP
        {
            get
            {
                return new Dictionary<string, float>()
                {
                    ["crate_normal_2"] = 1f,
                    ["crate_normal"] = 3f,
                    ["crate_elite"] = 15f,
                    ["crate_underwater_basic"] = 6f,
                    ["crate_underwater_advanced"] = 12f,
                    ["heli_crate"] = 10f,
                    ["bradley_crate"] = 10f,
                    ["codelockedhackablecrate"] = 10f,
                    ["codelockedhackablecrate_oilrig"] = 10f,
                    ["crate_tools"] = 1.5f
                };
            }
        }

        Dictionary<string, float> DefaultLootContainersSP
        {
            get
            {
                return new Dictionary<string, float>()
                {
                    ["crate_normal_2"] = 0f,
                    ["crate_normal"] = 0f,
                    ["crate_elite"] = 0f,
                    ["crate_underwater_basic"] = 0f,
                    ["crate_underwater_advanced"] = 1f,
                    ["heli_crate"] = 1f,
                    ["bradley_crate"] = 1f,
                    ["codelockedhackablecrate"] = 1f,
                    ["codelockedhackablecrate_oilrig"] = 1f,
                    ["crate_tools"] = 0f
                };
            }
        }

        STItemInfo DefaultXPItems
        {
            get
            {
                return new STItemInfo("xmas.present.small", "unwrap", DefaultSTXPItems, DefaultLootContainersXP);
            }
        }

        STItemInfo DefaultSPItems
        {
            get
            {
                return new STItemInfo("xmas.present.small", "unwrap", DefaultSTSPItems, DefaultLootContainersSP);
            }
        }

        List<STItem> DefaultSTXPItems
        {
            get
            {
                return new List<STItem>()
                {
                    new STItem(700, 1100, 2863540162, "research notes", 100),
                    new STItem(1000, 1500, 2863539973, "research notes", 50),
                    new STItem(1400, 2200, 2863540007, "research notes", 20),
                    new STItem(2000, 5000, 2863540048, "research notes", 5)
                };
            }
        }

        List<STItem> DefaultSTSPItems
        {
            get
            {
                return new List<STItem>()
                {
                    new STItem(1, 1, 2863540521, "tome of skill points", 200),
                    new STItem(1, 2, 2863539781, "tome of skill points", 40),
                    new STItem(2, 3, 2863539851, "tome of skill points", 15),
                    new STItem(2, 4, 2863539914, "tome of skill points", 3)
                };
            }
        }

        #endregion

        #region Data

        [PluginReference]
        private Plugin SkillTree;

        const string perm_use = "skilltreeitems.use";
        const string perm_admin = "skilltreeitems.admin";

        void Init()
        {
            if (!config.manage_stacks)
            {
                Unsubscribe(nameof(CanStackItem));
                Unsubscribe(nameof(CanCombineDroppedItem));
            }
            permission.RegisterPermission(perm_use, this);
            permission.RegisterPermission(perm_admin, this);
        }

        void Unload()
        {
            Monitored_actions.Clear();
            Monitored_actions = null;
        }

        #endregion;

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["givexpitemUsage"] = "Usage: givexpitem <amount> <skin ID> <display name>",
                ["givespitemUsage"] = "Usage: givespitem <amount> <skin ID> <display name>",
                ["givespitemtoUsage"] = "Usage: givespitemto <target ID> <amount> <skin ID> <display name>",
                ["givexpitemtoUsage"] = "Usage: givexpitemto <target ID> <amount> <skin ID> <display name>",
                ["giverandomxpitemUsage"] = "Usage giverandomxpitem <target ID>",
                ["giverandomxpitemNoMatch"] = "No ID matched {0}",
                ["giverandomxpitemConfirmation"] = "Gave 1x {0} to {1}",
                ["giverandomxpitemToTarget"] = "You received 1x {0}",                
                ["giverandomspitemUsage"] = "Usage giverandomspitem <target ID>",
                ["giverandomspitemNoMatch"] = "No ID matched {0}",
                ["giverandomspitemConfirmation"] = "Gave 1x {0} to {1}",
                ["giverandomspitemToTarget"] = "You received 1x {0}"
            }, this);
        }

        #endregion

        #region classes

        public class STItemInfo
        {
            [JsonProperty("Base item shortname")]
            public string shortname;

            [JsonProperty("Action that is called when using the item")]
            public string action_string = "unwrap";

            [JsonProperty("List of items that will be added to containers")]
            public List<STItem> items = new List<STItem>();

            [JsonProperty("List of containers that these items can drop from [%] [0=disabled]")]
            public Dictionary<string, float> drop_chance;

            public STItemInfo(string shortname, string action_string, List<STItem> items, Dictionary<string, float> drop_chance)
            {
                this.shortname = shortname;
                this.action_string = action_string;
                this.items = items;
                this.drop_chance = drop_chance;
            }
        }

        public class STItem
        {
            [JsonProperty("Skin ID")]
            public ulong skin;

            [JsonProperty("Minimum XP/Points given for using")]
            public int min;

            [JsonProperty("Maximum XP/Points given for using")]
            public int max;

            [JsonProperty("Display name of the item")]
            public string displayName;

            [JsonProperty("Drop weight [chance]")]
            public int dropWeight;

            public STItem(int min, int max, ulong skin = 0, string displayName = null, int dropWeight = 100)
            {
                this.skin = skin;
                this.min = min;
                this.max = max;
                this.displayName = displayName;
                this.dropWeight = dropWeight;
            }
        }

        #endregion

        #region enums

        enum ItemType
        {
            XP,
            SP
        }

        #endregion

        #region commands

        [ChatCommand("givexpitem")]
        void GiveXPItem(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            if (config.xp_items.items.Count == 0) return;
            if (args == null || args.Length < 4)
            {
                PrintToChat(player, lang.GetMessage("givexpitemUsage", this, player.UserIDString));
                return;
            }

            if (args == null || args.Length < 3)
            {
                PrintToChat(player, lang.GetMessage("givexpitemUsage", this, player.UserIDString));
                return;
            }

            var amount = Convert.ToInt32(args[0]);
            if (amount < 1) amount = 1;

            ulong skin = Convert.ToUInt64(args[1]);

            string displayName = string.Join(" ", args.Skip(2));

            GiveItem(player, amount, skin, displayName, ItemType.XP);
        }

        [ChatCommand("givespitem")]
        void GiveSPItem(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            if (config.sp_items.items.Count == 0) return;
            if (args == null || args.Length < 4)
            {
                PrintToChat(player, lang.GetMessage("givespitemUsage", this, player.UserIDString));
                return;
            }

            if (args == null || args.Length < 3)
            {
                PrintToChat(player, lang.GetMessage("givespitemUsage", this, player.UserIDString));
                return;
            }

            var amount = Convert.ToInt32(args[0]);
            if (amount < 1) amount = 1;

            ulong skin = Convert.ToUInt64(args[1]);

            string displayName = string.Join(" ", args.Skip(2));

            GiveItem(player, amount, skin, displayName, ItemType.SP);
        }

        [ConsoleCommand("givespitemto")]
        void GiveSPItemTo(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            // Target amount skin
            if (arg.Args == null || arg.Args.Length < 4)
            {
                arg.ReplyWith(lang.GetMessage("givespitemtoUsage", this, player.UserIDString ?? null));
                return;
            }
            var target = FindPlayerByID(arg.Args[0]);
            if (target == null) return;
            var amount = Convert.ToInt32(arg.Args[1]);
            if (amount < 1) amount = 1;
            ulong skin = Convert.ToUInt64(arg.Args[2]);
            string displayName = string.Join(" ", arg.Args.Skip(3));
            GiveItem(target, amount, skin, displayName, ItemType.SP);
        }

        [ConsoleCommand("givexpitemto")]
        void GiveXPItemTo(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            // Target amount skin
            if (arg.Args == null || arg.Args.Length < 4)
            {
                arg.ReplyWith(lang.GetMessage("givexpitemtoUsage", this, player.UserIDString ?? null));
                return;
            }
            var target = FindPlayerByID(arg.Args[0]);
            if (target == null) return;

            var amount = Convert.ToInt32(arg.Args[1]);
            if (amount < 1) amount = 1;

            ulong skin = Convert.ToUInt64(arg.Args[2]);

            string displayName = string.Join(" ", arg.Args.Skip(3));

            GiveItem(target, amount, skin, displayName, ItemType.XP);
        }

        [ConsoleCommand("giverandomxpitem")]
        void GiveRandomXPItem(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            if (arg.Args == null || arg.Args.Length == 0)
            {
                arg.ReplyWith(lang.GetMessage("giverandomxpitemUsage", this, player.UserIDString ?? null));
                return;
            }
            var target = FindPlayerByID(arg.Args[0], player ?? null);
            if (target == null)
            {
                arg.ReplyWith(string.Format(lang.GetMessage("giverandomxpitemNoMatch", this, player.UserIDString ?? null), arg.Args[0]));
                return;
            }

            List<STItem> items = Pool.GetList<STItem>();
            foreach (var item in config.xp_items.items)
            {
                if (item.max <= 0) continue;
                if (!items.Contains(item)) items.Add(item);
            }

            if (items.Count > 0)
            {
                var randProfile = items.GetRandom();
                var randItem = CreateXPItem(1, randProfile.min, randProfile.max, randProfile.skin, randProfile.displayName);
                if (randItem != null) target.GiveItem(randItem);
                PrintToChat(target, string.Format(lang.GetMessage("giverandomxpitemToTarget", this, player.UserIDString ?? null), randItem.name));
                arg.ReplyWith(string.Format(lang.GetMessage("giverandomxpitemConfirmation", this, player.UserIDString ?? null), randItem.name, target.displayName));
            }

            Pool.FreeList(ref items);
        }

        [ConsoleCommand("giverandomspitem")]
        void GiveRandomSPItem(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, perm_admin)) return;
            if (arg.Args == null || arg.Args.Length == 0)
            {
                arg.ReplyWith(lang.GetMessage("giverandomspitemUsage", this, player.UserIDString ?? null));
                return;
            }
            var target = FindPlayerByID(arg.Args[0], player ?? null);
            if (target == null)
            {
                arg.ReplyWith(string.Format(lang.GetMessage("giverandomspitemNoMatch", this, player.UserIDString ?? null), arg.Args[0]));
                return;
            }

            List<STItem> items = Pool.GetList<STItem>();
            foreach (var item in config.sp_items.items)
            {
                if (item.max <= 0) continue;
                if (!items.Contains(item)) items.Add(item);
            }

            if (items.Count > 0)
            {
                var randProfile = items.GetRandom();
                var randItem = CreateSPItem(1, randProfile.min, randProfile.max, randProfile.skin, randProfile.displayName);
                if (randItem != null) target.GiveItem(randItem);
                PrintToChat(target, string.Format(lang.GetMessage("giverandomspitemToTarget", this, player.UserIDString ?? null), randItem.name));
                arg.ReplyWith(string.Format(lang.GetMessage("giverandomspitemConfirmation", this, player.UserIDString ?? null), randItem.name, target.displayName));
            }

            Pool.FreeList(ref items);
        }

        #endregion

        #region oxide hooks

        void OnServerInitialized(bool initial)
        {
            if (SkillTree == null || !SkillTree.IsLoaded)
            {
                Puts("SkillTree is required to run this plugin.");
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            bool require_save = false;

            if (config.xp_items == null || config.xp_items.items?.Count == 0)
            {
                config.xp_items = DefaultXPItems;
                require_save = true;
            }

            if (config.sp_items == null || config.sp_items.items?.Count == 0)
            {
                config.sp_items = DefaultSPItems;
                require_save = true;
            }

            if (config.xp_items.drop_chance == null || config.xp_items.drop_chance.Count == 0)
            {
                config.xp_items.drop_chance = DefaultLootContainersXP;
                require_save = true;
            }

            if (config.sp_items.drop_chance == null || config.sp_items.drop_chance.Count == 0)
            {
                config.sp_items.drop_chance = DefaultLootContainersSP;
                require_save = true;
            }

            if (require_save) SaveConfig();

            if (!Monitored_actions.Contains(config.xp_items.action_string)) Monitored_actions.Add(config.xp_items.action_string);
            if (!Monitored_actions.Contains(config.sp_items.action_string)) Monitored_actions.Add(config.sp_items.action_string);           
        }

        object CanStackItem(Item item, Item targetItem)
        {
            if (item == null || targetItem == null) return null;
            if (IsXPItem(targetItem) || IsXPItem(item)) return false;
            return null;
        }

        object CanCombineDroppedItem(DroppedItem item, DroppedItem targetItem)
        {
            return CanStackItem(item.item, targetItem.item);
        }

        List<string> Monitored_actions = new List<string>();

        object OnItemAction(Item item, string action, BasePlayer player)
        {
            if (item == null || player == null) return null;
            if (Monitored_actions.Contains(action))
            {
                if (IsXPItem(item))
                {
                    if (!permission.UserHasPermission(player.UserIDString, perm_use))
                    {
                        PrintToChat(player, "You do not have permission to use this item.");
                        return true;
                    }
                    var xp = (double)GetXPAmount(item.name);
                    SkillTree.Call("AwardXP", player, xp);
                    PrintToChat(player, $"You gained {xp} xp from your {item.name.Split('[', ']')[0]}.");
                    item.RemoveFromContainer();
                    NextTick(() => item.Remove());
                    return true;
                }
                else if (IsSPItem(item))
                {
                    if (!permission.UserHasPermission(player.UserIDString, perm_use))
                    {
                        PrintToChat(player, "You do not have permission to use this item.");
                        return true;
                    }
                    var sp = GetSPAmount(item.name);
                    SkillTree.Call("GiveSkillPoints", player, sp);
                    PrintToChat(player, $"Вы получили {sp} очков навыков от {item.name.Split('(', ')')[0]}.");
                    item.RemoveFromContainer();
                    NextTick(() => item.Remove());
                    return true;
                }
            }
            if (action == "upgrade_item" && (IsXPItem(item) || IsSPItem(item))) return true;
            return null;
        }

        void OnEntityKill(LootContainer entity)
        {
            if (entity == null) return;
            looted_containers.Remove(entity);
        }

        #endregion

        #region methods

        BasePlayer FindPlayerByID(string id, BasePlayer searchingPlayer = null)
        {
            if (!id.IsSteamId()) return null;
            var player = BasePlayer.activePlayerList.Where(x => x.UserIDString == id).FirstOrDefault();
            if (player == null)
            {
                if (searchingPlayer != null) PrintToChat(searchingPlayer, $"No player found matching ID: {id}");
                else Puts($"No player found matching ID: {id}");
            }
            return player ?? null;
        }

        bool IsSPItem(Item item)
        {
            return item.info.shortname == config.sp_items.shortname && item.name != null && GetSPAmount(item.name) > 0;
        }

        int GetSPAmount(string name)
        {
            if (string.IsNullOrEmpty(name)) return 0;
            var splitString = name.Split('(', ')');
            if (splitString == null || splitString.Length < 2) return 0;
            var result = Convert.ToInt32(splitString[1]);
            return result;
        }

        bool IsXPItem(Item item)
        {
            return item.info.shortname == config.xp_items.shortname && item.name != null && GetXPAmount(item.name) > 0;            
        }

        int GetXPAmount(string name)
        {
            if (string.IsNullOrEmpty(name)) return 0;
            var splitString = name.Split('[', ']');
            if (splitString == null || splitString.Length < 2) return 0;            
            var result = Convert.ToInt32(splitString[1]);
            return result;
        }

        Item CreateXPItem(int amount, int xp_min, int xp_max, ulong skin = 0, string displayName = null)
        {
            var item = ItemManager.CreateByName(config.xp_items.shortname, amount, skin);
            if (item == null) return null;

            int xp = UnityEngine.Random.Range(xp_min, xp_max + 1);
            item.name = !string.IsNullOrEmpty(displayName) ? $"{displayName} [{xp}]" : $"{item.info.displayName.english} [{xp}]";

            return item;
        }

        Item CreateSPItem(int amount, int xp_min, int xp_max, ulong skin = 0, string displayName = null)
        {
            var item = ItemManager.CreateByName(config.sp_items.shortname, amount, skin);
            if (item == null) return null;
            int xp = UnityEngine.Random.Range(xp_min, xp_max + 1);
            item.name = !string.IsNullOrEmpty(displayName) ? $"{displayName} ({xp})" : $"{item.info.displayName.english} ({xp})";
            return item;
        }

        // player == target.void GiveItem(BasePlayer player, STItem def, int amount, ItemType type)
        {
            if (def == null) return;
            var item = type == ItemType.XP ? CreateXPItem(1, def.min, def.max, def.skin, def.displayName ?? null) : CreateSPItem(Math.Max(amount, 1), def.min, def.max, def.skin, def.displayName ?? null);
            if (item != null) player.GiveItem(item);
        }

        void GiveItem(BasePlayer player, int quantity, ulong skin, string displayName, ItemType type)
        {
            var item = type == ItemType.XP ? CreateXPItem(1, quantity, quantity, skin, displayName ?? null) : CreateSPItem(1, quantity, quantity, skin, displayName ?? null);
            if (item != null) player.GiveItem(item);
        }

        bool RollSuccessful(float luck)
        {            
            var roll = UnityEngine.Random.Range(0f, 100f);
            return (roll > 100f - luck);
        }

        #endregion

        #region loot

        List<LootContainer> looted_containers = new List<LootContainer>();

        object CanLootEntity(BasePlayer player, StorageContainer container)
        {
            if (container == null) return null;
            LootContainer lootContainer;            
            if ((lootContainer = container.GetEntity() as LootContainer) && lootContainer != null && !looted_containers.Contains(lootContainer))
            {
                looted_containers.Add(lootContainer);

                if (permission.UserHasPermission(player.UserIDString, perm_use))
                {
                    float chance;
                    if (config.xp_items.drop_chance.TryGetValue(lootContainer.ShortPrefabName, out chance) && RollSuccessful(chance)) RollItem(ItemType.XP, lootContainer);
                    if (config.sp_items.drop_chance.TryGetValue(lootContainer.ShortPrefabName, out chance) && RollSuccessful(chance)) RollItem(ItemType.SP, lootContainer);
                }                
            }
            return null;
        }

        void RollItem(ItemType type, LootContainer container)
        {
            if (type == ItemType.XP)
            {
                int totalWeight = config.xp_items.items.Sum(x => x.dropWeight);
                int count = 0;
                int roll = UnityEngine.Random.Range(0, totalWeight + 1);
                foreach (var data in config.xp_items.items)
                {
                    count += data.dropWeight;
                    if (roll <= count)
                    {
                        var item = CreateXPItem(1, data.min, data.max, data.skin, data.displayName);
                        if (item != null)
                        {
                            container.inventory.capacity++;
                            container.inventorySlots++;
                            item.MoveToContainer(container.inventory);
                        }
                        return;
                    }
                }
            }
            else
            {
                int totalWeight = config.sp_items.items.Sum(x => x.dropWeight);
                int count = 0;
                int roll = UnityEngine.Random.Range(0, totalWeight + 1);
                foreach (var data in config.sp_items.items)
                {
                    count += data.dropWeight;
                    if (roll <= count)
                    {
                        var item = CreateSPItem(1, data.min, data.max, data.skin, data.displayName);
                        if (item != null)
                        {
                            container.inventory.capacity++;
                            container.inventorySlots++;
                            item.MoveToContainer(container.inventory);
                        }
                        return;
                    }
                }
            }
        }

        #endregion
    }
}

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