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

FREE Luck : 1.9.2 1.9.2

Нет прав для скачивания
C#:
using Facepunch;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
    [Info("Luck", "Shady", "1.9.2", ResourceId = 0000)]
    [Description("Lets players level up as they harvest different resources and when crafting.-- extra GUI work by Shady, DO NOT REMOVE")]
    //extra everything work lmao
    public class Luck : RustPlugin {
        /*
         * Copyright 2024 PRISM
         *
         * This file is part of PRISM's plugins.*
         * PRISM's plugins is free software: you can redistribute it and/or modify
         * it under the terms of the GNU General Public License as published by
         * the Free Software Foundation, either version 3 of the License, or
         * (at your option) any later version.*
         * PRISM's plugins is distributed in the hope that it will be useful,
         * but WITHOUT ANY WARRANTY; without even the implied warranty of
         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
         * GNU General Public License for more details.*
         * You should have received a copy of the GNU General Public License
         * along with PRISM's plugins.If not, see <https://www.gnu.org/licenses/>.*/
        /*
         * The below is not a license (that can be found above), but simply a notice to the reader of this code:
         * The development of PRISM has been gradual and started in 2014.* Some of the code provided in this repository may be outdated and may not be the best representation of the author's current coding practices.* Some of the code provided in this repository may have been initially developed in 2014.* Files not containing the above license are not uniquely part of PRISM's plugins and are subject to the license of the original plugin, where applicable.* No copyright infringement is ever intended and the author of PRISM's plugins will comply with any requests to remove code.* PRISM's plugins are provided as is and no functionality is guaranteed.* Many of these plugins will not work without significant changes as there are numerous instances of hard-coded functions and may rely on external API calls that are not a part of this project itself.* 
         * 
         * With those notices out of the way, I, Shady, the author of this plugin, would like you to read and acknowledge the following:
         * These plugins are part of a decade long passion project where we, PRISM, created a unique experience to all players on our Rust servers.* This was a significant part of my life.I dedicated a decade to developing and maintaining these plugins and the servers themselves.* I implore you that, should you use any of the code or plugins provided in this repository, where it belongs solely to PRISM, that you respect the time and effort put into it.* Please remember that I, a single human, invested a significant amount of time and effort into these plugins and the servers they were used on.* Please feel free to critique my code as it is written; I am aware it is not perfect.Much of it is old, and I'm capable of doing far better now.* Moreover, I ask, sincerely, that you do not use these plugins or code without acknowledging that someone dedicated themselves to this passion project.* In asking that, it is my simple desire that you do not let these plugins be used in a way that is inconsistent with my own desires and love.* Please do not use them and claim them as your own.I wish for you to use them on your server and make that server something of your own.* Something unique and beautiful.However, I ask that you do not use these plugins and claim them as your own work.* Should you make changes to them, you are, of course, the author of those changes.But, if your code is based on one of PRISM's original plugins, please do not claim it as your own.* I also request that you do not use the plugins in a way that would be detrimental to the Rust community or the community of server owners.* In doing so, I ask that you please do not monetize the functions within these plugins with any changes you should make.* Should you use any of PRISM's plugins or its code, please do not lock anything behind a paywall or in a way that is unfair to the community of Rust.* My origin is that of one where I saw, daily, very young players who only wished to enjoy a few hours of their life on a video game and in many cases had little or no expendable income.* For many people, even purchasing the game is significantly difficult.It is, in my eyes, unfair to create fun, custom content, and suggest that you care about the community while also charging for it or creating an unfair environment where players who pay are significantly advantaged compared to those who cannot afford to do so.* I cannot control what you do with this code, but I ask that you respect the spirit in which it was created:
         * That is one of sincere love, care, and appreciation for the people who played on PRISM's servers.* Our community, much like yours, is your entire server.Your people matter, just as you matter.Please remember that *everyone* deserves a fair, fun environment.* I ask that should you use these plugins, you do so with the same love and care that I put into them.I ask that you do so with the same respect, love, care, and appreciation for the people who will play on your server.*
         * One of my greatest helps over the years was MBR.He has been a wonderful person, friend, and developer; I am beyond grateful for his contributions to us, but moreover, his friendship.* Some of these plugins were authored solely by him, or with his help.Where this has occurred, it should be noted in the author field at the top of the plugin.* Worthy of note is that he is solely responsible for our top-tier Discord integration.* If you so wish to see his GitHub page, here it is linked below:
         * https://github.com/MBR-0001
         * 
         * 
         * Should you wish to support the work that I have put into this project of the past decade, please consider doing so here:
         * https://www.buymeacoffee.com/shady757
         * 
         * I neither expect nor anticipate any such donations.You are by no means obligated, it is truly a donation.It should be done out of the kindness of your heart, if you so choose.* 
         * PRISM, as a community, has not ceased and continues to exist.We have no plans of ceasing our community.We have, however, ceased our Rust servers and thus made these plugins open source.* If you ever wish to contact me, or simply join our community and become one of our beloved members, please join us here:
         * https://discord.gg/DUCnZhZ
         * 
         * To quote Rush: "There is magic at your fingers".* With love,
         * Shady and all of PRISM.Thank you for everything, always.* 
         */
        //delivery jobs broke _banditConversationalist or will likely break it.please keep this in mind.FIX SOON.//use cl_punch for whirlwind fx? wonder if it can move in directions other than upper-right (june 2023 recommendation)
        //note feb 2024: has an old system for backpacks predating FP's backpacks.//A SORT OF TODO THING I NEED SOMEWHERE TO WRITE STUFF DOWN FOR NOW LOL
        //skt gui not refreshing (it used to??) - fixed
        //example: at woodcutting/mining level 50, get access to a luck skill specific to woodcutting/mining - but only accessible if lumberjack/miner, respectively - done for miner (level 25: map ores)
        //reminders that skills can be used again when off cooldown, like after hitting a tree a few times or something (done for wc/mining)
        //xp calculation method swapped over (done)
        //this has already largely been done, but Luck will move to a new XP calculation.ZLevels simply gets far less XP
        //note that bone frags require botanist (done)
        //research for loners?!?! duh (done, sort of) - needs ownerid fix
        //finish adding farmer legendary (overalls)
        //need to add checks for equipping legendary weapons (done)
        //ToA can be bought with a press button at class vm store? (done)
        //whirlwind end should undo the storm effects slower so it's not jarring and not accidentally triggered (done)
        //ww/wotw etc should probably require level 25 before any points can be spent on it? (like 25 wc) or something
        //legendary items probably need to be introduced better/implemented in a more user-accessible friendly way that sort of 'advertises' them.some sort of GUI, ala set items?
        //packrats should find guns with better durability (done? - needs testing, also, should be noted in GUI/info)
        //25 lvl cap for no class (done)
        //~20 minute grace period to change class again? (done, 45m)
        //class VMs need to be actually created (done)
        //solo classes need to actually be restricted to solo still (done)
        //skp price adjustments/level reqs (done, but idk if final)
        //fx when placing sleeping bag and chat notification for nomad
        //^ this is done
        //class set items, such as lumberjack clothing to get WC bonuses.think D2/D3 style
        //interesting fx: assets/bundled/prefabs/fx/item_unlock.prefab
        //soldier (mercenary class now) should also be able to use keycards more often?
        //maybe, but for now, packrats have this ability ^^ (done)
        //WORSE beds for nomads? (sleeping bags only good option)
        //lower TC costs may require harmony and it's questionable if that will even reflect upon the GUI as it should
        //class achievements/general achievements
        //switching class in grace period needs to reset stats!! (done)
        //charm gambler has his own spawn point, separate from everyone else.wears shady ( :^) ) clothing.private bool _initFailed = false;
        private readonly PropertyInfo _itemModWearable = typeof(ItemDefinition).GetProperty("ItemModWearable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        private readonly FieldInfo _strainTimer = typeof(BaseFishingRod).GetField("strainTimer", BindingFlags.Instance | BindingFlags.NonPublic);
        private const string DISABLE_LUCK_CHAT_MESSAGES_PERM = nameof(Luck) + ".nochatmessages";
        private const string DISABLE_CLASS_NAME_IN_CHAT = nameof(Luck) + ".nochattitle";
        private const string PRISM_RAINBOW_TXT = "<color=#FF0030>P</color><color=#FE950A>R</color><color=#FEF506>I</color><color=#53D559>S</color><color=#2BACE2>M</color>";
        private const string EGG_EXPLOSION_EFFECT = "assets/prefabs/misc/halloween/pumpkin_bucket/effects/eggexplosion.prefab";
        private const string CHAT_STEAM_ID = "76561198865536053";
        //private const string WIKI_LINK_TXT = "<color=#b9f542>For more information on the Luck skill, check out our wiki!</color> <color=#c35cff>prismatic.fandom.com</color>\n<color=#a5ff5c>You can also find a link to this wiki on our Discord.For more info on that, type <color=#ff5e97>/discord</color>!";
        private const string F1_HELP_MESSAGE = "<size=72><color=#FF0030>P</color><color=#FE950A>R</color><color=#FEF506>I</color><color=#53D559>S</color><color=#2BACE2>M</color></size>\r\n\r\n<size=21>Welcome! There's a lot to unwrap with our custom ARPG experience.\r\nHere's a sort of 'quick-start' guide:</size>\r\n\r\n<color=#FF0030>1</color>: <color=#FF0030>To choose your own class you should use the command</color> \"/class gui\".\r\n<size=16>•</size> <color=#FF0030>Be sure to <i>read</i> the various descriptions to choose the class that fits your style!</color>\r\n<size=16>•</size> <color=#FF0030>If you make a mistake, you can change your class <i>ONCE</i> within 45 minutes of choosing it </color><size=12>(<color=#ff0066>you can access this menu at any time to read the descriptions</color>).</size>\r\n<size=16>•</size> <color=#e60000>After that time, you'll only be able to choose a new class after forced wipe, or you can use</color> <i><color=#a300cc>the sacred way...</color></i>\r\n\r\n<color=#66ccff>2</color>: <color=#66ccff>As with any RPG experience, classes come with skills which you can upgrade</color>.\r\n<size=16>•</size> <color=#66ccff>The command</color> \"<color=#ff66bf>/skt gui</color>\" <color=#66ccff>allows you to upgrade countless skills so you can make a character build of your own</color>.\r\n<size=16>•</size> <color=#66ccff>Every class also has their own</color> <i><color=#ff66bf>special ultimate skill</color>.</i>\r\n<size=16>•</size> <color=#66ccff>Class ultimates include <color=#0080ff>Whirlwind</color> <i>(<color=#e65c00>Lumberjack</color>)</i>, <color=#00cc00>Weight of the World</color> <i>(<color=#008ae6>Miner</color>)</i>, and more.To upgrade skills you need skill points, and are gained by leveling up your luck.More on that later</color>!\r\n\r\n<color=#BE3455>3</color>: <color=#BE3455>Now we get to the <color=#ff80bf><i><size=14>juicy</size></i></color> part, <color=#824C1A>Legendary</color> items</color>! <color=#BE3455>These very rare items can be incredibly powerful in the right hands</color>.\r\n<size=16>•</size> <color=#BE3455>They can be found most commonly on scientists</color> <size=12><i>(<color=#BE3455>or players, whichever you prefer</color>).</i></size>\r\n<size=16>•</size> <color=#BE3455>They offer unique, custom effects & boosts to certain skills</color>.\r\n<size=16>•</size> <color=#BE3455>Some of them can be used by anyone, others are limited to specific classes</color>.\r\n<size=16>•</size> <color=#BE3455>The command</color> \"<color=#BE3455>/leg</color>\" <color=#BE3455>allows you to view all currently added legendaries & their descriptions</color>.\r\n\r\n<color=#6667AB>4</color>: <color=#6667AB>Class shops</color>.\r\n<size=16>•</size> <color=#6667AB>Every class has its own vending machine shop outside of Outpost</color>.\r\n<size=16>•</size> <color=#6667AB>Players can trade class specific items & resources for batteries - PRISM's currency - or vice versa</color>.\r\n<size=16>•</size> <color=#6667AB>It is also where you can use the <color=#a300cc><i>sacred way</i></color> to reset your class in the middle of the wipe</color>...\r\n\r\n<color=#FBDB65>5</color>: <color=#FBDB65>Resetting your class after the initial 45 minutes will require some work from you</color>.\r\n<size=16>•</size> <color=#FBDB65>3 pure ore teas, 3 pure wood teas, 3 pure scrap teas & 5 skulls of the fiercest wolves should grant you the passage to freedom, once you press the button in the class shop & provide the required items, that is</color>.\r\n<size=16>•</size> <color=#FBDB65>Aside from the cost of items, this freedom will also cost you knowledge</color>.\r\n<size=16>•</size> <color=#FBDB65>Your class specific stats (Woodcutting, Mining, etc) & your class specific skill (Whirlwind, etc) will be reset, & the skill points you spent on it will be refunded</color>.\r\n\r\n<color=#307FE2>6</color>: <color=#307FE2>Leveling up your skills</color>.\r\n<size=16>•</size> <color=#307FE2>As mentioned before, you need to gain skill points first</color>.\r\n<size=16>•</size> <color=#307FE2>You gain them by leveling up your Luck, & in order to do that you have to pick up stuff from the ground or do activities specific to your own class (Woodcutting, etc)</color>.\r\n<size=16>•</size> <color=#307FE2>As your level gets higher you will unlock more ways to level Luck, such as using the very same skills you just upgraded</color>.\r\n<size=16>•</size> <color=#307FE2>Other activities, such as Woodcutting, Farming & Survival in general will also boost your gather rate as you become more proficient in those areas</color>.\r\n\r\n<color=#FABBCB>7</color>: <color=#FABBCB>Battery shops</color>.\r\n<size=14>•</size> <color=#FABBCB>Everyone can access these!</color>\r\n<size=16>•</size> <color=#FABBCB>They are spread around the monuments randomly during a wipe, and class-specific shops can be found outside Outpost</color>.\r\n<size=16>•</size> <color=#FABBCB>Trade in your batteries for components or various other items</color>!\r\n<color=#FB637E><size=16>If anything else is unclear, feel free to ask us about it! discord.gg/DUCnZhZ\r\nYou can also type <i>\"<color=#F2F0A1>help</color>\"</i> here in the console for more info!</size></color>";
        private const string PRISM_BLUE_ICON_DISCORD = @"https://cdn.prismrust.com/PRISM_BLUE_LOGO_CROP_SOLID_SQUARED_UP_11_C3_test.jpg";
        //can we move these to some sort of faster image host? maybe.//   private const string PRISM_CLASS_SELECTS_URL = @"51.77.126.132/public/class_selects/jpg/"; //@"https://cdn.prismrust.com/class_selects/jpg/";
        //using discord as it is much faster
        private const string MUST_USE_WORKBENCH_REFILL_TOAST = "<color=#FF884C>You must be near a <color=#B7AF8B>Workbench</color> to refill!</color>";
        private const bool ERA_CORRUPTION = true;
        private Dictionary<string, string> ZLevelsColors = new();
        private Dictionary<string, object> ZLevelsMessages = new();
        private readonly HashSet<int> _ignoreItems = new() {
            878301596, -2027988285, -44066823, -1364246987, 62577426, 1776460938, -17123659, 999690781, -810326667, 996757362, 1015352446, 1414245162, -1449152644, -187031121, 1768112091, 1770744540, -602717596, 1223900335, 1036321299, 204970153, 236677901, -399173933, 1561022037, 1046904719, 1394042569, -561148628, 861513346, -1366326648, -1884328185, 1878053256, 550753330, 696029452, 755224797, 1230691307, 1364514421, -455286320, 1762167092, -282193997, 180752235, -1386082991, 70102328, 22947882, 81423963, 1409529282, -1779180711, -277057363, -544317637, 1113514903
        }
        ;
        private readonly HashSet<Coroutine> _coroutines = new();
        private static readonly System.Random _rarityRng = new();
        private static readonly System.Random xpRandom = new();
        private static readonly System.Random itemRandom = new();
        private static readonly System.Random scavRandom = new();
        private static readonly System.Random _charmTypeRng = new();
        //ww optimizations
        private readonly HitInfo _whirlwindImpactInfo = new();
        private readonly HitInfo _fellingHitInfo = new();
        private readonly HitInfo _whirlwindHitInfo = new();
        //lumberjack grenade optimization:
        private readonly HitInfo _lumberJackGrenadeHitInfo = new();
        private readonly DamageTypeEntry _whirlwindStabDmg = new() {
            type = DamageType.Stab
        }
        ;
        private readonly DamageTypeEntry _whirlwindSlashDmg = new() {
            type = DamageType.Slash
        }
        ;
        private readonly DamageTypeEntry _whirlwindBluntDmg = new() {
            type = DamageType.Blunt
        }
        ;
        private readonly List<DamageTypeEntry> _whirlwindDmgTypes = new(3);
        private readonly DamageTypeEntry _blunderbussBluntDmg = new() {
            type = DamageType.Blunt
        }
        ;
        private readonly HashSet<DroppedItem> allDropped = new();
        private readonly HashSet<LootContainer> allContainers = new();
        //fishes
        private readonly HashSet<ItemDefinition> _fishItems = new();
        private readonly HashSet<ItemId> _ignoreFish = new();
        private readonly HashSet<NetworkableId> _secondWindSleepingBags = new();
        private readonly HashSet<ulong> _secondWindThornsBonusActive = new();
        private readonly HashSet<int> _wolfHoundProjectileIDs = new();
        private readonly HashSet<int> _packratsBaneProjectileIDs = new();
        private readonly HashSet<int> _blunderBussProjectileIDs = new();
        private readonly HashSet<NetworkableId> _oreFireballs = new();
        private readonly HashSet<ItemId> _anglersBoonBaitItems = new();
        private Dictionary<string, ClassType> _userClass;
        //= new Dictionary<string, ClassType>(); //eventually we save this into a data file
        private LegendaryItemData _legendaryData;
        private NPCGearSetData _npcGearData;
        private List<StatInfo> _statInfos;
        private readonly HashSet<BasePlayer> _hasStormWeatherVars = new();
        private Dictionary<ulong, ulong> _itemUIDToBackPackContainerID;
        private readonly Dictionary<string, float> _lastMiningMarkerTime = new();
        private readonly Dictionary<string, int> _consecutiveGroundHits = new();
        private readonly Dictionary<string, List<OreResourceEntity>> _wotwPlayerOres = new();
        private readonly Dictionary<string, Vector3> _lastWotwHitPos = new();
        private readonly Dictionary<string, float> _lastWwReminder = new();
        private readonly Dictionary<string, float> _lastWotwReminder = new();
        private readonly Dictionary<string, BaseCombatEntity> _userBackpack = new();
        private readonly Dictionary<ItemId, NPCHitTarget.Tiers> _tagToTier = new();
        private readonly Dictionary<uint, HashSet<ulong>> _legendaryMapMarkerPlayers = new();
        private readonly Dictionary<string, float> _lastOverDriveReminder = new();
        private readonly Dictionary<string, float> _lastLegendaryNotice = new();
        private readonly Dictionary<string, float> _lastGuiUpdate = new();
        private readonly HashSet<NetworkableId> _cratesBeingRerolled = new();
        private readonly Dictionary<string, MetabolismSnapshot> _metabolicSnapshot = new();
        private readonly Dictionary<BasePlayer, BaseFishingRod> _playerToRodCache = new();
        private readonly Dictionary<string, Coroutine> _forgesCoroutine = new();
        private readonly Dictionary<string, TriggerTemperature> _forgesTrigger = new();
        private readonly HashSet<ulong> _overDrivePlayers = new();
        private readonly HashSet<ulong> _hasHitGui = new();
        private VehicleVendor _banditConversationalist = null;
        private static readonly System.Random charmLootRng = new();
        private static readonly System.Random charmXpRng = new();
        private const string TOKEN_INACTIVE_NAME = "Token of Absolution (Inactive)";
        private const string TOKEN_ACTIVE_NAME = "Token of Absolution (Active)";
        private const string BACKPACK_EQUIP_NOTE = "NOTE: You must equip your backpack to deposit items.";
        private const ulong TOKEN_INACTIVE_SKIN_ID = 2816921100;
        private const ulong TOKEN_ACTIVE_SKIN_ID = 2816925964;
        private const int WRAPPED_GIFT_ITEM_ID = 204970153;
        private const int SILENCER_ITEM_ID = -1850571427;
        private const int GAS_MASK_ITEM_ID = 1659114910;
        private const int BONE_FRAGMENTS_ITEM_ID = 1719978075;
        private const int ABYSS_ASSAULT_RIFLE_ITEM_ID = -139037392;
        private const ulong GENIE_LAMP_SKIN_ID_LUCK = 2939991120;
        private const ulong CORRUPTION_GLOVES_SKIN_ID = 2833922634;
        private const ulong LUMBERJACK_GRENADE_SKIN_ID = 836745325;
        private const ulong CLUSTER_GRENADE_SKIN_ID = 1163186435;
        private const ulong MOUSTACHE_COOKIE_SKIN_ID = 3043290470;
        private const ulong AESIRS_JACKET_SKIN_ID = 2843424058;
        private const ulong RUBY_STONE_HATCHET_SKIN_ID = 2138883683;
        private const ulong SMALL_CHARM_SKIN_ID_1 = 2829841447;
        private const ulong SMALL_CHARM_SKIN_ID_2 = 2829841540;
        private const ulong SMALL_CHARM_SKIN_ID_3 = 2829841593;
        private const ulong LARGE_CHARM_SKIN_ID_1 = 2829840753;
        private const ulong LARGE_CHARM_SKIN_ID_2 = 2829840858;
        private const ulong LARGE_CHARM_SKIN_ID_3 = 2829841032;
        private const ulong GRAND_CHARM_SKIN_ID_1 = 2829841251;
        private const ulong GRAND_CHARM_SKIN_ID_2 = 2829841319;
        private const ulong GRAND_CHARM_SKIN_ID_3 = 2829841370;
        private const ulong AMBER_HATCHET_SKIN_ID = 2637157054;
        private const ulong MINE_CAP_SKIN_ID = 788260164;
        private const ulong HUNTING_RIFLE_SKIN_ID = 2530302842;
        private const ulong GRISWOLDS_BLUNDERBUSS_SKIN_ID = 1209128595;
        private const ulong YESTERYEAR_SKIN_ID = 2296501936;
        private const ulong BURNING_FORGES_SKIN_ID = 796733487;
        private const ulong WINDFORCE_BOW_SKIN_ID = 1734427277;
        private const ulong TWITCHY_TOMMY_SKIN_ID = 2779119246;
        private const ulong GAMBLERS_PYTHON_SKIN_ID = 1258109891;
        private const ulong FANG_SAP_SKIN_ID = 1167255900;
        private const ulong ELECTRIC_GLOVES_SKIN_ID = 2714916868;
        private const ulong ANGLERS_BOON_SKIN_ID = 587812040;
        private const ulong ANGLERS_ANGST_SKIN_ID = 2557702256;
        private const ulong LONERS_BACKPACK_SKIN_ID = 2836989718;
        private const ulong LARGE_BACKPACK_SKIN_ID = 3016459319;
        private const ulong MEDIUM_BACKPACK_SKIN_ID = 855084816;
        private const ulong SMALL_BACKPACK_SKIN_ID = 2837964483;
        private const ulong CRAZY_EARL_SKIN_ID = 2786115544;
        //must also be a const as we want to be able to easily find this item repeatedly; it is not dynamic.it has an ability that must be coded in
        private const string SHOCK_EFFECT = "assets/prefabs/locks/keypad/effects/lock.code.shock.prefab";
        private const string LUCK_SHORTNAME = "LK";
        private const string CLASS_LOG_FILE_NAME = "Luck_class_log";
        private const int TREE_LAYER_MASK = 1073741824;
        private const int PLAYER_LAYER_MASK = 131072;
        private const int PYTHON_REVOLVER_ID = 1373971859;
        private const int REVOLVER_ID = 649912614;
        private const int PROTO_17_PISTOL_ID = 1914691295;
        private const int SEMI_AUTO_PISTOL_ID = 818877484;
        private const int CUSTOM_SMG_ID = 1796682209;
        private const int EOKA_PISTOL_ID = -75944661;
        private const int M92_PISTOL_ID = -852563019;
        private const int CHAINSAW_ID = 1104520648;
        private const int HATCHET_ID = -1252059217;
        private const int SALVAGED_AXE_ID = -262590403;
        private const int STONE_AXE_ID = -1583967946;
        private const int PROTO_AXE_ID = -399173933;
        private const int CONCRETE_AXE_ID = 1176355476;
        private const int ABYSS_AXE_ID = 1046904719;
        private const int BRONZE_EGG_ID = 844440409;
        private const int SILVER_EGG_ID = 1757265204;
        private const int GOLD_EGG_ID = -1002156085;
        private const int PURE_WOOD_TEA_ID = -557539629;
        private const int PURE_ORE_TEA_ID = 1729374708;
        private const int PURE_SCRAP_TEA_ID = 2024467711;
        private const int WOLF_SKULL_ID = 2048317869;
        private const int NOMAD_SUIT_ID = 491263800;
        private const ulong NOMAD_SUIT_SKIN_ID = 10201;
        //skin for nomad suit
        private const ulong BOOTS_OF_CLOUDWALKER_SKIN_ID = 2932448101;
        private const ulong LUCKY_GREASE_GUN_SKIN_ID = 2799637726;
        private const ulong BURLAP_TROUSERS_OVERALLS_SKIN_ID = 2039988322;
        private const ulong BURLAP_SHIRT_OVERALLS_SKIN_ID = 2039984110;
        private const ulong BOONIE_STRAW_HAT_SKIN_ID = 2037650796;
        private const int BURLAP_SHIRT_ITEM_ID = 602741290;
        private const int BURLAP_TROUSERS_ITEM_ID = 1992974553;
        private const int BOONIE_HAT_ITEM_ID = -23994173;
        private const int LUMBERJACK_HOODIE_ID = -763071910;
        private const int LUMBERJACK_SUIT_ID = 861513346;
        //LUMBERJACK SET (lower tier legendaries, really, but a set!):
        private const ulong LUMBERJACK_BEANIE_SKIN_ID = 10016;
        private const ulong LUMBERJACK_SHIRT_SKIN_ID = 802073199;
        private const ulong LUMBERJACK_PANTS_SKIN_ID = 1432967312;
        private const ulong LUMBERJACK_BOOTS_SKIN_ID = 1368418893;
        //Blacksmithing shirt:
        private const ulong STEELHEART_SKIN_ID = 1127407306;
        private const int MINING_HAT_ID = -1539025626;
        private const int DRACULA_CAPE_ID = -258574361;
        private const ulong NIMBLESTRIDERS_SKIN_ID = 1915955573;
        private const ulong SHOCK_ABSORBER_GLOVES_SKIN_ID = 2963716003;
        private const ulong MUDSLINGERS_SKIN_ID = 920390242;
        private const ulong UDDER_GLOVES_SKIN_ID = 2075536045;
        private const ulong PACKRATS_BANE_MUZZLE_BOOST_SKIN_ID = 2985792619;
        //1221
        private const ulong WOLFHOUND_SUPPRESSOR_SKIN_ID = 2938220613;
        private const int PICKAXE_ID = -1302129395;
        private const int STONE_PICKAXE_ID = 171931394;
        private const int ICE_PICK_ID = -1780802565;
        private const int JACKHAMMER_ID = 1488979457;
        private const int PROTO_PICK_ID = 236677901;
        private const int CONCRETE_PICK_ID = -1360171080;
        private const int ABYSS_PICK_ID = 1561022037;
        private const int GEIGER_COUNTER_ITEM_ID = 999690781;
        private const int RABBIT_MASK_ITEM_ID = -986782031;
        //todo: implement chance to gain a ds spin at any time while wearing
        private const int BATTERY_ID = 609049394;
        private const int WOOD_ITEM_ID = -151838493;
        private const int CHARCOAL_ITEM_ID = -1938052175;
        private const int SCRAP_ITEM_ID = -932201673;
        private const int SULFUR_ORE_ITEM_ID = -1157596551;
        private const int METAL_ORE_ITEM_ID = -4031221;
        private const int HQ_ORE_ITEM_ID = -1982036270;
        private const int STONES_ITEM_ID = -2099697608;
        private const int SULFUR_COOKED_ITEM_ID = -1581843485;
        private const int METAL_COOKED_ITEM_ID = 69511070;
        private const int HQ_COOKED_ITEM_ID = 317398316;
        private const uint FISH_TRAP_PREFAB_ID = 3119617183;
        private const uint OIL_BARREL_PREFAB_ID = 3438187947;
        private const uint CRATE_UNDERWATER_BASIC_PREFAB_ID = 3852690109;
        private const uint CRATE_ELITE_PREFAB_ID = 3286607235;
        private const uint CRATE_UNDERWATER_ELITE_PREFAB_ID = 96231181;
        private const uint CRATE_HELI_PREFAB_ID = 1314849795;
        private const uint CRATE_NORMAL_PREFAB_ID = 2857304752;
        private const uint CRATE_NORMAL_2_PREFAB_ID = 1546200557;
        private const uint CRATE_TOOLS_PREFAB_ID = 1892026534;
        private const uint CRATE_UNDERWATER_ADVANCED_PREFAB_ID = 2803512399;
        private const uint CRATE_UNDERWATER_NORMAL_PREFAB_ID = 1009499252;
        private const uint CRATE_UNDERWATER_NORMAL_2_PREFAB_ID = 2276830067;
        private const uint CRATE_UNDERWATER_TOOLS_PREFAB_ID = 3027334492;
        private const uint CRATE_BRADLEY_ID = 1737870479;
        private const uint CRATE_LOCKED_CHINOOK = 209286362;
        private const uint CRATE_LOCKED_OILRIG = 2043434947;
        private readonly ItemAmount _cachedSulfurItemAmount = new(ItemManager.FindItemDefinition(SULFUR_ORE_ITEM_ID), 1);
        private readonly ItemAmount _cachedMetalItemAmount = new(ItemManager.FindItemDefinition(METAL_ORE_ITEM_ID), 1);
        private readonly ItemAmount _cachedStonesItemAmount = new(ItemManager.FindItemDefinition(STONES_ITEM_ID), 1);
        private readonly ItemAmount _cachedHQMAmount = new(ItemManager.FindItemDefinition(HQ_ORE_ITEM_ID), 1);
        private readonly HashSet<ulong> _wokenPlayers = new();
        private readonly Dictionary<BasePlayer, Item> _lastActiveItem = new();
        private readonly Dictionary<string, float> _classGuiOnWakeTime = new();
        private readonly Dictionary<string, float> _classGuiStartTime = new();
        private readonly Dictionary<string, Action> _classGuiAction = new();
        private readonly Dictionary<string, ClassType> _classGuiLastClass = new();
        private readonly Dictionary<string, Coroutine> _transmuteCoroutine = new();
        private readonly Dictionary<string, HitInfo> _overdriveHitInfo = new();
        private readonly Dictionary<string, string> _currentSkillRotation = new();
        private readonly Dictionary<string, ClassType> _lastRotationType = new();
        private readonly Dictionary<NetworkableId, string> _corpseToAlivePrefabName = new();
        private readonly Dictionary<string, Action> _magpieCooldownStartAction = new();
        private readonly Dictionary<string, Action> _hitGuiAction = new();
        private Coroutine _saveCoroutine = null;
        private Timer _f1HelpTimer = null;
        private readonly HashSet<string> _forbiddenTags = new() {
            "</color>", "</size>", "<b>", "</b>", "<i>", "</i>"
        }
        ;
        private readonly Regex _colorRegex = new("(<color=.+?>)", RegexOptions.Compiled);
        private readonly Regex _sizeRegex = new("(<size=.+?>)", RegexOptions.Compiled);
        private bool _resetClassesOnInit = false;
        private Action _hitGenerateAction = null;
        private ItemDefinition _genericVehicleModuleDef = null;
        public ItemDefinition GenericVehicleModuleDef {
            get {
                if (_genericVehicleModuleDef == null) _genericVehicleModuleDef = ItemManager.FindItemDefinition(878301596);
                return _genericVehicleModuleDef;
            }
        }
        private MonumentInfo _largeOilRig = null;
        public MonumentInfo LargeOilRig {
            get {
                if (_largeOilRig == null) {
                    for (int i = 0; i < TerrainMeta.Path.Monuments.Count; i++) {
                        var mon = TerrainMeta.Path.Monuments[i];
                        if (mon.displayPhrase.english.Contains("large oil rig", CompareOptions.OrdinalIgnoreCase)) {
                            _largeOilRig = mon;
                            break;
                        }
                    }
                }
                return _largeOilRig;
            }
        }
        private MonumentInfo _oilRig = null;
        public MonumentInfo SmallOilRig {
            get {
                if (_oilRig == null) {
                    for (int i = 0; i < TerrainMeta.Path.Monuments.Count; i++) {
                        var mon = TerrainMeta.Path.Monuments[i];
                        if (mon != LargeOilRig && mon.displayPhrase.english.Contains("oil rig", CompareOptions.OrdinalIgnoreCase)) {
                            _oilRig = mon;
                            break;
                        }
                    }
                }
                return _oilRig;
            }
        }
        [PluginReference]
        private readonly Plugin Compilation;
        //temp
        [PluginReference]
        private readonly Plugin RadRain;
        [PluginReference]
        private readonly Plugin ZLevelsRemastered;
        [PluginReference]
        private readonly Plugin BuildLimiter;
        [PluginReference]
        private readonly Plugin SkinsAPI;
        // [PluginReference]
        // private readonly Plugin NoobBias;
        [PluginReference]
        private readonly Plugin ZZTaxChest;
        [PluginReference]
        private readonly Plugin LocalStatsAPI;
        [PluginReference]
        private readonly Plugin LevelsGUI;
        [PluginReference]
        private readonly Plugin PRISMAchievements;
        [PluginReference]
        private readonly Plugin DiscordAPI2;
        [PluginReference]
        private readonly Plugin Deathmatch;
        [PluginReference]
        private readonly Plugin FindGround;
        private ItemDefinition _woodDefinition = null;
        private ItemDefinition WoodDefinition {
            get {
                if (_woodDefinition == null) _woodDefinition = ItemManager.FindItemDefinition(-151838493);
                return _woodDefinition;
            }
        }
        private ItemDefinition _noteDefinition = null;
        private ItemDefinition NoteDefinition {
            get {
                if (_noteDefinition == null) _noteDefinition = ItemManager.FindItemDefinition(1414245162);
                return _noteDefinition;
            }
        }
        private EnvSync _envSync = null;
        public EnvSync EnvSync {
            get {
                if (_envSync == null) {
                    foreach (var entity in BaseNetworkable.serverEntities) {
                        var sync = entity as EnvSync;
                        if (sync != null) {
                            _envSync = sync;
                            break;
                        }
                    }
                }
                return _envSync;
            }
        }
        private TimeSpan SaveSpan {
            get {
                return DateTime.UtcNow - SaveRestore.SaveCreatedTime;
            }
        }
        public enum SkillTree {
            Undefined, Resource, NonCombat, Combat, Classes
        }
        ;
        private bool init = false;
        private void TryLoadZLevelsColors() => ZLevelsColors = ZLevelsRemastered?.Call<Dictionary<string, string>>("getColors") ?? null;
        private void TryLoadZLevelsMessages() => ZLevelsMessages = ZLevelsRemastered?.Call<Dictionary<string, object>>("getMessages") ?? null;
        public const string LUCK_COLOR = "#5DC540";
        public const string LUCK_COLOR_FORMATTED = "<color=#5DC540>";
        private string GetLuckColor() {
            return LUCK_COLOR;
        }
        private MetabolismSnapshot GetMetabolicSnapshot(string userId) {
            if (string.IsNullOrWhiteSpace(userId)) throw new ArgumentNullException(nameof(userId));
            return _metabolicSnapshot.TryGetValue(userId, out MetabolismSnapshot snap) ? snap : null;
        }
        //if performance becomes an issue, only take snapshots of players wearing the yesteryear legendary.private IEnumerator TakeMetabolicSnapshotsOfAllPlayers(TimeSpan timeInBetweenSnapshots)
        {
            PrintWarning(nameof(TakeMetabolicSnapshotsOfAllPlayers) + " initiated with TimeSpan: " + timeInBetweenSnapshots);
            while(true) {
                var players = Pool.Get<HashSet<BasePlayer>>();
                try {
                    players.Clear();
                    for (int i = 0; i < BasePlayer.activePlayerList.Count; i++) players.Add(BasePlayer.activePlayerList[i]);
                    foreach (var p in players) {
                        if (p == null || p.IsDestroyed || !p.IsConnected) continue;
                        var existingSnap = GetMetabolicSnapshot(p.UserIDString);
                        if (existingSnap != null) MetabolismSnapshot.UpdateSnapshot(p, existingSnap);
                        else _metabolicSnapshot[p.UserIDString] = MetabolismSnapshot.TakeSnapshot(p);
                        yield return CoroutineEx.waitForSecondsRealtime(0.05f);
                    }
                }
                finally {
                    Pool.Free(ref players);
                }
                yield return CoroutineEx.waitForSecondsRealtime((float)timeInBetweenSnapshots.TotalSeconds);
            }
        }
        private class MetabolismSnapshot  //for use in legendary yesteryear
        {
            public float Health {
                get;
                set;
            }
            public float Calories {
                get;
                set;
            }
            public float Hydration {
                get;
                set;
            }
            public float RadiationLevel {
                get;
                set;
            }
            public float RadiationPoisoning {
                get;
                set;
            }
            public float Bleeding {
                get;
                set;
            }
            public float Oxygen {
                get;
                set;
            }
            public float Wetness {
                get;
                set;
            }
            public bool Wounded {
                get;
                set;
            }
            public DateTime SnapshotTime {
                get;
                set;
            }
            public TimeSpan TimeSinceTaken {
                get {
                    return DateTime.UtcNow - SnapshotTime;
                }
            }
            public bool HasBeenApplied {
                get;
                set;
            }
            = false;
            public DateTime LastApplied {
                get;
                set;
            }
            = DateTime.MinValue;
            public MetabolismSnapshot() {
                SnapshotTime = DateTime.UtcNow;
            }
            public MetabolismSnapshot(BasePlayer player) {
                if (player?.metabolism == null) throw new ArgumentNullException(nameof(player.metabolism));
                SnapshotTime = DateTime.UtcNow;
                var metabolism = player.metabolism;
                Health = player.Health();
                Calories = metabolism.calories.value;
                Hydration = metabolism.hydration.value;
                Bleeding = metabolism.bleeding.value;
                RadiationLevel = metabolism.radiation_level.value;
                RadiationPoisoning = metabolism.radiation_poison.value;
                Wetness = metabolism.wetness.value;
                Oxygen = metabolism.oxygen.value;
                Wounded = player.IsWounded();
            }
            public static MetabolismSnapshot TakeSnapshot(BasePlayer player) {
                return new MetabolismSnapshot(player);
            }
            public static MetabolismSnapshot UpdateSnapshot(BasePlayer player, MetabolismSnapshot snap) {
                if (player?.metabolism == null) throw new ArgumentNullException(nameof(player.metabolism));
                if (snap == null) throw new ArgumentNullException(nameof(snap));
                snap.SnapshotTime = DateTime.UtcNow;
                snap.HasBeenApplied = false;
                snap.LastApplied = DateTime.MinValue;
                var metabolism = player.metabolism;
                snap.Health = player.Health();
                snap.Calories = metabolism.calories.value;
                snap.Hydration = metabolism.hydration.value;
                snap.Bleeding = metabolism.bleeding.value;
                snap.RadiationLevel = metabolism.radiation_level.value;
                snap.RadiationPoisoning = metabolism.radiation_poison.value;
                snap.Wetness = metabolism.wetness.value;
                snap.Oxygen = metabolism.oxygen.value;
                snap.Wounded = player.IsWounded();
                return snap;
            }
            public static void ApplyMetabolism(BasePlayer player, MetabolismSnapshot snap, bool forcePlayerUpdate = true) {
                if (player?.metabolism == null) throw new ArgumentNullException(nameof(player.metabolism));
                if (snap.HasBeenApplied) Interface.Oxide.LogWarning(nameof(ApplyMetabolism) + " called with snapshot that has HasBeenApplied!");
                snap.HasBeenApplied = true;
                snap.LastApplied = DateTime.UtcNow;
                if (snap.Health <= 0f) {
                    Interface.Oxide.LogWarning(nameof(ApplyMetabolism) + " had 0 or lower HP at metabolic snapshot - killing player!");
                    player.Hurt(9999f, DamageType.Suicide, player, false);
                    return;
                }
                if (snap.Wounded) player.BecomeWounded(new HitInfo(player, player, DamageType.Generic, 999f));
                else player.StopWounded();
                player.SetHealth(Mathf.Clamp(snap.Health, 0.1f, player.MaxHealth()));
                var metabolism = player.metabolism;
                metabolism.calories.value = snap.Calories;
                metabolism.hydration.value = snap.Hydration;
                metabolism.radiation_level.value = snap.RadiationLevel;
                metabolism.radiation_poison.value = snap.RadiationPoisoning;
                metabolism.bleeding.value = snap.Bleeding;
                metabolism.oxygen.value = snap.Oxygen;
                metabolism.wetness.value = snap.Wetness;
                if (forcePlayerUpdate) {
                    metabolism.SendChangesToClient();
                    player.SendNetworkUpdate();
                }
            }
        }
        private class WildTrapExt : FacepunchBehaviour {
            private WildlifeTrap _trap;
            public WildlifeTrap Trap {
                get {
                    if (_trap == null || (_trap?.IsDestroyed ?? true)) {
                        DoDestroy();
                        return null;
                    }
                    else return _trap;
                }
                set {
                    _trap = value;
                }
            }
            public float TickRate {
                get {
                    return Trap?.tickRate ?? -1;
                }
                set {
                    if (Trap == null) return;
                    Trap.tickRate = value;
                    ResetInvoke();
                }
            }
            public float DecayScale = 0.1f;
            private void Awake() {
                Trap = GetComponent<WildlifeTrap>();
                if (Trap == null) {
                    Interface.Oxide.LogError("WildTrapExt.Awake() called with null WildlifeTrap!!");
                    DoDestroy();
                    return;
                }
                Trap?.CancelInvoke(Trap.TrapThink);
                ResetInvoke();
            }
            private void ResetInvoke() {
                Trap.CancelInvoke(TrapThink);
                Trap.InvokeRepeating(TrapThink, (float)(Trap.tickRate * 0.800000011920929 + Trap.tickRate * (double)Random.Range(0.0f, 0.4f)), Trap.tickRate);
            }
            public void TrapThink() {
                if (Trap == null) return;
                var baitCalories = Trap?.GetBaitCalories() ?? 0;
                if (baitCalories < 1) return;
                var randomWildlife = Trap?.GetRandomWildlife() ?? null;
                if (baitCalories < randomWildlife.caloriesForInterest || Random.Range(0.0f, 1f) > (double)randomWildlife.successRate) return;
                Trap?.UseBaitCalories(randomWildlife.caloriesForInterest);
                if (Random.Range(0.0f, 1f) > (double)Trap?.trapSuccessRate) return;
                TrapWildlife(randomWildlife);
            }
            public void TrapWildlife(TrappableWildlife trapped) {
                if (trapped == null || Trap == null) return;
                var obj = ItemManager.Create(trapped.inventoryObject, Random.Range(trapped.minToCatch, trapped.maxToCatch + 1), 0UL);
                if (!obj.MoveToContainer(Trap.inventory, -1, true) && !obj.Drop(Trap.GetDropPosition(), Trap.GetDropVelocity())) {
                    Interface.Oxide.LogWarning("Couldn't move obj to inventory OR drop!");
                    obj.Remove(0.0f);
                }
                else Trap.SetFlag(BaseEntity.Flags.Reserved1, true, false);
                Trap.SetTrapActive(false);
                Trap.Hurt(Trap.StartMaxHealth() * DecayScale, DamageType.Decay, null, false);
            }
            public void DoDestroy() {
                _trap?.CancelInvoke(TrapThink);
                Destroy(this);
            }
        }
        public static Luck Instance;
        public class StatInfo {
            public string ShortName {
                get;
                set;
            }
            = string
// ... [Code preview truncated due to length. Full source in attached file] ...

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