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

FREE BradleyGuards : 1.6.7 1.6.7

Нет прав для скачивания
C#:
using Rust;
using Rust.Ai;
using Rust.Registry;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Network;
using Network.Visibility;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.AI;
using Facepunch;
namespace Oxide.Plugins {
    [Info("Bradley Guards", "Krungh Crow", "1.6.7", ResourceId = 183)]
    [Description("Bradley spawns A tank Crew when destroyed")]
    class BradleyGuards : RustPlugin {
#region Changelogs and ToDo
        /*******************************************************************************************
        * 
        * v1.1.2    :   fixed Guard npc not carrying a weapon if kit is not existing
        * v1.1.3    :   BradleyGuards and npc will not target each other
        * v1.1.4    :   Patched for BradleyTiers
        * v1.1.5    :   Added that Guards will ignore sleepers
        *           :   Improved Mono with extra waterchecks and removes the Guards if they happen to walk into water (submerged)
        *           :   Improved the spawning if in buildings and will find a new spawn location
        *           :   Some coding cleanup (regions)
        *           :   Guards will not recieve fireball damage from the bradley fires
        * v1.2.0    :   Added ResourceID
        *           :   Performance Update
        * v1.2.1    :   Fixed Bradley Guards despawn on plugin un/reload
        *           :   Fixed npc from targeting the Bradley Guards through global settings
        * v1.2.2    :   Patched for december 2nd rust update.
        * v1.2.3    :   Fixed oxide mixing up HumanNPC plugin(same name) and npc type
        * v1.3.0    :   Fix for NPC attackrange
        * v1.3.1    :   Patched various AI behaviour
        *           :   NPC now ignore players in safezone
        *           :   Fixed NPC being Idle after spawning
        *           :   Changed NPC spawnheight
        *           :   Switched from junkpile to roam scientists
        *           :   Skips HP and Crate settings if using Monument Bradley plugin
        * v1.3.2    :   Added Navhit check on npc spawn
        *           :   Npc are forced on navmesh
        *           :   Added npc spawnradius (10 by default) in config
        * v1.3.3    :   Patched for conflict with BotReSpawn (by steenamaroo)
        * v1.3.4    :   if Bradley spawns with less then 100hp destoys it
        * v1.4.0    :   Added support for Convoy
        *           :   Added MLRS rockets on lastditcheffort
        *               Side effect samsites can target the rockets 
        *           :   Removed Bradley health check and kill
        *           :   Added API : bool IsBradleyNpc(global::HumanNPC npc)
        *
        *               object OnEntityDeath(global::HumanNPC npc, HitInfo info)
                        {
                            if (npc == null) return null;
                            if (BradleyGuards.Call<bool>("IsBradleyNpc", npc))
                            {
                                Puts($"Target : {npc} net.ID : [{npc.net.ID}] Event : BradleyGuards NPC");
                            }
                            return null;
                        }
        * v1.4.1    :   Possible fix for the new nre
        *           :   Added better check if Convoy is installed
        *           :   Added (Bradley Crew Body to Bags) to destroy corpse and drops the npc loot
        *           :   Updated msg system (no need to redo language files)
        *           :   Fixed endless mlrs rockets when amount is set to 0
        *           :   Fixed npc will despawn instead of die when life duration ends
        *           :   Fixed the Radio sound when npc are killed
        * v1.4.2    :   Possible fix for runaway npc
        *           :   Added support for BetterNpcNames
        * v1.4.3    :   Added support for ArmoredTrain
        *           :   Pre patched for ArmoredTrain plugin update
        * v1.4.4    :   Hotfix for using same triggers
        *           :   Fixed Max crate spawns
        *           :   Fixed Health
        *           :   Fixed exploit npc corpses having their gears when using BetterNpcNames(v1.0.3)
        * v1.4.5    :   Possible fix for Targeting when BG and ArmoredTrain is installed
        *           :   BG ignores max amount of bradleycrates to spawn when the bradley is ArmoredTrain APC
        * v1.4.6    :   Static samsites will ignore the MLRS rockets
        *           :   Added MLRS rocket radius
        *           :   Added Last Ditch Effort Hardmode
        *           :   Repositioned console notification BG event started
        * v1.4.7    :   Removed ownerid checks to avoid locked bradleys from other plugins
        * v1.4.8    :   Fix for compile issues
        * v1.4.9    :   Patched for 6/7/2023 Rust Update
        * v1.5.0    :   Possible Roaming fix
        * v1.5.1    :   Bradley ignores sleepers or players in safezone
        *           :   Removed admin perm
        *           :   Fixed permissions
        *           :   Possible fix for npc strip issue on Carbon Servers
        * v1.5.2    :   Possible fix for runaway npc
        *           :   When going vanished npc should return roaming unless attacked first
        *           :   Fixed Bradley targeting players in Vanish when BradleyOptions is not loaded
        *           :   Replaced Fire rockets for the actual Molotovs
        *           :   Removed some redundant code
        *           :   Possible fix for NRE strip
        *           :   Molotovs will not spamm trigger the nades and mollotovs thrown by the bradley
        * v1.5.3    :   Patch for bradleytargeting nre
        * v1.6.0    :   External plugin cfg changed to use triggers incl npc spawning (true/false)
        *           :   Optimised checks for Convoy,ArmoredTrain and Satdish/HarborEvent
        *           :   Reworked the NPC spawn calls to be able to be used as Api for BradleyEvents/BradleyTiers
        *           :   Fixed APC target override for event/custom APC's
        *           :   Added Option to replace molotovs with firerockets
        *           :   Added support for BradleyEvents and BradleyDrops plugins
        * v1.6.1    :   Optimised OnSamSiteTarget trigger
        *               Updated API IsBradleyNpc now returns null or true
        *               Added API : OnBradleyNPCDeath(global::HumanNPC npc, HitInfo info)
        *               Added API : OnBradleyNPCGotHit(global::HumanNPC npc, HitInfo info)
        * v1.6.2    :   Changed npc type to (scientistnpc_bradleyapc_monument)
        * v1.6.3    :   Reverted back to scientistnpc_roam since new one was removed
        * v1.6.5    :   Patched for dec rust update
        * v1.6.6    :   Updates for fires with TruePVE compatibility (patched by Nivex)
        * 
        *******************************************************************************************/
#endregion
        [PluginReference]
        Plugin ArmoredTrain , BetterNpcNames, Bradley, BradleyTiers, BradleyEvents, Convoy, Kits;
#region OnServerInitialized
        void OnServerInitialized() => instance = this;
#endregion
#region Variables
        private readonly List<ulong> _Crew = new List<ulong>();
        const ulong chaticon = 76561198410558650;
        const string sci = "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_roam.prefab";
        //const string sci = "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_bradley.prefab";
        //const string sci = "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_bradley_heavy.prefab";
        const string bomb1 = "assets/prefabs/weapons/beancan grenade/grenade.beancan.deployed.prefab";
        const string bomb2 = "assets/prefabs/weapons/f1 grenade/grenade.f1.deployed.prefab";
        const string molotov = "assets/prefabs/weapons/molotov cocktail/grenade.molotov.deployed.prefab";
        const string rocketfire = "assets/prefabs/ammo/rocket/rocket_fire.prefab";
        const string MLRS = "assets/content/vehicles/mlrs/rocket_mlrs.prefab";
        const string ShowMessages_Perm = "bradleyguards.ShowMessages";
        const string ShowKillMessages_Perm = "bradleyguards.ShowKillMessages";
        string prefix;
        bool NPCTarget;
#endregion
#region Mono
        public static BradleyGuards instance;
        public static Dictionary<BasePlayer, BradleyCrew> SpawnedCrew {
            get;
            set;
        }
        = new Dictionary<BasePlayer, BradleyCrew>();
        void Unload() {
            RemoveAllNpc();
        }
        public class BradleyCrew : FacepunchBehaviour {
            public global : : HumanNPC npc;
            public bool ReturningToHome = false;
            public bool isRoaming = true;
            public Vector3 SpawnPoint;
            void Start() {
                npc = GetComponent<global : : HumanNPC>();
                InvokeRepeating("GoHome", 1.0f, 5.0f);
                Invoke(nameof(_UseBrain), 0.1f);
            }
            public void _UseBrain() {
#region navigation
                npc.Brain.Navigator.Agent.agentTypeID = -1372625422;
                npc.Brain.Navigator.DefaultArea = "Walkable";
                npc.Brain.Navigator.enabled = true;
                npc.Brain.Navigator.CanUseNavMesh = true;
                npc.Brain.Navigator.BestCoverPointMaxDistance = instance.configData.Event.CrewRoam /2;
                npc.Brain.Navigator.BestRoamPointMaxDistance = instance.configData.Event.CrewRoam;
                npc.Brain.Navigator.MaxRoamDistanceFromHome = instance.configData.Event.CrewRoam;
                npc.Brain.Navigator.Init(npc, npc.Brain.Navigator.Agent);
                npc.Brain.Navigator.SetDestination(SpawnPoint, BaseNavigator.NavigationSpeed.Slow, 0f, 0f);
#endregion
#region senses & Targeting
                npc.Brain.ForceSetAge(0);
                npc.Brain.AllowedToSleep = false;
                npc.Brain.sleeping = false;
                npc.Brain.SenseRange = 30f;
                npc.Brain.ListenRange = 40f;
                npc.Brain.TargetLostRange = 25f;
                npc.Brain.HostileTargetsOnly = false;
                npc.Brain.IgnoreSafeZonePlayers = true;
#endregion
            }
            void GoHome() {
                if (npc == null || npc.IsDestroyed || npc.isMounted) return;
                if (!npc.HasBrain) return;
                if (npc.Brain.Senses.Memory.Targets.Count > 0) {
                    for (var i = 0; i < npc.Brain.Senses.Memory.Targets.Count; i++) {
                        BaseEntity target = npc.Brain.Senses.Memory.Targets[i];
                        BasePlayer player = target as BasePlayer;
                        if (target == null || !player.IsAlive()) {
                            WipeMemory();
                            ReturningToHome = true;
                            isRoaming = false;
                            return;
                        }
                        if (npc.Distance(player.transform.position) > 40f) {
                            WipeMemory();
                            ReturningToHome = true;
                            isRoaming = false;
                            return;
                        }
                    }
                }
                var distanceHome = Vector3.Distance(npc.transform.position, SpawnPoint);
                if (ReturningToHome == false) {
                    if (isRoaming == true && distanceHome > instance.configData.Event.CrewRoam) {
                        ReturningToHome = true;
                        isRoaming = false;
                        return;
                    }
                    if (isRoaming == true && distanceHome < instance.configData.Event.CrewRoam) {
                        Vector3 random = UnityEngine.Random.insideUnitCircle.normalized * 10f;
                        Vector3 newPos = instance.GetNavPoint(SpawnPoint + new Vector3(random.x, 0f, random.y));
                        SettargetDestination(newPos);
                        return;
                    }
                }
                if (ReturningToHome && distanceHome > 2) {
                    if (npc.Brain.Navigator.Destination == SpawnPoint) return;
                    WipeMemory();
                    SettargetDestination(SpawnPoint);
                    return;
                }
                ReturningToHome = false;
                isRoaming = true;
            }
            private void SettargetDestination(Vector3 position) {
                npc.Brain.Navigator.Destination = position;
                npc.Brain.Navigator.SetDestination(position, BaseNavigator.NavigationSpeed.Slow, 0f, 0f);
            }
            void WipeMemory() {
                if (!npc.HasBrain) return;
                npc.Brain.Senses.Players.Clear();
                npc.Brain.Senses.Memory.Players.Clear();
                npc.Brain.Senses.Memory.Targets.Clear();
                npc.Brain.Senses.Memory.Threats.Clear();
                npc.Brain.Senses.Memory.LOS.Clear();
                npc.Brain.Senses.Memory.All.Clear();
            }
            void OnDestroy() {
                if (npc != null && !npc.IsDestroyed) {
                    npc.Kill();
                }
                CancelInvoke("GoHome");
                CancelInvoke(nameof(_UseBrain));
            }
        }
#endregion
#region Configuration
        void Init() {
            if (!LoadConfigVariables()) {
                Puts("Config file issue detected. Please delete file, or check syntax and fix.");
                return;
            }
            permission.RegisterPermission(ShowMessages_Perm, this);
            permission.RegisterPermission(ShowKillMessages_Perm, this);
            NPCTarget = configData.NPCTarget;
            prefix = lang.GetMessage("Prefix", this);
        }
        private ConfigData configData;
        class ConfigData {
            [JsonProperty(PropertyName = "Global NPC dont target")]
            public bool NPCTarget = false;
            [JsonProperty(PropertyName = "External Plugins")]
            public SettingsExternal External = new SettingsExternal();
            [JsonProperty(PropertyName = "Bradley Settings")]
            public SettingsBradley Bradley = new SettingsBradley();
            [JsonProperty(PropertyName = "Bradley Loot")]
            public SettingsBradleyLoot BradleyLoot = new SettingsBradleyLoot();
            [JsonProperty(PropertyName = "Bradley Canon")]
            public SettingsBradleyCanon BradleyCanon = new SettingsBradleyCanon();
            [JsonProperty(PropertyName = "Bradley Machinegun")]
            public SettingsBradleyMachinegun BradleyMachineGun = new SettingsBradleyMachinegun();
            [JsonProperty(PropertyName = "Event Settings")]
            public SettingsEvent Event = new SettingsEvent();
            [JsonProperty(PropertyName = "Tank Crew Driver")]
            public TankCrewDriver TankCrewDriver = new TankCrewDriver();
            [JsonProperty(PropertyName = "Tank Crew Guards")]
            public TankCrewGuards TankCrewGuards = new TankCrewGuards();
            [JsonProperty(PropertyName = "Tank Crew Gunners")]
            public TankCrewGunner TankCrewGunner = new TankCrewGunner();
        }
        class SettingsExternal {
            [JsonProperty(PropertyName = "Armored Train : Can trigger Events")]
            public bool CanTriggerTrain = false;
            [JsonProperty(PropertyName = "Convoy : Can trigger Events")]
            public bool CanTriggerConv = false;
            [JsonProperty(PropertyName = "SatDish/Harbor Event : Can trigger Events")]
            public bool CanTriggerSatdish = false;
            [JsonProperty(PropertyName = "BradleyDrops : Can trigger Events")]
            public bool CanTriggerBradleyDrops = false;
            [JsonProperty(PropertyName = "BetterNpcNames :  Driver Title")]
            public string DriverTitle = "Driver";
            [JsonProperty(PropertyName = "BetterNpcNames :  Guard Title")]
            public string GuardTitle = "Commander";
            [JsonProperty(PropertyName = "BetterNpcNames :  Gunner Title")]
            public string GunnerTitle = "Gunner";
        }
        class SettingsBradley {
            [JsonProperty(PropertyName = "Change Values")]
            public bool BSettingsUse = true;
            [JsonProperty(PropertyName = "Bradley Health")]
            public int BradleyHealth = 2000;
            [JsonProperty(PropertyName = "Bradley Max Fire Range")]
            public int BradleyMaxFireRange = 100;
            [JsonProperty(PropertyName = "Bradley Throttle Responce")]
            public float BradleySpeed = 1.0f;
        }
        class SettingsBradleyCanon {
            [JsonProperty(PropertyName = "Change Values")]
            public bool BCSettingsUse = true;
            [JsonProperty(PropertyName = "Bradley Canon Fire delay")]
            public float BradleyCanonFireDelay = 0.3f;
            [JsonProperty(PropertyName = "Bradley Canon Firerate")]
            public float BradleyCanonFireRate = 0.25f;
        }
        class SettingsBradleyLoot {
            [JsonProperty(PropertyName = "Change Values")]
            public bool LootSettingsUse = true;
            [JsonProperty(PropertyName = "Bradley Max crates after kill")]
            public int BradleyMaxCratesAfterKill = 4;
        }
        class SettingsBradleyMachinegun {
            [JsonProperty(PropertyName = "Change Values")]
            public bool BMGSettingsUse = true;
            [JsonProperty(PropertyName = "Bradley Machinegun Bullet Damage")]
            public int BradleyMachinegunBulletDamage = 15;
            [JsonProperty(PropertyName = "Bradley Machinegun Firerate")]
            public float BradleyMachinegunFirerate = 0.06667f;
        }
        class SettingsEvent {
            [JsonProperty(PropertyName = "Bradley Crew Max Spawn Distance")]
            public int CrewSpawnRadius = 10;
            [JsonProperty(PropertyName = "Bradley Crew Max Roam Distance")]
            public int CrewRoam = 50;
            [JsonProperty(PropertyName = "Bradley Crew Body to Bags")]
            public bool CrewBodybags = false;
            [JsonProperty(PropertyName = "Max throwing range of a Grenade")]
            public float MaxThrowingRangeOfAGrenade = 25.0f;
            [JsonProperty(PropertyName = "Max Grenades per trigger")]
            public int GrenadeAmount = 1;
            [JsonProperty(PropertyName = "Max throwing range of a Molotov")]
            public float MaxThrowingRangeOfAMolotov = 5.0f;
            [JsonProperty(PropertyName = "Max Molotovs per trigger")]
            public int MolotovAmount = 1;
            [JsonProperty(PropertyName = "Use Firerockets (instead of Molotovs)")]
            public bool UseFireRockets = false;
            [JsonProperty(PropertyName = "Hard Mode : Throws towards player (Grenades)")]
            public bool GrenadeHardMode = true;
            [JsonProperty(PropertyName = "Hard Mode : Max Grenades per trigger")]
            public int GrenadeAmountHM = 1;
            [JsonProperty(PropertyName = "Hard Mode : Max radius of a Grenade on player")]
            public float MaxThrowingRangeOfAGrenadeHM = 15.0f;
            [JsonProperty(PropertyName = "Hard Mode : Throws towards player (Molotovs)")]
            public bool MolotovHardMode = true;
            [JsonProperty(PropertyName = "Hard Mode : Max Molotovs per trigger")]
            public int MolotovAmountAmountHM = 1;
            [JsonProperty(PropertyName = "Hard Mode : Max radius of a Molotov on player")]
            public float MaxThrowingRangeOfAMolotovHM = 15.0f;
            [JsonProperty(PropertyName = "Napalm Support")]
            public bool DropSupportNapalmUse = true;
            [JsonProperty(PropertyName = "Napalm Support Area Radius")]
            public float DropSupportNapalmRange = 35.0f;
            [JsonProperty(PropertyName = "Napalm Support Rocket Amount")]
            public int DropSupportNapalmAmount = 3;
            [JsonProperty(PropertyName = "Napalm Support Rocket Height")]
            public int DropSupportNapalmHeight = 50;
            [JsonProperty(PropertyName = "Last Ditch Effort Rocket Amount")]
            public int LastDitchEffortNapalmAmount = 5;
            [JsonProperty(PropertyName = "Last Ditch Effort Grenade Amount")]
            public int LastDitchEffortGrenadeAmount = 5;
            [JsonProperty(PropertyName = "Last Ditch Effort MLRS rocket Radius")]
            public int LastDitchEffortMLRSRadius = 10;
            [JsonProperty(PropertyName = "Last Ditch Effort MLRS rocket Amount")]
            public int LastDitchEffortMLRSAmount = 5;
            [JsonProperty(PropertyName = "Last Ditch Effort Hard Mode : targets player location")]
            public bool LastDitchEffortHardMode = false;
        }
        class TankCrewDriver {
            [JsonProperty(PropertyName = "Tank Driver Health")]
            public float TankDriverHealth = 450.0f;
            [JsonProperty(PropertyName = "Tank Driver Lifetime (minutes)")]
            public float DriverLife = 10f;
            [JsonProperty(PropertyName = "Tank Driver Damage multiplier")]
            public float TankDriverDamageScale = 1.0f;
            [JsonProperty(PropertyName = "Tank Driver Spawn Chance 0-1")]
            public float TankDriverSpawnChance = 1.0f;
            [JsonProperty(PropertyName = "Tank Driver Spawn Amount")]
            public int TankDriverAmount = 1;
            [JsonProperty(PropertyName = "Tank Driver Use Outfit")]
            public bool UseOutfit1 = true;
            [JsonProperty(PropertyName = "Tank Driver Use other gun with outfit")]
            public bool UseOutfitG1 = false;
            [JsonProperty(PropertyName = "Tank Driver gun short prefabname")]
            public string UseOutfitGName1 = "smg.mp5";
            [JsonProperty(PropertyName = "Tank Driver gun skin id")]
            public ulong UseOutfitGSkin1 = 0;
            [JsonProperty(PropertyName = "Tank Driver Use kit (clothing)")]
            public bool UseKit1 = false;
            [JsonProperty(PropertyName = "Tank Driver Kit ID")]
            public string KitName1 = "";
        }
        class TankCrewGuards {
            [JsonProperty(PropertyName = "Tank Guards Health")]
            public float TankGuardsHealth = 800;
            [JsonProperty(PropertyName = "Tank Guards Lifetime (minutes)")]
            public float GuardsLife = 10f;
            [JsonProperty(PropertyName = "Tank Guards Damage multiplier")]
            public float TankGuardsDamageScale = 1.0f;
            [JsonProperty(PropertyName = "Tank Guards Spawn Chance 0-1")]
            public float TankGuardsSpawnChance = 1.0f;
            [JsonProperty(PropertyName = "Tank Guards Spawn Amount")]
            public int TankGuardsAmount = 2;
            [JsonProperty(PropertyName = "Tank Guards Use Outfit")]
            public bool UseOutfit2 = true;
            [JsonProperty(PropertyName = "Tank Guards Use other gun with outfit")]
            public bool UseOutfitG2 = false;
            [JsonProperty(PropertyName = "Tank Guards gun short prefabname")]
            public string UseOutfitGName2 = "smg.mp5";
            [JsonProperty(PropertyName = "Tank Guards gun skin id")]
            public ulong UseOutfitGSkin2 = 0;
            [JsonProperty(PropertyName = "Tank Guards Use kit (clothing)")]
            public bool UseKit2 = false;
            [JsonProperty(PropertyName = "Tank Guards Kit ID")]
            public string KitName2 = "";
        }
        class TankCrewGunner {
            [JsonProperty(PropertyName = "Tank Gunners Health")]
            public float TankGunnersHealth = 600;
            [JsonProperty(PropertyName = "Tank Gunners Lifetime (minutes)")]
            public float GunnersLife = 10f;
            [JsonProperty(PropertyName = "Tank Gunners Damage multiplier")]
            public float TankGunnersDamageScale = 1.0f;
            [JsonProperty(PropertyName = "Tank Gunners Spawn Chance 0-1")]
            public float TankGunnersSpawnChance = 1.0f;
            [JsonProperty(PropertyName = "Tank Gunners Spawn Amount")]
            public int TankGunnersAmount = 2;
            [JsonProperty(PropertyName = "Tank Gunners Use Outfit")]
            public bool UseOutfit3 = true;
            [JsonProperty(PropertyName = "Tank Gunners Use other gun with outfit")]
            public bool UseOutfitG3 = false;
            [JsonProperty(PropertyName = "Tank Gunners gun short prefabname")]
            public string UseOutfitGName3 = "smg.mp5";
            [JsonProperty(PropertyName = "Tank Gunners gun skin id")]
            public ulong UseOutfitGSkin3 = 0;
            [JsonProperty(PropertyName = "Tank Gunners Use kit (clothing)")]
            public bool UseKit3 = false;
            [JsonProperty(PropertyName = "Tank Gunners Kit ID")]
            public string KitName3 = "";
        }
        private bool LoadConfigVariables() {
            try {
                configData = Config.ReadObject<ConfigData>();
            }
            catch {
                return false;
            }
            SaveConf();
            return true;
        }
        protected override void LoadDefaultConfig() {
            Puts("Fresh install detected Creating a new config file.");
            configData = new ConfigData();
            SaveConf();
        }
        void SaveConf() => Config.WriteObject(configData, true);
#endregion
#region LanguageAPI
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Prefix"]
                = "<color=yellow>[BradleyGuards]</color> ", ["InvalidInput"] = "<color=red>Please enter a valid command!</color>", ["Version"] = "Version : V", ["Info"] = "\n<color=green>Available Commands</color>\n<color=green>/bgrespawncustom</color> : Respawns all killed custom placed bradleys <color=purple>[RustEdit]</color>.", ["BradleyDriver"] = "<color=yellow>Driver : </color>Damnit i just washed it!", ["BradleyDriverBomb"] = "<color=yellow>Driver : </color>Catch this!", ["BradleyGuards"] = "<color=yellow>Guard : </color>Stay away from our Bradley!", ["BradleyGunner"] = "<color=yellow>Gunner : </color>Prepare to die!", ["BradleyGunnerFire"] = "<color=yellow>Gunner : </color>Fire in the hooole!", ["BradleyNapalmSupport"] = "<color=yellow>Operator : </color>Support incomming!",
            }
            , this);
        }
#endregion
#region Commands
        [ChatCommand("bginfo")]
        void cmdBgInfo(BasePlayer player, string cmd, string[] args) {
            Player.Message(player, msg("Version") + this.Version.ToString() + " By : " + this.Author.ToString() , chaticon);
            return;
        }
#endregion
#region External Hooks
        List<ulong> BotReSpawns = new List<ulong>();
        void OnBotReSpawnNPCSpawned(ScientistNPC npc, string profilename, string group) => BotReSpawns.Add(npc.userID);
        object OnNpcKits(BasePlayer player) {
            if (_Crew.Contains(player.userID)) return true;
            return null;
        }
#endregion
#region Oxide Hooks
        private object OnNpcTarget(BasePlayer attacker, BasePlayer target) {
            if (attacker != null && _Crew.Contains(attacker.userID) && NPCTarget) {
                if (target.IsSleeping() || !target.userID.IsSteamId() || !target is BasePet) return true;
            }
            if (attacker != null && target != null && _Crew.Contains(target.userID) && NPCTarget) {
                return true;
            }
            return null;
        }
        private object OnSamSiteTarget(SamSite samsite , MLRSRocket target) {
            string ownerid = samsite.OwnerID.ToString();
            if ((samsite.staticRespawn && ownerid == "0") && target.skinID == 29051978) return false;
            else if ((samsite.staticRespawn && ownerid != "0") && target.skinID == 29051978) return true;
            return null;
        }
        private void OnBradleyApcInitialize(BradleyAPC bradley) {
            if (Interface.CallHook("IsTrainBradley", bradley) != null && configData.External.CanTriggerTrain == false) {
                return;
            }
            if (Interface.CallHook("IsConvoyVehicle", bradley) != null && bradley.skinID == 755446 && configData.External.CanTriggerConv == false) {
                return;
            }
            if (Interface.CallHook("CanBradleyTiersEdit", bradley) != null && configData.External.CanTriggerSatdish == false) {
                return;
            }
            if (configData.Bradley.BSettingsUse) {
                if (BradleyTiers == false) {
                    bradley._maxHealth = configData.Bradley.BradleyHealth;
                    bradley.health = bradley._maxHealth;
                }
                bradley.viewDistance = configData.Bradley.BradleyMaxFireRange;
                bradley.searchRange = configData.Bradley.BradleyMaxFireRange;
                bradley.throttle = configData.Bradley.BradleySpeed;
                bradley.leftThrottle = bradley.throttle;
                bradley.rightThrottle = bradley.throttle;
            }
            if (configData.BradleyLoot.LootSettingsUse && (!BradleyTiers || bradley.skinID != 755446)) {
                bradley.maxCratesToSpawn = configData.BradleyLoot.BradleyMaxCratesAfterKill;
            }
            if (configData.BradleyMachineGun.BMGSettingsUse) {
                bradley.bulletDamage = configData.BradleyMachineGun.BradleyMachinegunBulletDamage;
                bradley.coaxFireRate = configData.BradleyMachineGun.BradleyMachinegunFirerate;
            }
            if (configData.BradleyCanon.BCSettingsUse) {
                bradley.topTurretFireRate = configData.BradleyCanon.BradleyCanonFireRate;
                bradley.nextTopTurretTime = configData.BradleyCanon.BradleyCanonFireDelay;
            }
            bradley.SendNetworkUpdate();
        }
        void OnEntityKill(ScientistNPC npc) {
            if (npc == null) return;
            if (BotReSpawns.Contains(npc.userID)) BotReSpawns.Remove(npc.userID);
        }
        private object CanBradleyApcTarget(BradleyAPC bradley, BaseEntity target) {
            if (Interface.CallHook("IsTrainBradley" , bradley) != null && configData.External.CanTriggerTrain == false) {
                return null;
            }
            if (Interface.CallHook("IsConvoyVehicle" , bradley) != null && bradley.skinID == 755446 && configData.External.CanTriggerConv == false) {
                return null;
            }
            if (Interface.CallHook("CanBradleyTiersEdit" , bradley) != null && configData.External.CanTriggerSatdish == false) {
                return null;
            }
            var player = target as BasePlayer;
            if (player != null) {
                if (player is global : : HumanNPC || player.IsSleeping() || player.InSafeZone()) {
                    if (BotReSpawns.Contains(player.userID)) return null;
                    return false;
                }
                Vector3 mainTurretPosition = bradley.mainTurret.transform.position;
                if (!(player.IsVisible(mainTurretPosition, bradley.CenterPoint()) || player.IsVisible(mainTurretPosition, player.eyes.position) || player.IsVisible(mainTurretPosition, player.transform.position))) {
                    return false;
                }
                return null;
            }
            return null;
        }
        void OnEntityDeath(BradleyAPC bradley, HitInfo info) {
            if (Interface.CallHook("IsTrainBradley", bradley) != null && configData.External.CanTriggerTrain == false) {
                return;
            }
            if (Interface.CallHook("IsConvoyVehicle", bradley) != null && bradley.skinID == 755446 && configData.External.CanTriggerConv == false) {
                return;
            }
            if (Interface.CallHook("CanBradleyTiersEdit", bradley) != null && configData.External.CanTriggerSatdish == false) {
                return;
            }
            if (Interface.CallHook("IsBradleyDrop" , bradley) != null && configData.External.CanTriggerBradleyDrops == false) {
                return;
            }
            if (plugins.Exists("BradleyEvents") && plugins.Exists("BradleyTiers")) {
                Puts("BradleyTiers and Events are running, skipping BG spawns");
                return;
            }
            LogToFile("APCKills", $"{DateTime.Now:h:mm:ss tt}] {info.InitiatorPlayer} killed a BradleyAPC", this);
            var KillPosition = bradley.transform.position;
            BasePlayer player = info.InitiatorPlayer;
            if (UnityEngine.Random.Range(0f, 1f) <= configData.TankCrewDriver.TankDriverSpawnChance) {
                for (int i = 0; i < configData.TankCrewDriver.TankDriverAmount; i++) {
                    SpawnDriver(KillPosition, configData.TankCrewDriver.TankDriverHealth, configData.TankCrewDriver.TankDriverDamageScale);
                }
                if (player != null && HasPerm(player, ShowKillMessages_Perm)) Player.Message(player, msg("BradleyDriver"), chaticon);
                LogToFile("APCKills", $"{DateTime.Now:h:mm:ss tt}] {info.InitiatorPlayer} {configData.TankCrewDriver.TankDriverAmount} Tank Driver(s) got out", this);
            }
            if (UnityEngine.Random.Range(0f, 1f) <= configData.TankCrewGuards.TankGuardsSpawnChance) {
                for (int i = 0; i < configData.TankCrewGuards.TankGuardsAmount; i++) {
                    SpawnGuards(KillPosition, configData.TankCrewGuards.TankGuardsHealth, configData.TankCrewGuards.TankGuardsDamageScale);
                }
                if (player != null && HasPerm(player, ShowKillMessages_Perm)) Player.Message(player, msg("BradleyGuards"), chaticon);
                LogToFile("APCKills", $"{DateTime.Now:h:mm:ss tt}] {info.InitiatorPlayer} {configData.TankCrewGuards.TankGuardsAmount} Tank Guard(s) got out", this);
            }
            if (UnityEngine.Random.Range(0f, 1f) <= configData.TankCrewGunner.TankGunnersSpawnChance) {
                for (int i = 0; i < configData.TankCrewGunner.TankGunnersAmount; i++) {
                    SpawnGunner(KillPosition, configData.TankCrewGunner.TankGunnersHealth, configData.TankCrewGunner.TankGunnersDamageScale);
                }
                if (player != null && HasPerm(player, ShowKillMessages_Perm)) Player.Message(player, msg("BradleyGunner"), chaticon);
                LogToFile("APCKills", $"{DateTime.Now:h:mm:ss tt}] {info.InitiatorPlayer} {configData.TankCrewGunner.TankGunnersAmount} Tank Gunner(s) got out", this);
            }
            Vector3 TargetLocation = bradley.transform.position;
            Puts($"{info.InitiatorPlayer} Killed the BradleyApc in grid {GetGrid(TargetLocation)} starting the MiniGame ");
            if (configData.Event.LastDitchEffortHardMode) TargetLocation = player.transform.position;
            LastDitchEffort(TargetLocation);
        }
        private void OnEntitySpawned(BaseNetworkable entity) {
            var corpse = entity as LootableCorpse;
            if (corpse == null) return;
            if (_Crew.Contains(corpse.playerSteamID)) {
                if (configData.Event.CrewBodybags) timer.Once(0.1f, () => {
                    if (BetterNpcNames) corpse.containers[1].Clear();
                    //wipe clothing
                    if (BetterNpcNames) corpse.containers[2].Clear();
                    //wipe beltbar
                    corpse.Kill();
                    corpse.DropItems();
                }
                );
                _Crew.Remove(corpse.playerSteamID);
            }
        }
        void OnEntityTakeDamage(BradleyAPC bradley, HitInfo info, MolotovCocktail molly) {
            BasePlayer player = info.InitiatorPlayer;
            try {
                if (info.WeaponPrefab == molly) {
                    info.damageTypes = new DamageTypeList();
                    info.DoHitEffects = false;
                    return;
                }
                if (info == null || !player || BradleyEvents) return;
                if (!player) return;
                if (Interface.CallHook("IsTrainBradley", bradley) != null && configData.External.CanTriggerTrain == false) {
                    return;
                }
                if (Interface.CallHook("IsConvoyVehicle", bradley) != null && bradley.skinID == 755446 && configData.External.CanTriggerConv == false) {
                    return;
                }
                if (Interface.CallHook("CanBradleyTiersEdit", bradley) != null && configData.External.CanTriggerSatdish == false) {
                    return;
                }
                if (Interface.CallHook("IsBradleyDrop" , bradley) != null && configData.External.CanTriggerBradleyDrops == false) {
                    return;
                }
                if (player.userID.IsSteamId()) {
                    if (UnityEngine.Random.Range(0f, 1f) <= 0.05) {
                        if (configData.Event.GrenadeHardMode) Spawnbombs(player.transform.position);
                        else if (!configData.Event.GrenadeHardMode) Spawnbombs(bradley.transform.position);
                        if (player != null && HasPerm(player, ShowMessages_Perm)) Player.Message(player, msg("BradleyDriverBomb"), chaticon);
                    }
                    if (UnityEngine.Random.Range(0f, 1f) <= 0.05) {
                        if (configData.Event.MolotovHardMode) ThrowMolotov(player.transform.position);
                        else if (!configData.Event.MolotovHardMode) ThrowMolotov(bradley.transform.position);
                        if (player != null && HasPerm(player, ShowMessages_Perm)) Player.Message(player, msg("BradleyGunnerFire"), chaticon);
                    }
                    if (UnityEngine.Random.Range(0f, 1f) <= 0.01) {
                        if (configData.Event.DropSupportNapalmUse) {
                            SpawnSupportNapalm(player.transform.position);
                            if (player != null && HasPerm(player, ShowMessages_Perm)) Player.Message(player, msg("BradleyNapalmSupport"), chaticon);
                        }
                    }
                    return;
                }
            }
            catch {
            }
            return;
        }
        private void OnFireBallDamage(FireBall fire, global : : HumanNPC npc, HitInfo info) {
            if(info.Initiator is FireBall && fire != null && _Crew.Contains(npc.userID)) {
                info.damageTypes = new DamageTypeList();
                info.DoHitEffects = false;
                info.damageTypes.ScaleAll(0f);
            }
            return;
        }
        object OnEntityTakeDamage(global : : HumanNPC npc, HitInfo info) {
            if (!(_Crew.Contains(npc.userID))) return null;
            BasePlayer player = info.InitiatorPlayer;
            if (player) {
                Interface.CallHook("OnBradleyNPCGotHit" , npc, info);
            }
            if (info.WeaponPrefab is MLRSRocket) {
                info.damageTypes = new DamageTypeList();
                info.DoHitEffects = false;
                info.damageTypes.ScaleAll(0f);
                return true;
            }
            return null;
        }
        object OnPlayerDeath(global : : HumanNPC npc , HitInfo info) {
            if (!(_Crew.Contains(npc.userID))) return null;
            BasePlayer player = info.InitiatorPlayer;
            if (player) {
                Interface.CallHook("OnBradleyNPCDeath" , npc , info);
            }
            return null;
        }
#endregion
#region API
        private object IsBradleyNpc(global : : HumanNPC npc) {
            if (npc == null) return null;
            if (_Crew.Contains(npc.userID)) return true;
            return null;
        }
#endregion
#region Event Helpers
        private void RemoveAllNpc() {
            BradleyCrew[] BradleyCrew = UnityEngine.Object.FindObjectsOfType<BradleyCrew>();
            if (BradleyCrew != null) {
                foreach (BradleyCrew crew in BradleyCrew) UnityEngine.Object.Destroy(crew);
            }
        }
        public static Vector3 CheckPos(Vector3 pos) {
            pos.y = TerrainMeta.HeightMap.GetHeight(pos);
            NavMeshHit navMeshHit;
            if (!NavMesh.SamplePosition(pos, out navMeshHit, 1, 1)) pos = Vector3.zero;
            else if (WaterLevel.GetWaterDepth(pos, true, false) > 0) pos = Vector3.zero;
            else if (Physics.RaycastAll(navMeshHit.position + new Vector3(0, 100, 0), Vector3.down, 99f, 1235288065).Any()) pos = Vector3.zero;
            else pos = new Vector3(navMeshHit.position.x, TerrainMeta.HeightMap.GetHeight(navMeshHit.position), navMeshHit.position.z);
            return pos;
        }
        void SpawnDriver(Vector3 position, float Health , float DamageScale) {
            var pos = CheckPos(position);
            if (pos == Vector3.zero) return;
            int BGSR = configData.Event.CrewSpawnRadius;
            int x = UnityEngine.Random.Range(-BGSR, BGSR);
            int z = UnityEngine.Random.Range(-BGSR, BGSR);
            pos += new Vector3(x, 0, z);
            global : : HumanNPC driver = (global : : HumanNPC)GameManager.server.CreateEntity(sci, pos, new Quaternion(), true);
            driver.Spawn();
            NextTick(() => {
                if (driver == null) return;
                var mono = driver.gameObject.AddComponent<BradleyCrew>();
                mono.SpawnPoint = pos;
                driver.startHealth = Health;
                //configData.TankCrewDriver.TankDriverHealth
                driver.InitializeHealth(Health, Health);
                driver.displayName = "Bradley Driver";
                if (BetterNpcNames != null) driver.displayName = (BetterNpcNames.Call<string>("GiveName", driver , configData.External.DriverTitle, true, true));
                driver.damageScale = DamageScale;
                //configData.TankCrewDriver.TankDriverDamageScale
                (driver as ScientistNPC).radioChatterType = ScientistNPC.RadioChatterType.NONE;
                (driver as ScientistNPC).DeathEffects = new GameObjectRef[0];
                if (configData.TankCrewDriver.UseOutfit1) {
                    var inv_wear = driver.inventory.containerWear;
                    Item kilt = ItemManager.CreateByName("roadsign.kilt", 1, 2120628865);
                    Item chestplate = ItemManager.CreateByName("metal.plate.torso", 1, 2105505757);
                    Item facemask = ItemManager.CreateByName("metal.facemask", 1, 2120628865);
                    Item hoodie = ItemManager.CreateByName("hoodie", 1, 2080975449);
                    Item gloves = ItemManager.CreateByName("burlap.gloves", 1, 2090790324);
                    Item pants = ItemManager.CreateByName("pants", 1, 2080977144);
                    Item boots = ItemManager.CreateByName("shoes.boots", 1, 2090776132);
                    driver?.inventory?.Strip();
                    if (kilt != null) kilt.MoveToContainer(inv_wear);
                    if (chestplate != null) chestplate.MoveToContainer(inv_wear);
                    if (facemask != null) facemask.MoveToContainer(inv_wear);
                    if (hoodie != null) hoodie.MoveToContainer(inv_wear);
                    if (gloves != null) gloves.MoveToContainer(inv_wear);
                    if (pants != null) pants.MoveToContainer(inv_wear);
                    if (boots != null) boots.MoveToContainer(inv_wear);
                }
                if (configData.TankCrewDriver.UseOutfitG1) {
                    var shortname = configData.TankCrewDriver.UseOutfitGName1;
                    var skin = configData.TankCrewDriver.UseOutfitGSkin1;
                    var inv_belt = driver.inventory.containerBelt;
                    Item weapon = ItemManager.CreateByName(shortname, 1, skin);
                    inv_belt.Clear();
                    if (weapon != null) weapon.MoveToContainer(inv_belt);
                }
                else {
                    var inv_belt = driver.inventory.containerBelt;
                    Item weapon = ItemManager.CreateByName("smg.mp5", 1, 0);
                    inv_belt.Clear();
                    if (weapon != null) weapon.MoveToContainer(inv_belt);
                }
                if (configData.TankCrewDriver.UseKit1) {
                    object checkKit1 = Kits?.CallHook("GetKitInfo", configData.TankCrewDriver.KitName1);
                    if (checkKit1 == null) {
                        PrintWarning($"Kit for Driver ({configData.TankCrewDriver.KitName1}) does not exist - Using a default Scientistsuit.");
                    }
                    else {
                        driver?.inventory?.Strip();
                        Kits?.Call($"GiveKit", driver, configData.TankCrewDriver.KitName1);
                    }
                }
            }
            );
            if (driver.IsHeadUnderwater()) {
                driver.Kill();
                return;
            }
            if (!driver.IsOutside()) {
                driver.Kill();
                SpawnDriver(pos, Health, DamageScale);
                return;
            }
            _Crew.Add(driver.userID);
            timer.Once(configData.TankCrewDriver.DriverLife * 60, () => {
                if (driver != null) {
                    driver.Kill();
                    _Crew.Remove(driver.userID);
                    //Puts("Driver [" + driver.userID + "] Died of Natural causes!!!");
                }
            }
            );
        }
        void SpawnGuards(Vector3 position, float Health, float DamageScale) {
            var pos = CheckPos(position);
            if (pos == Vector3.zero) return;
            int BGSR = configData.Event.CrewSpawnRadius;
            int x = UnityEngine.Random.Range(-BGSR, BGSR);
            int z = UnityEngine.Random.Range(-BGSR, BGSR);
            pos += new Vector3(x, 0, z);
            global : : HumanNPC Guard = (global : : HumanNPC)GameManager.server.CreateEntity(sci, pos, new Quaternion(), true);
            Guard.Spawn();
            NextTick(() => {
                if (Guard == null) return;
                var mono = Guard.gameObject.AddComponent<BradleyCrew>();
                mono.SpawnPoint = pos;
                Guard.startHealth = Health;
                Guard.InitializeHealth(Health, Health);
                Guard.displayName = "Bradley Guard";
                if (BetterNpcNames != null) Guard.displayName = (BetterNpcNames.Call<string>("GiveName", Guard, configData.External.GuardTitle, true, true));
                Guard.damageScale = DamageScale;
                (Guard as ScientistNPC).radioChatterType = ScientistNPC.RadioChatterType.NONE;
                (Guard as ScientistNPC).DeathEffects = new GameObjectRef[0];
                if (configData.TankCrewGuards.UseOutfit2) {
       
// ... [Code preview truncated due to length. Full source in attached file] ...

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