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

FREE NpcHordeRustEdit : 1.0.6 1.0.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using System;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core.Plugins;
using Oxide.Plugins.NpcHordeRustEditExtensionMethods;
namespace Oxide.Plugins {
    [Info("NpcHordeRustEdit", "KpucTaJl", "1.0.6")]
    internal class NpcHordeRustEdit : RustPlugin {
#region Data
        private const bool En = true;
        public class ItemConfig {
            [JsonProperty("ShortName")]
            public string ShortName {
                get;
                set;
            }
            [JsonProperty(En ? "Minimum" : "Минимальное кол-во")]
            public int MinAmount {
                get;
                set;
            }
            [JsonProperty(En ? "Maximum" : "Максимальное кол-во")]
            public int MaxAmount {
                get;
                set;
            }
            [JsonProperty(En ? "Chance [0.0-100.0]" : "Шанс выпадения предмета [0.0-100.0]")]
            public float Chance {
                get;
                set;
            }
            [JsonProperty(En ? "Is this a blueprint? [true/false]" : "Это чертеж? [true/false]")]
            public bool IsBluePrint {
                get;
                set;
            }
            [JsonProperty("SkinID (0 - default)")]
            public ulong SkinID {
                get;
                set;
            }
            [JsonProperty(En ? "Name (empty - default)" : "Название (empty - default)")]
            public string Name {
                get;
                set;
            }
        }
        public class LootTableConfig {
            [JsonProperty(En ? "Minimum numbers of items" : "Минимальное кол-во элементов")]
            public int Min {
                get;
                set;
            }
            [JsonProperty(En ? "Maximum numbers of items" : "Максимальное кол-во элементов")]
            public int Max {
                get;
                set;
            }
            [JsonProperty(En ? "Use minimum and maximum values? [true/false]" : "Использовать минимальное и максимальное значение? [true/false]")]
            public bool UseCount {
                get;
                set;
            }
            [JsonProperty(En ? "List of items" : "Список предметов")]
            public List<ItemConfig> Items {
                get;
                set;
            }
        }
        public class PrefabConfig {
            [JsonProperty(En ? "Chance [0.0-100.0]" : "Шанс выпадения [0.0-100.0]")]
            public float Chance {
                get;
                set;
            }
            [JsonProperty(En ? "The path to the prefab" : "Путь к prefab-у")]
            public string PrefabDefinition {
                get;
                set;
            }
        }
        public class PrefabLootTableConfig {
            [JsonProperty(En ? "Minimum numbers of prefabs" : "Минимальное кол-во prefab-ов")]
            public int Min {
                get;
                set;
            }
            [JsonProperty(En ? "Maximum numbers of prefabs" : "Максимальное кол-во prefab-ов")]
            public int Max {
                get;
                set;
            }
            [JsonProperty(En ? "Use minimum and maximum values? [true/false]" : "Использовать минимальное и максимальное значение? [true/false]")]
            public bool UseCount {
                get;
                set;
            }
            [JsonProperty(En ? "List of prefabs" : "Список prefab-ов")]
            public List<PrefabConfig> Prefabs {
                get;
                set;
            }
        }
        public class NpcBelt {
            [JsonProperty("ShortName")]
            public string ShortName {
                get;
                set;
            }
            [JsonProperty("SkinID (0 - default)")]
            public ulong SkinID {
                get;
                set;
            }
            [JsonProperty(En ? "Mods" : "Модификации на оружие")]
            public HashSet<string> Mods {
                get;
                set;
            }
            [JsonProperty(En ? "Ammo" : "Боеприпасы")]
            public string Ammo {
                get;
                set;
            }
            [JsonProperty(En ? "Probability Percent [0.0-100.0]" : "Вероятность [0.0-100.0]")]
            public float Chance {
                get;
                set;
            }
        }
        public class NpcWear {
            [JsonProperty("ShortName")]
            public string ShortName {
                get;
                set;
            }
            [JsonProperty("SkinID (0 - default)")]
            public ulong SkinID {
                get;
                set;
            }
        }
        public class PresetConfig {
            [JsonProperty(En ? "Minimum" : "Минимальное кол-во")]
            public int Min {
                get;
                set;
            }
            [JsonProperty(En ? "Maximum" : "Максимальное кол-во")]
            public int Max {
                get;
                set;
            }
            [JsonProperty(En ? "List of locations" : "Список расположений")]
            public List<string> Positions {
                get;
                set;
            }
            [JsonProperty(En ? "NPCs setting" : "Настройки NPC")]
            public NpcConfig Config {
                get;
                set;
            }
            [JsonProperty(En ? "Which loot table should the plugin use? (0 - default; 1 - own; 2 - AlphaLoot; 3 - CustomLoot; 4 - loot table of the Rust objects; 5 - combine the 1 and 4 methods)" : "Какую таблицу предметов необходимо использовать? (0 - стандартную; 1 - собственную; 2 - AlphaLoot; 3 - CustomLoot; 4 - таблица предметов объектов Rust; 5 - совместить 1 и 4 методы)")]
            public int TypeLootTable {
                get;
                set;
            }
            [JsonProperty(En ? "Loot table from prefabs (if the loot table type is 4 or 5)" : "Таблица предметов из prefab-ов (если тип таблицы предметов - 4 или 5)")]
            public PrefabLootTableConfig PrefabLootTable {
                get;
                set;
            }
            [JsonProperty(En ? "Own loot table (if the loot table type is 1 or 5)" : "Собственная таблица предметов (если тип таблицы предметов - 1 или 5)")]
            public LootTableConfig OwnLootTable {
                get;
                set;
            }
        }
        public class NpcConfig {
            [JsonProperty(En ? "Name" : "Название")]
            public string Name {
                get;
                set;
            }
            [JsonProperty(En ? "Health" : "Кол-во ХП")]
            public float Health {
                get;
                set;
            }
            [JsonProperty(En ? "Chase Range" : "Дальность погони за целью")]
            public float ChaseRange {
                get;
                set;
            }
            [JsonProperty(En ? "Attack Range Multiplier" : "Множитель радиуса атаки")]
            public float AttackRangeMultiplier {
                get;
                set;
            }
            [JsonProperty(En ? "Sense Range" : "Радиус обнаружения цели")]
            public float SenseRange {
                get;
                set;
            }
            [JsonProperty(En ? "Target Memory Duration [sec.]" : "Длительность памяти цели [sec.]")]
            public float MemoryDuration {
                get;
                set;
            }
            [JsonProperty(En ? "Scale damage" : "Множитель урона")]
            public float DamageScale {
                get;
                set;
            }
            [JsonProperty(En ? "Aim Cone Scale" : "Множитель разброса")]
            public float AimConeScale {
                get;
                set;
            }
            [JsonProperty(En ? "Speed" : "Скорость")]
            public float Speed {
                get;
                set;
            }
            [JsonProperty(En ? "Disable radio effects? [true/false]" : "Отключать эффекты рации? [true/false]")]
            public bool DisableRadio {
                get;
                set;
            }
            [JsonProperty(En ? "Remove a corpse after death? (it is recommended to use the true value to improve performance) [true/false]" : "Удалять труп после смерти? (рекомендуется использовать значение true для повышения производительности) [true/false]")]
            public bool IsRemoveCorpse {
                get;
                set;
            }
            [JsonProperty(En ? "Wear items" : "Одежда")]
            public HashSet<NpcWear> WearItems {
                get;
                set;
            }
            [JsonProperty(En ? "Belt items" : "Быстрые слоты")]
            public HashSet<NpcBelt> BeltItems {
                get;
                set;
            }
            [JsonProperty(En ? "Kit (it is recommended to use the previous 2 settings to improve performance)" : "Kit (рекомендуется использовать предыдущие 2 пункта настройки для повышения производительности)")]
            public string Kit {
                get;
                set;
            }
        }
        public class SensorConfig {
            [JsonProperty(En ? "Sensor position" : "Позиция сенсора")]
            public string Position {
                get;
                set;
            }
            [JsonProperty(En ? "Minimum time between the appearance of new NPCs [sec.]" : "Минимальное время между появлением новых NPC [sec.]")]
            public float Time {
                get;
                set;
            }
            [JsonProperty(En ? "Presets setting" : "Настройка пресетов")]
            public HashSet<PresetConfig> Npc {
                get;
                set;
            }
        }
        public class CustomMapConfig {
            [JsonProperty(En ? "ID" : "Идентификатор")]
            public string ID {
                get;
                set;
            }
            [JsonProperty(En ? "List of sensors" : "Список датчиков")]
            public HashSet<SensorConfig> Sensors {
                get;
                set;
            }
        }
        private void LoadCustomMapConfigs() {
            Puts("Loading files on the /oxide/data/NpcHordeRustEdit/ path has started...");
            foreach (string name in Interface.Oxide.DataFileSystem.GetFiles("NpcHordeRustEdit/")) {
                string fileName = name.Split('/').Last().Split('.').First();
                CustomMapConfig config = Interface.Oxide.DataFileSystem.ReadObject<CustomMapConfig>($"NpcHordeRustEdit/{fileName}");
                if (config == null) {
                    PrintError($"File {fileName} is corrupted and cannot be loaded!");
                    continue;
                }
                if (!string.IsNullOrEmpty(config.ID) && !_ids.Any(x => Math.Abs(x - Convert.ToSingle(config.ID)) < 0.001f)) {
                    PrintWarning($"File {fileName} cannot be loaded on the current map!");
                    continue;
                }
                Puts($"File {fileName} has been loaded successfully!");
                foreach (SensorConfig sensor in config.Sensors) {
                    foreach (PresetConfig preset in sensor.Npc) {
                        CheckLootTable(preset.OwnLootTable);
                        CheckPrefabLootTable(preset.PrefabLootTable);
                    }
                    _sensors.Add(sensor);
                }
                Interface.Oxide.DataFileSystem.WriteObject($"NpcHordeRustEdit/{fileName}", config);
            }
        }
        private readonly HashSet<SensorConfig> _sensors = new HashSet<SensorConfig>();
        private readonly HashSet<float> _ids = new HashSet<float>();
        private void LoadIDs() {
            foreach (RANDSwitch entity in BaseNetworkable.serverEntities.OfType<RANDSwitch>()) _ids.Add(entity.transform.position.x + entity.transform.position.y + entity.transform.position.z);
        }
#endregion Data
#region Oxide Hooks
        private object OnSensorDetect(HBHFSensor sensor, BasePlayer target) {
            if (!target.IsPlayer()) return null;
            SensorConfig config = _sensors.FirstOrDefault(x => Vector3.Distance(x.Position.ToVector3(), sensor.transform.position) < 1f);
            if (config == null) return null;
            ulong sensorID = sensor.net.ID.Value;
            if (_data.Any(x => x.ID == sensorID)) return null;
            SensorData data = new SensorData {
                ID = sensorID, Scientists = new HashSet<ScientistNPC>()
            }
            ;
            foreach (PresetConfig preset in config.Npc) {
                int count = UnityEngine.Random.Range(preset.Min, preset.Max + 1);
                List<Vector3> positions = preset.Positions.Select(x => x.ToVector3());
                JObject cfg = GetObjectConfig(preset.Config, sensor.transform.position.ToString());
                for (int i = 0; i < count; i++) {
                    Vector3 pos = positions.GetRandom();
                    positions.Remove(pos);
                    ScientistNPC npc = (ScientistNPC)NpcSpawn.Call("SpawnNpc", pos, cfg);
                    if (npc != null) data.Scientists.Add(npc);
                }
            }
            _data.Add(data);
            timer.In(config.Time, () => {
                foreach (ScientistNPC npc in data.Scientists) if (npc.IsExists()) npc.Kill();
                _data.Remove(data);
            }
            );
            return null;
        }
        private void OnServerInitialized() {
            LoadIDs();
            LoadCustomMapConfigs();
        }
        private void Unload() {
            foreach (SensorData data in _data) foreach (ScientistNPC npc in data.Scientists) if (npc.IsExists()) npc.Kill();
        }
#endregion Oxide Hooks
#region Helpers
        [PluginReference]
        private readonly Plugin NpcSpawn;
        public class SensorData {
            public ulong ID;
            public HashSet<ScientistNPC> Scientists;
        }
        private readonly HashSet<SensorData> _data = new HashSet<SensorData>();
        private JObject GetObjectConfig(NpcConfig config, string homePos) {
            float chance = UnityEngine.Random.Range(0.0f, 100.0f);
            NpcBelt belt = config.BeltItems.WhereToList(x => chance <= x.Chance).GetRandom();
            JArray belts = new JArray {
                new JObject {
                    ["ShortName"]
                    = belt.ShortName, ["Amount"] = 1, ["SkinID"] = belt.SkinID, ["Mods"] = new JArray {
                        belt.Mods
                    }
                    , ["Ammo"] = belt.Ammo
                }
                , new JObject {
                    ["ShortName"]
                    = "grenade.beancan", ["Amount"] = 1, ["SkinID"] = 0, ["Mods"] = new JArray(), ["Ammo"] = string.Empty
                }
            }
            ;
            return new JObject {
                ["Name"]
                = config.Name, ["WearItems"] = new JArray {
                    config.WearItems.Select(x => new JObject {
                        ["ShortName"]
                        = x.ShortName, ["SkinID"] = x.SkinID
                    }
                    )
                }
                , ["BeltItems"] = belts, ["Kit"] = config.Kit, ["Health"] = config.Health, ["RoamRange"] = 10f, ["ChaseRange"] = config.ChaseRange, ["SenseRange"] = config.SenseRange, ["ListenRange"] = config.SenseRange / 2f, ["AttackRangeMultiplier"] = config.AttackRangeMultiplier, ["CheckVisionCone"] = false, ["VisionCone"] = 135f, ["HostileTargetsOnly"] = false, ["DamageScale"] = config.DamageScale, ["TurretDamageScale"] = 1f, ["AimConeScale"] = config.AimConeScale, ["DisableRadio"] = config.DisableRadio, ["CanRunAwayWater"] = true, ["CanSleep"] = true, ["SleepDistance"] = 100f, ["Speed"] = config.Speed, ["AreaMask"] = 1, ["AgentTypeID"] = -1372625422, ["HomePosition"] = homePos, ["MemoryDuration"] = config.MemoryDuration, ["States"] = new JArray {
                    "RoamState", "ChaseState", "CombatState"
                }
            }
            ;
        }
#endregion Helpers
#region Spawn Loot
        private void OnCorpsePopulate(ScientistNPC entity, NPCPlayerCorpse corpse) {
            if (entity == null) return;
            SensorData data = _data.FirstOrDefault(x => x.Scientists.Contains(entity));
            if (data != null) {
                data.Scientists.Remove(entity);
                PresetConfig preset = GetPreset(entity.displayName);
                NextTick(() => {
                    if (corpse == null) return;
                    ItemContainer container = corpse.containers[0];
                    if (preset.TypeLootTable == 0) {
                        for (int i = container.itemList.Count - 1; i >= 0; i--) {
                            Item item = container.itemList[i];
                            if (preset.Config.WearItems.Any(x => x.ShortName == item.info.shortname)) {
                                item.RemoveFromContainer();
                                item.Remove();
                            }
                        }
                        return;
                    }
                    if (preset.TypeLootTable == 2 || preset.TypeLootTable == 3) {
                        if (preset.Config.IsRemoveCorpse && !corpse.IsDestroyed) corpse.Kill();
                        return;
                    }
                    container.ClearItemsContainer();
                    if (preset.TypeLootTable == 4 || preset.TypeLootTable == 5) AddToContainerPrefab(container, preset.PrefabLootTable);
                    if (preset.TypeLootTable == 1 || preset.TypeLootTable == 5) AddToContainerItem(container, preset.OwnLootTable);
                    if (preset.Config.IsRemoveCorpse && !corpse.IsDestroyed) corpse.Kill();
                }
                );
            }
        }
        private object CanPopulateLoot(ScientistNPC entity, NPCPlayerCorpse corpse) {
            if (entity == null || corpse == null) return null;
            if (_data.Any(x => x.Scientists.Contains(entity))) {
                PresetConfig preset = GetPreset(entity.displayName);
                if (preset.TypeLootTable == 2) return null;
                else return true;
            }
            return null;
        }
        private object OnCustomLootNPC(NetworkableId netID) {
            SensorData data = _data.FirstOrDefault(x => x.Scientists.Any(y => y.IsExists() && y.net.ID.Value == netID.Value));
            if (data == null) return null;
            ScientistNPC entity = data.Scientists.FirstOrDefault(x => x.IsExists() && x.net.ID.Value == netID.Value);
            if (entity != null) {
                PresetConfig preset = GetPreset(entity.displayName);
                if (preset.TypeLootTable == 3) return null;
                else return true;
            }
            return null;
        }
        private PresetConfig GetPreset(string name) {
            foreach (SensorConfig sensor in _sensors) foreach (PresetConfig preset in sensor.Npc) if (preset.Config.Name == name) return preset;
            return null;
        }
        private void AddToContainerPrefab(ItemContainer container, PrefabLootTableConfig lootTable) {
            HashSet<string> prefabsInContainer = new HashSet<string>();
            if (lootTable.UseCount) {
                int count = UnityEngine.Random.Range(lootTable.Min, lootTable.Max + 1);
                while (prefabsInContainer.Count < count) {
                    foreach (PrefabConfig prefab in lootTable.Prefabs) {
                        if (prefabsInContainer.Contains(prefab.PrefabDefinition)) continue;
                        if (UnityEngine.Random.Range(0.0f, 100.0f) <= prefab.Chance) {
                            if (_allLootSpawnSlots.ContainsKey(prefab.PrefabDefinition)) {
                                LootContainer.LootSpawnSlot[] lootSpawnSlots = _allLootSpawnSlots[prefab.PrefabDefinition];
                                foreach (LootContainer.LootSpawnSlot lootSpawnSlot in lootSpawnSlots) for (int j = 0; j < lootSpawnSlot.numberToSpawn; j++) if (UnityEngine.Random.Range(0f, 1f) <= lootSpawnSlot.probability) lootSpawnSlot.definition.SpawnIntoContainer(container);
                            }
                            else _allLootSpawn[prefab.PrefabDefinition].SpawnIntoContainer(container);
                            prefabsInContainer.Add(prefab.PrefabDefinition);
                            if (prefabsInContainer.Count == count) return;
                        }
                    }
                }
            }
            else {
                foreach (PrefabConfig prefab in lootTable.Prefabs) {
                    if (prefabsInContainer.Contains(prefab.PrefabDefinition)) continue;
                    if (UnityEngine.Random.Range(0.0f, 100.0f) <= prefab.Chance) {
                        if (_allLootSpawnSlots.ContainsKey(prefab.PrefabDefinition)) {
                            LootContainer.LootSpawnSlot[] lootSpawnSlots = _allLootSpawnSlots[prefab.PrefabDefinition];
                            foreach (LootContainer.LootSpawnSlot lootSpawnSlot in lootSpawnSlots) for (int j = 0; j < lootSpawnSlot.numberToSpawn; j++) if (UnityEngine.Random.Range(0f, 1f) <= lootSpawnSlot.probability) lootSpawnSlot.definition.SpawnIntoContainer(container);
                        }
                        else _allLootSpawn[prefab.PrefabDefinition].SpawnIntoContainer(container);
                        prefabsInContainer.Add(prefab.PrefabDefinition);
                    }
                }
            }
        }
        private void AddToContainerItem(ItemContainer container, LootTableConfig lootTable) {
            HashSet<int> indexMove = new HashSet<int>();
            if (lootTable.UseCount) {
                int count = UnityEngine.Random.Range(lootTable.Min, lootTable.Max + 1);
                while (indexMove.Count < count) {
                    foreach (ItemConfig item in lootTable.Items) {
                        if (indexMove.Contains(lootTable.Items.IndexOf(item))) continue;
                        if (UnityEngine.Random.Range(0.0f, 100.0f) <= item.Chance) {
                            Item newItem = item.IsBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.ShortName, UnityEngine.Random.Range(item.MinAmount, item.MaxAmount + 1), item.SkinID);
                            if (newItem == null) {
                                PrintWarning($"Failed to create item! ({item.ShortName})");
                                continue;
                            }
                            if (item.IsBluePrint) newItem.blueprintTarget = ItemManager.FindItemDefinition(item.ShortName).itemid;
                            if (!string.IsNullOrEmpty(item.Name)) newItem.name = item.Name;
                            if (container.capacity < container.itemList.Count + 1) container.capacity++;
                            if (!newItem.MoveToContainer(container)) newItem.Remove();
                            else {
                                indexMove.Add(lootTable.Items.IndexOf(item));
                                if (indexMove.Count == count) return;
                            }
                        }
                    }
                }
            }
            else {
                foreach (ItemConfig item in lootTable.Items) {
                    if (indexMove.Contains(lootTable.Items.IndexOf(item))) continue;
                    if (UnityEngine.Random.Range(0.0f, 100.0f) <= item.Chance) {
                        Item newItem = item.IsBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.ShortName, UnityEngine.Random.Range(item.MinAmount, item.MaxAmount + 1), item.SkinID);
                        if (newItem == null) {
                            PrintWarning($"Failed to create item! ({item.ShortName})");
                            continue;
                        }
                        if (item.IsBluePrint) newItem.blueprintTarget = ItemManager.FindItemDefinition(item.ShortName).itemid;
                        if (!string.IsNullOrEmpty(item.Name)) newItem.name = item.Name;
                        if (container.capacity < container.itemList.Count + 1) container.capacity++;
                        if (!newItem.MoveToContainer(container)) newItem.Remove();
                        else indexMove.Add(lootTable.Items.IndexOf(item));
                    }
                }
            }
        }
        private static void CheckLootTable(LootTableConfig lootTable) {
            lootTable.Items = lootTable.Items.OrderBy(x => x.Chance);
            if (lootTable.Max > lootTable.Items.Count) lootTable.Max = lootTable.Items.Count;
            if (lootTable.Min > lootTable.Max) lootTable.Min = lootTable.Max;
        }
        private void CheckPrefabLootTable(PrefabLootTableConfig lootTable) {
            HashSet<PrefabConfig> prefabs = new HashSet<PrefabConfig>();
            foreach (PrefabConfig prefabConfig in lootTable.Prefabs) {
                if (prefabs.Any(x => x.PrefabDefinition == prefabConfig.PrefabDefinition)) PrintWarning($"Duplicate prefab removed from loot table! ({prefabConfig.PrefabDefinition})");
                else {
                    GameObject gameObject = GameManager.server.FindPrefab(prefabConfig.PrefabDefinition);
                    global : : HumanNPC humanNpc = gameObject.GetComponent<global : : HumanNPC>();
                    ScarecrowNPC scarecrowNPC = gameObject.GetComponent<ScarecrowNPC>();
                    LootContainer lootContainer = gameObject.GetComponent<LootContainer>();
                    if (humanNpc != null && humanNpc.LootSpawnSlots.Length != 0) {
                        if (!_allLootSpawnSlots.ContainsKey(prefabConfig.PrefabDefinition)) _allLootSpawnSlots.Add(prefabConfig.PrefabDefinition, humanNpc.LootSpawnSlots);
                        prefabs.Add(prefabConfig);
                    }
                    else if (scarecrowNPC != null && scarecrowNPC.LootSpawnSlots.Length != 0) {
                        if (!_allLootSpawnSlots.ContainsKey(prefabConfig.PrefabDefinition)) _allLootSpawnSlots.Add(prefabConfig.PrefabDefinition, scarecrowNPC.LootSpawnSlots);
                        prefabs.Add(prefabConfig);
                    }
                    else if (lootContainer != null && lootContainer.LootSpawnSlots.Length != 0) {
                        if (!_allLootSpawnSlots.ContainsKey(prefabConfig.PrefabDefinition)) _allLootSpawnSlots.Add(prefabConfig.PrefabDefinition, lootContainer.LootSpawnSlots);
                        prefabs.Add(prefabConfig);
                    }
                    else if (lootContainer != null && lootContainer.lootDefinition != null) {
                        if (!_allLootSpawn.ContainsKey(prefabConfig.PrefabDefinition)) _allLootSpawn.Add(prefabConfig.PrefabDefinition, lootContainer.lootDefinition);
                        prefabs.Add(prefabConfig);
                    }
                    else PrintWarning($"Unknown prefab removed! ({prefabConfig.PrefabDefinition})");
                }
            }
            lootTable.Prefabs = prefabs.OrderBy(x => x.Chance);
            if (lootTable.Max > lootTable.Prefabs.Count) lootTable.Max = lootTable.Prefabs.Count;
            if (lootTable.Min > lootTable.Max) lootTable.Min = lootTable.Max;
        }
        private readonly Dictionary<string, LootSpawn> _allLootSpawn = new Dictionary<string, LootSpawn>();
        private readonly Dictionary<string, LootContainer.LootSpawnSlot[]> _allLootSpawnSlots = new Dictionary<string, LootContainer.LootSpawnSlot[]>();
#endregion Spawn Loot
    }
}
namespace Oxide.Plugins.NpcHordeRustEditExtensionMethods {
    public static class ExtensionMethods {
        public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) return true;
            return false;
        }
        public static List<TSource> WhereToList<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
            List<TSource> result = new List<TSource>();
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) result.Add(enumerator.Current);
            return result;
        }
        public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (predicate(enumerator.Current)) return enumerator.Current;
            return default(TSource);
        }
        public static HashSet<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> predicate) {
            HashSet<TResult> result = new HashSet<TResult>();
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) result.Add(predicate(enumerator.Current));
            return result;
        }
        public static List<TResult> Select<TSource, TResult>(this IList<TSource> source, Func<TSource, TResult> predicate) {
            List<TResult> result = new List<TResult>();
            for (int i = 0; i < source.Count; i++) {
                TSource element = source[i];
                result.Add(predicate(element));
            }
            return result;
        }
        public static HashSet<T> OfType<T>(this IEnumerable<BaseNetworkable> source) {
            HashSet<T> result = new HashSet<T>();
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) if (enumerator.Current is T) result.Add((T)(object)enumerator.Current);
            return result;
        }
        public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
            List<TSource> result = new List<TSource>();
            using (var enumerator = source.GetEnumerator()) while (enumerator.MoveNext()) result.Add(enumerator.Current);
            return result;
        }
        public static TSource First<TSource>(this IList<TSource> source) => source[0];
        public static TSource Last<TSource>(this IList<TSource> source) => source[source.Count - 1];
        public static List<TSource> OrderBy<TSource>(this IEnumerable<TSource> source, Func<TSource, float> predicate) {
            List<TSource> result = source.ToList();
            for (int i = 0; i < result.Count; i++) {
                for (int j = 0; j < result.Count - 1; j++) {
                    if (predicate(result[j]) > predicate(result[j + 1])) {
                        TSource z = result[j];
                        result[j] = result[j + 1];
                        result[j + 1] = z;
                    }
                }
            }
            return result;
        }
        public static bool IsPlayer(this BasePlayer player) => player != null && player.userID.IsSteamId();
        public static bool IsExists(this BaseNetworkable entity) => entity != null && !entity.IsDestroyed;
        public static void ClearItemsContainer(this ItemContainer container) {
            for (int i = container.itemList.Count - 1; i >= 0; i--) {
                Item item = container.itemList[i];
                item.RemoveFromContainer();
                item.Remove();
            }
        }
    }
}

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