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

FREE AlphaLoot : 2.5.2 2.5.2

Нет прав для скачивания
C#:
using Rust;
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core.Configuration;
using Random = System.Random;
using Oxide.Core;
using Oxide.Core.Plugins;
using Facepunch.Extend;
namespace Oxide.Plugins {
    [Info("AlphaLoot", "FuJiCuRa", "2.5.2", ResourceId = 13)]
    public class AlphaLoot : RustPlugin {
        [PluginReference]
        Plugin CustomLootSpawns, FancyDrop, SkinBox, EventLoot;
        bool Changed = false;
        bool firstSetup = false;
        Random rng = new Random();
        Random rngHeli = new Random();
        List<int> rngHeliList = new List<int>();
        Random rngBradley = new Random();
        List<int> rngBradleyList = new List<int>();
        double fancyDropBpProbability;
        static AlphaLoot al = null;
        double baseItemRarity = 3;
        bool initialized = false;
        bool skinsLoaded = false;
        bool manualReload = false;
        int oldProtocol = 0;
        StoredExportNames storedExportNames = new StoredExportNames();
        DynamicConfigFile itemRaritys;
        DynamicConfigFile itemLootFractions;
        DynamicConfigFile lootTable;
        DynamicConfigFile heliLoot;
        DynamicConfigFile bradleyLoot;
        DynamicConfigFile fancyDropLoot;
        DynamicConfigFile getFile(string file) => Interface.Oxide.DataFileSystem.GetDatafile($"{this.Title}/{file}");
        bool chkFile(string file) => Interface.Oxide.DataFileSystem.ExistsDatafile($"{this.Title}/{file}");
        Dictionary<string, object> lootData = new Dictionary<string, object>();
        Dictionary<string, object> lootContainers = new Dictionary<string, object>();
        Dictionary<string, object> lootCategoryLimits = new Dictionary<string, object>();
        Dictionary<string, object> fancyDropData = new Dictionary<string, object>();
        Dictionary<string, object> fancyDropLootSpawn = new Dictionary<string, object>();
        List<object> heliData = new List<object>();
        List<object> bradleyData = new List<object>();
        Dictionary<string, object> rarityOverridesItems = new Dictionary<string, object>();
        Dictionary<string, object> rarityOverridesBlueprints = new Dictionary<string, object>();
        Dictionary<string, object> fractionOverrides = new Dictionary<string, object>();
        Dictionary<string, object> weaponAmmoConfig = new Dictionary<string, object>();
        Dictionary<string, List<ulong>> skinsCache = new Dictionary<string, List<ulong>>();
        List <string> newGameItems = new List <string>();
        List <ItemDefinition> showNewGameItems = new List <ItemDefinition>();
        Dictionary<string, string> AllContainerTypes = new Dictionary<string, string>();
        Dictionary<string, LootSpawn> AllLootSpawns = new Dictionary<string, LootSpawn>();
        Dictionary<string, LootContainer.LootSpawnSlot[]> AllLootSlots = new Dictionary<string, LootContainer.LootSpawnSlot[]>();
        static Dictionary<string, string> guidToPathCopy = new Dictionary<string, string>();
        Dictionary<string, List<string>[]> Items = new Dictionary<string, List<string>[]>();
        Dictionary<string, List<string>[]> Blueprints = new Dictionary<string, List<string>[]>();
        Dictionary<string, int[]> itemWeights = new Dictionary<string, int[]>();
        Dictionary<string, int[]> blueprintWeights = new Dictionary<string, int[]>();
        Dictionary<string, int> totalItemWeight = new Dictionary<string, int>();
        Dictionary<string, int> totalBlueprintWeight = new Dictionary<string, int>();
        Dictionary<string, List<string>[]> itemsDrop = new Dictionary<string, List<string>[]>();
        Dictionary<string, List<string>[]> blueprintsDrop = new Dictionary<string, List<string>[]>();
        Dictionary<string, int[]> itemWeightsDrop = new Dictionary<string, int[]>();
        Dictionary<string, int[]> blueprintWeightsDrop = new Dictionary<string, int[]>();
        Dictionary<string, int> totalItemWeightDrop = new Dictionary<string, int>();
        Dictionary<string, int> totalBlueprintWeightDrop = new Dictionary<string, int>();
        ConsoleSystem.Command[] alVars;
        static Dictionary<string, string> alVarDescriptions = new Dictionary<string, string> {
            ["admininputlootrefresh"]
            = "Enables fast container lootrefresh on hammerhit", ["adminlootrefreshinterval"] = "The interval in seconds for the admin loot check", ["blockplayeriteminput"] = "Blocks input of player items back into lootcontainers", ["enablefancydroploot"] = "Provides seperate itemlists for all drop types (FancyDropLoot.json)", ["enableheliloadout"] = "Provides predefined loadouts for heli crates (HeliLoot.json)", ["enablebradleyloadout"] = "Provides predefined loadouts for bradley crates (BradleyLoot.json)", ["excludecustomlootspawns"] = "Excludes CustomLootSpawn boxes from handling", ["excludeeventloot"] = "Excludes EventLoot boxes from handling", ["includeworkshopskins"] = "Randomize also WorkShopskins", ["itemamountminmax"] = "Enables all loottables and itemlists to use a min and max per item", ["lootstackfixenable"] = "Removal of stacked loot container at same position", ["lootstackfixrange"] = "Range to check for stacked loot containers", ["lootstackfixexclude"] = "from stackfix excluded containers by name", ["pluginenabled"] = "Enables/disables the plugin loot spawning", ["setupauthlevel"] = "AuthLevel to have access to the plugin commands", ["showadminlootinfo"] = "Writes the lootcontainer name to chat after a hammerhit", ["useskinboxskins"] = "Can re-use the skins loaded by Skinbox", ["blueprintprobability"] = "Can be used as bp dropchance modifier (default 0.11 > ~11%)", ["multiplyconditioneditems"] = "multiply with 'lootmultiplier' also items with condition", ["alignitemrarity"] = "Place all items in the lootpool on same rarity|weight", ["alignblueprintrarity"] = "Place all blueprints in the lootpool on same rarity|weight", ["renewraritysnewprotocol"] = "Overwrites rarities with their defaults at protocolupdate", ["extendedstatus"] = "Displays the extented status once per plugin load", ["enableSkinIdFields"] = "Adds a SkinId field to items (only when using also itemamountminmax)",
        }
        ;
        static Dictionary<string, string> alCmdDescriptions = new Dictionary<string, string> {
            ["reload"]
            = "Reloads the whole plugin internally", ["repopulateloot"] = "Repopulates loot for all supported containers on map", ["rarityreload"] = "Reloads the item raritys into server after changing them", ["rarityset"] = "Sets the item rarity for a specific item", ["raritysetbp"] = "Sets the blueprint rarity for a specific item", ["lootreset"] = "Can be used to recreate all or specific tables/files with new defaults", ["enable"] = "Enables the plugin from passive state", ["disable"] = "Disables the plugin into passive state", ["itemlimit"] = "Sets the maximum item limit for an item in 'LootTables.json'", ["itemremove"] = "Removes an item complete from 'LootTables.json'", ["itemfind"] = "Shows the entries for a specific item in 'LootTables.json'", ["itemadd"] = "Adds an item to specific containers in 'LootTables.json'", ["categorylist"] = "Lists the current category defaults", ["categoryset"] = "Modifies a given category in the plugin config", ["containertypes"] = "Lists the added container types and their status", ["containeradd"] = "Adds a not included containtertype to your loot tables", ["containerreset"] = "Resets a specific containtertype to the defaults", ["containerremove"] = "Removes a specific containtertype from your loot tables", ["containeronmap"] = "Lists all current containers on map", ["containeritemweights"] = "Shows calculated and used itemweights of 'LootTables.json'", ["showconfig"] = "Shows and explains the current config options", ["searchitems"] = "Search any game item(s) by partial name", ["shownewitems"] = "Lists any new items since last protocol update", ["lootmultiplier"] = "Simplified multiplier for all or specific tables/files"
        }
        ;
        static Dictionary<string, object> defaultCategoryLimits() {
            var dp = new Dictionary<string, object>();
            foreach (var cat in Enum.GetValues(typeof(ItemCategory)).Cast<ItemCategory>().ToList()) {
                if (cat.ToString() == "All" || cat.ToString() == "Common" || cat.ToString() == "Search") continue;
                var dp0 = new Dictionary<string, object>();
                dp0.Add("LootMultiplier", 1);
                dp0.Add("DropSkinned", false);
                dp.Add(cat.ToString(), dp0);
            }
            return dp;
        }
        bool pluginEnabled;
        bool debugLogEnabled;
        bool adminInputLootRefresh;
        float adminLootRefreshInterval;
        int setupAuthLevel;
        bool showAdminLootInfo;
        bool includeWorkShopSkins;
        bool blockPlayerItemInput;
        bool lootStackFixEnable;
        float lootStackFixRange;
        List<object> lootStackFixExclude;
        bool itemAmountMinMax;
        bool enableSkinIdFields;
        bool enableHeliLoadOut;
        bool enableBradleyLoadOut;
        bool enableFancyDropLoot;
        bool useSkinBoxSkins;
        bool excludeCustomLootSpawns;
        bool excludeEventLoot;
        double blueprintProbability;
        bool renewRaritysNewProtocol;
        bool multiplyConditionedItems;
        bool alignItemRarity;
        bool alignBlueprintRarity;
        string version;
        bool extendedStatus;
        object GetConfig(string menu, string datavalue, object defaultValue) {
            var data = Config[menu] as Dictionary<string, object>;
            if (data == null) {
                data = new Dictionary<string, object>();
                Config[menu] = data;
                Changed = true;
            }
            object value;
            if (!data.TryGetValue(datavalue, out value)) {
                value = defaultValue;
                data[datavalue] = value;
                Changed = true;
            }
            return value;
        }
        void LoadVariables() {
            lootCategoryLimits = (Dictionary<string, object>)GetConfig("LootCategorys", "Limits", defaultCategoryLimits());
            pluginEnabled = Convert.ToBoolean(GetConfig("Generic", "pluginEnabled", false));
            debugLogEnabled = Convert.ToBoolean(GetConfig("Debug", "debugLogEnabled", false));
            adminInputLootRefresh = Convert.ToBoolean(GetConfig("Generic", "adminInputLootRefresh", true));
            adminLootRefreshInterval = Convert.ToSingle(GetConfig("Generic", "adminLootRefreshInterval", 3f));
            setupAuthLevel = Convert.ToInt32(GetConfig("Generic", "setupAuthLevel", 2));
            showAdminLootInfo = Convert.ToBoolean(GetConfig("Generic", "showAdminLootInfo", true));
            includeWorkShopSkins = Convert.ToBoolean(GetConfig("Generic", "includeWorkShopSkins", false));
            blockPlayerItemInput = Convert.ToBoolean(GetConfig("Generic", "blockPlayerItemInput", true));
            lootStackFixEnable = Convert.ToBoolean(GetConfig("Generic", "lootStackFixEnable", true));
            lootStackFixRange = Convert.ToSingle(GetConfig("Generic", "lootStackFixRange", 0.3f));
            lootStackFixExclude = (List<object>)GetConfig("Generic", "lootStackFixExclude", new List<object> {
                "place-container-name-here", "example_name_1"
            }
            );
            itemAmountMinMax = Convert.ToBoolean(GetConfig("Generic", "itemAmountMinMax", true));
            enableSkinIdFields = Convert.ToBoolean(GetConfig("Generic", "enableSkinIdFields", false));
            enableHeliLoadOut = Convert.ToBoolean(GetConfig("Generic", "enableHeliLoadOut", true));
            enableBradleyLoadOut = Convert.ToBoolean(GetConfig("Generic", "enableBradleyLoadOut", true));
            enableFancyDropLoot = Convert.ToBoolean(GetConfig("Generic", "enableFancyDropLoot", false));
            useSkinBoxSkins = Convert.ToBoolean(GetConfig("Generic", "useSkinBoxSkins", false));
            excludeCustomLootSpawns = Convert.ToBoolean(GetConfig("Generic", "excludeCustomLootSpawns", true));
            excludeEventLoot = Convert.ToBoolean(GetConfig("Generic", "excludeEventLoot", true));
            blueprintProbability = Convert.ToDouble(GetConfig("Generic", "blueprintProbability", 0.11));
            renewRaritysNewProtocol = Convert.ToBoolean(GetConfig("Generic", "renewRaritysNewProtocol", false));
            multiplyConditionedItems = Convert.ToBoolean(GetConfig("Generic", "multiplyConditionedItems", false));
            alignItemRarity = Convert.ToBoolean(GetConfig("Generic", "alignItemRarity", false));
            alignBlueprintRarity = Convert.ToBoolean(GetConfig("Generic", "alignBlueprintRarity", false));
            extendedStatus = Convert.ToBoolean(GetConfig("Generic", "extendedStatus", true));
            version = Convert.ToString(GetConfig("Debug", "version", this.Version.ToString()));
            if (version != this.Version.ToString()) {
                Config["Debug", "version"] = this.Version.ToString();
                Changed = true;
            }
            if (blueprintProbability > 0.9d) blueprintProbability = 0.9d;
            var configremoval = false;
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("itemSlotVariance")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("itemSlotVariance");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("enableLootFraction")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("enableLootFraction");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("enableScrapSpawn")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("enableScrapSpawn");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("itemCanSpawnAsBlueprint")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("itemCanSpawnAsBlueprint");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("enableDefaultRarityOverrides")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("enableDefaultRarityOverrides");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("disableRefreshFunctions")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("disableRefreshFunctions");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("debugLootRepopulation")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("debugLootRepopulation");
                configremoval = true;
            }
            if ((Config.Get("Generic") as Dictionary<string, object>).ContainsKey("refreshMinutes")) {
                (Config.Get("Generic") as Dictionary<string, object>).Remove("refreshMinutes");
                configremoval = true;
            }
            if ((Config.Get("ExcludeFromMultiply") != null)) {
                Config.Remove("ExcludeFromMultiply");
                configremoval = true;
            }
            if ((Config.Get("Weapons") != null)) {
                Config.Remove("Weapons");
                configremoval = true;
            }
            foreach (var category in lootCategoryLimits.ToList()) {
                if (category.Key.ToString() == "All" || category.Key.ToString() == "Common" || category.Key.ToString() == "Search") {
                    lootCategoryLimits.Remove(category.Key);
                    configremoval = true;
                    continue;
                }
                var cat = category.Value as Dictionary<string, object>;
                if (cat.ContainsKey("VanillaMultiplier")) {
                    int tmp = (int)cat["VanillaMultiplier"];
                    cat.Add("LootMultiplier", tmp);
                    cat.Remove("VanillaMultiplier");
                    configremoval = true;
                }
            }
            if (!Changed && !configremoval) return;
            SaveConfig();
            Changed = false;
        }
        protected override void LoadDefaultConfig() {
            Config.Clear();
            LoadVariables();
        }
        void Loaded() {
            al = this;
            LoadVariables();
            InitConNames();
            guidToPathCopy = new Dictionary<string, string>(GameManifest.guidToPath);
        }
        void OnTerrainInitialized() {
            if (debugLogEnabled) LogToFile("population", $"{DateTime.Now.ToString()} - SERVERSTARTUP > fresh server startup detected", this);
        }
        void OnServerInitialized() {
            if (initialized) return;
            int varCount = (Config["Generic"] as Dictionary<string, object>).Count;
            alVars = new ConsoleSystem.Command[varCount];
            int i = 0;
            foreach (var conf in (Config["Generic"] as Dictionary<string, object>)) {
                alVars[i] = new ConsoleSystem.Command {
                    Name = conf.Key, Parent = "al", FullName = "al." +conf.Key.ToLower(), ServerAdmin = true, Arguments = "alphaloot", Description = alVarDescriptions.ContainsKey(conf.Key.ToLower()) && alVarDescriptions[conf.Key.ToLower()] != string.Empty ? $"| {alVarDescriptions[conf.Key.ToLower()]} |" : "| no description - contact the author |", Variable = true, GetOveride = (() => Config["Generic", conf.Key].ToString()), SetOveride = delegate(string str) {
                        bool changed = false;
                        TypeCode typeCode = Convert.GetTypeCode(conf.Value);
                        switch(typeCode ) {
                            case TypeCode.Boolean : if (conf.Value.ToString().ToBool() != str.ToBool()) {
                                Config["Generic", conf.Key] = str.ToBool();
                                changed = true;
                            }
                            break;
                            case TypeCode.Single : if (conf.Value.ToString().ToFloat() != str.ToFloat()) {
                                Config["Generic", conf.Key] = str.ToFloat();
                                changed = true;
                            }
                            break;
                            case TypeCode.Int32 : if (conf.Value.ToString().ToInt() != str.ToInt()) {
                                Config["Generic", conf.Key] = str.ToInt();
                                changed = true;
                            }
                            break;
                            default : break;
                        }
                        if (changed) {
                            Config.Save();
                            manualReload = true;
                            LoadConfig();
                            LoadVariables();
                            NextFrame(()=>ServerMgr.Instance.StartCoroutine(UpdateInternals(true)));
                        }
                    }
                }
                ;
                i++;
            }
            foreach (var alCmd in alCmdDescriptions) {
                if (ConsoleSystem.Index.Server.Dict.ContainsKey("al."+alCmd.Key)) {
                    ConsoleSystem.Index.Server.Dict["al."+alCmd.Key].Description = alCmd.Value;
                    ConsoleSystem.Index.Server.Dict["al."+alCmd.Key].Arguments = "alphaloot";
                }
            }
            foreach (var indexCmd in ConsoleSystem.Index.Server.Dict.Where(k => k.Key.StartsWith("al.") && (k.Value.Description == null || k.Value.Description == string.Empty))) {
                indexCmd.Value.Arguments = "alphaloot";
                indexCmd.Value.Description = "no description - contact the author -";
            }
            foreach (var alVar in alVars) ConsoleSystem.Index.Server.Dict[alVar.FullName.ToLower()] = alVar;
            ConsoleSystem.Index.All = ConsoleSystem.Index.Server.Dict.Values.ToArray<ConsoleSystem.Command>();
            NextFrame(()=> ServerMgr.Instance.StartCoroutine(UpdateInternals(true)));
        }
        void Unload() {
            if (Interface.Oxide.IsShuttingDown) return;
            ServerMgr.Instance.CancelInvoke(this.FixLoot);
            foreach (var cmd in alVars) ConsoleSystem.Index.Server.Dict.Remove(cmd.FullName.ToLower());
            var objsa = UnityEngine.Object.FindObjectsOfType<AdminLootHandler>().ToList();
            if (objsa.Count > 0) foreach (var obj in objsa) GameObject.Destroy(obj);
        }
        void OnPluginLoaded(Plugin name) {
            if (initialized && enableFancyDropLoot && name.Name == "FancyDrop") {
                if (FancyDrop?.Call("getFancyDropTypes") == null) return;
                Dictionary<string, object> setupDropTypes = FancyDrop.Call("getFancyDropTypes") as Dictionary<string, object>;
                if (setupDropTypes != null && setupDropTypes.Count != 0) GetFancyDropLoot(setupDropTypes);
            }
        }
        object OnLootSpawn(LootContainer container) {
            if (!initialized || !pluginEnabled || container == null || (!container.initialLootSpawn && !(container is SupplyDrop)) || (!(container is SupplyDrop) && container.OwnerID != 0uL) ) return null;
            if (CustomLootSpawns && excludeCustomLootSpawns && (bool)CustomLootSpawns.Call("IsLootBox", container.GetComponent<BaseEntity>())) return null;
            if (EventLoot && excludeEventLoot && (bool)EventLoot.Call("IsEventLootContainer", container.GetComponent<BaseEntity>())) return null;
            if (enableHeliLoadOut && container.ShortPrefabName == "heli_crate") {
                if (PopulateSpecial(container, false)) return true;
            }
            if (enableBradleyLoadOut && container.ShortPrefabName == "bradley_crate") {
                if (PopulateSpecial(container, false)) return true;
            }
            if (enableFancyDropLoot && container is SupplyDrop && FancyDrop) {
                if (blockPlayerItemInput && container.inventory != null) container.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
                return null;
            }
            if (PopulateContainer(container, false)) return true;
            return null;
        }
        void OnEntityKill(BaseNetworkable entity) {
            if (!initialized || !pluginEnabled || entity == null) return;
            if (enableHeliLoadOut && entity is BaseHelicopter) {
                timer.Once(1.0f, () => {
                    rngHeli = new Random();
                    rngHeliList = new List<int>();
                }
                );
            }
            if (enableBradleyLoadOut && entity is BradleyAPC) {
                timer.Once(1.0f, () => {
                    rngBradley = new Random();
                    rngBradleyList = new List<int>();
                }
                );
            }
        }
        IEnumerator UpdateInternals(bool doLog = true, bool reHeli = false, bool reBradley = false, bool reFancy = false, ConsoleSystem.Arg arg = null) {
            ClearDictionarys();
            SaveExportNames();
            LoadAllContainers();
            LoadItemRaritys(doLog);
            LoadLootFractions(doLog);
            LoadLootTables(doLog, arg);
            GetFancyDropLoot(new Dictionary<string, object>(), reFancy);
            GetHeliLoot(reHeli);
            GetBradleyLoot(reBradley);
            if (lootStackFixEnable) {
                FixLoot();
                ServerMgr.Instance.InvokeRepeating(this.FixLoot, 1800f, 1800f);
            }
            GetItemSkins(arg);
            LoadGunConfig();
            if (!pluginEnabled || Changed || firstSetup) {
                if (Changed) Config["Generic", "pluginEnabled"] = false;
                SaveConfig();
                Changed = false;
                if (doLog) PrintWarningCl("Plugin running in passive mode.Activate by command 'al.enable'", arg);
                yield break;
            }
            foreach (var data in lootData) {
                if (!(bool)(lootContainers[data.Key] as Dictionary<string, object>)["Enabled"] || (enableBradleyLoadOut && data.Key == "bradley_crate") || (enableHeliLoadOut && data.Key == "heli_crate") || (enableFancyDropLoot && FancyDrop && FancyDrop.IsLoaded && data.Key == "supply_drop")) continue;
                Items.Add(data.Key, new List<string>[5]);
                Blueprints.Add(data.Key, new List<string>[5]);
                for (var i = 0; i < 5; ++i) {
                    Items[data.Key][i] = new List<string>();
                    Blueprints[data.Key][i] = new List<string>();
                }
                var limits = (Dictionary<string, object>)data.Value;
                foreach (var limit in limits.ToList()) {
                    if (limit.Value is Dictionary<string, object>) {
                        var testFields = limit.Value as Dictionary<string, object>;
                        if (!testFields.ContainsKey("Min") || !testFields.ContainsKey("Max")) {
                            PrintWarningCl($"Item '{limit.Key}' of '{data.Key}' ignored by missing 'Min|Max'", arg);
                            continue;
                        }
                        else if ((int)testFields["Min"] == 0 || (int)testFields["Max"] == 0) {
                            PrintWarningCl($"Item '{limit.Key}' of '{data.Key}' ignored by having '0'", arg);
                            continue;
                        }
                    }
                    else if ((int)limit.Value < 1) {
                        PrintWarningCl($"Item '{limit.Key}' of '{data.Key}' ignored by having '0'", arg);
                        continue;
                    }
                    string name = limit.Key;
                    bool isBP = name.EndsWith(".bp") || name.EndsWith(".blueprint") ? true : false;
                    if (isBP) name = name.Replace(".bp", "").Replace(".blueprint", "");
                    ItemDefinition def = ItemManager.FindItemDefinition(name);
                    if (def != null) {
                        if (def.GetComponent<ItemModEntity>() != null && def.GetComponent<ItemModEntity>().entityPrefab != null && !guidToPathCopy.ContainsKey(def.GetComponent<ItemModEntity>().entityPrefab.guid)) continue;
                        if (isBP && def.Blueprint != null && def.Blueprint.isResearchable) {
                            {
                                var r = rarityOverridesBlueprints.ContainsKey(name) ? (int)rarityOverridesBlueprints[name] : (int)def.rarity;
                                if (!Blueprints[data.Key][alignBlueprintRarity ? 0 : r].Contains(name)) Blueprints[data.Key][alignBlueprintRarity ? 0 : r].Add(name);
                            }
                        }
                        {
                            var r = rarityOverridesItems.ContainsKey(name) ? (int)rarityOverridesItems[name] : (int)def.rarity;
                            if (!isBP && !Items[data.Key][alignItemRarity ? 0 : r].Contains(name)) Items[data.Key][alignItemRarity ? 0 : r].Add(name);
                        }
                    }
                }
                totalItemWeight.Add(data.Key, 0);
                totalBlueprintWeight.Add(data.Key, 0);
                itemWeights.Add(data.Key, new int[5]);
                blueprintWeights.Add(data.Key, new int[5]);
                for (var i = 0; i < 5; ++i) {
                    totalItemWeight[data.Key] += (itemWeights[data.Key][i] = ItemWeight(baseItemRarity, i) * Items[data.Key][i].Count);
                    totalBlueprintWeight[data.Key] += (blueprintWeights[data.Key][i] = ItemWeight(baseItemRarity, i) * Blueprints[data.Key][i].Count);
                }
            }
            int populatedContainers = 0;
            if (debugLogEnabled) LogToFile("population", $"{DateTime.Now.ToString()} - START > Initial LootPopulation started", this);
            foreach (var container in BaseNetworkable.serverEntities.Where(p => p != null && p.GetComponent<BaseEntity>() != null && p is LootContainer).Cast<LootContainer>().ToList()) {
                if ((!container.initialLootSpawn && !(container is SupplyDrop)) || (!(container is SupplyDrop) && container.OwnerID != 0uL)) continue;
                if(excludeCustomLootSpawns && CustomLootSpawns && (bool)CustomLootSpawns?.Call("IsLootBox", container.GetComponent<BaseEntity>())) continue;
                if (excludeEventLoot && EventLoot && (bool)EventLoot?.Call("IsEventLootContainer", container.GetComponent<BaseEntity>())) continue;
                if (enableHeliLoadOut && container.ShortPrefabName == "heli_crate") {
                    if (PopulateSpecial(container, true)) populatedContainers++;
                    continue;
                }
                if (enableBradleyLoadOut && container.ShortPrefabName == "bradley_crate") {
                    if (PopulateSpecial(container, true)) populatedContainers++;
                    continue;
                }
                if (enableFancyDropLoot && container is SupplyDrop && FancyDrop) continue;
                if (PopulateContainer(container, true)) populatedContainers++;
            }
            if (debugLogEnabled) LogToFile("population", $"{DateTime.Now.ToString()} - STARTED > Initial LootPopulation done with '{populatedContainers}' containers", this);
            if (doLog) PutsCl($"Populated '{populatedContainers}' LootContainer with custom Loot.", arg);
            if (!initialized && extendedStatus) {
                var sb = new StringBuilder();
                sb.AppendLine();
                sb.AppendLine(" AlphaLoot extended status | extendedStatus (True)");
                if (enableBradleyLoadOut) sb.AppendLine("  'enableBradleyLoadOut' (True) | using BradleyLoot.json for 'bradley_crate'");
                else sb.AppendLine("  'enableBradleyLoadOut' (False) | using LootTables.json for 'bradley_crate'");
                if (enableHeliLoadOut) sb.AppendLine("  'enableHeliLoadOut' (True) | using HeliLoot.json for 'heli_crate'");
                else sb.AppendLine("  'enableHeliLoadOut' (False) | using LootTables.json for 'heli_crate'");
                if (enableFancyDropLoot && FancyDrop) sb.AppendLine("  'enableFancyDropLoot' (True) | using FancyDropLoot.json for 'supply_drop'");
                else sb.AppendLine("  'enableFancyDropLoot' (False) | using LootTables.json for 'supply_drop'");
                sb.AppendLine("  For easy edit of these data-files, this is highly recommended > http://jsoneditoronline.org/ <");
                sb.AppendLine("  Use 'NamesList.json' (read-only) for item lookup | or use 'al.searchitems'");
                sb.AppendLine("  Find All main-config variables & commands | Srv: 'find alphaloot' | Cl: 'sv find alphaloot'");
                PutsCl(sb.ToString(), arg);
            }
            initialized = true;
            yield return null;
        }
        void PutsCl(string format, ConsoleSystem.Arg arg = null) {
            if (arg != null && arg.Connection != null) SendReply(arg, format);
            Puts(format);
        }
        void PrintWarningCl(string format, ConsoleSystem.Arg arg = null) {
            if (arg != null && arg.Connection != null) SendReply(arg, format);
            PrintWarning(format);
        }
        void SendReplyCl(ConsoleSystem.Arg arg, string format) {
            if (arg.Connection != null) SendReply(arg, format);
            Puts(format);
        }
        void ClearDictionarys() {
            lootData.Clear();
            lootContainers.Clear();
            heliData.Clear();
            bradleyData.Clear();
            fancyDropData.Clear();
            itemsDrop.Clear();
            blueprintsDrop.Clear();
            itemWeightsDrop.Clear();
            blueprintWeightsDrop.Clear();
            totalItemWeightDrop.Clear();
            totalBlueprintWeightDrop.Clear();
            Items.Clear();
            Blueprints.Clear();
            itemWeights.Clear();
            blueprintWeights.Clear();
            totalItemWeight.Clear();
            totalBlueprintWeight.Clear();
            newGameItems.Clear();
            showNewGameItems.Clear();
            rarityOverridesBlueprints.Clear();
            rarityOverridesItems.Clear();
            AllContainerTypes.Clear();
            AllLootSpawns.Clear();
        }
        void GetItemSkins(ConsoleSystem.Arg arg = null) {
            if (skinsLoaded) return;
            foreach (var itemDef in ItemManager.GetItemDefinitions()) {
                List<ulong> skins;
                skins = new List<ulong> {
                    0
                }
                ;
                skins.AddRange(ItemSkinDirectory.ForItem(itemDef).Select(skin => Convert.ToUInt64(skin.id)));
                skinsCache.Add(itemDef.shortname, skins);
            }
            bool skinBoxEnabled = SkinBox && useSkinBoxSkins;
            skinsLoaded = true;
            if (includeWorkShopSkins && !skinBoxEnabled) {
                GetWorkshopSkins(arg);
                return;
            }
            if (skinBoxEnabled) {
                GetSkinBoxSkins(arg);
                return;
            }
            if (includeWorkShopSkins) {
                GetWorkshopSkins(arg);
            }
        }
        void GetWorkshopSkins(ConsoleSystem.Arg arg = null) {
            int updated = 0;
            foreach (var shopskin in Rust.Workshop.Approved.All.Where(skin => skin.Skinnable.ItemName != null && skin.Skinnable.ItemName != "")) {
                if (!skinsCache.ContainsKey(shopskin.Skinnable.ItemName)) skinsCache[shopskin.Skinnable.ItemName] = new List<ulong>();
                if (!skinsCache[shopskin.Skinnable.ItemName].Contains(shopskin.WorkshopdId)) {
                    skinsCache[shopskin.Skinnable.ItemName].Add(shopskin.WorkshopdId);
                    updated++;
                }
            }
            if (updated > 0) PutsCl($"SkinCache filled with '{updated}' skins", arg);
        }
        void OnSkinCacheUpdate(Dictionary<string, LinkedList<ulong>> skinsCall, bool loading) {
            if (!initialized || !skinsLoaded || !useSkinBoxSkins) return;
            skinsCache = new Dictionary<string, List<ulong>>();
            foreach (var skinList in (skinsCall as Dictionary<string, LinkedList<ulong>>)) {
                skinsCache.Add(skinList.Key, new List<ulong>());
                foreach (var skin in skinList.Value as LinkedList<ulong>) skinsCache[skinList.Key].Add(skin);
            }
            int count = 0;
            int items = 0;
            foreach (var skin in skinsCache) {
                if (skin.Value.Count > 1) {
                    count += skin.Value.Count-1;
                    items++;
                }
            }
            if (loading) Puts($"Reveived '{items}' items from SkinBox with '{count}' skins at all");
            else Puts($"Reveived SkinBox skins update");
        }
        void GetSkinBoxSkins(ConsoleSystem.Arg arg = null) {
            var skinsCall = SkinBox?.Call("getSkincache") ?? null;
            if (skinsCall == null || skinsCall is bool) {
                GetWorkshopSkins();
                return;
            }
            skinsCache = new Dictionary<string, List<ulong>>();
            foreach (var skinList in (skinsCall as Dictionary<string, LinkedList<ulong>>)) {
                skinsCache.Add(skinList.Key, new List<ulong>());
                foreach (var skin in skinList.Value as LinkedList<ulong>) skinsCache[skinList.Key].Add(skin);
            }
            int count = 0;
            int items = 0;
            foreach (var skin in skinsCache) {
                if (skin.Value.Count > 1) {
                    count += skin.Value.Count-1;
                    items++;
                }
            }
            PutsCl($"Reveived '{items}' items from SkinBox with '{count}' skins at all", arg);
        }
        object OnFancyDropCrate(Dictionary<string, object> cratesettings, bool internalCall = false) {
            if(!internalCall) if (!enableFancyDropLoot || !cratesettings.ContainsKey("droptype")) return null;
            string crateName = string.Empty;
            if (internalCall) crateName = "regular";
            else crateName =(string)cratesettings["droptype"];
            if (fancyDropData.ContainsKey(crateName)) {
                if (((fancyDropData[crateName] as Dictionary<string, object>)["ItemsList"] as Dictionary<string, object>).Count > 0) {
                    var crateType = fancyDropData[crateName] as Dictionary<string, object>;
                    var maxItemCount = (crateType["ItemsList"] as Dictionary<string, object>).Count;
                    var itemCount = 6;
                    if (crateType.ContainsKey("ItemMin") && crateType.ContainsKey("ItemMax")) {
                        if ((int)crateType["ItemMin"] <= (int)crateType["ItemMax"]) itemCount = UnityEngine.Random.Range((int)crateType["ItemMin"], (int)crateType["ItemMax"]);
                        else itemCount = UnityEngine.Random.Range((int)crateType["ItemMax"], (int)crateType["ItemMin"]);
                    }
                    if (itemCount > maxItemCount) itemCount = maxItemCount;
                    var items = new List<Item>();
                    var itemNames = new List<string>();
                    var itemBlueprints = new List<int>();
                    var maxRetry = 10 * itemCount;
                    int divider = 1;
                    if (crateType.ContainsKey("ItemDivider")) divider = (int)crateType["ItemDivider"];
                    int conMaxBlueprintSpawns = (int)fancyDropLoot["CrateSettings", "MaxBlueprintSpawns"];
                    for (int i = 0; i < itemCount; ++i) {
                        if (maxRetry == 0) break;
                        Item item = null;
                        item = MightyRNGDrop(crateName, divider, itemCount, (bool)(itemBlueprints.Count >= conMaxBlueprintSpawns));
                        if (item == null) {
                            --maxRetry;
                            --i;
                            continue;
                        }
                        if (itemNames.Contains(item.info.shortname) || (item.IsBlueprint() && itemBlueprints.Contains(item.blueprintTarget))) {
                            item.Remove(0f);
                            --maxRetry;
                            --i;
                            continue;
                        }
                        else if (item.IsBlueprint()) itemBlueprints.Add(item.blueprintTarget);
                        else itemNames.Add(item.info.shortname);
                        items.Add(item);
                        if (!item.IsBlueprint() && item.info.category == ItemCategory.Weapon && weaponAmmoConfig.ContainsKey(item.info.shortname)) {
                            var setup = weaponAmmoConfig[item.info.shortname] as Dictionary<string, object>;
                            var magazine = (item.GetHeldEntity() as BaseProjectile).primaryMagazine;
                            if ((int)setup["roundsWeaponAmount"] >= 0) magazine.contents = Math.Min(magazine.capacity, (int)setup["roundsWeaponAmount"]);
                            var ammo = ItemManager.FindItemDefinition((string)setup["roundsWeaponType"]);
                            if (ammo != null) magazine.ammoType = ammo;
                            if ((bool)setup["xtraRoundsEnabled"]) {
                                var xType = ItemManager.FindItemDefinition((string)setup["xtraRoundsType"]);
                                if (xType != null) {
                                    var xAmmo = ItemManager.Create(xType, (int)setup["xtraRoundsAmount"]);
                                    if (xAmmo != null) items.Add(xAmmo);
                                }
                            }
                        }
                    }
                    bool conLootFraction = (bool)fancyDropLoot["CrateSettings", "LootFraction"];
                    int conScrapAmount = (int)fancyDropLoot["CrateSettings", "ScrapAmount"];
                    int conScrapVariance = (int)fancyDropLoot["CrateSettings", "ScrapVariance"];
                    if (conLootFraction) {
                        foreach (Item current in items.ToList()) if (current.hasCondition) current.condition = UnityEngine.Random.Range(current.info.condition.foundCondition.fractionMin, current.info.condition.foundCondition.fractionMax) * current.info.condition.max;
                    }
                    if (conScrapAmount > 0) {
                        int scrapCount = 0;
                        if (conScrapVariance != 0) scrapCount = Mathf.RoundToInt(UnityEngine.Random.Range(Convert.ToSingle(Mathf.Min(conScrapAmount, conScrapAmount + conScrapVariance))*100f, Convert.ToSingle(Mathf.Max(conScrapAmount, conScrapAmount + conScrapVariance))*100f) / 100f);
                        else scrapCount = conScrapAmount;
                        Item item = ItemManager.Create(ItemManager.FindItemDefinition("scrap"), scrapCount, 0uL);
                        items.Add(item);
                    }
                    return items;
                }
            }
            return null;
        }
        void FixLoot() {
            var excludes = lootStackFixExclude.ConvertAll(obj => Convert.ToString(obj));
            var spawns = UnityEngine.Object.FindObjectsOfType<LootContainer>().Where(c => !excludes.Contains(c.ShortPrefabName)).OrderBy(c => c.transform.position.x).ThenBy(c => c.transform.position.z).ThenBy(c => c.transform.position.z).ToList();
            var count = spawns.Count();
            var racelimit = count * count;
            var antirace = 0;
            var deleted = 0;
            for (var i = 0; i < count; i++) {
                var box = spawns[i];
                var next = i + 1;
                var pos = new Vector2(box.transform.position.x, box.transform.position.z);
                if (++antirace > racelimit) return;
                while (next < count) {
                    var box2 = spawns[next];
                    var pos2 = new Vector2(box2.transform.position.x, box2.transform.position.z);
                    var distance = Vector2.Distance(pos, pos2);
                    if (++antirace > racelimit) return;
                    if (distance < lootStackFixRange) {
                        spawns.RemoveAt(next);
                        count--;
                        if (box2.gameObject.GetComponent<SpawnPointInstance>()) box2.gameObject.GetComponent<SpawnPointInstance>().Invoke("OnDestroy", 0);
                        (box2 as BaseEntity).Kill();
                        deleted++;
                    }
                    else break;
                }
            }
            if (deleted > 0) Puts($"Removed {deleted} stacked LootContainer.");
        }
        Item MightyRNG(string type, int divider, int itemCount, bool blockBPs = false) {
            bool asBP = (rng.NextDouble() < blueprintProbability && !blockBPs);
            List<string> selectFrom;
            int limit = 0;
            string itemName;
            Item item;
            if (divider < 1) divider = 1;
            int maxRetry = 10 * itemCount;
            do {
                selectFrom = null;
                item = null;
                if (asBP) {
                    var r = rng.Next(totalBlueprintWeight[type]);
                    for (var i = 0; i < 5; ++i) {
                        limit += blueprintWeights[type][i];
                        if (r < limit) {
                            selectFrom = Blueprints[type][i];
                            break;
                        }
                    }
                }
                else {
                    var r = rng.Next(totalItemWeight[type]);
                    for (var i = 0; i < 5; ++i) {
                        limit += itemWeights[type][i];
                        if (r < limit) {
                            selectFrom = Items[type][i];
                            break;
                        }
                    }
                }
                if (selectFrom == null) {
                    if (--maxRetry <= 0) break;
                    continue;
                }
                itemName = selectFrom[rng.Next(0, selectFrom.Count)];
                ItemDefinition itemDef = ItemManager.FindItemDefinition(itemName);
                if (asBP && itemDef.Blueprint != null && itemDef.Blueprint.isResearchable) {
                    var blueprintBaseDef = ItemManager.FindItemDefinition("blueprintbase");
                    item = ItemManager.Create(blueprintBaseDef, 1, 0uL);
                    item.blueprintTarget = itemDef.itemid;
                }
                else {
                    object limits;
                    bool DropSkinned = false;
                    if (lootCategoryLimits.TryGetValue(itemDef.category.ToString(), out limits)) DropSkinned = (bool)(limits as Dictionary<string, object>)["DropSkinned"];
                    if (DropSkinned && skinsCache[itemName].Count > 1) item = ItemManager.Create(itemDef, 1, skinsCache[itemName].GetRandom());
                    else item = ItemManager.CreateByName(itemName, 1);
                }
                if (item == null || item.info == null) continue;
                break;
            }
            while (true);
            if (item == null) return null;
            object itemLimit;
            if (!item.IsBlueprint() && (lootData[type] as Dictionary<string, object>).TryGetValue(item.info.shortname, out itemLimit)) {
                if ((itemLimit as Dictionary<string, object>) != null) {
                    Dictionary<string, object> limits = itemLimit as Dictionary<string, object>;
                    item.amount = UnityEngine.Random.Range(Math.Min((int)limits["Min"], (int)limits["Max"]), Math.Max((int)limits["Min"], (int)limits["Max"]));
                    if (enableSkinIdFields && limits.ContainsKey("SkinId") && (int)limits["SkinId"] != 0) item.skin = Convert.ToUInt64(limits["SkinId"]);
                }
                else if ((int)itemLimit > 1) item.amount = UnityEngine.Random.Range(Mathf.CeilToInt(Convert.ToSingle(itemLimit) / divider), (int)itemLimit);
            }
            item.OnVirginSpawn();
            return item;
        }
        Item MightyRNGDrop(string type, int divider, int itemCount, bool blockBPs = false) {
            bool asBP = (rng.NextDouble() < fancyDropBpProbability && !blockBPs);
            List<string> selectFrom;
            int limit = 0;
            string itemName;
            Item item;
            if (divider < 1) divider = 1;
            int maxRetry = 10 * itemCount;
            do {
                selectFrom = null;
                item = null;
                if (asBP) {
                    var r = rng.Next(tota
// ... [Code preview truncated due to length. Full source in attached file] ...

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