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

FREE CustomHelicopterTiers : 2.5.1 2.5.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using ConVar;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Rust;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Physics = UnityEngine.Physics;
using Pool = Facepunch.Pool;
using Random = UnityEngine.Random;
using Time = UnityEngine.Time;
using Network;
using Facepunch;
using Oxide.Game.Rust.Libraries;
namespace Oxide.Plugins {
    [Info("Custom Helicopter Tiers", "Dana", "2.5.1")]
    [Description("Create and customize an unlimited number of patrol helicopter levels with different difficulties.")]
    class CustomHelicopterTiers : RustPlugin {
#region References
        [PluginReference]
        private Plugin ServerRewards;
        [PluginReference]
        private Plugin Economics;
        [PluginReference]
        private Plugin TruePVE;
#endregion References
#region Config Auto-Update
        private bool AutoUpdateConfig(DynamicConfigFile configFile) {
            PrintWarning("Checking for auto-update config...");
            if (configFile == null) {
                PrintWarning("Invalid config file! auto-update skipped.");
                return false;
            }
            var config = configFile["Config"] as Dictionary<string, object>;
            var latestVersion = new PluginConfig().Config.Version;
            if (config == null) {
                PrintWarning("Config is either new or not supported.auto-update skipped.loading default config...");
                ApplyDefaultConfig();
                return false;
            }
            object configVersion = -1;
            config.TryGetValue("Config Version", out configVersion);
            if (configVersion == null) {
                //PrintWarning("Couldn't detect config version.consider adding \"Config Version\": 0 to your config files.auto-update skipped");
                //return false;
                configVersion = 1;
            }
            var oldVersion = -1;
            if (!int.TryParse(configVersion.ToString(), out oldVersion) || oldVersion == -1) {
                PrintWarning("Couldn't read config version.make sure that config version has a value and is an integer.auto-update skipped");
                return false;
            }
            /*if (latestVersion > 0 && oldVersion == 0)
            {
                PrintWarning($"Auto-Updating config version {oldVersion} to {latestVersion} started...");
                var helicopterTiers = config["Helicopter - Tiers"] as Dictionary<string, object>;
                if (helicopterTiers == null)
                {
                    PrintWarning("Config format is not supported.auto-update skipped.");
                    return false;
                }
                config["Config Version"] = 1;
                helicopterTiers["Military"] = helicopterTiers["Regular"];
                helicopterTiers["Elite"] = helicopterTiers["Regular"];
                config["Helicopter - Tiers"] = helicopterTiers;
                var spawnLocations = config["Spawn Locations"] as Dictionary<string, object>;
                if (spawnLocations != null)
                {
                    var itemsToRemove = new List<string>();
                    foreach (var location in spawnLocations)
                    {
                        var locationValue = location.Value as Dictionary<string, object>;
                        if (locationValue != null)
                        {
                            var position = locationValue["Position"] as Dictionary<string, object>;
                            if (position != null)
                            {
                                var x = -1f;
                                float.TryParse(position["x"].ToString(), out x);
                                var y = -1f;
                                float.TryParse(position["y"].ToString(), out y);
                                var z = -1f;
                                float.TryParse(position["z"].ToString(), out z);
                                if (x == 0 && y == 0 && z == 0)
                                {
                                    itemsToRemove.Add(location.Key);
                                }
                            }
                        }
                    }
                    foreach (var itemToRemove in itemsToRemove)
                    {
                        spawnLocations.Remove(itemToRemove);
                    }
                }
                configFile["Spawn Locations"] = spawnLocations;
                configFile.WriteObject(new { Config = config });
                configFile.Save();
                PrintWarning("Auto-Update config finished.");
                if (latestVersion == 1)
                    return true;
                oldVersion = 1;
            }*/
            PrintWarning("No config updates found.");
            return false;
        }
#endregion Config Auto-Update
#region Permissions
        private const string CustomHelicopterTiersAdmin = "customhelicoptertiers.admin";
        public static string GetTierSpawnPermissionName(string tierName) => "customhelicoptertiers.call." + tierName.ToLower();
        public static string GetLimitPermissionName(string limitName) => "customhelicoptertiers.limits." + limitName.ToLower();
        public static string AllTierSpawnPermissionName = GetTierSpawnPermissionName("all");
#endregion Permissions
#region Fields
        private static CustomHelicopterTiers _instance;
        public const string MainFolderName = "CHT";
        private PluginConfig _pluginConfig = new PluginConfig();
        private const int BlueprintId = -996920608;
        private static readonly string PATROL_HELICOPTER_PREFAB = "assets/prefabs/npc/patrol helicopter/patrolhelicopter.prefab";
        private static readonly float HelicopterItemsRadius = 25f;
        // 10f
        private Dictionary<string, PlayerCommandTracker> CommandTracker = new Dictionary<string, PlayerCommandTracker>(StringComparer.InvariantCultureIgnoreCase);
        private Dictionary<PatrolHelicopter, int> strafeCount = new Dictionary<PatrolHelicopter, int>();
        private Dictionary<PatrolHelicopter, HelicopterHitInfo> heliHitTracker = new Dictionary<PatrolHelicopter, HelicopterHitInfo>();
        private Dictionary<ulong, TempBoxData> _tempBoxes = new Dictionary<ulong, TempBoxData>();
        private HashSet<HelicopterDebris> _debris = new HashSet<HelicopterDebris>();
        private Dictionary<BasePlayer, HashSet<FireBall>> _fireBalls = new Dictionary<BasePlayer, HashSet<FireBall>>();
        private Dictionary<string, HashSet<PatrolHelicopter>> SpawnedHelicopters {
            get;
            set;
        }
        = new Dictionary<string, HashSet<PatrolHelicopter>>(StringComparer.InvariantCultureIgnoreCase);
        private const int LAYER_RAGDOLL = Layers.Mask.Ragdoll;
        private HashSet<LockedByEntCrate> _crates = new HashSet<LockedByEntCrate>();
        private const string CRATE_PREFAB = "assets/prefabs/npc/patrol helicopter/heli_crate.prefab";
        private const string SMALL_FIREBALL_PREFAB = "assets/bundled/prefabs/oilfireballsmall.prefab";
        private const string BLUEPRINT_TEMPLATE = "blueprintbase";
#endregion Fields
#region Hooks
        void Loaded() {
            if (!_pluginConfig.Config.IsEnabled) return;
            LoadTrackers();
            if (CommandTracker == null) CommandTracker = new Dictionary<string, PlayerCommandTracker>(StringComparer.InvariantCultureIgnoreCase);
        }
        void OnServerInitialized() {
            if (!_pluginConfig.Config.IsEnabled) return;
            SpawnedHelicopters = new Dictionary<string, HashSet<PatrolHelicopter>>(StringComparer.InvariantCultureIgnoreCase);
            foreach (var entity in BaseNetworkable.serverEntities) {
                if (entity == null) continue;
                PatrolHelicopter helicopter = entity as PatrolHelicopter;
                HelicopterDebris debris = entity as HelicopterDebris;
                if (helicopter != null) AddToHelicopterCollection(helicopter);
                if (debris != null) _debris.Add(debris);
            }
            if (_pluginConfig.Config.GlobalHelicopterConfig.DisableRustDefaultHelicopter) DisableDefaultSpawning();
            ConVar.PatrolHelicopter.bulletAccuracy = _pluginConfig.Config.GlobalHelicopterConfig.DamageTurretsBulletAccuracy;
            ConVar.PatrolHelicopter.lifetimeMinutes = _pluginConfig.Config.GlobalHelicopterConfig.SpawnMaximumHelicopterLifeTime;
            GetMonumentsPositions();
            InitializeHelicopters();
        }
        private void Init() {
            _instance = this;
            if (!_pluginConfig.Config.IsEnabled) return;
            var tiers = _pluginConfig.Config.Tiers;
            if (tiers == null) {
                Puts(Lang(PluginMessages.NoTiersFound));
            }
            else {
                foreach (var tier in tiers) {
                    if (tier.Value == null) {
                        continue;
                    }
                    var spawnPermName = GetTierSpawnPermissionName(tier.Key);
                    if (!permission.PermissionExists(spawnPermName, this)) permission.RegisterPermission(spawnPermName, this);
                    if (tier.Value.CallCommand.CommandLimits != null) foreach (var limit in tier.Value.CallCommand.CommandLimits) {
                        var permissionName = GetLimitPermissionName(limit.Key);
                        if (!permission.PermissionExists(permissionName)) permission.RegisterPermission(permissionName, this);
                    }
                }
                if (!permission.PermissionExists(AllTierSpawnPermissionName)) permission.RegisterPermission(AllTierSpawnPermissionName, this);
            }
            if (!permission.PermissionExists(CustomHelicopterTiersAdmin)) permission.RegisterPermission(CustomHelicopterTiersAdmin, this);
            if (!plugins.Exists(nameof(Economics))) PrintWarning("No Economics plugin found");
            if (!plugins.Exists(nameof(ServerRewards))) PrintWarning("No ServerRewards plugin found");
            var allPermissions = permission.GetPermissions();
            var oldKillPermissions = allPermissions.Where(x => x.StartsWith("customhelicoptertiers.kill."));
            var oldSpawnPermissions = "customhelicoptertiers.spawn";
            var oldEditPermissions = "customhelicoptertiers.edit";
            foreach (var basePlayer in BasePlayer.allPlayerList) {
                var shouldGrantAdminPermission = false;
                if (permission.UserHasPermission(basePlayer.UserIDString, oldSpawnPermissions)) {
                    shouldGrantAdminPermission = true;
                    permission.RevokeUserPermission(basePlayer.UserIDString, oldSpawnPermissions);
                }
                if (permission.UserHasPermission(basePlayer.UserIDString, oldEditPermissions)) {
                    shouldGrantAdminPermission = true;
                    permission.RevokeUserPermission(basePlayer.UserIDString, oldEditPermissions);
                }
                foreach (var oldKillPermission in oldKillPermissions) {
                    if (permission.UserHasPermission(basePlayer.UserIDString, oldKillPermission)) {
                        shouldGrantAdminPermission = true;
                        permission.RevokeUserPermission(basePlayer.UserIDString, oldKillPermission);
                    }
                }
                if (shouldGrantAdminPermission) {
                    permission.GrantUserPermission(basePlayer.UserIDString, CustomHelicopterTiersAdmin, this);
                }
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            if (!AutoUpdateConfig(Config) && _pluginConfig?.Config == null) {
                ApplyDefaultConfig();
                SaveConfig();
            }
            _pluginConfig = Config.ReadObject<PluginConfig>();
            SaveConfig();
            Config.Settings.Converters = new JsonConverter[] {
                new StringEnumConverter()
            }
            ;
            PrintWarning("Config Loaded");
        }
        protected override void SaveConfig() => Config.WriteObject(_pluginConfig, true);
        private void ApplyDefaultConfig() {
            _pluginConfig.Config = new HelicopterTierConfig {
                IsEnabled = true, UseEconomics = false, UseServerRewards = true, GlobalHelicopterConfig = new GlobalHelicopterConfig {
                    DamageTurretsBulletAccuracy = 2, DisableRustDefaultHelicopter = true, SpawnMaximumHelicopterLifeTime = 15, MaximumActivePatrolHelicopters = 3
                }
                , SpawnLocations = new Dictionary<string, SpawnLocationData>(), MonumentSpawnLocations = new Dictionary<string, SpawnLocationData>(), Tiers = GetDefaultTiers()
            }
            ;
        }
        protected override void LoadDefaultConfig() {
            ApplyDefaultConfig();
            PrintWarning("Loading Default Config");
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                [PluginMessages.KillSingleRewardMessage]
                = "<color=#CCEE33>{0}</color> has been rewarded <color=#00FF00>{1} {2}</color>", [PluginMessages.KillDoubleRewardMessage] = "<color=#CCEE33>{0}</color> has been rewarded <color=#00FF00>{1} {2}</color> and <color=#00FF00>{3} {4}</color>", [PluginMessages.ServerRewardsName] = "RP", [PluginMessages.EconomicsName] = "Money", [PluginMessages.KillStats] = "It took {0} and total {1} damage to destroy {2} and <color=#CCEE33>{3}</color> with top rotor accuracy of <color=#00FF00>{4}%</color>!", [PluginMessages.NoTiersFound] = "No Tiers Found", [PluginMessages.TierNotFound] = "Tier Not Found", [PluginMessages.TierNameExist] = "This tier name is currently exist", [PluginMessages.PlayerNotFound] = "Player Not Found", [PluginMessages.NoCustomLootsFound] = "Unable to populate heli crate with custom loot items because no items were specified in config", [PluginMessages.NoItemDefinition] = "Failed to use custom helicopter crate loot item \"{0}\" because no such item definition exists", [PluginMessages.IsNotResearchable] = "Failed create helicopter crate loot item \"{0}\" as a blueprint because it is not researchable", [PluginMessages.ItemNotFound] = "Failed to create heli crate loot item \"{0}\" because no such item exists", [PluginMessages.HelicopterCrateItems] = "--- Helicopter Crate Items ---", [PluginMessages.NoLootPermission] = "You don't have permission to loot this container.", [PluginMessages.PluginDisabled] = "This plugin is disabled.", [PluginMessages.TierAdded] = "New tier Added.", [PluginMessages.TierRemoved] = "Tier removed.", [PluginMessages.TierNameRequired] = "You must add a tier name as an argument.", [PluginMessages.TierNoCallPermission] = "You don't have permission to call this tier.", [PluginMessages.TierNoCallPermissionAdmin] = "You don't have {0} permission to call this tier.", [PluginMessages.HelicopterTierDisabled] = "That helicopter tier is disabled.", [PluginMessages.HelicopterCalledChatMessage] = "Helicopter tier {0} called for {1}", [PluginMessages.HelicopterCalledConsoleMessage] = "{0} called helicopter tier {1} for {2}", [PluginMessages.HelicopterSpawned] = "Helicopter tier {0} spawned for {1}", [PluginMessages.InvalidArgumentForKillCommand] = "You must add a tier name, or \"all\" as an argument.", [PluginMessages.TierNoKillPermission] = "You don't have permission to destroy this tier.", [PluginMessages.TierNoKillPermissionAdmin] = "You don't have {0} permission to destroy this tier.", [PluginMessages.NoHelicoptersToDestroy] = "No helicopters to destroy.", [PluginMessages.HelicoptersDestroyedChatMessage] = "You destroyed {0} tier {1} helicopter(s).", [PluginMessages.HelicoptersDestroyedConsoleMessage] = "{0} destroyed {1} tier {2} helicopter(s).", [PluginMessages.HelicopterListTitle] = "Helicopters Tiers:",  //[PluginMessages.HelicopterListItem] = "Tier: {0}, Enabled: {1}, AutoSpawn: {2}, RandomSpawn: {3}, Current Active: {4}",
                [PluginMessages.HelicopterListNoData]
                = "Tier: {0}, No Data To Display", [PluginMessages.Days] = "Day(s)", [PluginMessages.Hours] = "Hour(s)", [PluginMessages.Minutes] = "Minute(s)", [PluginMessages.Seconds] = "Second(s)", [PluginMessages.PatrolHelicopterInfo] = "<color=#EE0000>{0}</color> Patrol Helicopter", [PluginMessages.NoTiersFoundToSpawn] = "No auto or random spawn helicopters since there are no tiers", [PluginMessages.NoEnabledTiersFoundToSpawn] = "No auto or random spawn helicopters since all tiers are disabled", [PluginMessages.NoAutoSpawnTiersFound] = "No auto spawn helicopters found to spawn", [PluginMessages.NoRandomSpawnTiersFound] = "No random spawn helicopters found to spawn", [PluginMessages.CooldownMessage] = "You can use this again in {0}.", [PluginMessages.DailyLimitMessage] = "You have reached your daily limit for this helicopter ({0}).", [PluginMessages.DefaultHelicopterSpawningDisabled] = "Default helicopter spawning disabled", [PluginMessages.WrongCommand] = "Wrong Command, Use <color=#5af>{0}</color> to get available commands list", [PluginMessages.NoSpawnPermission] = "You don't have permission to use this command", [PluginMessages.NoEditPermission] = "You don't have permission to use this command", [PluginMessages.InvalidCoordinates] = "Invalid Coordinates", [PluginMessages.SpawnNameRequired] = "You must add a spawn name as an argument.", [PluginMessages.SpawnPositionSet] = "Spawn position set", [PluginMessages.SpawnPositionDeleted] = "Spawn position deleted", [PluginMessages.SpawnPositionNotFound] = "Spawn Position Not Found", [PluginMessages.HelicopterLimitReached] = "Unable to spawn tier {0} helicopter, because maximum limit reached.", [PluginMessages.GlobalActiveHelicoptersLimitReached] = "Cannot spawn patrol helicopter of tier {0} because the maximum limit of active helicopters has been reached.", [PluginMessages.InvalidBoxData] = "Invalid box data", [PluginMessages.LootBoxUpdated] = "Loot box table updated for helicopter tier {0}", [PluginMessages.LootBoxCooldown] = "You should wait {0} for opening this crate", [PluginMessages.ManualSpawnBroadcastMessage] = "An aggressive {0} helicopter started flying & patrolling {1}!", [PluginMessages.CustomSpawnBroadcastMessage] = "An aggressive {0} helicopter started flying & patrolling around monuments!", [PluginMessages.RandomSpawnBroadcastMessage] = "An aggressive {0} helicopter started flying & patrolling!", [PluginMessages.Reservation] = "{0} has been reserved to {1}"
            }
            , this);
        }
        void OnEntitySpawned(BaseNetworkable entity) {
            var name = entity.ShortPrefabName;
            var baseHelicopter = entity as PatrolHelicopter;
            if (baseHelicopter != null) {
                var tieredComponent = baseHelicopter.GetComponent<TieredPatrolHelicopterComponent>();
                if (tieredComponent == null) return;
                var baseHelicopterAi = baseHelicopter.GetComponent<PatrolHelicopterAI>();
                if (baseHelicopterAi == null) return;
                Helicopter helicopter;
                if (!_pluginConfig.Config.Tiers.TryGetValue(tieredComponent.Tier, out helicopter) || helicopter == null) {
                    Puts(Lang(PluginMessages.TierNotFound));
                    return;
                }
                baseHelicopter.bulletDamage = helicopter.Damage.DamageTurretsBulletDamage;
                baseHelicopter.bulletSpeed = helicopter.Damage.DamageTurretsBulletSpeed;
                if (baseHelicopterAi.leftGun != null && baseHelicopterAi.rightGun != null) {
                    baseHelicopterAi.leftGun.fireRate = baseHelicopterAi.rightGun.fireRate = helicopter.Damage.DamageTurretsFireRate;
                    baseHelicopterAi.leftGun.burstLength = baseHelicopterAi.rightGun.burstLength = helicopter.Damage.DamageTurretsDurationOfBurst;
                    baseHelicopterAi.leftGun.timeBetweenBursts = baseHelicopterAi.rightGun.timeBetweenBursts = helicopter.Damage.DamageTurretsIntervalBetweenBursts;
                    baseHelicopterAi.leftGun.maxTargetRange = baseHelicopterAi.rightGun.maxTargetRange = helicopter.Damage.DamageTurretsBulletRange;
                }
                if (Math.Abs(baseHelicopter.startHealth - helicopter.Health.HealthBodyHealth) > 0.0001f) {
                    baseHelicopter.startHealth = helicopter.Health.HealthBodyHealth;
                    baseHelicopter.InitializeHealth(helicopter.Health.HealthBodyHealth, helicopter.Health.HealthBodyHealth);
                }
                if (helicopter.Speed.MiscHelicopterStartupLength > 0.0f && Math.Abs(helicopter.Speed.MiscHelicopterStartupSpeed - helicopter.Speed.MiscHelicopterSpeed) > 0.0001f) {
                    baseHelicopterAi.maxSpeed = helicopter.Speed.MiscHelicopterStartupSpeed;
                    baseHelicopterAi.Invoke(() => {
                        if (baseHelicopterAi == null || baseHelicopterAi.gameObject == null || baseHelicopter == null || baseHelicopter.IsDestroyed || baseHelicopter.gameObject == null || baseHelicopter.IsDead()) return;
                        baseHelicopterAi.maxSpeed = helicopter.Speed.MiscHelicopterSpeed;
                    }
                    , helicopter.Speed.MiscHelicopterStartupLength);
                }
                baseHelicopter.weakspots[0].health = helicopter.Health.HealthMainRotorHealth;
                baseHelicopter.weakspots[1].health = helicopter.Health.HealthTailRotorHealth;
                baseHelicopter.maxCratesToSpawn = helicopter.Loot.MaximumCratesToSpawn;
                baseHelicopterAi.timeBetweenRockets = Mathf.Clamp(helicopter.Damage.DamageRocketsTimeBetweenEachRocket, 0.1f, 1f);
                baseHelicopterAi.numRocketsLeft = Mathf.Clamp(helicopter.Damage.DamageRocketsMaxLaunchedRockets, 0, 48);
            }
            else if (entity is HelicopterDebris) {
                var gib = entity as HelicopterDebris;
                var helis = Facepunch.Pool.GetList<PatrolHelicopter>();
                var (tieredComponent, tieredConfig) = GetTierSettingsFromVicinity(entity, helis, true);
                if (tieredComponent != null && tieredConfig != null) {
                    if (!tieredConfig.Debris.SpawnAfterCrash || tieredConfig.Debris.HarvestableHitPoints <= 0) gib.Kill();
                    else {
                        if (Math.Abs(tieredConfig.Debris.HarvestableHitPoints - 500f) > 0.0001f) {
                            gib.InitializeHealth(tieredConfig.Debris.HarvestableHitPoints, tieredConfig.Debris.HarvestableHitPoints);
                            gib.massReductionScalar = 5 / (tieredConfig.Debris.HarvestableHitPoints / 500);
                            gib.SendNetworkUpdate();
                        }
                        if (Math.Abs(tieredConfig.Debris.CoolingPeriodSeconds - 480f) > 0.0001f) {
                            gib.tooHotUntil = Time.realtimeSinceStartup + tieredConfig.Debris.CoolingPeriodSeconds;
                            gib.SendNetworkUpdate();
                        }
                        _debris.Add(gib);
                    }
                }
                Facepunch.Pool.FreeList(ref helis);
            }
            else if (entity is FireBall) {
                var fireball = entity as FireBall;
                var helis = Facepunch.Pool.GetList<PatrolHelicopter>();
                var (tieredComponent, tieredConfig) = GetTierSettingsFromVicinity(entity, helis, true);
                if (tieredComponent != null && tieredConfig != null) {
                    if (fireball != null && (fireball.PrefabName.Contains("oilfireballsmall"))) {
                        if (tieredComponent.Invoker != null) {
                            if (!_fireBalls.ContainsKey(tieredComponent.Invoker)) _fireBalls[tieredComponent.Invoker] = new HashSet<FireBall>();
                            _fireBalls[tieredComponent.Invoker].Add(fireball);
                        }
                    }
                }
                Facepunch.Pool.FreeList(ref helis);
            }
            else if (name.Contains("rocket_heli")) {
                var explosion = entity as TimedExplosive;
                if (explosion == null || explosion.IsDestroyed) return;
                var helis = Facepunch.Pool.GetList<PatrolHelicopter>();
                var heliComponent = entity.GetComponent<HelicopterRocket>();
                var strafeHeli = heliComponent != null ? heliComponent.Helicopter : GetHelicopterFromVicinity(entity, helis, false, p => p != null && !p.IsDestroyed && p.gameObject != null && (p?.GetComponent<PatrolHelicopterAI>()?._currentState ?? PatrolHelicopterAI.aiState.IDLE) == PatrolHelicopterAI.aiState.STRAFE);
                if (strafeHeli == null) {
                    //explosion.Kill();
                    Facepunch.Pool.FreeList(ref helis);
                    return;
                }
                explosion.creatorEntity = strafeHeli;
                var tieredComponent = strafeHeli.GetComponent<TieredPatrolHelicopterComponent>();
                if (tieredComponent == null) {
                    Facepunch.Pool.FreeList(ref helis);
                    return;
                }
                Helicopter helicopter;
                if (!_pluginConfig.Config.Tiers.TryGetValue(tieredComponent.Tier, out helicopter) || helicopter == null) {
                    Facepunch.Pool.FreeList(ref helis);
                    return;
                }
                var heliAI = strafeHeli.GetComponent<PatrolHelicopterAI>();
                var ownerID = (entity as BaseEntity).OwnerID;
                if (helicopter.Damage.DamageRocketsMaxLaunchedRockets < 1) explosion.Kill();
                else {
                    if (helicopter.Damage.DamageRocketsMaxLaunchedRockets > 12 && ownerID == 0) {
                        if (strafeHeli.IsDestroyed) {
                            Facepunch.Pool.FreeList(ref helis);
                            return;
                        }
                        var curCount = 0;
                        if (!strafeCount.TryGetValue(strafeHeli, out curCount)) curCount = strafeCount[strafeHeli] = 1;
                        else curCount = strafeCount[strafeHeli] += 1;
                        if (curCount >= 12) {
                            if (heliAI == null) {
                                Facepunch.Pool.FreeList(ref helis);
                                return;
                            }
                            var actCount = 0;
                            Action fireAct = null;
                            fireAct = new Action(() => {
                                if (actCount >= helicopter.Damage.DamageRocketsMaxLaunchedRockets - 12) {
                                    InvokeHandler.CancelInvoke(heliAI, fireAct);
                                    return;
                                }
                                actCount++;
                                FireRocket(strafeHeli, heliAI);
                            }
                            );
                            InvokeHandler.InvokeRepeating(heliAI, fireAct, helicopter.Damage.DamageRocketsTimeBetweenEachRocket, helicopter.Damage.DamageRocketsTimeBetweenEachRocket);
                            strafeCount[strafeHeli] = 0;
                        }
                    }
                    else if (helicopter.Damage.DamageRocketsMaxLaunchedRockets < 12 && heliAI.ClipRocketsLeft() > helicopter.Damage.DamageRocketsMaxLaunchedRockets) {
                        explosion.Kill();
                        Facepunch.Pool.FreeList(ref helis);
                        return;
                    }
                    var dmgTypes = explosion != null ? explosion.damageTypes : null;
                    explosion.explosionRadius = helicopter.Damage.DamageRocketsExplosionRadius;
                    if (dmgTypes != null && dmgTypes.Count > 0) {
                        for (var i = 0; i < dmgTypes.Count; i++) {
                            var dmg = dmgTypes[i];
                            if (dmg.type == Rust.DamageType.Blunt) dmg.amount = helicopter.Damage.DamageRocketsBluntDamage;
                            if (dmg.type == Rust.DamageType.Explosion) dmg.amount = helicopter.Damage.DamageRocketsExplosionDamage;
                        }
                    }
                }
                Facepunch.Pool.FreeList(ref helis);
            }
        }
        private void OnEntityKill(PatrolHelicopter patrolHelicopter) {
            if (patrolHelicopter == null) return;
            TieredPatrolHelicopterComponent tieredComponent = patrolHelicopter.GetComponent<TieredPatrolHelicopterComponent>();
            if (tieredComponent == null) return;
            PatrolHelicopterAI patrolHelicopterAi = patrolHelicopter.GetComponent<PatrolHelicopterAI>();
            if (patrolHelicopterAi == null) return;
            Helicopter patrolHelicopterConfig;
            if (!_pluginConfig.Config.Tiers.TryGetValue(tieredComponent.Tier, out patrolHelicopterConfig) || patrolHelicopterConfig == null) return;
            HashSet<PatrolHelicopter> spawnedPatrolHelicopters;
            if (SpawnedHelicopters.TryGetValue(tieredComponent.Tier, out spawnedPatrolHelicopters)) spawnedPatrolHelicopters.Remove(patrolHelicopter);
            InitializeHelicopters(tieredComponent.Tier, patrolHelicopterConfig);
            // Verify the patrol helicopter was actually taken down, rather than retired or forcibly killed.if (!patrolHelicopterAi.isDead)
            return;
            CalculateStats(patrolHelicopter);
            CaptureAfterExplosionCrates(patrolHelicopter.transform.position);
            SpawnAndAttachFireBallsToCrates(patrolHelicopterConfig.Loot);
            SetupAndPopulateCratesLoot(tieredComponent, patrolHelicopterConfig.Loot);
        }
#region Loot Crates Management
        private void SetupAndPopulateCratesLoot(TieredPatrolHelicopterComponent tieredComponent, LootConfig lootConfig) {
            foreach (LockedByEntCrate crate in _crates) {
                TieredCrateComponent tieredCrate = crate.gameObject.AddComponent<TieredCrateComponent>();
                tieredCrate.Invoker = tieredComponent.Invoker;
                tieredCrate.AdminBypass = lootConfig.AlwaysLootableByAdmins;
                tieredCrate.OnlyInvokerCanLoot = tieredComponent.Invoker != null && lootConfig.CanBeOpenedOnlyBySummoner;
                tieredCrate.InvokerTeamCanLoot = tieredComponent.Invoker != null && lootConfig.CanBeOpenedBySummonerTeam;
                if (lootConfig.DelayBeforeCratesBecomeLootableMinutes <= 0) UnlockCrate(crate);
                else tieredCrate.TimeToUnlock = DateTime.UtcNow.AddMinutes(lootConfig.DelayBeforeCratesBecomeLootableMinutes);
                if (!lootConfig.LootEnableCustomLootTable || lootConfig.CustomLootTable == null) continue;
                List<ItemInfo> lootTable = lootConfig.CustomLootTable;
                int lootSpawnSlots = Random.Range(lootConfig.MinimumLootSpawnSlots, lootConfig.MaximumLootSpawnSlots + 1);
                if (lootSpawnSlots > lootTable.Count) lootSpawnSlots = lootTable.Count;
                // Ensure that it doesn't exceed 12
                lootSpawnSlots = Mathf.Min(lootSpawnSlots, 12);
                crate.inventory.capacity = lootSpawnSlots;
                crate.inventory.Clear();
                var lootCrate = crate as LootContainer;
                if (lootCrate == null) continue;
                lootCrate.inventory.Clear();
                var items = lootCrate.inventory.itemList.ToList();
                for (var i = 0; i < items.Count; i++) items[i].DoRemove();
                // Keep track of items that have already been spawned in this crate.HashSet<string> spawnedItems = new HashSet<string>();
                for (int i = 0; i < lootSpawnSlots; i++) {
                    Rarity chosenRarity = ChooseRarity(lootConfig.RarityWeights);
                    List<ItemInfo> itemsOfChosenRarity = lootConfig.CustomLootTable.Where(ii => ii.Rarity == chosenRarity && !spawnedItems.Contains(ii.Shortname)).ToList();
                    if (itemsOfChosenRarity.Count == 0) continue;
                    ItemInfo itemInfo = itemsOfChosenRarity[Random.Range(0, itemsOfChosenRarity.Count)];
                    spawnedItems.Add(itemInfo.Shortname);
                    Item item;
                    ItemDefinition itemDefinition = itemInfo.GetItemDefinition();
                    var amount = Random.Range(itemInfo.MinimumSpawnAmount, itemInfo.MaximumSpawnAmount + 1);
                    if (itemInfo.SpawnAsBlueprint) item = ItemManager.CreateByItemID(BlueprintId, amount, itemInfo.SkinId);
                    else item = ItemManager.CreateByName(itemInfo.Shortname, amount, itemInfo.SkinId);
                    if (item == null) {
                        Puts(Lang(PluginMessages.ItemNotFound, null, itemInfo.Shortname));
                        continue;
                    }
                    if (itemInfo.SpawnAsBlueprint) item.blueprintTarget = itemDefinition.itemid;
                    item.MoveToContainer(crate.inventory);
                }
            }
        }
        private Rarity ChooseRarity(Dictionary<Rarity, int> weights) {
            int totalWeight = weights.Sum(x => x.Value);
            int randomValue = Random.Range(0, totalWeight);
            int currentWeight = 0;
            foreach (var rarity in weights.Keys) {
                currentWeight += weights[rarity];
                if (randomValue < currentWeight) return rarity;
            }
            return Rarity.Common;
            // Default fallback
        }
        private void CaptureAfterExplosionCrates(Vector3 crashSitePosition) {
            _crates.Clear();
            List<LockedByEntCrate> nearbyCrates = Pool.GetList<LockedByEntCrate>();
            Vis.Entities(crashSitePosition, 30f, nearbyCrates, LAYER_RAGDOLL, QueryTriggerInteraction.Ignore);
            if (nearbyCrates.Count != 0) {
                foreach (BaseEntity capturedEntity in nearbyCrates) {
                    LockedByEntCrate crate = capturedEntity as LockedByEntCrate;
                    if (crate != null && crate.PrefabName == CRATE_PREFAB) {
                        _crates.Add(crate);
                        FireBall fireBall = FindChildByType<FireBall>(crate);
                        if (fireBall != null) fireBall.Extinguish();
                    }
                }
            }
            Pool.FreeList(ref nearbyCrates);
        }
        private void SpawnAndAttachFireBallsToCrates(LootConfig lootConfig) {
            if (!lootConfig.BurnCrates) return;
            foreach (LockedByEntCrate crate in _crates) {
                FireBall fireBall = GameManager.server.CreateEntity(SMALL_FIREBALL_PREFAB, crate.transform.position, Quaternion.identity, false) as FireBall;
                if (!fireBall) continue;
                fireBall.SetParent(crate, true, true);
                fireBall.SetActive(true);
                fireBall.Spawn();
                fireBall.GetComponent<Rigidbody>().isKinematic = true;
                fireBall.GetComponent<Collider>().enabled = false;
                crate.SendMessage("SetLockingEnt", fireBall.gameObject, SendMessageOptions.DontRequireReceiver);
                SetupFireBall(fireBall, lootConfig.FireBall);
            }
        }
        private void SetupFireBall(FireBall fireBall, FireBallConfig fireBallconfig) {
            fireBall.tickRate = fireBallconfig.DamageOccurrenceFrequencySeconds;
            fireBall.lifeTimeMin = fireBallconfig.MinimumLifetimeSeconds;
            fireBall.lifeTimeMax = fireBallconfig.MaximumLifetimeSeconds;
            fireBall.radius = fireBallconfig.BurnDamageReach;
            fireBall.damagePerSecond = fireBallconfig.BaseBurnDamageAmount;
            fireBall.waterToExtinguish = fireBallconfig.WaterAmountToExtinguish;
            fireBall.generation = (fireBallconfig.SpreadProbabilityPercentage == 0) ? 9f : (1f - (fireBallconfig.SpreadProbabilityPercentage / 100f)) / 0.1f;
            fireBall.Think();
            float lifeTime = Random.Range(fireBall.lifeTimeMax, fireBall.lifeTimeMin);
            fireBall.Invoke(() => fireBall.Extinguish(), lifeTime);
            float spreadDelay = lifeTime * (fireBallconfig.ElapsedLifetimePercentageToBeginSpreading / 100f);
            fireBall.Invoke(() => fireBall.TryToSpread(), spreadDelay);
        }
        private static T FindChildByType<T>(BaseEntity parentEntity, string prefabName = null) where T : BaseEntity {
            T result = null;
            foreach (BaseEntity childEntity in parentEntity.children) {
                T specificChild = childEntity as T;
                if (specificChild != null) {
                    if (prefabName == null || childEntity.PrefabName == prefabName) {
                        result = specificChild;
                        break;
                    }
                }
            }
            return result;
        }
#endregion Loot Crates Management
        private void OnEntityKill(HelicopterDebris debris) {
            if (debris != null) _debris.Remove(debris);
        }
        private void OnEntityKill(FireBall fireball) {
            if (fireball != null && (fireball.PrefabName.Contains("oilfireballsmall"))) foreach (var pair in _fireBalls) {
                if (pair.Value.Contains(fireball)) {
                    pair.Value.Remove(fireball);
                    break;
                }
            }
        }
        private object OnEntityTakeDamage(BaseEntity entity, HitInfo hitInfo) {
            if (entity == null || hitInfo == null) return null;
            if (hitInfo.Initiator == null || entity is BasePlayer) return null;
            if (hitInfo.Initiator is PatrolHelicopter) {
                TieredPatrolHelicopterComponent tieredComponent = hitInfo.Initiator.GetComponent<TieredPatrolHelicopterComponent>();
                if (tieredComponent == null) return null;
                if (tieredComponent.EnablePlayerVersusEnvironment && tieredComponent.Invoker != null) {
                    if (entity.OwnerID == tieredComponent.Invoker.userID) return null;
                    if (tieredComponent.Invoker.Team != null && tieredComponent.Invoker.Team.members.Contains(entity.OwnerID)) return null;
                    hitInfo.damageTypes.Clear();
                    return true;
                }
            }
            else if (hitInfo.Initiator is FireBall) {
                FireBall fireBall = hitInfo.Initiator as FireBall;
                if (fireBall != null) {
                    bool ownerMatch = false;
                    foreach (var pair in _fireBalls) {
                        if (pair.Key != null && pair.Value.Contains(fireBall)) {
                            if (pair.Key.userID == entity.OwnerID || (pair.Key.Team != null && pair.Key.Team.members.Contains(entity.OwnerID))) {
                                ownerMatch = true;
                                break;
                            }
                        }
                    }
                    if (!ownerMatch) {
                        hitInfo.damageTypes.Clear();
                        return true;
                    }
                }
            }
            return null;
        }
        private void OnFireBallSpread(FireBall motherFireBall, BaseEntity childFireBall) {
            if (motherFireBall == null || childFireBall == null) return;
            foreach (var fireBallSet in _fireBalls.Values) {
                if (fireBallSet.Contains(motherFireBall)) {
                    fireBallSet.Add(childFireBall as FireBall);
                    break;
                }
            }
        }
        object OnEntityTakeDamage(PatrolHelicopter helicopter, HitInfo hitInfo) {
            var hitter = hitInfo?.Initiator;
            if (hitter == null) return null;
            var tieredComponent = helicopter.GetComponent<TieredPatrolHelicopterComponent>();
            if (tieredComponent != null) {
                if (hitter is BasePlayer) {
                    var playerInitiator = hitter.ToPlayer();
                    if (tieredComponent.Invoker != null && tieredComponent.LockToInvoker) {
                        if (tieredComponent.Invoker.userID == playerInitiator.userID) {
                            RegisterHeliHitInfo(helicopter, playerInitiator, hitInfo);
                        }
                        else if (tieredComponent.IncludeTeammates && tieredComponent.Invoker.currentTeam > 0 && tieredComponent.Invoker.currentTeam == playerInitiator.currentTeam) {
                            RegisterHeliHitInfo(helicopter, playerInitiator, hitInfo);
                        }
                        else {
                            hitInfo.damageTypes.Clear();
                            return true;
                        }
                    }
                    else if (tieredComponent.Invoker == null) {
                        Helicopter tierhelicopter;
                        if (_pluginConfig.Config.Tiers.TryGetValue(tieredComponent.Tier, out tierhelicopter) && tierhelicopter != null && tierhelicopter.PlayerVsPlayer.LockToAttacker) {
                            tieredComponent.Invoker = playerInitiator;
                            Server.Broadcast(Lang(PluginMessages.Reservation, null, tieredComponent.Tier, playerInitiator.displayName));
                        }
                        RegisterHeliHitInfo(helicopter, playerInitiator, hitInfo);
                    }
                }
            }
            return null;
        }
        private object OnHelicopterStrafeEnter(PatrolHelicopterAI helicopter, Vector3 strafePosition) {
            var tieredComponent = helicopter.GetComponent<TieredPatrolHelicopterComponent>();
            if (tieredComponent != null && tieredComponent.Invoker != null && tieredComponent.LockToInvoker) {
                if (Vector3.Distance(strafePosition, tieredComponent.Invoker.ServerPosition) < 50) {
                    return null;
                }
                if (tieredComponent.IncludeTeammates && tieredComponent.Invoker.currentTeam > 0) {
                    foreach (var teamMemberId in tieredComponent.Invoker.Team.members) {
                        var teamMember = BasePlayer.FindByID(teamMemberId);
                        if (teamMember != null && Vector3.Distance(strafePosition, teamMember.ServerPosition) < 50) {
                            return null;
                        }
                    }
                }
                return false;
            }
            return null;
        }
        private object CanHelicopterTarget(PatrolHelicopterAI helicopter, BasePlayer player) {
            var tieredComponent = helicopter.GetComponent<TieredPatrolHelicopterComponent>();
            if (tieredComponent != null && tieredComponent.Invoker != null && tieredComponent.LockToInvoker) {
                if (tieredComponent.Invoker.userID == player.userID) {
                    return null;
                }
                if (tieredComponent.IncludeTeammates && tieredComponent.Invoker.currentTeam > 0 && tieredComponent.Invoker.currentTeam == player.currentTeam) {
                    return null;
                }
                return false;
            }
            return null;
        }
        private object CanHelicopterStrafeTarget(PatrolHelicopterAI heli, BasePlayer target) => CanHelicopterTarget(heli, target);
        private object OnHelicopterTarget(HelicopterTurret turret, BasePlayer player) {
            var tieredComponent = turret._heliAI.GetComponent<TieredPatrolHelicopterComponent>();
            if (tieredComponent != null && tieredComponent.Invoker != null && tieredComponent.LockToInvoker) {
                if (tieredComponent.Invoker.userID == player.userID) {
                    return null;
                }
                if (tieredComponent.IncludeTeammates && tieredComponent.Invoker.currentTeam > 0 && tieredComponent.Invoker.currentTeam == player.currentTeam) {
                    return null;
                }
                return false;
            }
            return null;
        }
        private object CanLootEntity(BasePlayer player, LockedByEntCrate crate) {
            if (crate.ShortPrefabName != "heli_crate") return null;
            var crateInfo = crate.GetComponent<TieredCrateComponent>();
            if (crateInfo == null) return null;
            if (crateInfo.AdminBypass && player.IsAdmin) return null;
            if (crateInfo.OnlyInvokerCanLoot && crateInfo.Invoker != player) {
                if (!crateInfo.InvokerTeamCanLoot || crateInfo.Invoker.currentTeam == 0 || crateInfo.Invoker.currentTeam != player.currentTeam) {
                    SendReply(player, Lang(PluginMessages.NoLootPermission, player.UserIDString));
                    return true;
                }
            }
            if (!crateInfo.TimeToUnlock.HasValue) {
                return null;
            }
            if (!WaterLevel.Test(crate.ServerPosition, false, false, crate) && crateInfo.TimeToUnlock.Value > DateTime.UtcNow) {
                player.ChatMessage(Lang(PluginMessages.LootBoxCooldown, player.UserIDString, Humanize(crateInfo.TimeToUnlock.Value.Subtract(DateTime.UtcNow))));
                return true;
            }
            return null;
        }
        private void OnPlayerLootEnd(PlayerLoot inventory) {
            var player = inventory.GetComponent<BasePlayer>();
            TempBoxData boxData;
            if (inventory.entitySource != null && _tempBoxes.TryGetValue(player.userID, out boxData) && boxData != null && inventory.entitySource is StorageContainer) {
                StoreTempBoxData(player, inventory.entitySource as StorageContainer, boxData.Tier);
            }
        }
        object OnHelicopterRetire(PatrolHelicopterAI entity) {
            if (heliHitTracker != null && heliHitTracker.ContainsKey(entity.helicopterBase)) {
                heliHitTracker.Remove(entity.helicopterBase);
            }
            return null;
        }
        private void Unload() {
            foreach (var spawnedHelicopter in SpawnedHelicopters) {
                var destroyedCount = DestroySpawnedTier(spawnedHelicopter.Key, spawnedHelicopter.Value.ToList());
                SendEchoConsole(null, Lang(PluginMessages.HelicoptersDestroyedConsoleMessage, null, string.Empty, destroyedCount, spawnedHelicopter.Key));
            }
            _fireBalls.Clear();
            SpawnedHelicopters.Clear();
            _crates.Clear();
            _instance = null;
        }
#endregion Hooks
#region Commands
        // heli.help
        [ChatCommand(Commands.Help)]
        void HelicopterHelpChatCommand(BasePlayer player, string cmd, string[] args) {
            SendReply(player, GetCommands(player));
        }
        // heli.call <Tier>
        // heli.call <Tier> here
        [ChatCommand(Commands.Call)]
        void CallHelicopterTier(BasePlayer player, string cmd, string[] args)
// ... [Code preview truncated due to length. Full source in attached file] ...

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