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

FREE AirFieldEvent : 1.0.27 1.0.27

Нет прав для скачивания
C#:
using System.Collections.Generic;
using System.Collections;
using Oxide.Core.Configuration;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Oxide.Core;
using System;
using Oxide.Game.Rust.Cui;
using UnityEngine.SceneManagement;
using System.Text.RegularExpressions;
using Color = UnityEngine.Color;
using UnityEngine.AI;
using Facepunch;
using Facepunch.Utility;
using VLB;
using Rust;
using System.Reflection;
using ProtoBuf;
using Newtonsoft.Json.Linq;
using Rust.Ai;
using System.Globalization;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
    [Info("AirField event", "Ts3Hosting", "1.0.27", ResourceId = 31)]
    [Description("Cargo Plane AirField Event")]
    public class AirFieldEvent : RustPlugin {
        [PluginReference]
        Plugin Kits;
        private static List<NpcAIcontroler> _AllNpcAI = new List<NpcAIcontroler>();
        public static AirFieldEvent _;
        private const string CARGOPLANE = "assets/prefabs/npc/cargo plane/cargo_plane.prefab";
        readonly Dictionary<int, Timer> CheckEvent = new Dictionary<int, Timer>();
        static System.Random random = new System.Random();
        MonumentInfo monumentInfo;
        private Vector3 airfieldLocation;
        private Quaternion airfieldQuaternion;
        public List<BaseEntity> _allNPC = new List<BaseEntity>();
        public List<AirFieldNPC> allScientists = new List<AirFieldNPC>();
        private List<HackableLockedCrate> eventCrate = new List<HackableLockedCrate>();
        private bool eventRunning;
        public radZonesEvent towerMain;
        public radZonesEvent towerOne;
        public radZonesEvent towerTwo;
        public radZonesEvent towerThree;
        public radZonesEvent towerFour;
        private bool isStrikePlane(CargoPlane plane) => plane.GetComponent<cargoPlainMono>();
        private bool isEventPlane(CargoPlane plane) => plane.GetComponent<cargoPlainMono>();
        private static bool debug = true;
        private new void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["NoPerm"]
                = "<color=#ce422b>You can not use this command.</color>", ["StartingEvent"] = "<color=#ce422b>You spawned event crate at Airfield.</color>", ["AlreadyCrate"] = "<color=#ce422b>There is a crate already at Airfield</color>", ["EventRunning"] = "<color=#ce422b>There is a event already running.</color>",
            }
            , this);
        }
#region Config
        private ConfigData configData;
        class ConfigData {
            [JsonProperty(PropertyName = "Settings")]
            public Settings settings {
                get;
                set;
            }
            [JsonProperty(PropertyName = "HumanNPC Settings")]
            public SettingsNpc settingsNpc {
                get;
                set;
            }
            public class Settings {
                public string PermissionUse {
                    get;
                    set;
                }
                public float StartDistance {
                    get;
                    set;
                }
                public bool SpawnScientists {
                    get;
                    set;
                }
                public bool RadTowers {
                    get;
                    set;
                }
                public float MaxRads {
                    get;
                    set;
                }
                public bool NoBradleyCrates {
                    get;
                    set;
                }
            }
            public class SettingsNpc {
                public List<TheData> loadOut {
                    get;
                    set;
                }
            }
            public Oxide.Core.VersionNumber Version {
                get;
                set;
            }
        }
        protected override void LoadConfig() {
            _ = this;
            base.LoadConfig();
            configData = Config.ReadObject<ConfigData>();
            if (configData.Version < Version) UpdateConfigValues();
            Config.WriteObject(configData, true);
        }
        protected override void LoadDefaultConfig() => configData = GetBaseConfig();
        private ConfigData GetBaseConfig() {
            return new ConfigData {
                settings = new ConfigData.Settings {
                    PermissionUse = "airfieldevent.admin", StartDistance = 2000f, SpawnScientists = true, RadTowers = true, MaxRads = 50.0f, NoBradleyCrates = false
                }
                , settingsNpc = new ConfigData.SettingsNpc {
                    loadOut = new List<TheData>()
                }
                , Version = Version
            }
            ;
        }
        protected override void SaveConfig() => Config.WriteObject(configData, true);
        private void UpdateConfigValues() {
            PrintWarning("Config update detected! Updating config values...");
            ConfigData baseConfig = GetBaseConfig();
            if (configData.Version < new VersionNumber(1, 0, 1)) configData = baseConfig;
            configData.Version = Version;
            PrintWarning("Config update completed!");
        }
#endregion
        public class TheData {
            public float roamRange;
            public float health;
            public float Speed;
            public float agroRange;
            public int totalToSpawn;
            public bool radio;
            public List<string> kits;
        }
        void Init() {
            permission.RegisterPermission(configData.settings.PermissionUse, this);
        }
        private void OnServerInitialized() {
            bool hasAirfield = false;
            foreach (var monument in UnityEngine.Object.FindObjectsOfType<MonumentInfo>()) {
                var monumentName = GetMonumentName(monument);
                if (monumentName == null || !monumentName.Contains("airfield")) continue;
                hasAirfield = true;
                monumentInfo = monument;
                airfieldQuaternion = Quaternion.Euler(monument.transform.localEulerAngles.x, monument.transform.localEulerAngles.y, monument.transform.localEulerAngles.z);
                airfieldLocation = monument.transform.position;
            }
            if (!hasAirfield) {
                PrintWarning("No AirField found on your map PLUGIN UNLOADED.");
                covalence.Server.Command("o.unload CargoPlaneEvent");
                return;
            }
            if (configData.settingsNpc.loadOut.Count <= 0) {
                configData.settingsNpc.loadOut.Add(new TheData {
                    roamRange = 30, health = 100, Speed = 2.4f, agroRange = 100, totalToSpawn = 5, radio = false, kits = new List<string>()
                }
                );
                SaveConfig();
            }
            booted = true;
        }
        public bool booted;
        private void Unload() {
            foreach (var Controler in UnityEngine.Object.FindObjectsOfType<radZonesEvent>()) {
                UnityEngine.Object.Destroy(Controler);
            }
            cargoPlainMono[] planes = UnityEngine.Object.FindObjectsOfType<cargoPlainMono>();
            for (int i = 0; i < planes?.Length; i++) {
                if (planes[i] == null) continue;
                UnityEngine.Object.Destroy(planes[i]);
            }
            foreach (BaseEntity entity in _allNPC.ToList()) {
                entity?.Kill();
            }
            runeventEnd();
        }
#region Radation Zone Trigger
        public class radZonesEvent : MonoBehaviour {
            private Rigidbody rigidbody;
            private Collider collider;
            private Bounds bounds;
            private BoxCollider boxCollider;
            public List<BasePlayer> radPlayer = new List<BasePlayer>();
            private void Awake() {
                //transform.rotation = Quaternion.Euler(0f, _instance.configData.eventSettings.RedZoneRotation, 0f);
                if (rigidbody != null) DestroyImmediate(rigidbody);
                gameObject.layer = (int)Layer.Reserved1;
                gameObject.name = "Trigger";
                rigidbody = gameObject.AddComponent<Rigidbody>();
                rigidbody.useGravity = false;
                rigidbody.isKinematic = true;
                rigidbody.detectCollisions = true;
                rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete;
                boxCollider = gameObject.GetComponent<BoxCollider>();
            }
            public void setUpPosition(Vector3 position, Vector3 size) {
                transform.position = position;
                if (position != Vector3.zero) {
                    if (boxCollider == null) {
                        boxCollider = gameObject.AddComponent<BoxCollider>();
                        boxCollider.isTrigger = true;
                    }
                    boxCollider.size = size;
                    bounds = boxCollider.bounds;
                    collider = boxCollider;
                }
                //foreach (BasePlayer player in BasePlayer.activePlayerList.ToList())
                //_.drawZones(player, position, 0f, boxCollider.size / 2);
                InvokeRepeating("radPlayers", 0.5f, 0.6f);
            }
            private void radPlayers() {
                foreach (BasePlayer player in radPlayer.ToList()) {
                    if (player == null || player.IsDead() || Vector3.Distance(transform.position, player.transform.position) > 50f) {
                        radPlayer.Remove(player);
                    }
                    else if (player.metabolism.radiation_level.value < _.configData.settings.MaxRads || _.configData.settings.MaxRads == 0) {
                        player.metabolism.radiation_level.value += 1f;
                        player.metabolism.radiation_poison.value += 1f;
                        player.UpdateRadiation(player.metabolism.radiation_level.value);
                        player.SendNetworkUpdate();
                    }
                }
            }
            void OnDestroy() => UnityEngine.GameObject.Destroy(gameObject);
            public void Destory() {
                if (rigidbody != null) DestroyImmediate(rigidbody);
                if (boxCollider != null) DestroyImmediate(boxCollider);
                UnityEngine.GameObject.Destroy(gameObject);
            }
            private void OnTriggerEnter(Collider col) {
                BaseEntity baseEntity = col?.ToBaseEntity();
                if (!baseEntity.IsValid() || !baseEntity is BasePlayer) return;
                BasePlayer thePlayer = baseEntity as BasePlayer;
                if (thePlayer == null || radPlayer.Contains(thePlayer)) return;
                radPlayer.Add(thePlayer);
            }
            private void OnTriggerExit(Collider col) {
                BaseEntity baseEntity = col?.ToBaseEntity();
                if (!baseEntity.IsValid() || !baseEntity is BasePlayer) return;
                BasePlayer thePlayer = baseEntity as BasePlayer;
                if (thePlayer == null || !radPlayer.Contains(thePlayer)) return;
                radPlayer.Remove(thePlayer);
            }
        }
#endregion
#region Cargo Plane
        private class cargoPlainMono : MonoBehaviour {
            private CargoPlane plane;
            private BradleyAPC bradly;
            private bool islanding;
            private bool landed;
            private bool eventRunning;
            private Transform tr;
            private MonumentInfo monument = _.monumentInfo;
            private Vector3 startPos;
            public Vector3 endPos;
            public Vector3 endPosPrepLand;
            private Vector3 startPosLand;
            public Vector3 endPosLand;
            public Vector3 endPosstart;
            public Vector3 endPosEvent;
            public Vector3 dropHeavys = Vector3.zero;
            public Vector3 dropTank = Vector3.zero;
            private Vector3 bradleySpawn;
            private bool takeOFf;
            private bool isEnding;
            private float currentSpeed;
            private Vector3 baseEulerAngles;
            private float timeTaken;
            private bool radSet;
            private string fireCannonEffect = "assets/prefabs/npc/m2bradley/effects/maincannonattack.prefab";
            readonly Dictionary<Vector3, Timer> rockettimer = new Dictionary<Vector3, Timer>();
            private Vector3 tower0;
            private Vector3 tower1;
            private Vector3 tower2;
            private Vector3 tower3;
            private Vector3 tower4;
            private void Awake() {
                plane = GetComponent<CargoPlane>();
                plane.enabled = false;
                tr = plane.transform;
                //138.1356f, 25.5209f, -42.6026f
                startPos = monument.transform.TransformPoint(new Vector3(1714.0540f, 93.2331f, -139.9399f));
                endPos = monument.transform.TransformPoint(new Vector3(714.0540f, 93.2331f, -39.9399f));
                endPosPrepLand = monument.transform.TransformPoint(new Vector3(138.1356f, 0.3f, -42.6026f));
                endPosEvent = monument.transform.TransformPoint(new Vector3(-19.1976f, 0.5572f, -43.5018f));
                bradleySpawn = monument.transform.TransformPoint(new Vector3(81.6523f, 1.0561f, -43.6350f));
                baseEulerAngles = endPosPrepLand;
                tower0 = monument.transform.TransformPoint(new Vector3(-42.9318f, 25.9105f, -83.7037f));
                tower1 = monument.transform.TransformPoint(new Vector3(107.5858f, 22.3148f, -101.7767f));
                tower2 = monument.transform.TransformPoint(new Vector3(119.1027f, 22.0004f, 21.3733f));
                tower3 = monument.transform.TransformPoint(new Vector3(-109.3187f, 22.1835f, 68.3177f));
                tower4 = monument.transform.TransformPoint(new Vector3(-106.3504f, 19.1489f, -108.7641f));
                gameObject.layer = (int)Layer.Reserved2;
                gameObject.name = "EventPlane";
                ColliderAdd();
                currentSpeed = 35f;
                _.NextTick(() => {
                    setupPlane();
                }
                );
            }
            public void FireRocket(Vector3 hitPos) {
                Effect.server.Run(fireCannonEffect, plane, 0u, Vector3.zero, Vector3.zero, null, false);
                Vector3 launchPos = plane.transform.position + plane.transform.forward * 1;
                Vector3 newTarget = hitPos;
                BaseEntity rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_hv.prefab", launchPos, new Quaternion(), true);
                TimedExplosive rocketExplosion = rocket.GetComponent<TimedExplosive>();
                ServerProjectile rocketProjectile = rocket.GetComponent<ServerProjectile>();
                rocketProjectile.speed = 30;
                rocketProjectile.gravityModifier = 0;
                rocketExplosion.timerAmountMin = 60;
                rocketExplosion.timerAmountMax = 60;
                Vector3 newDirection = (newTarget - launchPos);
                rocketProjectile.InitializeVelocity(newDirection * 2);
                rocket.Spawn();
                rockettimer[hitPos] = _.timer.Every(0.5f, () => {
                    if (rocket == null) {
                        if (hitPos == tower1) {
                            _.towerOne = new GameObject().AddComponent<radZonesEvent>();
                            _.towerOne.setUpPosition(hitPos, new Vector3(19f, 20f, 19f));
                        }
                        else if (hitPos == tower2) {
                            _.towerTwo = new GameObject().AddComponent<radZonesEvent>();
                            _.towerTwo.setUpPosition(hitPos, new Vector3(19f, 18f, 19f));
                        }
                        else if (hitPos == tower3) {
                            _.towerThree = new GameObject().AddComponent<radZonesEvent>();
                            _.towerThree.setUpPosition(hitPos, new Vector3(19f, 20f, 19f));
                        }
                        else if (hitPos == tower4) {
                            _.towerFour = new GameObject().AddComponent<radZonesEvent>();
                            _.towerFour.setUpPosition(hitPos, new Vector3(19f, 20f, 19f));
                        }
                        rockettimer[hitPos].Destroy();
                    }
                }
                );
            }
            private void setRadZones() {
                FireRocket(tower1);
                _.timer.Once(10, () => {
                    FireRocket(tower2);
                }
                );
                _.timer.Once(3, () => {
                    FireRocket(tower3);
                }
                );
                _.timer.Once(11, () => {
                    FireRocket(tower4);
                }
                );
            }
            private void setupPlane() {
                float x = TerrainMeta.Size.x;
                float y;
                startPos.y = (TerrainMeta.HighestPoint.y * 1.0f);
                tr.rotation = Quaternion.LookRotation(endPos - startPos);
                plane.transform.position = startPos;
                plane.transform.position = tr.position + plane.transform.forward * -_.configData.settings.StartDistance;
            }
            private void ColliderAdd() {
                Rigidbody rigidbody = gameObject.AddComponent<Rigidbody>();
                rigidbody.useGravity = false;
                rigidbody.isKinematic = true;
                rigidbody.detectCollisions = true;
                rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete;
                BoxCollider collider = gameObject.AddComponent<BoxCollider>();
                collider.isTrigger = true;
                collider.size = new Vector3(50, 10, 50);
                collider.transform.localPosition = Vector3.up * 6;
            }
            private void Update() {
                if (!islanding && Vector3.Distance(tr.position, endPos) <= 15) {
                    baseEulerAngles = tr.eulerAngles;
                    islanding = true;
                    if (!radSet && _.configData.settings.RadTowers) setRadZones();
                }
                if (islanding) {
                    if (!landed && Vector3.Distance(tr.position, endPosPrepLand) <= 5) {
                        islanding = false;
                        landed = true;
                        return;
                    }
                    timeTaken = timeTaken + Time.deltaTime;
                    float delta = Mathf.InverseLerp(0, 20, timeTaken);
                    if (delta < 1) {
                        // currentSpeed = currentSpeed - Mathf.Lerp(0, 100, delta);
                        Vector3 direction = baseEulerAngles;
                        float yaw = Mathf.Lerp(0f, 25f, delta * 2f);
                        float turn = Mathf.Lerp(0f, 5f, delta * 2f);
                        direction.x -= yaw;
                        direction.y -= turn;
                        tr.eulerAngles = direction;
                    }
                    tr.position = Vector3.MoveTowards(tr.position, endPosPrepLand, currentSpeed * UnityEngine.Time.deltaTime);
                }
                else if (!landed) {
                    tr.position = Vector3.MoveTowards(tr.position, endPos, currentSpeed * UnityEngine.Time.deltaTime);
                }
                else if (landed && !eventRunning) {
                    if (!takeOFf && bradly == null && Vector3.Distance(tr.position, bradleySpawn) <= 1.2f) {
                        Vector3 dropOff = tr.position + plane.transform.forward * -15f;
                        dropOff.y = bradleySpawn.y + 1f;
                        spawnBradley(dropOff);
                    }
                    if (Vector3.Distance(tr.position, endPosEvent) <= 0.1) {
                        eventRunning = true;
                        timeTaken = 0;
                        baseEulerAngles = tr.eulerAngles;
                        takeOFf = true;
                    }
                    tr.position = Vector3.MoveTowards(tr.position, endPosEvent, currentSpeed * UnityEngine.Time.deltaTime);
                }
                else if (takeOFf) {
                    if (!isEnding) {
                        isEnding = true;
                        _.timer.Once(180, () => {
                            if (this != null) UnityEngine.GameObject.Destroy(gameObject);
                        }
                        );
                    }
                    timeTaken = timeTaken + Time.deltaTime;
                    float delta = Mathf.InverseLerp(0, 20, timeTaken);
                    if (delta < 1) {
                        Vector3 direction = baseEulerAngles;
                        float yaw = Mathf.Lerp(0f, 15f, delta * 2f);
                        direction.x -= yaw;
                        tr.eulerAngles = direction;
                    }
                    if (currentSpeed < 45f) currentSpeed = currentSpeed + 0.02f;
                    Vector3 enddirection = tr.position + tr.forward * 30f;
                    if (enddirection is Vector3) {
                        if (tr.position.y < 1200f) enddirection.y = tr.position.y + 10f;
                        tr.position = Vector3.MoveTowards(tr.position, enddirection, currentSpeed * UnityEngine.Time.deltaTime);
                    }
                }
            }
            private void spawnBradley(Vector3 position) {
                bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
                bradly.enableSaving = false;
                bradly.transform.rotation = tr.rotation;
                bradly.Spawn();
                _._allNPC.Add(bradly);
                BradlyAIPlane Brad = bradly.gameObject.AddComponent<BradlyAIPlane>();
                if (_.configData.settings.NoBradleyCrates) bradly.maxCratesToSpawn = 0;
            }
            private void OnDestroy() {
                if (plane != null) plane?.Kill();
            }
        }
#endregion
#region Brwdley controler
        public class BradlyAIPlane : MonoBehaviour {
            public BradleyAPC bradly;
            public BasePlayer player;
            public MonumentInfo monument = _.monumentInfo;
            public List<Vector3> Path = new List<Vector3>();
            private Coroutine QueuedRoutine;
            public bool stopped;
            public float lastSeenTime = 0f;
            public int currentPathIndex;
            public DateTime Active;
            private Vector3 aimVector = Vector3.forward;
            private Vector3 aimVectorTop = Vector3.forward;
            private int oldpath = 0;
            private bool IsAiming;
            private bool okGo;
            private float moveForce = 650.0f;
            private bool spawnSupport;
            private Coroutine QueuedRoutineSpawn;
            private void Awake() {
                bradly = GetComponent<BradleyAPC>();
                Active = DateTime.Now.AddSeconds(2);
                _.NextTick(() => {
                    MakePath();
                }
                );
                moveForce = 2650f;
                bradly.moveForceMax = moveForce;
            }
            private void OnDestroy() {
                if (QueuedRoutineSpawn != null) {
                    ServerMgr.Instance.StopCoroutine(QueuedRoutineSpawn);
                    QueuedRoutineSpawn = null;
                }
                if (QueuedRoutine != null) {
                    ServerMgr.Instance.StopCoroutine(QueuedRoutine);
                    QueuedRoutine = null;
                }
            }
            void Relocate() {
                if (bradly.targetList.Count <= 0) {
                    aimWeaponAt();
                    StartMoving();
                    CancelInvoke("Relocate");
                    return;
                }
            }
            private void MakePath() {
                Path.Clear();
                Path.Add(monument.transform.TransformPoint(new Vector3(-70.1203f, 0.5f, -43.5743f)));
                Path.Add(monument.transform.TransformPoint(new Vector3(-83.3062f, 0.5f, -52.4218f)));
                Path.Add(monument.transform.TransformPoint(new Vector3(-85.1310f, 0.2761f, -64.1430f)));
                Path.Add(monument.transform.TransformPoint(new Vector3(-71.2152f, 0.5f, -74.1124f)));
                Path.Add(monument.transform.TransformPoint(new Vector3(-56.8051f, 0.5f, -55.6783f)));
                bradly.currentPath = Path;
                bradly.currentPathIndex = 0;
                bradly.pathLooping = true;
                bradly.SendNetworkUpdateImmediate();
            }
            private void StopMoving() {
                currentPathIndex = bradly.currentPathIndex;
                bradly.pathLooping = false;
                bradly.ClearPath();
            }
            void StartMoving() {
                if (Path.Count <= 0) MakePath();
                bradly.currentPath = Path;
                bradly.currentPathIndex = currentPathIndex;
                bradly.pathLooping = true;
                bradly.moveForceMax = moveForce;
                stopped = false;
            }
            private IEnumerator updateAim() {
                while (!stopped) {
                    aimWeaponAt();
                    yield return new WaitForSeconds(4);
                }
                if (QueuedRoutine != null && stopped) InvokeHandler.Instance.StopCoroutine(QueuedRoutine);
                QueuedRoutine = null;
            }
            private void spawnScientists() {
                if (QueuedRoutineSpawn != null) return;
                TheData dataLoadOut = null;
                if (_.configData.settingsNpc.loadOut.Count == 1) dataLoadOut = _.configData.settingsNpc.loadOut[0];
                else dataLoadOut = _.configData.settingsNpc.loadOut[UnityEngine.Random.Range(0, _.configData.settingsNpc.loadOut.Count - 1)];
                if (dataLoadOut != null && QueuedRoutineSpawn == null) QueuedRoutineSpawn = ServerMgr.Instance.StartCoroutine(SpawnAllScientists(dataLoadOut.totalToSpawn, dataLoadOut));
            }
            private IEnumerator SpawnAllScientists(int total, TheData dataLoadOut) {
                while (total > 0) {
                    total--;
                    _.SpawnScientist(bradly.transform.position, dataLoadOut, _.monumentInfo.transform.TransformPoint(new Vector3(-71.1748f, 0.3189f, -62.0878f)));
                    yield return CoroutineEx.waitForSeconds(0.2f);
                }
                if (QueuedRoutineSpawn != null) {
                    ServerMgr.Instance.StopCoroutine(QueuedRoutineSpawn);
                    QueuedRoutineSpawn = null;
                }
            }
            private void Update() {
                if (!spawnSupport && bradly.currentPathIndex == 1 && bradly.moveForceMax != 650f) {
                    spawnSupport = true;
                    moveForce = 650f;
                    bradly.moveForceMax = moveForce;
                    stopped = true;
                    StopMoving();
                    if (_.configData.settings.SpawnScientists) spawnScientists();
                    _.timer.Once(10, () => {
                        if (this != null) okGo = true;
                        stopped = false;
                        StartMoving();
                    }
                    );
                }
                if (bradly == null || !okGo) return;
                if (monument == null) return;
                if (!stopped && bradly.targetList.Count >= 1) {
                    stopped = true;
                    StopMoving();
                    float delay = random.Next(2, 6);
                    InvokeRepeating("Relocate", delay, delay);
                    return;
                }
                //Ajust Aim
                if (QueuedRoutine == null && !stopped) {
                    QueuedRoutine = InvokeHandler.Instance.StartCoroutine(updateAim());
                }
                //Fix if loses path
                if (!stopped && Active < DateTime.Now && bradly.currentPath != Path && bradly.targetList.Count <= 0) {
                    StartMoving();
                }
            }
            //SetAim
            void aimWeaponAt() {
                bradly.desiredAimVector = bradly.topTurretAimVector;
                bradly.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                IsAiming = false;
            }
            private void OnCollisionEnter(Collision collision) {
                GameObject gObject = collision.gameObject;
                if (gObject == null) return;
                ResourceEntity resource = gObject.GetComponentInParent<ResourceEntity>();
                if (resource != null) {
                    resource.Kill(BaseNetworkable.DestroyMode.None);
                    return;
                }
                ModularCar car = gObject.GetComponentInParent<ModularCar>();
                if (car != null) {
                    Rigidbody rBody = car.GetComponent<Rigidbody>();
                    if (rBody != null) {
                        if (rBody.IsSleeping()) rBody.WakeUp();
                        var nullHit = new HitInfo(bradly, car, Rust.DamageType.Explosion, 100, car.transform.position);
                        nullHit.damageTypes.Add(Rust.DamageType.AntiVehicle, 50f);
                        car.Hurt(nullHit);
                    }
                    return;
                }
            }
        }
#endregion
#region spawningNPC
        internal AirFieldNPC SpawnScientist(Vector3 pos, TheData loadOut, Vector3 center) {
            pos.y = TerrainMeta.HeightMap.GetHeight(pos);
            object position = FindPointOnNavmesh(pos, 10f);
            if (position is Vector3 && (Vector3)position != Vector3.zero) {
                AirFieldNPC scientistNPC = InstantiateEntity((Vector3)position, Quaternion.Euler(0, 0, 0));
                if (scientistNPC == null) return null;
                scientistNPC.enableSaving = false;
                scientistNPC.Spawn();
                _allNPC.Add(scientistNPC);
                allScientists.Add(scientistNPC);
                scientistNPC.gameObject.SetActive(true);
                NextTick(() => {
                    if (scientistNPC == null) return;
                    scientistNPC.InitNewSettings(center, loadOut.health, 20f, loadOut.agroRange);
                    scientistNPC.setUpGear(loadOut.kits.GetRandom());
                }
                );
                NpcAIcontroler controler = scientistNPC.GetOrAddComponent<NpcAIcontroler>();
                if (scientistNPC != null) return scientistNPC;
            }
            return null;
        }
        private static AirFieldNPC InstantiateEntity(Vector3 position, Quaternion rotation) {
            GameObject gameObject = Instantiate.GameObject(GameManager.server.FindPrefab("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_any.prefab"), position, Quaternion.identity);
            gameObject.name = "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_any.prefab";
            gameObject.SetActive(false);
            ScientistNPC scientistNPC = gameObject.GetComponent<ScientistNPC>();
            ScientistBrain defaultBrain = gameObject.GetComponent<ScientistBrain>();
            defaultBrain._baseEntity = scientistNPC;
            AirFieldNPC component = gameObject.AddComponent<AirFieldNPC>();
            NpcRaiderBrain brains = gameObject.AddComponent<NpcRaiderBrain>();
            brains.Pet = false;
            brains.AllowedToSleep = false;
            CopySerializeableFields<NPCPlayer>(scientistNPC, component);
            brains._baseEntity = component;
            UnityEngine.Object.DestroyImmediate(defaultBrain, true);
            UnityEngine.Object.DestroyImmediate(scientistNPC, true);
            UnityEngine.SceneManagement.SceneManager.MoveGameObjectToScene(gameObject, Rust.Server.EntityScene);
            UnityEngine.Object.Destroy(gameObject.GetComponent<Spawnable>());
            return component;
        }
#region navMesh
        private static NavMeshHit navmeshHit;
        private static RaycastHit raycastHit;
        private static Collider[] _buffer = new Collider[256];
        private const int WORLD_LAYER = 65536;
        internal static object FindPointOnNavmesh(Vector3 targetPosition, float maxDistance = 4f) {
            for (int i = 0; i < 10; i++) {
                Vector3 position = i == 0 ? targetPosition : targetPosition + (UnityEngine.Random.onUnitSphere * maxDistance);
                if (NavMesh.SamplePosition(position, out navmeshHit, maxDistance, 1)) {
                    if (IsInRockPrefab2(navmeshHit.position)) continue;
                    if (IsNearWorldCollider(navmeshHit.position)) continue;
                    return navmeshHit.position;
                }
            }
            return null;
        }
        internal static bool IsInRockPrefab(Vector3 position) {
            Physics.queriesHitBackfaces = true;
            bool isInRock = Physics.Raycast(position, Vector3.up, out raycastHit, 20f, WORLD_LAYER, QueryTriggerInteraction.Ignore) && blockedColliders.Any(s => raycastHit.collider?.gameObject?.name.ToLower().Contains(s) ?? false);
            Physics.queriesHitBackfaces = false;
            return isInRock;
        }
        internal static bool IsInRockPrefab2(Vector3 position) {
            Vector3 p1 = position + new Vector3(0, 20f, 0);
            Vector3 p2 = position + new Vector3(0, -2f, 0);
            Vector3 diff = p2 - p1;
            RaycastHit[] hits;
            hits = Physics.RaycastAll(p1, diff, diff.magnitude);
            if (hits.Length > 0) {
                for (int i = 0; i < hits.Length; i++) {
                    RaycastHit hit = hits[i];
                    if (hit.collider != null) {
                        bool isRock = blockedColliders.Any(s => hit.collider?.gameObject?.name.ToLower().Contains(s) ?? false);
                        if (isRock) return true;
                    }
                }
            }
            return false;
        }
        internal static bool IsNearWorldCollider(Vector3 position) {
            Physics.queriesHitBackfaces = true;
            int count = Physics.OverlapSphereNonAlloc(position, 2f, _buffer, WORLD_LAYER, QueryTriggerInteraction.Ignore);
            Physics.queriesHitBackfaces = false;
            int removed = 0;
            for (int i = 0; i < count; i++) {
                if (acceptedColliders.Any(s => _buffer[i].gameObject.name.Contains(s))) removed++;
            }
            return count - removed > 0;
        }
        private static readonly string[] acceptedColliders = new string[] {
            "road", "carpark", "rocket_factory", "range", "train_track", "runway", "_grounds", "concrete_slabs", "lighthouse", "cave", "office", "walkways", "sphere", "tunnel", "industrial", "junkyard"
        }
        ;
        private static readonly string[] blockedColliders = new string[] {
            "rock", "junk", "range", "invisible", "cliff"
        }
        ;
#endregion
        private static void CopySerializeableFields<T>(T src, T dst) {
            FieldInfo[] srcFields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo field in srcFields) {
                object value = field.GetValue(src);
                field.SetValue(dst, value);
            }
        }
        public class AirFieldNPC : NPCPlayer, IAISenses, IAIAttack, IThinker {
            public int AdditionalLosBlockingLayer;
            public LootContainer.LootSpawnSlot[] LootSpawnSlots;
            public float aimConeScale = 2f;
            public float lastDismountTime;
            [NonSerialized]
            protected bool lightsOn;
            private float nextZoneSearchTime;
            private AIInformationZone cachedInfoZone;
            private float targetAimedDuration;
            private float lastAimSetTime;
            private Vector3 aimOverridePosition = Vector3.zero;
            public BaseCombatEntity currentTarget {
                get;
                set;
            }
            private List<int> _ProjectilesSlot = new List<int>();
            private List<int> _MeleWeaponSlot = new List<int>();
            public Vector3 HomePosition {
                get;
                set;
            }
            public bool isMountedAgent {
                get;
                set;
            }
            private float lastTargetTime {
                get;
                set;
            }
            private Vector3 lastTargetPosition {
                get;
                set;
            }
            public Vector3 lostPosition() => lastTargetPosition;
            public bool GoodLastTime() => lastTargetTime > Time.time;
            public override float StartHealth() => this.startHealth;
            public override float StartMaxHealth() => this.startHealth;
            public override float MaxHealth() => this.startHealth;
            public NpcRaiderBrain Brain {
                get;
                private set;
            }
            public override bool IsLoadBalanced() => true;
            public bool HasTarget() => (currentTarget != null);
            public override void ServerInit() {
                if (NavAgent == null) NavAgent = GetComponent<NavMeshAgent>();
                NavAgent.areaMask = 1;
                NavAgent.agentTypeID = -1372625422;
                GetComponent<BaseNavigator>().DefaultArea = "Walkable";
                base.ServerInit();
                Brain = this.GetComponent<NpcRaiderBrain>();
                AIThinkManager.Add((IThinker)this);
                _.NextTick(() => {
                    if (this == null) return;
                    InitNewSettings(this.transform.position);
                    InitMovementSettings();
                    setupweapons();
                }
                );
            }
            public void InitNewSettings(Vector3 home, float health = 100f, float Memory = 20f, float SenseRange = 30f, float LostRange = 250f, float attackRange = 2f, bool isMounted = false) {
                _.NextFrame(() => {
                    if (this == null) return;
                    if (home == Vector3.zero) HomePosition = this.transform.position;
                    else HomePosition = home;
                    this.startHealth = health;
                    this.InitializeHealth(health, health);
                    this.health = health;
                    Brain.Senses.MemoryDuration = Memory;
                    Brain.AttackRangeMultiplier = attackRange;
                    Brain.SenseRange = SenseRange;
                    Brain.TargetLostRange = LostRange;
                    isMountedAgent = isMounted;
                    //attackEntity.aiOnlyInRange
                }
                );
            }
            public void InitMovementSettings(float Acceleration = 12f, float Speed = 6.0f, float TurnSpeed = 120f, float NormalSpeedFraction = 0.5f, float FastSpeedFraction = 1f, float LowHealthMaxSpeedFraction = 0.9f, float SlowestSpeedFraction = 0.16f, float SlowSpeedFraction = 0.3f, float BestMovementPointMaxDistance = 20f, float MaxRoamDistanceFromHome = 30f, float BestRoamPointMaxDistance = 25f, float BestCoverPointMaxDistance = 5f) {
                _.NextFrame(() => {
                    if (this == null) return;
                    Brain.Navigator.Acceleration = Acceleration;
                    Brain.Navigator.Speed = Speed;
                    Brain.Navigator.TurnSpeed = TurnSpeed;
                    Brain.Navigator.NormalSpeedFraction = NormalSpeedFraction;
                    Brain.Navigator.FastSpeedFraction = FastSpeedFraction;
                    Brain.Navigator.LowHealthMaxSpeedFraction = LowHealthMaxSpeedFraction;
                    Brain.Navigator.SlowestSpeedFraction = SlowestSpeedFraction;
                    Brain.Navigator.SlowSpeedFraction = SlowSpeedFraction;
                    Brain.Navigator.BestMovementPointMaxDistance = BestMovementPointMaxDistance;
                    Brain.Navigator.MaxRoamDistanceFromHome = MaxRoamDistanceFromHome;
                    Brain.Navigator.BestRoamPointMaxDistance = BestRoamPointMaxDistance;
                    Brain.Navigator.BestCoverPointMaxDistance = BestCoverPointMaxDistance;
                    EquipWeapon();
                }
                );
            }
            public void setUpGear(string kitname = "") {
                if (!string.IsNullOrEmpty(kitname)) {
                    this.inventory.Strip();
                    object success = _.Kits.Call("GetKitInfo", kitname);
                    if (success == null) {
                        addDefaultGear();
                        _.PrintWarning($"Unable to find a kit with name {kitname}?");
                    }
                    else {
                        JObject obj = success as JObject;
                        JArray items = obj["items"] as JArray;
                        for (int i = 0; i < items.Count; i++) {
                            JObject itemObject = items[i] as JObject;
                            string container = (string)itemObject["container"];
                            if (container == "wear") ItemManager.CreateByItemID((int)itemObject["itemid"], (int)itemObject["amount"], (ulong)itemObject["skinid"]).MoveToContainer(this.inventory.containerWear, 0);
                            else if (container == "belt") {
                                Item item = ItemManager.CreateByItemID((int)itemObject["itemid"], (int)itemObject["amount"], (ulong)itemObject["skinid"]);
                                item.MoveToContainer(this.inventory.containerBelt, -1, true);
                                this.inventory.containerBelt.OnChanged();
                            }
                        }
                        setupweapons();
                        if (_ProjectilesSlot.Count > 0) EquipNewWeapon(_ProjectilesSlot[0]);
                        else if (_MeleWeaponSlot.Count > 0) EquipNewWeapon(_MeleWeaponSlot[0]);
                    }
                }
                else {
                    addDefaultGear();
                    EquipWeapon();
                    setupweapons();
                }
            }
            private void addDefaultGear() {
                switch (UnityEngine.Random.Range(0, 7)) {
                    case 0 : ItemManager.CreateByName("scientistsuit_heavy").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 1 : ItemManager.CreateByName("hazmatsuit_scientist_peacekeeper").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 2 : ItemManager.CreateByName("hazmatsuit_scientist").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 3 : ItemManager.CreateByName("hazmatsuit").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 4 : ItemManager.CreateByName("scientistsuit_heavy").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 5 : ItemManager.CreateByName("hazmatsuit_scientist_peacekeeper").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 6 : ItemManager.CreateByName("hazmatsuit_scientist").MoveToContainer(this.inventory.containerWear);
                    break;
                    case 7 : ItemManager.CreateByName("hazmatsuit").MoveToContainer(this.inventory.containerWear);
                    break;
                    default : ItemManager.CreateByName("hazmatsuit_scientist").MoveToContainer(this.inventory.containerWear);
                    break;
                }
                switch (UnityEngine.Random.Range(0, 9)) {
                    case 0 : ItemManager.CreateByName("smg.mp5").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 1 : ItemManager.CreateByName("shotgun.spas12").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 2 : ItemManager.CreateByName("rifle.lr300").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 3 : ItemManager.CreateByName("lmg.m249").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 4 : ItemManager.CreateByName("pistol.m92").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 5 : ItemManager.CreateByName("smg.mp5").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 6 : ItemManager.CreateByName("shotgun.spas12").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 7 : ItemManager.CreateByName("rifle.lr300").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 8 : ItemManager.CreateByName("lmg.m249").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    case 9 : ItemManager.CreateByName("pistol.m92").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                    default : ItemManager.CreateByName("pistol.m92").MoveToContainer(this.inventory.containerBelt, 0);
                    break;
                }
                this.inventory.containerBelt.OnChanged();
            }
            private void setupweapons() {
                _ProjectilesSlot = new List<int>();
                _MeleWeaponSlot = new List<int>();
                foreach (Item slot in inventory.containerBelt.itemList) {
                    if (slot != null) {
                        BaseEntity heldEntity = slot.GetHeldEntity();
                        if (heldEntity != null) {
                            AttackEntity _attackEntity = heldEntity.GetComponent<AttackEntity>();
                            if (_attackEntity != null) {
                                if (_attackEntity is BaseProjectile) {
                                    _ProjectilesSlot.Add(slot.position);
                                    _attackEntity.aiOnlyInRange = false;
                                }
                                else _MeleWeaponSlot.Add(slot.position);
                            }
                        }
                    }
                }
            }
            public bool EquipNewWeapon(int slot = 0) {
                Item weapon = this.inventory.containerBelt.GetSlot(slot);
                if (weapon != null) {
                    BaseEntity heldEntity = weapon.GetHeldEntity();
                    if (heldEntity != null) {
                        AttackEntity _
// ... [Code preview truncated due to length. Full source in attached file] ...

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