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

FREE Professions : 1.0.3 1.0.3

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Professions", "imthenewguy", "1.0.3")]
    [Description("Professions")]
    class Professions : RustPlugin {
#region Config
        private Configuration config;
        public class Configuration {
            [JsonProperty("Prime meat default chance [%]")]
            public float prime_meat_default = 1f;
            [JsonProperty("Prime meat professional chance [%]")]
            public float prime_meat_professional = 4f;
            [JsonProperty("Prime meat chance increase per level [%]")]
            public float prime_meat_chance_per_level = 0.1f;
            [JsonProperty("Skinning experience per hit")]
            public float skinner_xp_per_hit = 8f;
            [JsonProperty("Skinning experience animal modifier", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, float> skinner_modifier = new Dictionary<string, float>();
            [JsonProperty("Skinner tools", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> skinner_tools;
            [JsonProperty("Enable animal tracking for skinners using the /track command")]
            public bool tracking_enabled = true;
            [JsonProperty("Time delay between tracking attempts")]
            public float tracking_delay = 5;
            [JsonProperty("Gold nugget default chance [%]")]
            public float gold_nugget_default = 1f;
            [JsonProperty("Gold nugget professional chance [%]")]
            public float gold_nugget_professional = 4f;
            [JsonProperty("Gold nugget chance increase per level [%]")]
            public float gold_nugget_chance_per_level = 0.1f;
            [JsonProperty("Mining experience per hit")]
            public float miner_xp_per_hit = 7f;
            [JsonProperty("Miner tools", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> miner_tools;
            [JsonProperty("Jackhammer xp modifier [1.0 = full xp per hit]")]
            public double jackhammer_xp_modifier = 0.4;
            [JsonProperty("Allow jackhammer to obtain gold nuggets?")]
            public bool allow_jackhammer_drops = false;
            [JsonProperty("Pinecone default chance [%]")]
            public float pinecone_default = 1f;
            [JsonProperty("Pinecone professional chance [%]")]
            public float pinecone_professional = 4f;
            [JsonProperty("Pinecone chance increase per level [%]")]
            public float pinecone_chance_per_level = 0.1f;
            [JsonProperty("Logging experience per hit")]
            public float logger_xp_per_hit = 5f;
            [JsonProperty("Logger tools", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> logger_tools;
            [JsonProperty("Chainsaw xp modifier [1.0 = full xp per hit]")]
            public double chainsaw_xp_modifier = 0.05;
            [JsonProperty("Allow chainsaws to obtain pinecones?")]
            public bool allow_chainsaw_drops = false;
            [JsonProperty("Experience increase per level for gathering skills")]
            public double xp_increase = 100f;
            public double xp_additive = 20f;
            public int max_level = 50;
            [JsonProperty("Additional resources per level [%]")]
            public double gather_yield_per_level = 2;
            [JsonProperty("Item information", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, Iteminfo> item_info = new Dictionary<string, Iteminfo>();
            [JsonProperty("Experience required for crafting level 1")]
            public double crafting_level_1 = 100;
            [JsonProperty("Experience required for crafting level 2")]
            public double crafting_level_2 = 1100;
            [JsonProperty("Experience required for crafting level 3")]
            public double crafting_level_3 = 4100;
            [JsonProperty("Cost to change class?")]
            public float ClassChangeCost = 0;
            [JsonProperty("Job information", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, JobInfo> job_info = new Dictionary<string, JobInfo>();
            [JsonProperty("Job info font size")]
            public int JobInfoFontSize = 12;
            [JsonProperty("Add a warning at the bottom of the job info page telling players that their xp will be reset if they change roles?")]
            public bool job_change_warning_text = true;
            [JsonProperty("Component xp", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, float> component = new Dictionary<string, float>();
            [JsonProperty("Research xp multiplier")]
            public double research_xp_multiplier = 3;
            [JsonProperty("Crafting level is required to craft items (setting to false will allow crafters of any level to craft all tiers of items)")]
            public bool crafting_level_required = true;
            [JsonProperty("Allow the use of resource bags")]
            public bool allow_resource_bags = true;
            [JsonProperty("Allow users to access the resource bag via chat command [requires professions.chat.bag permissions]")]
            public bool bag_chat_command_allow = true;
            [JsonProperty("Chat command to open the resource bag")]
            public string bag_chat_cmd = "rbag";
            [JsonProperty("Max stack size when the item is placed in the bag from gathering?")]
            public int max_stack_size_in_bag = 10;
            [JsonProperty("What method should we use to handle crafting - [0 = Prevent craft, 1 = Tax economics, 2 = Tax scrap")]
            public CraftMethod craft_method = CraftMethod.TaxEcon;
            [JsonProperty("Currency to use for market and quitting [economics, scrap]")]
            public string currency = "economics";
            [JsonProperty("Chat command to open the market [requires professions.chat.market permissions]")]
            public string market_chat_cmd = "pmarket";
            [JsonProperty("Name of the human NPC that will open the store.")]
            public string market_npc_name = "resource market";
            [JsonProperty("IDs of NPCs that will open the market", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> market_npc_ids = new List<ulong>();
            [JsonProperty("Chat command to open the job menu [requires professions.chat.jobmenu permissions]")]
            public string jobmenu_chat_cmd = "jobmenu";
            [JsonProperty("Name of the human NPC that will open the job menu.")]
            public string job_npc_name = "centrelink";
            [JsonProperty("Send a message showing what % of players are the selected profession when using the menu")]
            public bool send_profession_msg = true;
            [JsonProperty("IDs of NPCs that will open the job menu", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> job_npc_ids = new List<ulong>();
            [JsonProperty("Tier 1 default items tax")]
            public int default_tax_items_tier_1 = 50;
            [JsonProperty("Tier 2 default items tax")]
            public int default_tax_items_tier_2 = 125;
            [JsonProperty("Tier 3 default items tax")]
            public int default_tax_items_tier_3 = 500;
            [JsonProperty("Delete the NPC vending machines that sell car parts on wipe?")]
            public bool delete_carpart_vendors = false;
            [JsonProperty("Disable crafting professions?")]
            public bool disable_crafting_professions = false;
            [JsonProperty("Better chat titles", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, TitleInfo> titles = new Dictionary<string, TitleInfo>() {
                {
                    "logger", new TitleInfo() {
                        title = "Logger", colour = "#6D3D23"
                    }
                }
                , {
                    "miner", new TitleInfo() {
                        title = "Miner", colour = "#556F80"
                    }
                }
                , {
                    "skinner", new TitleInfo() {
                        title = "Skinner", colour = "#A92727"
                    }
                }
                , {
                    "weaponsmith", new TitleInfo() {
                        title = "Weaponsmith", colour = "#1A2C41"
                    }
                }
                , {
                    "tailor", new TitleInfo() {
                        title = "Tailor", colour = "#B1D94E"
                    }
                }
                , {
                    "electrician", new TitleInfo() {
                        title = "Electrician", colour = "#F3C920"
                    }
                }
                , {
                    "mechanic", new TitleInfo() {
                        title = "Mechanic", colour = "#5979DE"
                    }
                }
                ,
            }
            ;
            public class JobInfo {
                public string description;
                public string img;
            }
            public class Iteminfo {
                public string shortname;
                public ulong skin;
                public string displayName;
                public int quantity = 1;
                public int sell_price = 10;
            }
            public class TitleInfo {
                public string title;
                public string colour;
            }
            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }
        PCDInfo playerData;
        public enum CraftMethod {
            PreventCraft, TaxEcon, TaxScrap
        }
        private void LevelCrafting(BasePlayer player, double xp) {
            if (config.disable_crafting_professions) return;
            if (!pcdData.pEntity.TryGetValue(player.userID, out playerData)) {
                SetupPlayer(player);
                playerData = pcdData.pEntity[player.userID];
            }
            if (playerData.level == 3) return;
            playerData.xp += xp;
            if (playerData.xp >= config.crafting_level_1) {
                if (playerData.xp >= config.crafting_level_2) {
                    if (playerData.xp >= config.crafting_level_3) {
                        if (playerData.level == 2) PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("CanMakeT", this, player.UserIDString), 3)}");
                        playerData.level = 3;
                        SaveData();
                        return;
                    }
                    if (playerData.level == 1) PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("CanMakeT", this, player.UserIDString), 2)}");
                    playerData.level = 2;
                    SaveData();
                    return;
                }
                if (playerData.level == 0) PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("CanMakeT", this, player.UserIDString), 1)}");
                playerData.level = 1;
                SaveData();
                return;
            }
        }
        protected override void LoadDefaultConfig() {
            config = new Configuration();
            foreach (var animal in new string[] {
                "chicken", "bear", "boar", "horse", "stag", "wolf", "shark"
            }
            ) {
                config.skinner_modifier.Add(animal, 1.0f);
            }
            config.skinner_tools = new List<string>() {
                "knife.bone", "knife.butcher", "knife.combat", "rock", "axe.salvaged", "stonehatchet", "hatchet", "hammer.salvaged"
            }
            ;
            config.logger_tools = new List<string>() {
                "rock", "axe.salvaged", "stonehatchet", "hatchet", "hammer.salvaged"
            }
            ;
            config.miner_tools = new List<string>() {
                "rock", "hammer.salvaged", "pickaxe", "stone.pickaxe", "icepick.salvaged"
            }
            ;
            config.item_info = new Dictionary<string, Configuration.Iteminfo>();
            config.item_info.Add("skinner", new Configuration.Iteminfo() {
                shortname = "bearmeat.cooked", skin = 2403118688, displayName = "Prime Meat"
            }
            );
            config.item_info.Add("miner", new Configuration.Iteminfo() {
                shortname = "battery.small", skin = 2405961582, displayName = "Gold Nugget"
            }
            );
            config.item_info.Add("logger", new Configuration.Iteminfo() {
                shortname = "battery.small", skin = 2405963120, displayName = "Pinecone"
            }
            );
            foreach (var profession in professions) {
                config.job_info.Add(profession, new Configuration.JobInfo() {
                    description = GetDefaultDescription(profession), img = GetDefaultImage(profession)
                }
                );
            }
            config.component.Add("targeting.computer", 20f);
            config.component.Add("cctv.camera", 15f);
            config.component.Add("propanetank", 0.5f);
            config.component.Add("metalblade", 0.4f);
            config.component.Add("metalpipe", 1f);
            config.component.Add("metalspring", 4f);
            config.component.Add("riflebody", 10f);
            config.component.Add("roadsigns", 1f);
            config.component.Add("rope", 0.35f);
            config.component.Add("gears", 2f);
            config.component.Add("semibody", 5f);
            config.component.Add("sewingkit", 1.5f);
            config.component.Add("sheetmetal", 4f);
            config.component.Add("smgbody", 5f);
            config.component.Add("tarp", 1.5f);
            config.component.Add("stones", 0.001f);
            config.component.Add("lowgradefuel", 0.005f);
            config.component.Add("cloth", 0.001f);
            config.component.Add("leather", 0.01f);
            config.component.Add("metal.refined", 0.2f);
            config.component.Add("metal.fragments", 0.005f);
            config.component.Add("techparts", 5f);
        }
        string GetDefaultDescription(string job) {
            switch(job) {
                case "miner" : return "Miners make money mining resources.\n\nThey have a higher chance to obtain Gold Nuggets when mining nodes, which can be sold to the Resouce Market.\n\nLevel up your mining to increase the amount of resources you gather, as well as your chance to obtain Gold Nuggets.";
                case "logger" : return "Loggers make money chopping trees.\n\nThey have a higher chance to obtain Pinecones when woodcutting, which can be sold to the Resouce Market.\n\nLevel up your woodcutting to increase the amount of wood you gather, as well as your chance to obtain Pinecones.";
                case "skinner" : return "Skinners make money skinning animals.\nThey have a higher chance to obtain Prime Meat when skinning, which can be sold to the Resouce Market.\nSkinners can also track animals down using the /track command.\nLevel up your skinning to increase the amount of resources you gather, as well as your chance to obtain Prime Meat.";
                case "electrician" : return "Electricians specialize in the production of electrical equipment, from branches and switches, to solar panels and batteries.\nThey can exclusively make, or receive tax breaks when producing the wares that they specialize in.";
                case "weaponsmith" : return "Weaponsmiths specialize in creating weapons from knives and swords, to firearms and explosives.\nThey can exclusively make, or receive tax breaks when producing the wares that they specialize in.";
                case "tailor" : return "Tailors specialize in the creation of clothing and armour.\nThey can exclusively make, or receive tax breaks when producing the wares that they specialize in.";
                case "mechanic" : return "Mechanics specialize in the creation of vehicle modules and engine parts.\nThey can exclusively make, or receive tax breaks when producing the wares that they specialize in.";
            }
            return "Add description here.";
        }
        string GetDefaultImage(string job) {
            switch (job) {
                case "miner" : return "https://i.imgur.com/lm71k74.png";
                case "logger" : return "https://imgur.com/e27vfnW.png";
                case "skinner" : return "https://imgur.com/q0slnz9.png";
                case "electrician" : return "https://imgur.com/oHxhaMO.png";
                case "weaponsmith" : return "https://imgur.com/DpDCQMR.png";
                case "tailor" : return "https://imgur.com/UeLlUhh.png";
                case "mechanic" : return "https://i.imgur.com/6rQI7x6.png";
            }
            return "";
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                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 (Exception ex) {
                UnityEngine.Debug.LogException(ex);
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            PrintToConsole($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }
#endregion
#region Data
        const string default_job = "unemployed";
        public string[] professions = {
            "miner", "logger", "skinner", "electrician", "weaponsmith", "tailor", "mechanic"
        }
        ;
        PlayerEntity pcdData;
        Crafting crafting_info;
        private DynamicConfigFile PCDDATA;
        private DynamicConfigFile CRAFTING;
        void Init() {
            PCDDATA = Interface.Oxide.DataFileSystem.GetFile("Professions/players");
            CRAFTING = Interface.Oxide.DataFileSystem.GetFile("Professions/crafting_info");
            LoadData();
            foreach (var profession in professions) {
                if (!permission.GroupExists(profession)) permission.CreateGroup(profession, "", 0);
            }
            Levels.Add(0, 0);
            for (int i = 1; i < config.max_level + 1; i++) {
                Levels.Add(i, (config.xp_increase * i) + (config.xp_additive * i));
            }
            permission.RegisterPermission("professions.admin", this);
            permission.RegisterPermission("professions.chat.bag", this);
            permission.RegisterPermission("professions.chat.market", this);
            permission.RegisterPermission("professions.chat.jobmenu", this);
        }
        void Unload() {
            SaveData();
            foreach (var player in BasePlayer.activePlayerList) {
                CuiHelper.DestroyUi(player, "Professions_Menu");
                CuiHelper.DestroyUi(player, "Rust Quit UI");
            }
            foreach (var container in containers) {
                if (container.inventory.itemList.Count > 0) {
                    if (container.OwnerID == 0) {
                        Puts("Error - OwnerID is 0");
                        continue;
                    }
                    if (!pcdData.resource_bag.TryGetValue(container.OwnerID, out bagData)) {
                        pcdData.resource_bag.Add(container.OwnerID, new ResourceBag());
                        bagData = pcdData.resource_bag[container.OwnerID];
                    }
                    bagData._storage.Clear();
                    foreach (var item in container.inventory.itemList) {
                        var displayName = item.info.displayName.english;
                        if (item.name != null) displayName = item.name;
                        bagData._storage.Add(new BagInfo() {
                            shortname = item.info.shortname, displayName = displayName, amount = item.amount, slot = item.position, skin = item.skin
                        }
                        );
                    }
                }
                container.Kill();
            }
        }
        public enum SaveType {
            PCDDATA, CRAFTING
        }
        void SaveData(SaveType type = SaveType.PCDDATA) {
            if (type == SaveType.PCDDATA) PCDDATA.WriteObject(pcdData);
            else if (type == SaveType.CRAFTING) CRAFTING.WriteObject(crafting_info);
        }
        void LoadData() {
            try {
                pcdData = Interface.Oxide.DataFileSystem.ReadObject<PlayerEntity>("Professions/players");
            }
            catch {
                Puts("Couldn't load player data, creating new Playerfile");
                pcdData = new PlayerEntity();
            }
            try {
                Puts("Loaded Crafting Info");
                crafting_info = Interface.Oxide.DataFileSystem.ReadObject<Crafting>("Professions/crafting_info");
            }
            catch {
                Puts("Couldn't load crafting data, creating new Playerfile");
                crafting_info = new Crafting();
            }
        }
        class PlayerEntity {
            public Dictionary<ulong, PCDInfo> pEntity = new Dictionary<ulong, PCDInfo>();
            public Dictionary<ulong, ResourceBag> resource_bag = new Dictionary<ulong, ResourceBag>();
        }
        class Crafting {
            public Dictionary<string, CraftingInfo> blueprints = new Dictionary<string, CraftingInfo>();
        }
        class PCDInfo {
            public string name;
            public string profession = default_job;
            public string job_type;
            public int level;
            public double xp;
            public double bonus_chance;
            public int gold_nuggets_acquired;
            public int prime_meat_acquired;
            public int pinecones_acquired;
        }
        class CraftingInfo {
            public List<string> classes = new List<string>();
            public double xp;
            public double xp_multiplier = 1f;
            public double research_xp = 0;
            public int tax;
        }
        List<ulong> skins = new List<ulong>();
        Dictionary<string, double> weaponsmith = new Dictionary<string, double>();
        Dictionary<string, double> electrician = new Dictionary<string, double>();
        Dictionary<string, double> tailor = new Dictionary<string, double>();
        Dictionary<string, double> mechanic = new Dictionary<string, double>();
        string quitText;
        void OnServerInitialized(bool initial) {
            if (ImageLibrary == null) {
                Puts("ImageLibrary is required to run this plugin.");
                Unsubscribe("Unload");
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }
            if (config.craft_method == CraftMethod.PreventCraft) {
                Unsubscribe("OnItemCraftCancelled");
            }
            if (config.disable_crafting_professions) {
                Unsubscribe("CanCraft");
                Unsubscribe("OnItemCraftFinished");
                Unsubscribe("OnItemCraftCancelled");
            }
            if (config.currency.ToLower() == "economics") quitText = string.Format(lang.GetMessage("QuitJob1", this), config.ClassChangeCost);
            else if (config.currency.ToLower() == "scrap") quitText = string.Format(lang.GetMessage("QuitJob2", this), config.ClassChangeCost);
            cmd.AddChatCommand(config.bag_chat_cmd, this, "ResourceBagCommand");
            cmd.AddChatCommand(config.market_chat_cmd, this, "OpenMarket");
            cmd.AddChatCommand(config.jobmenu_chat_cmd, this, "JobMenuCMD");
            if (crafting_info.blueprints.Count == 0) {
                foreach (var bp in ItemManager.GetBlueprints()) {
                    if (bp.isResearchable || bp.defaultBlueprint) {
                        var item = bp.GetComponent<ItemDefinition>();
                        if (item == null) continue;
                        var exp = CalculateXP(bp);
                        crafting_info.blueprints.Add(item.shortname, new CraftingInfo() {
                            classes = {
                                GetItemCategory(item)
                            }
                            , xp = exp
                        }
                        );
                    }
                }
                SaveData(SaveType.CRAFTING);
                Puts("Loaded xp values");
            }
            else {
                Dictionary<string, int> bp_counts = new Dictionary<string, int>();
                foreach (KeyValuePair<string, CraftingInfo> kvp in crafting_info.blueprints) {
                    if (kvp.Value.classes != null) {
                        if (!bp_counts.ContainsKey(kvp.Value.classes.First())) bp_counts.Add(kvp.Value.classes.First(), 1);
                        else bp_counts[kvp.Value.classes.First()]++;
                    }
                }
                foreach (KeyValuePair<string, int> kvp in bp_counts) {
                    Puts($"Loaded {kvp.Value} blueprints for {kvp.Key.TitleCase()}");
                }
            }
            foreach (var item in config.item_info) {
                skins.Add(item.Value.skin);
            }
            if (!config.allow_resource_bags) {
                Unsubscribe("CanMoveItem");
                Unsubscribe("OnLootEntityEnd");
            }
            foreach (KeyValuePair<string, CraftingInfo> kvp in crafting_info.blueprints) {
                if (kvp.Value.classes.Contains("weaponsmith") && !weaponsmith.ContainsKey(kvp.Key)) weaponsmith.Add(kvp.Key, kvp.Value.xp * kvp.Value.xp_multiplier);
                if (kvp.Value.classes.Contains("tailor") && !tailor.ContainsKey(kvp.Key)) tailor.Add(kvp.Key, kvp.Value.xp * kvp.Value.xp_multiplier);
                if (kvp.Value.classes.Contains("mechanic") && !mechanic.ContainsKey(kvp.Key)) mechanic.Add(kvp.Key, kvp.Value.xp * kvp.Value.xp_multiplier);
                if (kvp.Value.classes.Contains("electrician") && !electrician.ContainsKey(kvp.Key)) electrician.Add(kvp.Key, kvp.Value.xp * kvp.Value.xp_multiplier);
            }
            foreach (KeyValuePair<string, Configuration.JobInfo> kvp in config.job_info) {
                ImageLibrary?.Call("AddImage", kvp.Value.img, kvp.Key);
                if (!permission.GroupExists(kvp.Key)) permission.CreateGroup(kvp.Key, "", 0);
            }
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/arIzmlS.png", "pinecone");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/3ySNtDo.png", "primemeat");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/Xyotu52.png", "goldnugget");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/TGHA3yK.png", "quitui");
        }
#endregion;
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["prefix"]
                = "<color=#FF0000>[Jobs]</color>", ["CanMakeT"] = "You can now make Tier {0} items.", ["ResearchXP"] = "You gained {0} xp for researching {1}", ["PTC1"] = "You must be crafting level {0} to craft this item.Type /class to see your current level.", ["PTC2"] = "You must be a {0} to craft this item.Type /class to see your current profession.", ["PTC3"] = "You paid ${0} to craft {1}x {2} as you are not a {3}", ["PTC4"] = "You do not have enough cash to craft this item.Requires ${0} per item unless you are a {1}.", ["PTC5"] = "You need {0} scrap per item in order to craft this item.", ["PTC6"] = "You paid {0} scrap to craft {1}x {2} as you are not a {3}", ["PTC7"] = "Refunded ${0}.", ["PTC8"] = "Refunded {0} scrap.", ["PTC9"] = "Your {0} is now level {1}", ["PTC10"] = "You were removed from your job.", ["PTC11"] = "You have been employed as a {0}", ["PTC12"] = "You can access the gathering bag by typing <color=#FF229A>/{0}</color>", ["PTC13"] = "You acquired a <color=#B600FF>{0}</color>.It was placed into your bag.", ["PTC14"] = "You acquired a <color=#B600FF>{0}</color>.It was placed into a new slot in your bag.", ["PTC15"] = "You acquired a <color=#B600FF>{0}</color>.", ["PTC16"] = "More than one player found: {0}", ["PTC17"] = "No player was found that matched: {0}", ["PTC18"] = "You were retro-actively awarded {0} xp for items researched in your current profession.", ["PTC19"] = "Added {0} new items.", ["PTC20"] = "Updated xp values.", ["PTC21"] = "Usage: /setjob <name> <job>", ["PTC22"] = "{0} is not valid.Valid jobs are: {1}", ["PTC23"] = "Unemployed.Go to town and get a job you bum.", ["PTC24"] = "<color=#FF7C00>Job information</color>\n<color=#FF7C00>- Job:</color> {0}\n<color=#FF7C00>- Level:</color> {1}\n<color=#FF7C00>- XP:</color> <color=#B827FC>{2}/{3}</color>", ["PTC25"] = "usage: /updatemultiplier <item shortname> <value>", ["PTC26"] = "Invalid shortname specified.", ["PTC27"] = "You need a crafting job to print a list of items and their xp values.", ["PTC28"] = "A list of items for your class has been printed to console.", ["PTC29"] = "You are already unemployed.", ["PTC30"] = "You do not have enough cash to quit your job.", ["PTC31"] = "You paid ${0} to quit your job.", ["PTC32"] = "You do not have enough scrap to quit your job.", ["PTC33"] = "You paid {0} scrap to quit your job.", ["PTC34"] = "You are already employed as a {0}", ["PTC35"] = "You you ate the {0} but do not feel wiser, as you are not employed!", ["PTC36"] = "You consume the {0} and are rewarded with 200 xp.", ["PTC37"] = "Please wait a moment before opening the bag again.", ["PTC38"] = "You can only move gold nuggets, prime meat and pinecones into this bag.", ["PTC39"] = "You sold 1x {0}.", ["PTC40"] = "You sold {0}x {1}.", ["PTC41"] = "You do not have any {0}.", ["QuitJob1"] = "It costs ${0} to quit your job, are you sure?", ["QuitJob2"] = "It costs {0} scrap to quit your job, are you sure?", ["TrackerClose"] = "You see fresh tracks to the", ["TrackerMid"] = "You see slightly old tracks to the", ["TrackerFar"] = "You see very old tracks to the", ["WarnSkinner"] = "You must be a skinner to use this command.", ["NoAnimals"] = "No animals were found.", ["TrackWait"] = "You need to wait a few seconds before attempting to track the animal again.", ["EmploymentStats"] = "There are <color=#E8FF00>{0}</color> [<color=#00F3FF>{1}%</color>] players who are employed as a <color=#00F3FF>{2}</color>.", ["JobPickWarn"] = "<color=#FF0C00>All levels and xp will be lost if you change your job.</color>"
            }
            , this);
        }
#endregion
#region Levels
        const string Prefix = "<color=#FF0000>[Jobs]</color>";
        public Dictionary<int, double> Levels = new Dictionary<int, double>();
#endregion
#region Hooks
        object OnItemAction(Item bp, string action, BasePlayer player) {
            if (action == "study") {
                if (pcdData.pEntity.TryGetValue(player.userID, out playerData)) {
                    if (!bp.IsBlueprint()) return null;
                    var itemDef = bp.blueprintTargetDef;
                    if (!player.blueprints.HasUnlocked(itemDef)) {
                        if (crafting_info.blueprints.TryGetValue(itemDef.shortname, out bpinfo)) {
                            if (!bpinfo.classes.Contains(playerData.profession)) return null;
                            PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("ResearchXP", this, player.UserIDString), Math.Round(bpinfo.research_xp, 2), itemDef.displayName.english)}");
                            LevelCrafting(player, bpinfo.research_xp);
                        }
                    }
                }
            }
            else if (action.Equals("unwrap") && bp.skin == 2582646034) {
                OpenBag(player);
                return false;
            }
            else if (action.Equals("upgrade")) return false;
            return null;
        }
        void OnNewSave(string filename) {
            pcdData.pEntity.Clear();
            pcdData.resource_bag.Clear();
            UpdateXP();
            var newItems = 0;
            CheckForNewItems(out newItems);
            if (newItems > 0) Puts($"Added {newItems} new items.");
            ClearJobGroups();
            SaveData();
            if (config.delete_carpart_vendors) RemoveVendingMachines();
        }
        void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            var player = entity as BasePlayer;
            var roll = UnityEngine.Random.Range(0f, 100f);
            var tool = player.GetActiveItem()?.info?.shortname;
            if (!pcdData.pEntity.TryGetValue(player.userID, out playerData)) {
                SetupPlayer(player);
                playerData = pcdData.pEntity[player.userID];
            }
            if (tool == null) return;
            if (dispenser.gatherType == ResourceDispenser.GatherType.Flesh) {
                if (!config.skinner_tools.Contains(tool)) return;
                var animal = GetAnimal(dispenser.baseEntity.ShortPrefabName);
                if (animal == null) return;
                if (playerData.profession.Equals("skinner")) {
                    object hookResult = Interface.CallHook("CanLevelSkinner", player, dispenser.baseEntity);
                    if (hookResult is bool && (bool)hookResult == false) return;
                    UpdateLevel(player, config.skinner_xp_per_hit, "skinner");
                    if (playerData.level > 0) {
                        var amount = Convert.ToInt32(((playerData.level * config.gather_yield_per_level) / 100) * item.amount);
                        if (amount < 1 && amount > 0.5) amount = 1;
                        if (amount >= 1) {
                            NextTick(() => {
                                var extra_items = ItemManager.CreateByItemID(item.info.itemid, amount);
                                player.GiveItem(extra_items);
                            }
                            );
                        }
                    }
                }
                if ((permission.UserHasGroup(player.UserIDString, "skinner") && roll >= 100 - ((config.prime_meat_professional * config.skinner_modifier[animal]) + playerData.bonus_chance)) || roll >= 100 - (config.prime_meat_default * config.skinner_modifier[animal])) {
                    var itemInfo = config.item_info["skinner"];
                    GiveItem(player, itemInfo.shortname, itemInfo.skin, itemInfo.displayName, itemInfo.quantity);
                    playerData.prime_meat_acquired++;
                    SaveData();
                }
            }
            else if (dispenser.gatherType == ResourceDispenser.GatherType.Ore) {
                if (config.miner_tools.Contains(tool) || (tool == "jackhammer" && config.jackhammer_xp_modifier > 0)) {
                    if (playerData.profession.Equals("miner")) {
                        object hookResult = Interface.CallHook("CanLevelMiner", player, dispenser.baseEntity);
                        if (hookResult is bool && (bool)hookResult == false) return;
                        if (tool == "jackhammer") UpdateLevel(player, config.miner_xp_per_hit * config.jackhammer_xp_modifier, "logger");
                        else UpdateLevel(player, config.miner_xp_per_hit, "miner");
                        if (playerData.level > 0) {
                            var amount = Convert.ToInt32(((playerData.level * config.gather_yield_per_level) / 100) * item.amount);
                            if (amount < 1 && amount > 0.5 && tool != "jackhammer") amount = 1;
                            if (amount >= 1) {
                                NextTick(() => {
                                    var extra_items = ItemManager.CreateByItemID(item.info.itemid, amount);
                                    player.GiveItem(extra_items);
                                }
                                );
                            }
                        }
                    }
                    if (tool == "jackhammer" && !config.allow_jackhammer_drops) return;
                    if ((permission.UserHasGroup(player.UserIDString, "miner") && roll >= 100 - (config.gold_nugget_professional + playerData.bonus_chance)) || roll >= 100 - config.gold_nugget_default) {
                        var itemInfo = config.item_info["miner"];
                        GiveItem(player, itemInfo.shortname, itemInfo.skin, itemInfo.displayName, itemInfo.quantity);
                        playerData.gold_nuggets_acquired++;
                        SaveData();
                    }
                }
            }
            else if (dispenser.gatherType == ResourceDispenser.GatherType.Tree) {
                if (config.logger_tools.Contains(tool) || (tool == "chainsaw" && config.chainsaw_xp_modifier > 0)) {
                    if (playerData.profession.Equals("logger")) {
                        object hookResult = Interface.CallHook("CanLevelLogger", player, dispenser.baseEntity);
                        if (hookResult is bool && (bool)hookResult == false) return;
                        if (tool == "chainsaw") UpdateLevel(player, config.logger_xp_per_hit * config.chainsaw_xp_modifier, "logger");
                        else UpdateLevel(player, config.logger_xp_per_hit, "logger");
                        SaveData();
                        if (playerData.level > 0) {
                            var amount = Convert.ToInt32(((playerData.level * config.gather_yield_per_level) / 100) * item.amount);
                            if (amount < 1 && amount > 0.5 && tool != "chainsaw") amount = 1;
                            if (amount >= 1) {
                                NextTick(() => {
                                    var extra_items = ItemManager.CreateByItemID(item.info.itemid, amount);
                                    player.GiveItem(extra_items);
                                }
                                );
                            }
                        }
                    }
                    if (tool == "chainsaw" && !config.allow_chainsaw_drops) return;
                    if ((permission.UserHasGroup(player.UserIDString, "logger") && roll >= 100 - (config.pinecone_professional + playerData.bonus_chance)) || roll >= 100 - config.pinecone_default) {
                        var itemInfo = config.item_info["logger"];
                        GiveItem(player, itemInfo.shortname, itemInfo.skin, itemInfo.displayName, itemInfo.quantity);
                        playerData.pinecones_acquired++;
                        SaveData();
                    }
                }
            }
        }
        void OnDispenserBonus(ResourceDispenser dispenser, BaseEntity entity, Item item) => OnDispenserGather(dispenser, entity, item);
        private object CanCraft(ItemCrafter itemCrafter, ItemBlueprint bp, int amount) {
            var player = itemCrafter.GetComponent<BasePlayer>();
            var item = bp.GetComponent<ItemDefinition>();
            var playerData = pcdData.pEntity[player.userID];
            if (!crafting_info.blueprints.TryGetValue(item.shortname, out bpinfo)) return null;
            if (bpinfo.classes.Contains("free_craft")) return null;
            else {
                foreach (var profession in bpinfo.classes) {
                    if (permission.UserHasGroup(player.UserIDString, profession)) {
                        if (playerData.level >= bp.workbenchLevelRequired || !config.crafting_level_required) return null;
                        PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC1", this, player.UserIDString), bp.workbenchLevelRequired)}");
                        return false;
                    }
                }
                if (config.craft_method == CraftMethod.PreventCraft) {
                    PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC2", this, player.UserIDString), String.Join(" or ", bpinfo.classes))}");
                    return false;
                }
                else if (config.craft_method == CraftMethod.TaxEcon) {
                    var balance = (double)Economics?.Call("Balance", player.userID);
                    var cost = (double)(bpinfo.tax * amount);
                    if (balance >= cost && Convert.ToBoolean(Economics?.Call("Withdraw", player.userID, cost))) {
                        PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC3", this, player.UserIDString), cost, amount, item.displayName.english, String.Join(" or ", bpinfo.classes))}");
                        return null;
                    }
                    else {
                        PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC4", this, player.UserIDString), bpinfo.tax, String.Join(" or ", bpinfo.classes))}");
                        return false;
                    }
                }
                else {
                    var found = 0;
                    var cost = bpinfo.tax * amount;
                    foreach (var scrap in player.inventory.AllItems()) {
                        if (scrap.info.shortname == "scrap") found += scrap.amount;
                        if (found >= cost) break;
                    }
                    if (found < cost) {
                        PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC5", this, player.UserIDString), bpinfo.tax)}");
                        return false;
                    }
                    foreach (var scrap in player.inventory.AllItems()) {
                        if (scrap.info.shortname == "scrap") {
                            if (cost <= 0) {
                                break;
                            }
                            if (scrap.amount >= cost) {
                                scrap.UseItem(cost);
                                break;
                            }
                            else {
                                cost -= scrap.amount;
                                scrap.UseItem(scrap.amount);
                            }
                        }
                    }
                    PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC6", this, player.UserIDString), bpinfo.tax * amount, amount, item.displayName.english, String.Join(" or ", bpinfo.classes))}");
                    return null;
                }
            }
        }
        void OnItemCraftCancelled(ItemCraftTask task) {
            if (config.craft_method == CraftMethod.PreventCraft) return;
            if (crafting_info.blueprints.TryGetValue(task.blueprint.targetItem.shortname, out bpinfo)) {
                if (bpinfo.classes.Contains("free_craft")) return;
                var player = task.owner;
                foreach (var profession in bpinfo.classes) {
                    if (permission.UserHasGroup(player.UserIDString, profession)) {
                        return;
                    }
                }
                if (config.craft_method == CraftMethod.TaxEcon) {
                    var cost = (double)(task.amount * bpinfo.tax);
                    if (Convert.ToBoolean(Economics?.Call("Deposit", player.userID, cost))) {
                        PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC7", this, player.UserIDString), cost)}");
                        return;
                    }
                }
                else {
                    var cost = task.amount * bpinfo.tax;
                    var item = ItemManager.CreateByName("scrap", cost);
                    player.GiveItem(item);
                    PrintToChat(player, $"{Prefix} {string.Format(lang.GetMessage("PTC8", this, player.UserIDString), cost)}");
                }
            }
        }
        void OnItemCraftFinished(ItemCraftTask task, Item item) {
            var player = task.owner;
            if (player == null) return;
            if (!pcdData.pEntity.TryGetValue(player.userID, out playerData)) return;
            if (!crafting_info.blueprints.TryGetValue(item.info.shortname, out bpinfo)) return;
            foreach (var c in bpinfo.classes) {
                if (permission.UserHasGroup(player.UserIDString, c) || (playerData.level == 0 && playerData.job_type == "crafting")) {
                    LevelCrafting(player, bpinfo.xp * bpinfo.xp_multiplier);
                    return;
                }
            }
        }
#endregion
#region Helper
        CraftingInfo bpinfo;
        void ClearJobGroups() {
            foreach (var job in professions) {
                foreach (var jobUser in permission.GetUsersInGroup(job)) {
                    permission.RemoveUserGroup(jobUser.Split(' ')[0], job);
                }
            }
        }
        void UpdateXP() {
            foreach (var bp in ItemManager.GetBlueprints()) {
                if (bp.isResearchable || bp.defaultBlueprint) {
                    var item = bp.GetComponent<ItemDefinition>();
                    if (item == null) continue;
                    var exp = CalculateXP(bp);
                    if (crafting_info.blueprints.TryGetValue(item.shortname, out bpinfo)) {
                        bpinfo.xp = exp;
                        bpinfo.research_xp = exp * bpinfo.xp_multiplier * config.research_xp_multiplier;
                    }
                    else {
                        crafting_info.blueprints.Add(item.shortname, new CraftingInfo() {
                            classes = {
                                GetItemCategory(item)
                            }
                            , xp = exp, xp_multiplier = 1, research_xp = exp * config.research_xp_multiplier
                        }
                        );
                    }
                }
            }
            SaveData(SaveType.CRAFTING);
            Puts("Loaded new xp values");
        }
        double CalculateXP(ItemBlueprint bp) {
            var xp = 0d;
            float ingredient;
            foreach (var material in bp.ingredients) {
                if (config.component.TryGetValue(material.itemDef.shortname, out ingredient)) xp = xp + (ingredient * material.amount);
            }
            return Math.Round(xp, 2);
        }
        bool ItemIsMechanical(ItemDefinition item) {
            for (int i = 1; i < 4; i++) {
                if (item.shortname.StartsWith("carburetor")) return true;
                if (item.s
// ... [Code preview truncated due to length. Full source in attached file] ...

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