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

FREE RaidableBases : 2.4.1 2.4.1

Нет прав для скачивания
C#:
/*
*  <----- End-User License Agreement ----->
*  
*  You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of This Software without the Developer’s consent
*  
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*
*  Developer: nivex (mswenson82@yahoo.com)
*
*  Copyright © 2021 nivex
*/
using Facepunch;
using Facepunch.Math;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using Oxide.Game.Rust.Libraries;
using Oxide.Plugins.RaidableBasesExtensionMethods;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
namespace Oxide.Plugins {
    [Info("Raidable Bases", "nivex", "2.4.1")]
    [Description("Create fully automated raidable bases with npcs.")]
    class RaidableBases : RustPlugin {
        [PluginReference]
        private Plugin DangerousTreasures, ZoneManager, IQEconomic, Economics, ServerRewards, GUIAnnouncements, CopyPaste, Friends, Clans, Kits, TruePVE, NightLantern, Wizardry, NextGenPVE, Imperium, Backpacks, BaseRepair, Notify;
        private new const string Name = "RaidableBases";
        private const int visibleLayer = Layers.Mask.Deployed | Layers.Mask.Default | Layers.Mask.Construction | Layers.Mask.World | Layers.Mask.Terrain;
        private const int targetLayer = Layers.Mask.Default | Layers.Mask.Water | Layers.Solid;
        private static RaidableBases Instance {
            get;
            set;
        }
        protected RotationCycle Cycle {
            get;
            set;
        }
        = new RotationCycle();
        public Dictionary<int, List<BaseEntity>> Bases {
            get;
        }
        = new Dictionary<int, List<BaseEntity>>();
        public Dictionary<int, RaidableBase> Raids {
            get;
        }
        = new Dictionary<int, RaidableBase>();
        public Dictionary<ulong, RaidableBase> Npcs {
            get;
            set;
        }
        = new Dictionary<ulong, RaidableBase>();
        public Dictionary<ulong, DelaySettings> PvpDelay {
            get;
        }
        = new Dictionary<ulong, DelaySettings>();
        public Dictionary<ulong, HumanoidBrain> HumanoidBrains {
            get;
            set;
        }
        = new Dictionary<ulong, HumanoidBrain>();
        private Dictionary<string, SkinInfo> Skins {
            get;
        }
        = new Dictionary<string, SkinInfo>();
        protected Dictionary<string, BuyableInfo> buyCooldowns {
            get;
            set;
        }
        = new Dictionary<string, BuyableInfo>();
        private Dictionary<uint, BMGELEVATOR> _elevators = new Dictionary<uint, BMGELEVATOR>();
        public static StoredData data {
            get;
            set;
        }
        = new StoredData();
        private static StringBuilder _sb {
            get;
            set;
        }
        private bool wiped {
            get;
            set;
        }
        private bool buyableEnabled {
            get;
            set;
        }
        private float lastSpawnRequestTime {
            get;
            set;
        }
        private bool IsUnloading {
            get;
            set;
        }
        private bool bypassRestarting {
            get;
            set;
        }
        private List<string> tryBuyCooldowns {
            get;
            set;
        }
        = new List<string>();
        private BuildingTables Buildings {
            get;
            set;
        }
        private bool DebugMode {
            get;
            set;
        }
        private List<RandomBase> Locations {
            get;
            set;
        }
        = new List<RandomBase>();
        private Dictionary<string, ItemDefinition> _definitions {
            get;
            set;
        }
        = new Dictionary<string, ItemDefinition>();
        private Dictionary<Vector3, float> LoadingTimes {
            get;
            set;
        }
        = new Dictionary<Vector3, float>();
        private List<string> Helms {
            get;
            set;
        }
        = new List<string> {
            "hat.wolf", "attire.hide.helterneck", "hat.beenie", "hat.boonie", "bucket.helmet", "burlap.headwrap", "hat.candle", "hat.cap", "clatter.helmet", "coffeecan.helmet", "deer.skull.mask", "heavy.plate.helmet", "hat.miner", "partyhat", "riot.helmet", "wood.armor.helmet", "mask.balaclava", "mask.bandana", "metal.facemask", "nightvisiongoggles", "hat.dragonmask", "hat.ratmask", "attire.nesthat"
        }
        ;
        private List<string> Boots {
            get;
            set;
        }
        = new List<string> {
            "boots.frog", "shoes.boots", "burlap.shoes", "attire.hide.boots"
        }
        ;
        private List<string> Gloves {
            get;
            set;
        }
        = new List<string> {
            "burlap.gloves.new", "burlap.gloves", "roadsign.gloves", "tactical.gloves"
        }
        ;
        private List<string> Vests {
            get;
            set;
        }
        = new List<string> {
            "bone.armor.suit", "heavy.plate.jacket", "jacket.snow", "jacket", "wood.armor.jacket", "attire.hide.poncho", "metal.plate.torso", "roadsign.jacket"
        }
        ;
        private List<string> Legs {
            get;
            set;
        }
        = new List<string> {
            "burlap.trousers", "heavy.plate.pants", "attire.hide.pants", "pants.shorts", "wood.armor.pants", "pants"
        }
        ;
        private List<string> Shirts {
            get;
            set;
        }
        = new List<string> {
            "hoodie", "burlap.shirt", "shirt.collared", "attire.hide.vest", "shirt.tanktop", "tshirt.long", "tshirt"
        }
        ;
        private List<string> Other {
            get;
            set;
        }
        = new List<string> {
            "movembermoustachecard", "movembermoustache", "sunglasses02black", "sunglasses02camo", "sunglasses02red", "sunglasses03black", "sunglasses03chrome", "sunglasses03gold", "sunglasses", "twitchsunglasses", "gloweyes", "attire.bunnyears"
        }
        ;
        private List<string> Furnaces {
            get;
            set;
        }
        = new List<string> {
            "furnace.large", "furnace", "furnace_static"
        }
        ;
        private List<string> BBQs {
            get;
            set;
        }
        = new List<string> {
            "bbq", "bbq.deployed", "bbq.static"
        }
        ;
        private List<string> Lanterns {
            get;
            set;
        }
        = new List<string> {
            "chineselantern.deployed", "jackolantern.angry", "jackolantern.happy", "lantern.deployed", "tunalight.deployed"
        }
        ;
        private List<string> Refineries {
            get;
            set;
        }
        = new List<string> {
            "refinery_small_deployed", "small_refinery_static"
        }
        ;
        private List<uint> ExcludedMounts {
            get;
            set;
        }
        = new List<uint> {
            3552983236, 4218596772, 1845856065, 1992774774, 629849447, 4267988016, 1418740895, 2493676858, 3814928951, 1980628900, 703403829, 3061223907, 113644298, 3691382632, 3858860623, 286221745, 2230162530, 51176708, 3363531184, 3224878175
        }
        ;
        private List<string> Blocks {
            get;
            set;
        }
        = new List<string> {
            "wall.doorway", "wall", "wall.frame", "wall.half", "wall.low", "wall.window", "foundation.triangle", "foundation", "wall.external.high.wood", "wall.external.high.stone", "wall.external.high.ice", "floor.triangle.frame", "floor.triangle", "floor.frame"
        }
        ;
        private List<string> TrueDamage {
            get;
            set;
        }
        = new List<string> {
            "spikes.floor", "barricade.metal", "barricade.woodwire", "barricade.wood", "wall.external.high.wood", "wall.external.high.stone", "wall.external.high.ice"
        }
        ;
        private List<string> arguments {
            get;
            set;
        }
        = new List<string> {
            "add", "remove", "list", "clean", "easy", "med", "medium", "hard", "expert", "nightmare", "0", "1", "2", "3", "4"
        }
        ;
        private List<RaidableMode> RaidableModes {
            get;
            set;
        }
        = new List<RaidableMode> {
            RaidableMode.Easy, RaidableMode.Medium, RaidableMode.Hard, RaidableMode.Expert, RaidableMode.Nightmare
        }
        ;
        private SkinSettingsImportedWorkshop ImportedWorkshopSkins {
            get;
            set;
        }
        public const float M_RADIUS = 25f;
        public const float CELL_SIZE = M_RADIUS / 2f;
        private List<Record> Records = new List<Record> {
            new Record("raidablebases.ladder.easy", "raideasy", RaidableMode.Easy), new Record("raidablebases.ladder.medium", "raidmedium", RaidableMode.Medium), new Record("raidablebases.ladder.hard", "raidhard", RaidableMode.Hard), new Record("raidablebases.ladder.expert", "raidexpert", RaidableMode.Expert), new Record("raidablebases.ladder.nightmare", "raidnightmare", RaidableMode.Nightmare), new Record("raidablebases.th", "raidhunter", RaidableMode.Points),
        }
        ;
        public enum RaidableType {
            None, Manual, Scheduled, Purchased, Maintained, Grid
        }
        public enum RaidableMode {
            Disabled = -1, Easy = 0, Medium = 1, Hard = 2, Expert = 3, Nightmare = 4, Points = 8888, Random = 9999
        }
        public enum AlliedType {
            All, Clan, Friend, Team
        }
        public enum CacheType {
            Close, Delete, Generic, Temporary, Privilege, Submerged
        }
        public enum ConstructionType {
            Barricade, Ladder, Any
        }
        public enum LootType {
            Easy, Medium, Hard, Expert, Nightmare, Default
        }
        public enum SpawnResult {
            Failure, Transfer, Success, Skipped
        }
        public class StoredData {
            public Dictionary<string, Lockout> Lockouts {
                get;
            }
            = new Dictionary<string, Lockout>();
            public Dictionary<string, PlayerInfo> Players {
                get;
                set;
            }
            = new Dictionary<string, PlayerInfo>();
            public Dictionary<string, UI.Info> UI {
                get;
                set;
            }
            = new Dictionary<string, UI.Info>();
            public string RaidTime {
                get;
                set;
            }
            = DateTime.MinValue.ToString();
            public int TotalEvents {
                get;
                set;
            }
            public StoredData() {
            }
            public static void Load() {
                try {
                    data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
                }
                catch {
                }
                if (data == null) data = new StoredData();
                if (data.UI == null) data.UI = new Dictionary<string, UI.Info>();
                if (data.Players == null) data.Players = new Dictionary<string, PlayerInfo>();
            }
            public void Save() {
                data.Lockouts.RemoveAll((userid, lo) => lo.IsExpired());
                data.UI.RemoveAll((userid, uii) => uii.All());
                data.Players.RemoveAll((userid, playerInfo) => playerInfo.TotalRaids == 0 || playerInfo.IsExpired());
                Interface.Oxide.DataFileSystem.WriteObject(Name, this);
            }
        }
        public class RandomBase {
            public string BaseName;
            public Vector3 Position;
            public BaseProfile Profile;
            public RaidableType Type;
        }
        public class BackpackData {
            public DroppedItemContainer backpack;
            public BasePlayer player;
            public ulong userID;
        }
        public class BuyableInfo {
            public float Time;
            public Timer Timer;
        }
        public class DelaySettings {
            public RaidableBase RaidableBase;
            public Timer Timer;
            public bool AllowPVP;
        }
        public class MountInfo {
            public Vector3 position;
            public float radius;
            public BaseMountable mountable;
        }
        public class RaiderInfo {
            public ulong uid;
            public string id;
            public string displayName;
            public BasePlayer player;
            public bool reward = true;
            public RaiderInfo(BasePlayer target) {
                player = target;
                uid = target.userID;
                id = target.UserIDString;
                displayName = target.displayName;
            }
        }
        public class SkinInfo {
            public List<ulong> skins = new List<ulong>();
            public List<ulong> workshopSkins = new List<ulong>();
            public List<ulong> importedSkins = new List<ulong>();
            public List<ulong> allSkins = new List<ulong>();
        }
        public class Lockout {
            public double Easy, Medium, Hard, Expert, Nightmare;
            public bool Any() => Easy > 0 || Medium > 0 || Hard > 0 || Expert > 0 || Nightmare > 0;
            public bool IsExpired(RaidableMode mode) {
                switch (mode) {
                    case RaidableMode.Easy : return Easy <= 0 || Easy - Epoch.Current <= 0;
                    case RaidableMode.Medium : return Medium <= 0 || Medium - Epoch.Current <= 0;
                    case RaidableMode.Hard : return Hard <= 0 || Hard - Epoch.Current <= 0;
                    case RaidableMode.Expert : return Expert <= 0 || Expert - Epoch.Current <= 0;
                    case RaidableMode.Nightmare : return Nightmare <= 0 || Nightmare - Epoch.Current <= 0;
                    default : return true;
                }
            }
            public bool IsExpired() {
                var modes = (RaidableMode[])Enum.GetValues(typeof(RaidableMode));
                return modes.All(mode => IsExpired(mode));
            }
        }
        public class Record {
            public string Permission;
            public string Group;
            public RaidableMode Mode;
            public Record(string permission, string group, RaidableMode mode) {
                Permission = permission;
                Group = group;
                Mode = mode;
            }
        }
        public class Elevation {
            public float Min;
            public float Max;
        }
        public class RaidableSpawnLocation {
            public List<Vector3> Surroundings = new List<Vector3>();
            public Elevation Elevation = new Elevation();
            public Vector3 Location = Vector3.zero;
            public float WaterHeight;
            public float TerrainHeight;
            public float SpawnHeight;
            public float Radius;
            public bool AutoHeight;
            public RaidableSpawnLocation(Vector3 Location) {
                this.Location = Location;
            }
        }
        public class MonumentInfoEx {
            public float size;
            public Bounds bounds;
            public string translated;
            public Transform transform;
            public MonumentInfo monument;
            public MonumentInfoEx(MonumentInfo monument) {
                this.monument = monument;
                transform = monument.transform;
                translated = Translated();
                size = Size();
                bounds = new Bounds(monument.Bounds.center, new Vector3(size, size, size));
                if (config.Settings.Management.MonumentDistance > 0f) {
                    bounds.Expand(config.Settings.Management.MonumentDistance);
                }
            }
            public bool IsInBounds(Vector3 target) {
                return monument.IsInBounds(target) || new OBB(monument.transform.position, monument.transform.rotation, bounds).Contains(target);
            }
            private float Size() {
                if (string.IsNullOrEmpty(monument.displayPhrase.translated.TrimEnd())) {
                    return monument.name.Contains("power_sub") ? 50f : monument.name.Contains("cave") ? 75f : monument.name.Contains("OilrigAI") ? 225f : Mathf.Max(monument.Bounds.size.Max(), 75f);
                }
                switch (monument.displayPhrase.translated.TrimEnd()) {
                    case "power_sub_small_1" : case "power_sub_small_2" : case "power_sub_big_1" : case "power_sub_big_2" : case "Stone Quarry" : case "Sulfur Quarry" : case "Water Well" : case "Wild Swamp" : case "HQM Quarry" : return 50f;
                    case "Abandoned Cabins" : case "Abandoned Supermarket" : case "Fishing Village" : case "Large Fishing Village" : case "Lighthouse" : case "Mining Outpost" : case "Ice Lake" : case "The Dome" : case "Oxum's Gas Station" : return 100f;
                    case "Military Tunnel" : case "Sewer Branch" : case "Satellite Dish" : case "Junkyard" : case "Underwater Lab" : return 125f;
                    case "Harbor" : case "Train Yard" : case "Power Plant" : return 150f;
                    case "Barn" : case "Large Barn" : case "Ranch" : return 200f;
                    case "Airfield" : case "Oil Rig" : case "Large Oil Rig" : case "Water Treatment Plant" : case "Giant Excavator Pit" : return 225f;
                    case "Bandit Camp" : case "Outpost" : return 350f;
                    case "Launch Site" : return 300f;
                }
                return monument.Bounds.size.Max() > 0f ? monument.Bounds.size.Max() : 100f;
            }
            private string Translated() {
                if (!string.IsNullOrEmpty(monument.displayPhrase.translated.TrimEnd())) {
                    return monument.displayPhrase.translated.TrimEnd();
                }
                else if (monument.name.Contains("Oilrig")) {
                    return "Oil Rig";
                }
                else if (monument.name.Contains("cave")) {
                    return "Cave";
                }
                else if (monument.name.Contains("power_sub")) {
                    return "Power Sub Station";
                }
                return "Unknown Monument";
            }
        }
        public class ZoneInfo {
            public Vector3 Position;
            public Vector3 Size;
            public float Distance;
            public OBB OBB;
            public ZoneInfo(object location, object radius, object size) {
                Position = (Vector3)location;
                if (radius is float) {
                    Distance = (float)radius + M_RADIUS + config.Settings.ZoneDistance;
                }
                if (size is Vector3) {
                    Size = (Vector3)size;
                }
                var bounds = new Bounds(Position, Size);
                if (config.Settings.ZoneDistance > 0f) {
                    bounds.Expand(config.Settings.ZoneDistance);
                }
                OBB = new OBB(Position, default(Quaternion), bounds);
            }
        }
        public class BaseProfile {
            public List<LootItem> BaseLootList {
                get;
                set;
            }
            = new List<LootItem>();
            public BuildingOptions Options {
                get;
                set;
            }
            = new BuildingOptions();
            public RaidableSpawns Spawns {
                get;
                set;
            }
            = new RaidableSpawns();
            public string Name {
                get;
                set;
            }
            public BaseProfile() {
                Options.AdditionalBases = new Dictionary<string, List<PasteOption>>();
            }
            public BaseProfile(BuildingOptions options, string name) {
                Options = options;
                Name = name;
            }
            public static BaseProfile Clone(BaseProfile profile) {
                return profile.MemberwiseClone() as BaseProfile;
            }
        }
        private class BuildingTables {
            public Dictionary<LootType, List<LootItem>> DifficultyLootLists {
                get;
                set;
            }
            = new Dictionary<LootType, List<LootItem>>();
            public Dictionary<DayOfWeek, List<LootItem>> WeekdayLootLists {
                get;
                set;
            }
            = new Dictionary<DayOfWeek, List<LootItem>>();
            public Dictionary<string, BaseProfile> Profiles {
                get;
                set;
            }
            = new Dictionary<string, BaseProfile>();
        }
        public class BackboneController : SingletonComponent<BackboneController> {
            private RaidableBases Plugin {
                get;
                set;
            }
            public Core.Libraries.Lang lang => Plugin.lang;
            private StringBuilder sb {
                get;
                set;
            }
            = new StringBuilder();
            public float OceanLevel {
                get;
                set;
            }
            internal ScheduledController Scheduled {
                get;
                set;
            }
            internal MaintainedController Maintained {
                get;
                set;
            }
            public void Initialize(RaidableBases instance) {
                Scheduled = new ScheduledController(instance) {
                    Enabled = config.Settings.Schedule.Enabled
                }
                ;
                Maintained = new MaintainedController(instance) {
                    Enabled = config.Settings.Maintained.Enabled
                }
                ;
                OceanLevel = WaterSystem.OceanLevel;
                Plugin = instance;
                InvokeRepeating(CheckOceanLevel, 60f, 60f);
            }
            private void CheckOceanLevel() {
                if (OceanLevel != WaterSystem.OceanLevel) {
                    OceanLevel = WaterSystem.OceanLevel;
                    RaidableSpawns spawns;
                    if (GridController.Spawns.TryGetValue(RaidableType.Grid, out spawns)) {
                        spawns.TryAddRange(CacheType.Submerged);
                    }
                }
            }
            public void Message(BasePlayer player, string key, params object[] args) {
                if (player.IsValid()) {
                    Plugin.Player.Message(player, GetMessage(key, player.UserIDString, args), config.Settings.ChatID);
                }
            }
            public string GetMessage(string key, string id = null, params object[] args) {
                sb.Length = 0;
                if (config.EventMessages.Prefix) {
                    sb.Append(lang.GetMessage("Prefix", Plugin, id));
                }
                sb.Append(id == "server_console" || id == null ? RemoveFormatting(lang.GetMessage(key, Plugin, id)) : lang.GetMessage(key, Plugin, id));
                return args.Length > 0 ? string.Format(sb.ToString(), args) : sb.ToString();
            }
            public string GetMessageEx(string key, string id = null, params object[] args) {
                sb.Length = 0;
                sb.Append(id == "server_console" || id == null ? RemoveFormatting(lang.GetMessage(key, Plugin, id)) : lang.GetMessage(key, Plugin, id));
                return args.Length > 0 ? string.Format(sb.ToString(), args) : sb.ToString();
            }
            public string RemoveFormatting(string source) => source.Contains(">") ? Regex.Replace(source, "<.*?>", string.Empty) : source;
            public void StopCoroutines() {
                Scheduled.StopCoroutine();
                Maintained.StopCoroutine();
                GridController.StopCoroutine();
                GarbageController.StopCoroutine();
            }
            public double GetRaidTime() => DateTime.Parse(data.RaidTime).Subtract(DateTime.Now).TotalSeconds;
            public void StartAutomation() {
                if (Scheduled.Enabled) {
                    if (data.RaidTime != DateTime.MinValue.ToString() && GetRaidTime() > config.Settings.Schedule.IntervalMax) {
                        data.RaidTime = DateTime.MinValue.ToString();
                    }
                    Scheduled.StartCoroutine();
                }
                if (Maintained.Enabled) {
                    Maintained.StartCoroutine();
                }
            }
        }
        public class UndoSettings {
            public List<BaseEntity> Entities;
            public object[] hookObjects;
            public bool Structures;
            public bool Deployables;
            public bool Mounts;
            public bool Teleport;
            public int Limit;
        }
        public static class GarbageController {
            internal static Coroutine despawnCoroutine {
                get;
                set;
            }
            internal static Dictionary<BaseEntity, MountInfo> Mounts {
                get;
                set;
            }
            = new Dictionary<BaseEntity, MountInfo>();
            internal static Dictionary<BaseEntity, RaidableBase> RaidEntities {
                get;
                set;
            }
            = new Dictionary<BaseEntity, RaidableBase>();
            public static void UndoLoop(UndoSettings undo, int count = 0) {
                undo.Entities.RemoveAll(e => e.IsKilled());
                undo.Entities.Sort((x, y) => (x is BuildingBlock).CompareTo(y is BuildingBlock));
                undo.Entities.Take(undo.Limit).ToList().ForEach(entity => {
                    undo.Entities.Remove(entity);
                    if (entity.IsKilled() || KeepEntity(entity, undo)) {
                        return;
                    }
                    if (entity is IOEntity) {
                        var io = entity as IOEntity;
                        io.ClearConnections();
                        if (entity is SamSite) {
                            var ss = entity as SamSite;
                            ss.staticRespawn = false;
                        }
                    }
                    if (undo.Teleport) {
                        entity.transform.position = new Vector3(0f, -500f, 0f);
                        Interface.Oxide.NextTick(entity.SafelyKill);
                    }
                    else entity.Kill(BaseNetworkable.DestroyMode.None);
                }
                );
                if (count != 0 && undo.Entities.Count != 0 && undo.Entities.Count == count) {
                    goto done;
                }
                if (undo.Entities.Count > 0) {
                    Interface.Oxide.NextTick(() => UndoLoop(undo, undo.Entities.Count));
                    return;
                }
                done : GarbageController.RaidEntities.RemoveAll((e, raid) => e.IsKilled());
                if (GarbageController.RaidEntities.Count == 0) {
                    GarbageController.Mounts.Clear();
                }
                if (undo.hookObjects != null) {
                    Interface.CallHook("OnRaidableBaseDespawned", undo.hookObjects);
                }
            }
            private static bool KeepEntity(BaseEntity entity, UndoSettings undo) {
                if (!undo.Mounts && KeepMountable(entity) || entity.OwnerID.IsSteamId() && KeepPlayerEntity(entity, undo)) {
                    return true;
                }
                RaidEntities.Remove(entity);
                return false;
            }
            private static bool KeepPlayerEntity(BaseEntity entity, UndoSettings undo) {
                if (entity.PrefabName.Contains("assets/prefabs/deployable/")) {
                    if (!undo.Deployables) {
                        if (entity is IItemContainerEntity) {
                            var ice = entity as IItemContainerEntity;
                            if (ice != null) {
                                DropUtil.DropItems(ice.inventory, entity.transform.position + Vector3.up);
                            }
                        }
                        return false;
                    }
                }
                else if (!undo.Structures) {
                    return false;
                }
                RaidEntities.Remove(entity);
                return true;
            }
            private static bool KeepMountable(BaseEntity entity) {
                MountInfo mi;
                if (!Mounts.TryGetValue(entity, out mi) || !Mounts.Remove(entity)) {
                    return false;
                }
                return mi.mountable.GetMounted() != null || !InRange(entity.transform.position, mi.position, mi.radius);
            }
            public static void RemoveHeldEntities() {
                foreach (var element in RaidEntities.ToList()) {
                    if (element.Key is IItemContainerEntity) {
                        var ice = element.Key as IItemContainerEntity;
                        if (ice == null || ice.inventory == null) {
                            continue;
                        }
                        foreach (Item item in ice.inventory.itemList) {
                            var e = item.GetHeldEntity();
                            if (e.IsValid()) {
                                e.enableSaving = false;
                                BaseEntity.saveList.Remove(e);
                            }
                        }
                        ice.inventory.Clear();
                    }
                }
                ItemManager.DoRemoves();
            }
            public static void StopCoroutine() {
                if (despawnCoroutine != null) {
                    ServerMgr.Instance.StopCoroutine(despawnCoroutine);
                    despawnCoroutine = null;
                }
            }
            public static void StartDespawn(bool inactiveOnly) {
                if (Instance.Raids.Count == 0) {
                    return;
                }
                if (despawnCoroutine != null) {
                    Instance.timer.Once(0.1f, () => StartDespawn(inactiveOnly));
                    return;
                }
                despawnCoroutine = ServerMgr.Instance.StartCoroutine(DespawnCoroutine(inactiveOnly));
            }
            private static IEnumerator DespawnCoroutine(bool inactiveOnly) {
                foreach (var raid in Instance.Raids.Values.ToList()) {
                    if (raid == null || inactiveOnly && (raid.intruders.Count > 0 || raid.ownerId.IsSteamId())) {
                        continue;
                    }
                    var baseIndex = raid.BaseIndex;
                    Instance.Raids.Remove(raid.uid);
                    raid.Despawn();
                    yield return new WaitWhile(() => Instance.Bases.ContainsKey(baseIndex));
                    yield return CoroutineEx.waitForSeconds(0.1f);
                }
                despawnCoroutine = null;
            }
        }
        public class EjectController : FacepunchBehaviour {
            private static EjectController _ejectController;
            private GameObject _gameObject;
            private Vector3 position;
            private float radius;
            private void OnDestroy() {
                _ejectController = null;
            }
            public static void DestroyMe() {
                if (_ejectController == null) {
                    return;
                }
                DestroyImmediate(_ejectController._gameObject);
            }
            public static void Initialize(Vector3 position, float radius) {
                GameObject go;
                if (_ejectController == null) {
                    go = new GameObject("EjectController");
                    _ejectController = go.AddComponent<EjectController>();
                    _ejectController._gameObject = go;
                }
                else go = _ejectController._gameObject;
                go.transform.position = _ejectController.position = position;
                go.layer = (int)Layer.Trigger;
                var collider = go.AddComponent<SphereCollider>();
                collider.isTrigger = true;
                collider.radius = _ejectController.radius = radius;
                collider.center = Vector3.zero;
            }
            private void OnTriggerEnter(Collider collider) {
                if (collider == null || collider.name == "ZoneManager") {
                    return;
                }
                var entity = GetEntity(collider);
                if (entity is BasePlayer) {
                    var player = entity as BasePlayer;
                    if (CanBypass(player) || IsUnderground(player.transform.position)) {
                        return;
                    }
                    RaidableBase.RemovePlayer(player, 7, position, radius, RaidableType.Manual);
                }
                else if (entity is BaseMountable) {
                    var m = entity as BaseMountable;
                    var players = RaidableBase.GetMountedPlayers(m);
                    if (players.Count == 0 || players.Exists(player => CanBypass(player))) {
                        return;
                    }
                    RaidableBase.RemoveMountable(m, players, position, radius);
                }
            }
            private bool CanBypass(BasePlayer player) {
                return !player.IsHuman() || player.IsFlying || player.limitNetworking || player.HasPermission("raidablebases.canbypass");
            }
        }
        public static class GridController {
            internal static HashSet<RaidableSpawnLocation> Seabed {
                get;
                set;
            }
            internal static Dictionary<RaidableType, RaidableSpawns> Spawns {
                get;
                set;
            }
            internal static Coroutine gridCoroutine {
                get;
                set;
            }
            internal static float gridTime {
                get;
                set;
            }
            public static void Initialize() {
                Seabed = new HashSet<RaidableSpawnLocation>();
                Spawns = new Dictionary<RaidableType, RaidableSpawns>();
            }
            public static void Clear() {
                Seabed.Clear();
                Spawns.Clear();
            }
            public static void Setup() {
                if (Spawns.Count >= 5) {
                    Instance.timer.Once(5f, () => BackboneController.Instance.StartAutomation());
                    return;
                }
                StopCoroutine();
                Interface.Oxide.NextTick(() => gridCoroutine = ServerMgr.Instance.StartCoroutine(GenerateGrid()));
            }
            public static void StopCoroutine() {
                if (gridCoroutine != null) {
                    ServerMgr.Instance.StopCoroutine(gridCoroutine);
                    gridCoroutine = null;
                }
            }
            private static IEnumerator GenerateGrid() {
                var gridStopwatch = new Stopwatch();
                gridStopwatch.Start();
                RaidableSpawns spawns = Spawns[RaidableType.Grid] = new RaidableSpawns();
                gridTime = Time.realtimeSinceStartup;
                float waterDepthMax = Instance.Buildings.Profiles.Exists(x => x.Value.Options.Water.AllowSubmerged) ? 3f : 0f;
                float monumentDist = M_RADIUS * 2f + config.Settings.Management.MonumentDistance;
                bool seabed = Instance.Buildings.Profiles.Exists(x => x.Value.Options.Water.Seabed > 0f);
                int minPos = (int)(World.Size / -2f);
                int maxPos = (int)(World.Size / 2f);
                float protectionRadius = 50f;
                float elevation = 0.5f;
                int checks = 0;
                foreach (var profile in Instance.Buildings.Profiles.Values) {
                    protectionRadius = Mathf.Max(profile.Options.ProtectionRadii.Max(), profile.Options.ArenaWalls.Radius, protectionRadius);
                    waterDepthMax = Mathf.Max(profile.Options.Water.WaterDepth, seabed ? waterDepthMax : 40f);
                    elevation = Mathf.Max(profile.Options.Elevation, elevation);
                }
                for (float x = minPos; x < maxPos; x += CELL_SIZE)  // Credits to Jake_Rich for creating this for me!
                {
                    for (float z = minPos; z < maxPos; z += CELL_SIZE) {
                        var position = new Vector3(x, 0f, z);
                        position.y = SpawnsController.GetSpawnHeight(position);
                        SpawnsController.ExtractLocation(spawns, position, elevation, monumentDist, protectionRadius, waterDepthMax, seabed);
                        if (++checks >= 75) {
                            checks = 0;
                            yield return CoroutineEx.waitForSeconds(0.025f);
                        }
                    }
                }
                gridCoroutine = null;
                gridStopwatch.Stop();
                BackboneController.Instance.StartAutomation();
                Puts(BackboneController.Instance.GetMessageEx("InitializedGrid", null, gridStopwatch.Elapsed.Seconds, gridStopwatch.Elapsed.Milliseconds, World.Size, spawns.Count));
                if (GridController.Seabed.Count > 0) Puts(BackboneController.Instance.GetMessageEx("InitializedGridSea", null, GridController.Seabed.Count));
            }
            public static void LoadSpawns() {
                Spawns.Clear();
                Spawns.Add(RaidableType.Grid, new RaidableSpawns());
                if (SpawnsFileValid(config.Settings.Manual.SpawnsFile)) {
                    var spawns = GetSpawnsLocations(config.Settings.Manual.SpawnsFile);
                    if (spawns.Count > 0) {
                        Puts(BackboneController.Instance.GetMessageEx("LoadedManual", null, spawns.Count));
                        Spawns[RaidableType.Manual] = new RaidableSpawns(spawns);
                    }
                }
                if (SpawnsFileValid(config.Settings.Schedule.SpawnsFile)) {
                    var spawns = GetSpawnsLocations(config.Settings.Schedule.SpawnsFile);
                    if (spawns?.Count > 0) {
                        Puts(BackboneController.Instance.GetMessageEx("LoadedScheduled", null, spawns.Count));
                        Spawns[RaidableType.Scheduled] = new RaidableSpawns(spawns);
                    }
                }
                if (SpawnsFileValid(config.Settings.Maintained.SpawnsFile)) {
                    var spawns = GetSpawnsLocations(config.Settings.Maintained.SpawnsFile);
                    if (spawns?.Count > 0) {
                        Puts(BackboneController.Instance.GetMessageEx("LoadedMaintained", null, spawns.Count));
                        Spawns[RaidableType.Maintained] = new RaidableSpawns(spawns);
                    }
                }
                if (SpawnsFileValid(config.Settings.Buyable.SpawnsFile)) {
                    var spawns = GetSpawnsLocations(config.Settings.Buyable.SpawnsFile);
                    if (spawns?.Count > 0) {
                        Puts(BackboneController.Instance.GetMessageEx("LoadedBuyable", null, spawns.Count));
                        Spawns[RaidableType.Purchased] = new RaidableSpawns(spawns);
                    }
                }
            }
            public static bool SpawnsFileValid(string spawnsFile) {
                if (string.IsNullOrEmpty(spawnsFile) || spawnsFile.Equals("none", StringComparison.OrdinalIgnoreCase)) {
                    return false;
                }
                return FileExists($"SpawnsDatabase{Path.DirectorySeparatorChar}{spawnsFile}");
            }
            public static HashSet<RaidableSpawnLocation> GetSpawnsLocations(string spawnsFile) {
                Spawnfile data;
                try {
                    data = Interface.Oxide.DataFileSystem.ReadObject<Spawnfile>($"SpawnsDatabase{Path.DirectorySeparatorChar}{spawnsFile}");
                }
                catch (JsonReaderException) {
                    return null;
                }
                var locations = new HashSet<RaidableSpawnLocation>();
                if (data == null) {
                    return locations;
                }
                foreach (var element in data.spawnPoints) {
                    if (element.Value == null) continue;
                    var value = element.Value.ToString();
                    if (string.IsNullOrEmpty(value)) continue;
                    var vector = value.ToVector3();
                    if (vector == Vector3.zero) continue;
                    locations.Add(new RaidableSpawnLocation(vector));
                }
                return locations;
            }
        }
        private class Spawnfile {
            public Dictionary<string, object> spawnPoints = new Dictionary<string, object>();
        }
        public class MaintainedController {
            internal Coroutine Coroutine {
                get;
                set;
            }
            internal bool Enabled {
                get;
                set;
            }
            internal RaidableBases Instance {
                get;
                set;
            }
            public MaintainedController(RaidableBases instance) {
                Instance = instance;
            }
            public void StopCoroutine() {
                if (Coroutine != null) {
                    ServerMgr.Instance.StopCoroutine(Coroutine);
                    Coroutine = null;
                }
            }
            public void StartCoroutine() {
                if (!Enabled || config.Settings.Maintained.Max <= 0) {
                    return;
                }
                if (Instance.IsGridLoading) {
                    Instance.timer.Once(1f, () => StartCoroutine());
                    return;
                }
                StopCoroutine();
                if (!Instance.CanContinueAutomation()) {
                    Puts(BackboneController.Instance.GetMessageEx("MaintainCoroutineFailedToday"));
                    return;
                }
                Instance.timer.Once(0.2f, () => Coroutine = ServerMgr.Instance.StartCoroutine(MaintainCoroutine()));
            }
            private IEnumerator MaintainCoroutine() {
                string message;
                RaidableMode mode;
                RandomBase randomBase;
                while (true) {
                    if (Enabled && CanMaintainOpenEvent()) {
                        if (!Instance.IsCopyPasteLoaded(null)) {
                            yield return CoroutineEx.waitForSeconds(60f);
                        }
                        else if (SaveRestore.IsSaving) {
                            PrintDebugMessage("Maintained: Server saving");
                            yield return CoroutineEx.waitForSeconds(15f);
                        }
                        else if (!IsModeValid(mode = Instance.GetRandomDifficulty(RaidableType.Maintained))) {
                            PrintDebugMessage($"Maintained: Invalid mode {mode}");
                            yield return CoroutineEx.waitForSeconds(1f);
                        }
                        else if ((randomBase = Instance.SpawnRandomBase(out message, RaidableType.Maintained, mode)) != null) {
                            RaidableBase.IsSpawning = true;
                            PrintDebugMessage($"Maintained: Waiting for base at {randomBase.Position} to be setup by the plugin.");
                            yield return new WaitWhile(() => RaidableBase.IsSpawning);
                            PrintDebugMessage($"Maintained: Base has been setup by the plugin.");
                            if (config.Settings.Maintained.Time > 0) {
                                PrintDebugMessage($"Maintained: Waiting {config.Settings.Maintained.Time} seconds.");
                                yield return CoroutineEx.waitForSeconds(config.Settings.Maintained.Time);
                            }
                        }
                        else {
                            if (string.IsNullOrEmpty(message)) {
                                message = "Maintained: Failed to find position; trying again...";
                            }
                            PrintDebugMessage(message);
                        }
                    }
                    if (Enabled) PrintDebugMessage("Maintained coroutine is waiting for 1 second.");
                    yield return CoroutineEx.waitForSeconds(1f);
                }
            }
            private bool CanMaintainOpenEvent() {
                if (Instance.Raids.Values.Exists(raid => raid.IsDespawning)) {
                    var vector = Instance.Raids.Values.FirstOrDefault(raid => raid.IsDespawning).Location;
                    PrintDebugMessage($"Maintained: Paste not available; a base is currently despawning at {vector}");
                    return false;
                }
                if (!Instance.IsPasteAvailable) {
                    var vector = Instance.Raids.Values.FirstOrDefault(raid => raid.IsLoading)?.Location;
                    PrintDebugMessage($"Maintained: Paste not available; a base is currently loading at {vector}");
                    return false;
                }
                if (RaidableBase.IsSpawning) {
                    PrintDebugMessage($"Maintained: Paste not available; a base is currently spawning.");
                    return false;
                }
                if (Instance.IsGridLoading) {
                    PrintDebugMessage($"Maintained: Grid is loading.");
                    re
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху