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

FREE RaidableBases : 1.7.1 1.7.1

Нет прав для скачивания
C#:
#define USE_HTN_HOOK
//#define DEBUG_DRAWINGS
//#define DEBUG_ROCKS
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 Rust;
using Rust.Ai;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
using static NPCPlayerApex;
namespace Oxide.Plugins {
    [Info("Raidable Bases", "nivex", "1.7.1")]
    [Description("Create fully automated raidable bases with npcs.")]
    class RaidableBases : RustPlugin {
        [PluginReference]
        private Plugin DangerousTreasures, Vanish, LustyMap, ZoneManager, Economics, ServerRewards, Map, GUIAnnouncements, CopyPaste, Friends, Clans, Kits, TruePVE, Spawns, NightLantern, Wizardry, NextGenPVE, Imperium, Titan, Backpacks;
        private void OnPluginLoaded(Plugin plugin) {
            if (plugin.Name == "Titan") {
                Titan = plugin;
                Unsubscribe(nameof(OnNpcTarget));
                Unsubscribe(nameof(OnPlayerDropActiveItem));
            }
        }
        protected static SingletonBackbone Backbone {
            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<BaseEntity, RaidableBase> RaidEntities {
            get;
        }
        = new Dictionary<BaseEntity, RaidableBase>();
        public Dictionary<int, RaidableBase> Indices {
            get;
            set;
        }
        = new Dictionary<int, RaidableBase>();
        public Dictionary<ulong, RaidableBase> Npcs {
            get;
            set;
        }
        = new Dictionary<ulong, RaidableBase>();
        protected Dictionary<ulong, DelaySettings> PvpDelay {
            get;
        }
        = new Dictionary<ulong, DelaySettings>();
        private Dictionary<string, SkinInfo> Skins {
            get;
        }
        = new Dictionary<string, SkinInfo>();
        private Dictionary<MonumentInfo, float> monuments {
            get;
            set;
        }
        = new Dictionary<MonumentInfo, float>();
        private Dictionary<Vector3, ZoneInfo> managedZones {
            get;
            set;
        }
        = new Dictionary<Vector3, ZoneInfo>();
        private Dictionary<int, MapInfo> mapMarkers {
            get;
            set;
        }
        = new Dictionary<int, MapInfo>();
        private Dictionary<int, string> lustyMarkers {
            get;
            set;
        }
        = new Dictionary<int, string>();
        protected Dictionary<RaidableType, RaidableSpawns> raidSpawns {
            get;
            set;
        }
        = new Dictionary<RaidableType, RaidableSpawns>();
        protected Dictionary<string, float> buyCooldowns {
            get;
            set;
        }
        = new Dictionary<string, float>();
        protected Dictionary<uint, AutoTurret> ElectricalConnections {
            get;
            set;
        }
        = new Dictionary<uint, AutoTurret>();
        public StoredData storedData {
            get;
            set;
        }
        = new StoredData();
        protected Coroutine despawnCoroutine {
            get;
            set;
        }
        protected Coroutine maintainCoroutine {
            get;
            set;
        }
        protected Coroutine scheduleCoroutine {
            get;
            set;
        }
        protected Coroutine gridCoroutine {
            get;
            set;
        }
        private Stopwatch gridStopwatch {
            get;
        }
        = new Stopwatch();
        private StringBuilder _sb {
            get;
        }
        = new StringBuilder();
        protected const float Radius = 25f;
        private bool wiped {
            get;
            set;
        }
        private float lastSpawnRequestTime {
            get;
            set;
        }
        private float gridTime {
            get;
            set;
        }
        private bool IsUnloading {
            get;
            set;
        }
        private int _maxOnce {
            get;
            set;
        }
        private List<string> tryBuyCooldowns {
            get;
            set;
        }
        = new List<string>();
        private static BuildingTables Buildings {
            get;
            set;
        }
        = new BuildingTables();
        private const uint LARGE_WOODEN_BOX = 2206646561;
        private const uint SMALL_WOODEN_BOX = 1560881570;
        private const uint COFFIN_STORAGE = 4080262419;
        private const float INSTRUCTION_TIME = 0.02f;
        private bool maintainEnabled {
            get;
            set;
        }
        private bool scheduleEnabled {
            get;
            set;
        }
        private bool buyableEnabled {
            get;
            set;
        }
        private static List<ulong> BoxSkins {
            get;
            set;
        }
        = new List<ulong>();
        private static Dictionary<string, ItemDefinition> shortnameDefs = new Dictionary<string, ItemDefinition>();
        private static List<string> shortnames = new List<string>();
        private static Dictionary<Vector3, float> LoadingTimes = new Dictionary<Vector3, float>();
        private static bool IsBox(uint prefabID) => prefabID == LARGE_WOODEN_BOX || prefabID == SMALL_WOODEN_BOX || prefabID == COFFIN_STORAGE;
        private List<string> Helms = 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 = new List<string> {
            "boots.frog", "shoes.boots", "burlap.shoes", "attire.hide.boots"
        }
        ;
        private List<string> Gloves = new List<string> {
            "burlap.gloves.new", "burlap.gloves", "roadsign.gloves", "tactical.gloves"
        }
        ;
        private List<string> Vests = 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 = new List<string> {
            "burlap.trousers", "heavy.plate.pants", "attire.hide.pants", "pants.shorts", "wood.armor.pants", "pants"
        }
        ;
        private List<string> Shirts = new List<string> {
            "hoodie", "burlap.shirt", "shirt.collared", "attire.hide.vest", "shirt.tanktop", "tshirt.long", "tshirt"
        }
        ;
        private List<string> Other = new List<string> {
            "movembermoustachecard", "movembermoustache", "sunglasses02black", "sunglasses02camo", "sunglasses02red", "sunglasses03black", "sunglasses03chrome", "sunglasses03gold", "sunglasses", "twitchsunglasses", "gloweyes", "attire.bunnyears"
        }
        ;
        private List<uint> Furnaces = new List<uint> {
            1374462671, 2931042549, 1402456403
        }
        ;
        private List<uint> BBQs = new List<uint> {
            2409469892, 128449714
        }
        ;
        private List<uint> Lanterns = new List<uint> {
            3887352222, 1889323056, 630866573, 4027991414, 1392608348
        }
        ;
        private List<uint> Refineries = new List<uint> {
            1057236622, 919097516
        }
        ;
        //campfire: 4160694184, campfire_static: 1339281147, cursedcauldron.deployed: 1348425051, fireplace.deployed: 110576239, hobobarrel_static: 754638672, skull_fire_pit: 1906669538
        private enum SpawnResult {
            Failure, Transfer, Success, Skipped
        }
        private enum LootType {
            Easy, Medium, Hard, Expert, Nightmare, Default
        }
        public class ZoneInfo {
            public Vector3 Position;
            public Vector3 Size;
            public float Distance;
            public OBB OBB;
        }
        public class SkinInfo {
            public List<ulong> skins = new List<ulong>();
            public List<ulong> allSkins = new List<ulong>();
        }
        public class BaseProfile {
            public List<TreasureItem> BaseLootList {
                get;
                set;
            }
            = new List<TreasureItem>();
            public BuildingOptions Options {
                get;
                set;
            }
            = new BuildingOptions();
            public BaseProfile() {
            }
            public BaseProfile(BuildingOptions options) {
                Options = options;
            }
            public static BaseProfile Clone(BaseProfile profile) {
                return profile.MemberwiseClone() as BaseProfile;
            }
        }
        private class BuildingTables {
            public Dictionary<LootType, List<TreasureItem>> DifficultyLootLists {
                get;
                set;
            }
            = new Dictionary<LootType, List<TreasureItem>>();
            public Dictionary<DayOfWeek, List<TreasureItem>> WeekdayLootLists {
                get;
                set;
            }
            = new Dictionary<DayOfWeek, List<TreasureItem>>();
            public Dictionary<string, BaseProfile> Profiles {
                get;
                set;
            }
            = new Dictionary<string, BaseProfile>();
            public bool ContainsKey(string fileName) {
                if (string.IsNullOrEmpty(fileName)) {
                    return true;
                }
                foreach (var profile in Profiles.Values) {
                    if (profile.Options.AdditionalBases.ContainsKey(fileName)) {
                        return true;
                    }
                }
                return Profiles.ContainsKey(fileName);
            }
        }
        private enum OperationalState {
            On, Off, Unknown
        }
        public class DelaySettings {
            public RaidableBase RaidableBase;
            public Timer Timer;
            public bool AllowPVP;
        }
        public enum RaidableType {
            None, Manual, Scheduled, Purchased, Maintained, Grid
        }
        public enum RaidableMode {
            Disabled = -1, Easy = 0, Medium = 1, Hard = 2, Expert = 3, Nightmare = 4, Random = 9999
        }
        public class ResourcePath {
            public List<uint> Blocks {
                get;
            }
            public List<uint> TrueDamage {
                get;
            }
            public ItemDefinition BoxDefinition {
                get;
            }
            public string ExplosionMarker {
                get;
            }
            public string CodeLock {
                get;
            }
            public string FireballSmall {
                get;
            }
            public string Fireball {
                get;
            }
            public string HighExternalWoodenWall {
                get;
            }
            public string HighExternalStoneWall {
                get;
            }
            public string Ladder {
                get;
            }
            public string Murderer {
                get;
            }
            public string RadiusMarker {
                get;
            }
            public string Sphere {
                get;
            }
            public string Scientist {
                get;
            }
            public string VendingMarker {
                get;
            }
            public ResourcePath() {
                Blocks = new List<uint> {
                    803699375, 2194854973, 919059809, 3531096400, 310235277, 2326657495, 3234260181, 72949757, 1745077396, 1585379529
                }
                ;
                TrueDamage = new List<uint> {
                    976279966, 3824663394, 1202834203, 4254045167, 1745077396, 1585379529
                }
                ;
                BoxDefinition = ItemManager.FindItemDefinition(StringPool.Get(2735448871));
                CodeLock = StringPool.Get(3518824735);
                ExplosionMarker = StringPool.Get(4060989661);
                FireballSmall = StringPool.Get(2086405370);
                Fireball = StringPool.Get(3369311876);
                HighExternalWoodenWall = StringPool.Get(1745077396);
                HighExternalStoneWall = StringPool.Get(1585379529);
                Ladder = StringPool.Get(2150203378);
                Murderer = StringPool.Get(3879041546);
                RadiusMarker = StringPool.Get(2849728229);
                Sphere = StringPool.Get(3211242734);
                Scientist = StringPool.Get(4223875851);
                VendingMarker = StringPool.Get(3459945130);
            }
        }
        public class SingletonBackbone : SingletonComponent<SingletonBackbone> {
            public RaidableBases Plugin {
                get;
                private set;
            }
            public ResourcePath Path {
                get;
                private set;
            }
            public Oxide.Core.Libraries.Lang lang => Plugin.lang;
            private StringBuilder sb => Plugin._sb;
            public StoredData Data => Plugin.storedData;
            public Dictionary<ulong, FinalDestination> Destinations {
                get;
                set;
            }
            public string Easy {
                get;
                set;
            }
            public string Medium {
                get;
                set;
            }
            public string Hard {
                get;
                set;
            }
            public string Expert {
                get;
                set;
            }
            public string Nightmare {
                get;
                set;
            }
            public float OceanLevel {
                get;
                set;
            }
            public SingletonBackbone(RaidableBases plugin) {
                Plugin = plugin;
                Path = new ResourcePath();
                Destinations = new Dictionary<ulong, FinalDestination>();
                Easy = RemoveFormatting(GetMessage("ModeEasy")).ToLower();
                Medium = RemoveFormatting(GetMessage("ModeMedium")).ToLower();
                Hard = RemoveFormatting(GetMessage("ModeHard")).ToLower();
                Expert = RemoveFormatting(GetMessage("ModeExpert")).ToLower();
                Nightmare = RemoveFormatting(GetMessage("ModeNightmare")).ToLower();
                OceanLevel = WaterSystem.OceanLevel;
                InvokeRepeating(CheckOceanLevel, 60f, 60f);
            }
            public void Destroy() {
                BoxSkins.Clear();
                Path = null;
                Plugin = null;
                DestroyImmediate(Instance);
            }
            private void CheckOceanLevel() {
                if (OceanLevel != WaterSystem.OceanLevel) {
                    OceanLevel = WaterSystem.OceanLevel;
                    RaidableSpawns rs;
                    if (!Plugin.raidSpawns.TryGetValue(RaidableType.Grid, out rs)) {
                        return;
                    }
                    rs.TryAddRange(CacheType.Submerged);
                }
            }
            public void InitializeSkins() {
                foreach (var def in ItemManager.GetItemDefinitions()) {
                    if (!shortnames.Contains(def.shortname)) shortnames.Add(def.shortname);
                    var imd = def.GetComponent<ItemModDeployable>();
                    if (imd == null || shortnameDefs.ContainsKey(imd.entityPrefab.resourcePath)) continue;
                    shortnameDefs.Add(imd.entityPrefab.resourcePath, def);
                }
                if (Path.BoxDefinition == null) {
                    return;
                }
                BoxSkins.Clear();
                var skinInfo = RaidableBase.GetItemSkins(Path.BoxDefinition);
                if (_config.Skins.Boxes.RandomWorkshopSkins && skinInfo.allSkins.Count > 0) {
                    BoxSkins.AddRange(skinInfo.allSkins);
                }
                else if (skinInfo.skins.Count > 0) {
                    BoxSkins.AddRange(skinInfo.skins);
                }
            }
            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 && id != null && id != "server_console" && !key.EndsWith("Flag")) {
                    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 RemoveFormatting(string source) => source.Contains(">") ? Regex.Replace(source, "<.*?>", string.Empty) : source;
            public Timer Timer(float seconds, Action action) => Plugin.timer.Once(seconds, action);
            public bool HasPermission(string id, string perm) => Plugin.permission.UserHasPermission(id, perm);
        }
        public class Elevation {
            public float Min {
                get;
                set;
            }
            public float Max {
                get;
                set;
            }
        }
        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 enum CacheType {
            Generic, Construction, Privilege, Submerged,
        }
        public class RaidableSpawns {
            public readonly HashSet<RaidableSpawnLocation> Spawns = new HashSet<RaidableSpawnLocation>();
            private readonly Dictionary<CacheType, HashSet<RaidableSpawnLocation>> Cached = new Dictionary<CacheType, HashSet<RaidableSpawnLocation>>();
            public int Count {
                get {
                    return Spawns.Count;
                }
            }
            public void Add(RaidableSpawnLocation rsl, CacheType cacheType) {
                if (cacheType == CacheType.Submerged) {
                    if (Backbone.Plugin.IsSubmerged(rsl)) {
                        Get(cacheType).Add(rsl);
                        return;
                    }
                }
                else if (cacheType == CacheType.Generic) {
                    if (Backbone.Plugin.EventTerritory(rsl.Location)) {
                        return;
                    }
                }
                Spawns.Add(rsl);
            }
            public void TryAddRange(CacheType cacheType = CacheType.Generic) {
                HashSet<RaidableSpawnLocation> cache = Get(cacheType);
                foreach (var rsl in cache) {
                    Add(rsl, cacheType);
                }
                cache.RemoveWhere(rsl => Spawns.Contains(rsl));
            }
            public HashSet<RaidableSpawnLocation> Active => Spawns;
            public HashSet<RaidableSpawnLocation> Inactive(CacheType cacheType) => Get(cacheType);
            public void Check() {
                if (Spawns.Count == 0) {
                    TryAddRange();
                }
            }
            public RaidableSpawnLocation GetRandom() {
                var rsl = Spawns.ElementAt(UnityEngine.Random.Range(0, Spawns.Count));
                Remove(rsl, CacheType.Generic);
                return rsl;
            }
            public HashSet<RaidableSpawnLocation> Get(CacheType cacheType) {
                HashSet<RaidableSpawnLocation> cache;
                if (!Cached.TryGetValue(cacheType, out cache)) {
                    Cached[cacheType] = cache = new HashSet<RaidableSpawnLocation>();
                }
                return cache;
            }
            public void AddNear(Vector3 target, float radius, CacheType cacheType) {
                HashSet<RaidableSpawnLocation> cache = Get(cacheType);
                AddNear(cache, target, radius);
            }
            public void AddNear(HashSet<RaidableSpawnLocation> cache, Vector3 target, float radius) {
                foreach (var b in cache) {
                    if (InRange(target, b.Location, radius)) {
                        Spawns.Add(b);
                    }
                }
                cache.RemoveWhere(x => Spawns.Contains(x));
            }
            public void Remove(RaidableSpawnLocation a, CacheType cacheType) {
                HashSet<RaidableSpawnLocation> cache = Get(cacheType);
                cache.Add(a);
                Spawns.Remove(a);
            }
            public static float GetDistance(RaidableType type) {
                float distance;
                switch (type) {
                    case RaidableType.Maintained : {
                        distance = _config.Settings.Maintained.Distance;
                        break;
                    }
                    case RaidableType.Purchased : {
                        distance = _config.Settings.Buyable.Distance;
                        break;
                    }
                    case RaidableType.Scheduled : {
                        distance = _config.Settings.Schedule.Distance;
                        break;
                    }
                    case RaidableType.Manual : {
                        distance = _config.Settings.Manual.Distance;
                        break;
                    }
                    default : {
                        distance = 100f;
                        break;
                    }
                }
                return distance;
            }
            public float RemoveNear(Vector3 target, float radius, CacheType cacheType, RaidableType type) {
                if (cacheType == CacheType.Generic) {
                    float r = GetDistance(type);
                    if (r > radius) {
                        radius = r;
                    }
                }
                var cache = Get(cacheType);
                foreach (var b in Spawns) {
                    if (InRange(target, b.Location, radius)) {
                        cache.Add(b);
                    }
                }
                Spawns.RemoveWhere(x => cache.Contains(x));
                return radius;
            }
            public RaidableSpawns(HashSet<RaidableSpawnLocation> spawns) {
                Spawns = spawns;
            }
            public RaidableSpawns() {
            }
        }
        private class MapInfo {
            public string Url;
            public string IconName;
            public Vector3 Position;
        }
        public class PlayerInfo {
            public int TotalRaids {
                get;
                set;
            }
            public int Raids {
                get;
                set;
            }
            public PlayerInfo() {
            }
        }
        public class Lockout {
            public double Easy {
                get;
                set;
            }
            public double Medium {
                get;
                set;
            }
            public double Hard {
                get;
                set;
            }
            public double Expert {
                get;
                set;
            }
            public double Nightmare {
                get;
                set;
            }
            public bool Any() => Easy > 0 || Medium > 0 || Hard > 0 || Expert > 0 || Nightmare > 0;
        }
        public class RotationCycle {
            private Dictionary<RaidableMode, List<string>> _buildings = new Dictionary<RaidableMode, List<string>>();
            public void Add(RaidableType type, RaidableMode mode, string key) {
                if (!_config.Settings.Management.RequireAllSpawned || type == RaidableType.Grid || type == RaidableType.Manual) {
                    return;
                }
                List<string> keyList;
                if (!_buildings.TryGetValue(mode, out keyList)) {
                    _buildings[mode] = keyList = new List<string>();
                }
                if (!keyList.Contains(key)) {
                    keyList.Add(key);
                }
            }
            public bool CanSpawn(RaidableType type, RaidableMode mode, string key) {
                if (mode == RaidableMode.Disabled) {
                    return false;
                }
                if (!_config.Settings.Management.RequireAllSpawned || mode == RaidableMode.Random || type == RaidableType.Grid || type == RaidableType.Manual) {
                    return true;
                }
                List<string> keyList;
                if (!_buildings.TryGetValue(mode, out keyList)) {
                    return true;
                }
                return TryClear(type, mode, keyList) || !keyList.Contains(key);
            }
            public bool TryClear(RaidableType type, RaidableMode mode, List<string> keyList) {
                foreach (var profile in Buildings.Profiles) {
                    if (profile.Value.Options.Mode != mode || !CanSpawnDifficultyToday(mode) || MustExclude(type, profile.Value.Options.AllowPVP)) {
                        continue;
                    }
                    if (!keyList.Contains(profile.Key) && FileExists(profile.Key)) {
                        return false;
                    }
                    foreach (var kvp in profile.Value.Options.AdditionalBases) {
                        if (!keyList.Contains(kvp.Key) && FileExists(kvp.Key)) {
                            return false;
                        }
                    }
                }
                keyList.Clear();
                return true;
            }
        }
        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() {
            }
        }
        private class PlayWithFire : FacepunchBehaviour {
            private FireBall fireball {
                get;
                set;
            }
            private BaseEntity target {
                get;
                set;
            }
            private bool fireFlung {
                get;
                set;
            }
            private Coroutine mcCoroutine {
                get;
                set;
            }
            public BaseEntity Target {
                get {
                    return target;
                }
                set {
                    target = value;
                    enabled = true;
                }
            }
            private void Awake() {
                fireball = GetComponent<FireBall>();
                enabled = false;
            }
            private void FixedUpdate() {
                if (!IsValid(target) || target.Health() <= 0) {
                    fireball.Extinguish();
                    Destroy(this);
                    return;
                }
                fireball.transform.RotateAround(target.transform.position, Vector3.up, 5f);
                fireball.transform.hasChanged = true;
            }
            public void FlingFire(BaseEntity attacker) {
                if (fireFlung) return;
                fireFlung = true;
                mcCoroutine = StartCoroutine(MakeContact(attacker));
            }
            private IEnumerator MakeContact(BaseEntity attacker) {
                float distance = Vector3.Distance(fireball.ServerPosition, attacker.transform.position);
                while (!Backbone.Plugin.IsUnloading && attacker != null && fireball != null && !fireball.IsDestroyed && !InRange(fireball.ServerPosition, attacker.transform.position, 2.5f)) {
                    fireball.ServerPosition = Vector3.MoveTowards(fireball.ServerPosition, attacker.transform.position, distance * 0.1f);
                    yield return CoroutineEx.waitForSeconds(0.3f);
                }
            }
            private void OnDestroy() {
                if (mcCoroutine != null) {
                    StopCoroutine(mcCoroutine);
                    mcCoroutine = null;
                }
                Destroy(this);
            }
        }
        public class PlayerInputEx : FacepunchBehaviour {
            public BasePlayer player {
                get;
                set;
            }
            private InputState input {
                get;
                set;
            }
            private RaidableBase raid {
                get;
                set;
            }
            public void Setup(BasePlayer player, RaidableBase raid) {
                this.player = player;
                this.raid = raid;
                raid.Inputs[player] = this;
                input = player.serverInput;
                InvokeRepeating(Repeater, 0f, 0.1f);
            }
            public void Restart() {
                CancelInvoke(Repeater);
                InvokeRepeating(Repeater, 0f, 0.1f);
            }
            private void Repeater() {
                if (raid == null) {
                    Destroy(this);
                    return;
                }
                if (!player || !player.IsConnected) {
                    raid.TryInvokeResetPayLock();
                    Destroy(this);
                    return;
                }
                TryPlaceLadder(player, raid);
            }
            public static bool TryPlaceLadder(BasePlayer player, RaidableBase raid) {
                if (player.svActiveItemID == 0) {
                    return false;
                }
                var input = player.serverInput;
                if (!input.WasJustReleased(BUTTON.FIRE_PRIMARY) && !input.IsDown(BUTTON.FIRE_PRIMARY)) {
                    return false;
                }
                Item item = player.GetActiveItem();
                if (item?.info.shortname != "ladder.wooden.wall") {
                    return false;
                }
                RaycastHit hit;
                if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 4f, Layers.Mask.Construction, QueryTriggerInteraction.Ignore)) {
                    return false;
                }
                var block = hit.GetEntity();
                if (!block.IsValid() || block.OwnerID != 0 || !Backbone.Path.Blocks.Contains(block.prefabID))  // walls and foundations
                {
                    return false;
                }
                int amount = item.amount;
                var action = new Action(() => {
                    if (raid == null || item == null || item.amount != amount || IsLadderNear(hit.point)) {
                        return;
                    }
                    var rot = Quaternion.LookRotation(hit.normal, Vector3.up);
                    var e = GameManager.server.CreateEntity(Backbone.Path.Ladder, hit.point, rot, true);
                    if (e == null) {
                        return;
                    }
                    e.gameObject.SendMessage("SetDeployedBy", player, SendMessageOptions.DontRequireReceiver);
                    e.OwnerID = 0;
                    e.Spawn();
                    item.UseItem(1);
                    var planner = item.GetHeldEntity() as Planner;
                    if (planner != null) {
                        var deployable = planner?.GetDeployable();
                        if (deployable != null && deployable.setSocketParent && block.SupportsChildDeployables()) {
                            e.SetParent(block, true, false);
                        }
                    }
                    raid.Entities.Add(e);
                    raid.BuiltList.Add(e.net.ID);
                }
                );
                player.Invoke(action, 0.1f);
                return true;
            }
            public static bool IsLadderNear(Vector3 target) {
                var list = Pool.GetList<BaseLadder>();
                Vis.Entities(target, 0.3f, list, Layers.Mask.Deployed, QueryTriggerInteraction.Ignore);
                bool result = list.Count > 0;
                Pool.FreeList(ref list);
                return result;
            }
            private void OnDestroy() {
                CancelInvoke();
                raid?.Inputs?.Remove(player);
                Destroy(this);
            }
        }
        public class FinalDestination : FacepunchBehaviour {
            public NPCPlayerApex npc;
            private List<Vector3> positions;
            public AttackOperator.AttackType attackType;
            private NpcSettings settings;
            private bool isRanged;
            private BasePlayer target;
            private ulong userID;
            public bool stationary;
            private bool _isDormant;
            private Vector3 home;
            private float maxRoamRange;
            private void OnDestroy() {
                Backbone?.Destinations?.Remove(userID);
                CancelInvoke();
                Destroy(this);
            }
            public void Set(bool isDormant) {
                if (_isDormant == isDormant || isDormant && npc.AttackTarget is BasePlayer) {
                    return;
                }
                _isDormant = npc.IsDormant = isDormant;
                if (_isDormant) {
                    CancelInvoke(Go);
                    return;
                }
                npc.IsStopped = false;
                npc.RandomMove();
                InvokeRepeating(Go, 0f, 7.5f);
            }
            public void Set(NPCPlayerApex npc, List<Vector3> positions, NpcSettings settings, Vector3 home, float maxRoamRange) {
                this.npc = npc;
                this.positions = positions;
                this.settings = settings;
                this.home = home;
                this.maxRoamRange = maxRoamRange;
                attackType = IsMelee(npc) ? AttackOperator.AttackType.CloseRange : AttackOperator.AttackType.LongRange;
                isRanged = attackType != AttackOperator.AttackType.CloseRange;
                Backbone.Destinations[userID = npc.userID] = this;
                if (!(stationary = positions == null)) {
                    if (_config.Settings.Management.NpcIsDormant) {
                        Set(true);
                        return;
                    }
                    InvokeRepeating(Go, 0f, 7.5f);
                }
                else InvokeRepeating(Attack, 0f, 1f);
            }
            public void Attack(BasePlayer player, bool converge = true) {
                if (_isDormant) {
                    Set(false);
                }
                if (target == player) {
                    return;
                }
                if (!IsInvoking(Attack)) {
                    InvokeRepeating(Attack, 0f, 1f);
                }
                if (npc.Stats.AggressionRange < 150f) {
                    npc.Stats.AggressionRange += 150f;
                    npc.Stats.DeaggroRange += 100f;
                }
                npc.AttackTarget = player;
                npc.lastAttacker = player;
                npc.AiContext.LastAttacker = player;
                target = player;
                if (converge) {
                    Converge(player);
                }
            }
            private void Attack() {
                if (stationary) {
                    StationaryAttack();
                    return;
                }
                if (npc.AttackTarget == null || !(npc.AttackTarget is BasePlayer)) {
                    return;
                }
                var attacker = npc.AttackTarget as BasePlayer;
                if (attacker.IsDead() || !InRange(attacker.transform.position, npc.transform.position, maxRoamRange * 2f)) {
                    Forget();
                    CancelInvoke(Attack);
                    if (_config.Settings.Management.NpcIsDormant) {
                        Set(true);
                        return;
                    }
                    InvokeRepeating(Go, 0f, 7.5f);
                    return;
                }
                if (!npc.GetMounted()) {
                    npc.NeverMove = false;
                    npc.IsStopped = false;
                    npc.RandomMove();
                }
                if (attacker.IsVisible(npc.eyes.position, attacker.eyes.position)) {
                    HumanAttackOperator.AttackEnemy(npc.AiContext, attackType);
                }
            }
            private void StationaryAttack() {
                npc.SetAimDirection(new Vector3(npc.transform.forward.x, 0, npc.transform.forward.z));
                if (npc.AttackTarget == null || !(npc.AttackTarget is BasePlayer)) {
                    return;
                }
                var attacker = npc.AttackTarget as BasePlayer;
                if (attacker.IsDead()) {
                    Forget();
                    return;
                }
                if (attacker.IsVisible(npc.eyes.position, attacker.eyes.position)) {
                    npc.SetAimDirection((attacker.transform.position - npc.transform.position).normalized);
                    HumanAttackOperator.AttackEnemy(npc.AiContext, attackType);
                }
            }
            private void Forget() {
                npc.Stats.AggressionRange = settings.AggressionRange;
                npc.Stats.DeaggroRange = settings.AggressionRange * 1.125f;
                npc.lastDealtDamageTime = Time.time - 21f;
                npc.SetFact(Facts.HasEnemy, 0, true, true);
                npc.SetFact(Facts.EnemyRange, 3, true, true);
                npc.SetFact(Facts.AfraidRange, 1, true, true);
                npc.AttackTarget = null;
                npc.lastAttacker = null;
                npc.lastAttackedTime = Time.time - 31f;
                npc.LastAttackedDir = Vector3.zero;
            }
            public void Warp() {
                var position = positions.GetRandom();
                npc.Pause();
                npc.ServerPosition = position;
                npc.GetNavAgent.Warp(position);
                npc.stuckDuration = 0f;
                npc.IsStuck = false;
                npc.Resume();
            }
            private void Go() {
                if (npc.GetMounted()) {
                    return;
                }
                if (npc.IsHeadUnderwater()) {
                    npc.Kill();
                    Destroy(this);
                    return;
                }
                if (npc.AttackTarget == null) {
                    npc.NeverMove = true;
                    if (npc.IsStuck) {
                        Warp();
                    }
                    var position = positions.GetRandom();
                    if (npc.GetNavAgent == null || !npc.GetNavAgent.isOnNavMesh) {
                        npc.finalDestination = position;
                    }
                    else npc.GetNavAgent.SetDestination(position);
                    npc.IsStopped = false;
                    npc.Destination = position;
                }
            }
            private void Converge(BasePlayer player) {
                foreach (var fd in Backbone.Destinations.Values) {
                    if (fd != this && fd.npc.IsValid() && fd.npc.AttackTarget == null && fd.npc.IsAlive() && fd.npc.Distance(npc) < 25f) {
                        if (fd.attackType != attackType) continue;
                        fd.npc.SetFact(Facts.AllyAttackedRecently, 1, true, true);
                        fd.npc.SetFact(Facts.AttackedRecently, 1, true, true);
                        fd.Attack(player, false);
                        fd.Attack();
                    }
                }
            }
            private bool IsMelee(BasePlayer player) {
                var attackEntity = player.GetHeldEntity() as AttackEntity;
                if (attackEntity == null) {
                    return false;
                }
                return attackEntity is BaseMelee;
            }
            public bool NpcCanRoam(Vector3 destination) => InRange(home, destination, maxRoamRange);
        }
        public class BlockProperties {
            public OBB obb;
            public Vector3 position;
            public uint prefabID;
        }
        public class BackpackData {
            public DroppedItemContainer backpack;
            public BasePlayer player;
            public ulong userID;
        }
        public class RaidableBase : FacepunchBehaviour {
            private List<BaseMountable> mountables {
                get;
                set;
            }
            = Pool.GetList<BaseMountable>();
            public Hash<uint, float> conditions {
                get;
                set;
            }
            = Pool.Get<Hash<uint, float>>();
            private Dictionary<string, string> _clans {
                get;
                set;
            }
            = Pool.Get<Dictionary<string, string>>();
            private Dictionary<string, List<string>> _friends {
                get;
                set;
            }
            = Pool.Get<Dictionary<string, List<string>>>();
            public List<StorageContainer> _containers {
                get;
                set;
            }
            = Pool.GetList<StorageContainer>();
            public List<StorageContainer> _allcontainers {
                get;
                set;
            }
            = Pool.GetList<StorageContainer>();
            public Dictionary<BasePlayer, PlayerInputEx> Inputs {
                get;
                set;
            }
            = Pool.Get<Dictionary<BasePlayer, PlayerInputEx>>();
            public List<NPCPlayerApex> npcs {
                get;
                set;
            }
            = Pool.GetList<NPCPlayerApex>();
            public Dictionary<uint, BasePlayer> records {
                get;
                set;
            }
            = Pool.Get<Dictionary<uint, BasePlayer>>();
            public Dictionary<ulong, BasePlayer> raiders {
                get;
                set;
            }
            = Pool.Get<Dictionary<ulong, BasePlayer>>();
            public List<BasePlayer> friends {
                get;
                set;
            }
            = Pool.GetList<BasePlayer>();
            public List<BasePlayer> intruders {
                get;
                set;
            }
            = Pool.GetList<BasePlayer>();
            public Dictionary<uint, BackpackData> corpses {
                get;
                set;
            }
            = Pool.Get<Dictionary<uint, BackpackData>>();
            private Dictionary<FireBall, PlayWithFire> fireballs {
                get;
                set;
            }
            = Pool.Get<Dictionary<FireBall, PlayWithFire>>();
            private List<Vector3> foundations {
                get;
                set;
            }
            = Pool.GetList<Vector3>();
            private List<BlockProperties> blockProperties {
                get;
                set;
            }
            = Pool.GetList<BlockProperties>();
            private List<SphereEntity> spheres {
                get;
                set;
            }
            = Pool.GetList<SphereEntity>();
            private List<BaseEntity> lights {
                get;
                set;
            }
            = Pool.GetList<BaseEntity>();
            private List<BaseOven> ovens {
                get;
                set;
            }
            = Pool.GetList<BaseOven>();
            public List<AutoTurret> turrets {
                get;
                set;
            }
            = Pool.GetList<AutoTurret>();
            private List<Door> doors {
                get;
                set;
            }
            = Pool.GetList<Door>();
            private List<CustomDoorManipulator> doorControllers {
                get;
                set;
            }
            = Pool.GetList<CustomDoorManipulator>();
            public Dictionary<string, float> lastActive {
                get;
                set;
            }
            = Pool.Get<Dictionary<string, float>>();
            public List<string> ids {
                get;
                set;
            }
            = Pool.GetList<string>();
            private List<Locker> lockers {
                get;
                set;
            }
            = Pool.GetList<Locker>();
            private Dictionary<string, ulong> skins {
                get;
                set;
            }
            = Pool.Get<Dictionary<string, ulong>>();
            public BuildingPrivlidge priv {
                get;
                set;
            }
            private Dictionary<string, List<string>> npcKits {
                get;
                set;
            }
            private MapMarkerExplosion explosionMarker {
                get;
                set;
            }
            private M
// ... [Code preview truncated due to length. Full source in attached file] ...

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