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

FREE Convoy : 2.2.0 2.2.0

Нет прав для скачивания
C#:
using System.Collections.Generic;
using Newtonsoft.Json;
using CompanionServer.Handlers;
using UnityEngine;
using Oxide.Core.Plugins;
using Network;
using Rust;
using Rust.Modular;
using System.Collections;
using Newtonsoft.Json.Linq;
using Oxide.Game.Rust.Cui;
using Oxide.Core;
using System;
using Oxide.Plugins.ConvoyExtensionMethods;
namespace Oxide.Plugins {
    [Info("Convoy", "Adem", "2.2.0")]
    class Convoy : RustPlugin {
        [PluginReference]
        Plugin NpcSpawn, GUIAnnouncements, DiscordMessages, PveMode, Economics, ServerRewards, IQEconomic, DynamicPVP;
#region Variables
        const bool en = true;
        static Convoy ins;
        int pathCount = 0;
        bool active;
        bool round = true;
        int stopTime = 0;
        int destroyTime = 0;
        int eventTime = 0;
        bool destroying = false;
        bool failed = false;
        bool hackedCrate = false;
        ConvoySetting convoySetting = null;
        HashSet<string> subscribeMetods = new HashSet<string> {
            "OnEntityKill", "OnEntityTakeDamage", "OnVehicleModulesAssign", "CanHackCrate", "OnEntitySpawned", "OnHelicopterRetire", "CanHelicopterTarget", "CanBradleyApcTarget"
        }
        ;
        List<Vector3> currentPath = new List<Vector3>();
        List<ConvoyVehicle> convoyVehicles = new List<ConvoyVehicle>();
        HashSet<uint> convoyVehicleNetIds = new HashSet<uint>();
        List<ScientistNPC> freeConvoyNpc = new List<ScientistNPC>();
        HashSet<BasePlayer> players = new HashSet<BasePlayer>();
        HashSet<ulong> owners = new HashSet<ulong>();
        ulong owner;
        HashSet<BaseEntity> convoySummons = new HashSet<BaseEntity>();
        HashSet<uint> bradleyContainers = new HashSet<uint>();
        DoorCloser doorCloser;
        ConvoyTruck convoyModular;
        ConvoyHeli convoyHeli;
        HeliConfig heliConfig;
        BradleyConfig bradleyConfig;
        ModularConfig modularConfig;
        SupportModularConfig supportModularConfig;
        SedanConfig sedanConfig;
        Vector3 deathBradleyCoord = Vector3.zero;
        Vector3 deathHeliCoord = Vector3.zero;
        Coroutine stopCoroutine;
        Coroutine eventCoroutine;
        Coroutine destroyCoroutine;
#endregion Variables
#region API
        private bool IsConvoyVehicle(BaseEntity entity) {
            if (entity == null) return false;
            return convoyVehicleNetIds.Any(x => x == entity.net.ID);
        }
        private bool IsConvoyCrate(HackableLockedCrate crate) {
            if (crate == null) return false;
            if (convoyModular != null && convoyModular.crate != null && convoyModular.crate.net.ID == crate.net.ID) return true;
            return false;
        }
        private bool IsConvoyHeli(BaseHelicopter baseHelicopter) {
            if (baseHelicopter == null) return false;
            return convoyHeli != null && convoyHeli.baseHelicopter.net.ID == baseHelicopter.net.ID;
        }
#endregion API
#region Hooks
        void Init() {
            ins = this;
            UpdateConfig();
            Unsubscribes();
            Unsubscribe("OnLootSpawn");
            if (!_config.blockFirstAttack) Unsubscribe("OnExplosiveThrown");
            if (_config.betterNpcConfig.bradleyNpc) Unsubscribe("CanBradleySpawnNpc");
            if (_config.betterNpcConfig.heliNpc) Unsubscribe("CanHelicopterSpawnNpc");
            LoadData();
        }
        void OnServerInitialized() {
            LoadDefaultMessages();
            CheckZeroCoord();
            int vehicleCount = 0;
            Subscribe("OnLootSpawn");
            foreach (ConvoySetting convoySetting in _config.convoys) {
                int count = convoySetting.firstBradleyCount + convoySetting.firstModularCount + convoySetting.firstSedanCount + 1 + convoySetting.endSedanCount + convoySetting.endModularCount + convoySetting.endBradleyCount;
                if (count > vehicleCount) vehicleCount = count;
            }
            int rootCount = vehicleCount * _config.carDistance * 2 + vehicleCount + 20;
            int roadCount = _config.roadCount <= rootCount ? rootCount : _config.roadCount;
            if (_config.customRootName != "" && roots.ContainsKey(_config.customRootName)) {
                List<List<string>> rootsPrefab = roots[_config.customRootName];
                List<List<string>> goodRoads = rootsPrefab.Where(x => x.Count > roadCount).ToList();
                if (goodRoads.Count > 0) {
                    List<string> currentpathString = goodRoads.GetRandom();
                    foreach (string vectorString in currentpathString) currentPath.Add(vectorString.ToVector3());
                }
            }
            if (_config.rounRoadPriority && currentPath.Count == 0) {
                PathList pathList = TerrainMeta.Path.Roads.FirstOrDefault(x => x.Path.Points.Length > roadCount && Vector3.Distance(x.Path.Points[0], x.Path.Points[x.Path.Points.Length - 1]) < 10f && Vector3.Distance(x.Path.Points[0], x.Path.Points[x.Path.Points.Length / 2]) > 50f);
                if (pathList != null && pathList.Path != null && pathList.Path.Points != null) currentPath = pathList.Path.Points.ToList();
            }
            if (currentPath.Count == 0) {
                List<PathList> goodRoads = TerrainMeta.Path.Roads.Where(x => !_config.blockRoads.Contains(TerrainMeta.Path.Roads.IndexOf(x)) && x.Path.Points.Length > roadCount && Vector3.Distance(x.Path.Points[0], x.Path.Points[x.Path.Points.Length - 1]) > 100 && UnityEngine.Physics.RaycastAll(new Ray(x.Path.Points[10] + new Vector3(0, 1, 0), Vector3.down), 4f).Any(y => y.collider.name.Contains("Road Mesh")) && UnityEngine.Physics.RaycastAll(new Ray(x.Path.Points[x.Path.Points.Length / 2] + new Vector3(0, 1, 0), Vector3.down), 4f).Any(y => y.collider.name.Contains("Road Mesh"))).ToList();
                if (goodRoads.Count > 0) {
                    PathList path = goodRoads.GetRandom();
                    currentPath = path.Path.Points.ToList();
                    pathCount = currentPath.Count;
                }
            }
            pathCount = currentPath.Count;
            if (pathCount == 0) {
                PrintError("No road detected");
                return;
            }
            if (Vector3.Distance(currentPath[0], currentPath[currentPath.Count - 1]) > 10f) round = false;
            if (_config.autoEvent && _config.convoys.Any(x => x.on && x.chance > 0)) {
                timer.In(UnityEngine.Random.Range(_config.minStartTime, _config.maxStartTime), () => {
                    if (!active) CreateConvoy();
                    else Puts("This event is active now");
                }
                );
            }
        }
        void Unload() {
            if (active) DeleteConvoy(false);
            RootCar.RootStop();
            ins = null;
        }
        void OnEntitySpawned(LockedByEntCrate crate) {
            if (crate == null) return;
            timer.In(0.35f, () => {
                if (crate == null) return;
                if (crate.ShortPrefabName == "bradley_crate" && Vector3.Distance(deathBradleyCoord, crate.transform.position) < 15f) {
                    if (bradleyConfig.offDelay) {
                        crate.CancelInvoke(crate.Think);
                        crate.SetLocked(false);
                        crate.lockingEnt = null;
                    }
                    if (bradleyConfig.typeLootTable == 1) {
                        for (int i = crate.inventory.itemList.Count - 1; i >= 0; i--) {
                            Item item = crate.inventory.itemList[i];
                            item.RemoveFromContainer();
                            item.Remove();
                        }
                        AddToContainer(crate.inventory, bradleyConfig.lootTable.Items, UnityEngine.Random.Range(bradleyConfig.lootTable.Min, bradleyConfig.lootTable.Max + 1));
                    }
                }
                else if (crate.ShortPrefabName == "heli_crate" && Vector3.Distance(deathHeliCoord, crate.transform.position) < 15f) {
                    if (heliConfig.offDelay) {
                        crate.CancelInvoke(crate.Think);
                        crate.SetLocked(false);
                        crate.lockingEnt = null;
                    }
                    if (heliConfig.typeLootTable == 1) {
                        for (int i = crate.inventory.itemList.Count - 1; i >= 0; i--) {
                            Item item = crate.inventory.itemList[i];
                            item.RemoveFromContainer();
                            item.Remove();
                        }
                        AddToContainer(crate.inventory, heliConfig.lootTable.Items, UnityEngine.Random.Range(heliConfig.lootTable.Min, heliConfig.lootTable.Max + 1));
                    }
                }
            }
            );
        }
        void OnEntitySpawned(HelicopterDebris entity) => NextTick(() => {
            if (entity != null && !entity.IsDestroyed && deathBradleyCoord != null && (Vector3.Distance(entity.transform.position, deathBradleyCoord) < 20f || Vector3.Distance(entity.transform.position, deathHeliCoord) < 20f)) entity.Kill();
        }
        );
        object OnEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo info) {
            if (baseVehicleModule == null || info == null) return null;
            BaseModularVehicle modularVehicle = baseVehicleModule.Vehicle;
            if (modularVehicle != null && convoyVehicles.Any(x => x != null && x.baseEntity != null && x.baseEntity == modularVehicle)) {
                if (info.InitiatorPlayer != null) {
                    if (!PveModeAllowAction(info.InitiatorPlayer)) return true;
                    float damageScale = convoyModular.baseEntity == modularVehicle ? modularConfig.damageMultiplier : supportModularConfig.damageMultiplier;
                    if (info.damageTypes.Has(DamageType.Explosion)) modularVehicle.health -= damageScale * info.damageTypes.Total() / 10;
                    else modularVehicle.health -= damageScale * info.damageTypes.Total() / 5;
                    if (!modularVehicle.IsDestroyed && modularVehicle.health <= 0) modularVehicle.Kill();
                    else {
                        for (int i = 0; i <= modularVehicle.moduleSockets.Count; i++) {
                            BaseVehicleModule module;
                            if (modularVehicle.TryGetModuleAt(i, out module)) module.SetHealth(module._maxHealth * modularVehicle.health / modularVehicle._maxHealth);
                        }
                        ConvoyTakeDamage(modularVehicle, info);
                    }
                }
                return true;
            }
            return null;
        }
        object OnEntityTakeDamage(ModularCar entity, HitInfo info) {
            if (convoyModular != null && convoyVehicles.Any(x => x.baseEntity == entity)) {
                if (info.InitiatorPlayer != null) {
                    if (!PveModeAllowAction(info.InitiatorPlayer)) return true;
                }
                if (entity == convoyModular.baseEntity) info.damageTypes.ScaleAll(modularConfig.damageMultiplier);
                else info.damageTypes.ScaleAll(supportModularConfig.damageMultiplier);
            }
            return ConvoyTakeDamage(entity, info);
        }
        object OnEntityTakeDamage(BasicCar entity, HitInfo info) {
            if (info.InitiatorPlayer != null && convoySummons.Contains(entity)) return ConvoyTakeDamage(entity, info);
            return null;
        }
        object OnEntityTakeDamage(BradleyAPC entity, HitInfo info) {
            return ConvoyTakeDamage(entity, info);
        }
        object OnEntityTakeDamage(ScientistNPC entity, HitInfo info) {
            if (info == null || entity == null) return null;
            if ((info.InitiatorPlayer == null || !info.InitiatorPlayer.userID.IsSteamId()) && convoyVehicles.Count > 0 && convoyVehicles.Any(x => x.roamNpc.Contains(entity))) return true;
            ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.scientists.Contains(entity));
            if (convoyVehicle != null) StopConvoy();
            if (convoyVehicles.Any(x => x != null && x.driver == entity)) return true;
            return null;
        }
        void OnEntityTakeDamage(BaseHelicopter entity, HitInfo info) {
            if (convoyHeli == null || info == null || entity == null || convoyHeli.baseHelicopter != entity) return;
            if (info.InitiatorPlayer != null) StopConvoy();
        }
        void OnEntityTakeDamage(BasePlayer player, HitInfo info) {
            if (player == null || info == null || info.Initiator == null) return;
            BradleyAPC bradleyAPC = info.Initiator as BradleyAPC;
            if (bradleyAPC != null && convoyVehicles.Any(x => x.baseEntity == bradleyAPC)) {
                if (!player.userID.IsSteamId()) info.damageTypes.ScaleAll(0);
                else info.damageTypes.ScaleAll(bradleyConfig.scaleDamage);
            }
        }
        void OnEntityKill(ModularCar entity) {
            if (entity != null && convoyVehicles.Any(x => x != null && x.baseEntity == entity)) {
                if (convoyModular != null && entity == convoyModular.baseEntity) {
                    failed = true;
                    if (convoyVehicles.Contains(convoyModular)) convoyVehicles.Remove(convoyModular);
                    StopConvoy();
                    if (!destroying && destroyCoroutine == null) {
                        destroying = true;
                        NotifyManager.SendMessageToAll("Failed", _config.prefix);
                        NotifyManager.SendMessageToAll("PreFinish", _config.prefix, _config.preFinishTime);
                        destroyCoroutine = ServerMgr.Instance.StartCoroutine(DestroyCounter());
                    }
                }
                else ConvoyVehicleDie(entity);
            }
        }
        void OnEntityKill(BradleyAPC entity) => ConvoyVehicleDie(entity);
        void OnEntityKill(BasicCar entity) => ConvoyVehicleDie(entity);
        void OnEntityKill(BaseHelicopter entity) {
            if (entity == null || convoyHeli == null || convoyHeli.baseHelicopter != entity) return;
            deathHeliCoord = entity.transform.position;
            if (_config.pveMode.pve && plugins.Exists("PveMode")) timer.In(1f, () => {
                PveMode.Call("EventAddCrates", Name, bradleyContainers);
            }
            );
            ConvoyVehicleDie(entity);
        }
        void OnEntityKill(BasePlayer player) {
            if (player == null) return;
            if (player.userID.IsSteamId() && players.Contains(player)) {
                players.Remove(player);
                if (_config.GUI.IsGUI) CuiHelper.DestroyUi(player, "TextMain");
            }
        }
        void OnEntityDeath(ModularCar entity, HitInfo info) {
            if (entity == null || info == null || info.InitiatorPlayer == null) return;
            ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null && x.baseEntity.net.ID == entity.net.ID);
            if (convoyVehicle == null) return;
            EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Modular");
        }
        void OnEntityDeath(BradleyAPC entity, HitInfo info) {
            if (entity == null || info == null || info.InitiatorPlayer == null) return;
            ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null && x.baseEntity.net.ID == entity.net.ID);
            if (convoyVehicle == null) return;
            EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Bradley");
        }
        void OnEntityDeath(BasicCar entity, HitInfo info) {
            if (entity == null || info == null || info.InitiatorPlayer == null) return;
            ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null && x.baseEntity.net.ID == entity.net.ID);
            if (convoyVehicle == null) return;
            EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Sedan");
        }
        void OnEntityDeath(BaseHelicopter entity, HitInfo info) {
            if (entity == null || info == null || info.InitiatorPlayer == null) return;
            if (convoySummons.Count > 0 && convoySummons.Contains(entity)) EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Heli");
        }
        void OnEntityDeath(ScientistNPC scientistNPC, HitInfo info) {
            if (scientistNPC != null && info != null && info.InitiatorPlayer != null) {
                ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.roamNpc.Contains(scientistNPC));
                if (convoyVehicle != null) {
                    if (_config.blockSpawnDieNpc) convoyVehicle.NpcDie(scientistNPC);
                    EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Npc");
                }
                else if (freeConvoyNpc.Contains(scientistNPC)) EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Npc");
            }
        }
        object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
            if (crate == null || player == null || convoyModular == null || convoyModular.crate == null || crate.net.ID != convoyModular.crate.net.ID) return null;
            else if (!player.InSafeZone() && (!_config.needStopConvoy || stopTime > 0) && (!_config.needKillCars || (convoySummons.Count == 0 && !convoySummons.Any(x => x != null && !x.IsDestroyed))) && (!_config.needKillNpc || (!freeConvoyNpc.Any(x => x != null && !x.IsDestroyed) && !convoyVehicles.Any(x => x != null && x.roamNpc.Any(y => y != null && !y.IsDestroyed))))) {
                if (_config.pveMode.pve && plugins.Exists("PveMode") && !_config.pveMode.hackCrate && PveMode.Call("CanActionEvent", Name, player) != null) return true;
                NotifyManager.SendMessageToAll("StartHackCrate", _config.prefix, player.displayName);
                if (destroying) destroyTime += (int)modularConfig.crateUnlockTime + 30;
                hackedCrate = true;
                timer.In(modularConfig.crateUnlockTime, () => {
                    if (destroyCoroutine == null && !destroying) {
                        destroying = true;
                        destroyCoroutine = ServerMgr.Instance.StartCoroutine(DestroyCounter());
                        NotifyManager.SendMessageToAll("PreFinish", _config.prefix, _config.preFinishTime);
                    }
                }
                );
                if (stopTime <= 0) StopConvoy();
                timer.In(0.5f, () => crate.hackSeconds = HackableLockedCrate.requiredHackSeconds - ins.modularConfig.crateUnlockTime);
                return null;
            }
            else {
                NotifyManager.SendMessageToPlayer(player, "CantHackCrate", _config.prefix);
                return true;
            }
        }
        object CanMountEntity(BasePlayer player, BaseMountable entity) {
            BaseEntity parrent = entity.VehicleParent();
            if (parrent != null && player.userID.IsSteamId() && convoyVehicles.Any(x => x != null && x.baseEntity == parrent)) return true;
            return null;
        }
        object OnHelicopterRetire(PatrolHelicopterAI ai) {
            if (convoyHeli != null && convoyHeli.patrolHelicopterAI == ai) return true;
            return null;
        }
        object CanHelicopterTarget(PatrolHelicopterAI heli, BasePlayer player) {
            if (convoyHeli != null && heli != null && heli == convoyHeli.patrolHelicopterAI && ((_config.blockFirstAttack && stopTime == 0 && !failed && !hackedCrate) || player == null || !player.userID.IsSteamId() || player.IsSleeping())) return false;
            return null;
        }
        object CanBradleyApcTarget(BradleyAPC apc, BaseEntity entity) {
            if (apc != null && convoySummons.Count > 0 && convoySummons.Contains(apc)) {
                if (_config.blockFirstAttack && stopTime == 0 && !failed && !hackedCrate) return false;
                BasePlayer player = entity as BasePlayer;
                if (player == null || !player.userID.IsSteamId() || player.IsSleeping()) return false;
            }
            return null;
        }
        object OnBotReSpawnCrateDropped(HackableLockedCrate crate) {
            if (active && convoyModular != null && convoyModular.crate != null && convoyModular.crate == crate) return true;
            return null;
        }
        object OnTurretTarget(AutoTurret turret, ScientistNPC scientistNPC) {
            if (turret == null || scientistNPC == null) return null;
            NpcConfig npcConfig = _config.NPC.FirstOrDefault(x => x.name == scientistNPC.displayName);
            if (npcConfig != null && scientistNPC.isMounted) return true;
            return null;
        }
        void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon item) {
            if (player != null && player.userID.IsSteamId() && stopTime <= 0 && convoyVehicles.Any(x => x != null && x.baseEntity != null && Vector3.Distance(player.transform.position, x.baseEntity.transform.position) < 17.5f)) StopConvoy(player);
        }
        object CanBradleySpawnNpc(BradleyAPC bradley) {
            if (bradley != null && convoySummons.Any(x => x != null && x.net.ID == bradley.net.ID)) return true;
            return null;
        }
        object CanHelicopterSpawnNpc(BaseHelicopter helicopter) {
            if (helicopter != null && convoyHeli != null && convoyHeli.baseHelicopter != null && convoyHeli.baseHelicopter.net.ID == helicopter.net.ID) return true;
            return null;
        }
#region OtherPLugins
        void OnCorpsePopulate(BasePlayer entity, NPCPlayerCorpse corpse) {
            if (entity == null || corpse == null) return;
            if (entity is ScientistNPC) {
                NpcConfig npcConfig = _config.NPC.FirstOrDefault(x => x.name == entity.displayName);
                if (npcConfig == null) return;
                NextTick(() => {
                    if (corpse == null) return;
                    ItemContainer container = corpse.containers[0];
                    if (npcConfig.typeLootTable == 0) {
                        for (int i = container.itemList.Count - 1; i >= 0; i--) {
                            Item item = container.itemList[i];
                            if (npcConfig.wearItems.Any(x => x.shortName == item.info.shortname)) {
                                item.RemoveFromContainer();
                                item.Remove();
                            }
                        }
                        if (npcConfig.deleteCorpse && corpse != null && !corpse.IsDestroyed) corpse.Kill();
                        return;
                    }
                    if (npcConfig.typeLootTable == 2 || npcConfig.typeLootTable == 3) {
                        if (npcConfig.deleteCorpse && !corpse.IsDestroyed) corpse.Kill();
                        return;
                    }
                    for (int i = container.itemList.Count - 1; i >= 0; i--) {
                        Item item = corpse.containers[0].itemList[i];
                        item.RemoveFromContainer();
                        item.Remove();
                    }
                    if (npcConfig.typeLootTable == 1 && npcConfig.lootTable.Min > 0) AddToContainer(container, npcConfig.lootTable.Items, UnityEngine.Random.Range(npcConfig.lootTable.Min, npcConfig.lootTable.Max + 1));
                    if (npcConfig.deleteCorpse && corpse != null && !corpse.IsDestroyed) corpse.Kill();
                }
                );
            }
        }
        object CanPopulateLoot(LootContainer container) {
            if (container == null) return null;
            else if (container is HackableLockedCrate && convoyModular != null && convoyModular.crate != null && convoyModular.crate == container) {
                if (modularConfig.typeLootTable == 2) return null;
                else return true;
            }
            else if (container.ShortPrefabName == "bradley_crate" && Vector3.Distance(deathBradleyCoord, container.transform.position) < 15f) {
                bradleyContainers.Add(container.net.ID);
                if (bradleyConfig.typeLootTable == 2) return null;
                else return true;
            }
            else if (container.ShortPrefabName == "heli_crate" && Vector3.Distance(deathHeliCoord, container.transform.position) < 25f) {
                if (heliConfig.typeLootTable == 2) return null;
                else return true;
            }
            else return null;
        }
        object CanPopulateLoot(ScientistNPC scientistNPC, NPCPlayerCorpse corpse) {
            if (scientistNPC == null || corpse == null || convoyVehicles.Count == 0) return null;
            if (convoyVehicles.Any(x => x != null && x.scientists.Contains(scientistNPC))) {
                NpcConfig npcConfig = _config.NPC.FirstOrDefault(x => x.name == scientistNPC.name);
                if (npcConfig == null) return null;
                if (npcConfig.typeLootTable == 2) return null;
                else return true;
            }
            return null;
        }
        private object OnCustomLootContainer(uint netID) {
            if (!active) return null;
            if (convoyModular != null && convoyModular.baseEntity != null && !convoyModular.baseEntity.IsDestroyed && convoyModular.crate != null && convoyModular.crate.net.ID == netID) {
                if (modularConfig.typeLootTable == 3) return null;
                else return true;
            }
            return null;
        }
        object CanEntityTakeDamage(BasePlayer victim, HitInfo hitinfo) {
            if (victim == null || hitinfo == null || !_config.eventZone.isCreateZonePVP || victim == null || !victim.userID.IsSteamId() || hitinfo == null || !active || doorCloser == null || doorCloser.IsDestroyed) return null;
            BasePlayer attacker = hitinfo.InitiatorPlayer;
            if (players.Contains(victim) && (attacker == null || (attacker != null && players.Contains(attacker)))) return true;
            else return null;
        }
        object CanEntityTakeDamage(BasicCar victim, HitInfo hitinfo) {
            if (victim == null || hitinfo == null || active == false || hitinfo.InitiatorPlayer == null || !hitinfo.InitiatorPlayer.userID.IsSteamId()) return null;
            if (convoySummons.Contains(victim)) return true;
            else return null;
        }
        object CanEntityTakeDamage(ModularCar victim, HitInfo hitinfo) {
            if (victim == null || hitinfo == null || active == false || hitinfo.InitiatorPlayer == null || !hitinfo.InitiatorPlayer.userID.IsSteamId()) return null;
            if (!PveModeAllowAction(hitinfo.InitiatorPlayer)) return false;
            if (convoyVehicles.Count > 0 && convoyVehicles.Any(x => x != null && x.baseEntity != null && x.baseEntity.net.ID == victim.net.ID)) return true;
            else return null;
        }
        object CanEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo hitinfo) {
            if (baseVehicleModule == null || hitinfo == null || active == false || hitinfo.InitiatorPlayer == null || !hitinfo.InitiatorPlayer.userID.IsSteamId() || baseVehicleModule.Vehicle == null || baseVehicleModule.Vehicle.IsDestroyed) return null;
            if (!PveModeAllowAction(hitinfo.InitiatorPlayer)) return false;
            if (convoyVehicles.Any(x => x != null && x.baseEntity != null && !x.baseEntity.IsDestroyed && x.baseEntity.net.ID == baseVehicleModule.Vehicle.net.ID)) return true;
            else return null;
        }
        object OnCreateDynamicPVP(string eventName, BradleyAPC entity) {
            if (entity == null) return null;
            if (IsConvoyVehicle(entity)) return true;
            if (deathBradleyCoord != Vector3.zero && Vector3.Distance(deathBradleyCoord, entity.transform.position) < 20) return true;
            return null;
        }
        object OnCreateDynamicPVP(string eventName, BaseHelicopter entity) {
            if (entity == null) return null;
            if (IsConvoyHeli(entity)) return true;
            if (deathHeliCoord != Vector3.zero && Vector3.Distance(deathHeliCoord, entity.transform.position) < 50) return true;
            return null;
        }
#endregion OtherPLugins
#endregion Hooks
#region Commands
        [ChatCommand("convoystart")]
        void StartCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            if (active) {
                NotifyManager.SendMessageToPlayer(player, "EventActive", _config.prefix);
                return;
            }
            if (arg != null && arg.Length >= 1) CreateConvoy(arg[0]);
            else CreateConvoy();
        }
        [ChatCommand("convoystop")]
        void StopCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            if (active) DeleteConvoy(true);
        }
        [ConsoleCommand("convoystart")]
        void ConsoleStartCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            if (arg.Args != null && arg.Args.Length > 0) CreateConvoy(arg.Args[0]);
            CreateConvoy();
        }
        [ConsoleCommand("convoystartpersonal")]
        void ConsoleStartPersonalCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            if (owners != null) owners.Clear();
            foreach (var a in arg.Args) {
                ulong id = Convert.ToUInt64(a);
                if (id != 0 && id.IsSteamId()) owners.Add(id);
            }
            if (arg.Args != null && arg.Args.Length > 0 && _config.convoys.Any(x => x.name == arg.Args[0])) CreateConvoy(arg.Args[0]);
            CreateConvoy();
        }
        [ConsoleCommand("convoystop")]
        void ConsoleStopCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() == null && active) DeleteConvoy(true);
        }
        [ChatCommand("convoyrootstart")]
        void RootStartCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin || player.isInAir) return;
            RootCar.CreateRootCar(player);
        }
        [ChatCommand("convoyrootstop")]
        void RootStopCommand(BasePlayer player, string command, string[] arg) {
            if (player.IsAdmin) RootCar.RootStop();
        }
        [ChatCommand("convoyrootsave")]
        void RootSaveCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            if (arg == null || arg.Length == 0) {
                NotifyManager.SendMessageToPlayer(player, $"{_config.prefix} To save the route, use the command: <color=#738d43>convoyrootsave [rootpresetname]</color>");
                return;
            }
            RootCar.SaveRoot(player, arg[0]);
        }
        [ChatCommand("convoyroadblock")]
        void RoadBlockCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin || player.isInAir) return;
            PathList blockRoad = TerrainMeta.Path.Roads.FirstOrDefault(x => x.Path.Points.Any(y => Vector3.Distance(player.transform.position, y) < 10));
            if (blockRoad == null) NotifyManager.SendMessageToPlayer(player, $"{_config.prefix} Road not found <color=#ce3f27>not found</color>");
            int index = TerrainMeta.Path.Roads.IndexOf(blockRoad);
            if (_config.blockRoads.Contains(index)) NotifyManager.SendMessageToPlayer(player, $"{_config.prefix} The road is already <color=#ce3f27>blocked</color>");
            else if (blockRoad != null) {
                _config.blockRoads.Add(index);
                SaveConfig();
                NotifyManager.SendMessageToPlayer(player, $"{_config.prefix} The road with the index <color=#738d43>{index}</color> is <color=#ce3f27>blocked</color>");
            }
        }
#endregion Commands
#region Method
        void UpdateConfig() {
            if (_config.version != Version.ToString()) {
                VersionNumber versionNumber;
                var versionArray = _config.version.Split('.');
                versionNumber.Major = Convert.ToInt32(versionArray[0]);
                versionNumber.Minor = Convert.ToInt32(versionArray[1]);
                versionNumber.Patch = Convert.ToInt32(versionArray[2]);
                if (versionNumber.Major == 2) {
                    if (versionNumber.Minor == 0) {
                        if (versionNumber.Patch == 0) {
                            foreach (ConvoySetting convoySetting in _config.convoys) convoySetting.displayName = "Convoy";
                        }
                        if (versionNumber.Patch <= 7) {
                            foreach (NpcConfig npcConfig in _config.NPC) npcConfig.kit = "";
                        }
                        if (versionNumber.Patch <= 9) {
                            _config.autoEvent = true;
                            foreach (string name in trains) if (!_config.barriers.Contains(name)) _config.barriers.Add(name);
                        }
                        versionNumber.Minor = 1;
                        versionNumber.Patch = 0;
                    }
                    if (versionNumber.Minor == 1) {
                        if (versionNumber.Patch <= 5) {
                            if (!_config.barriers.Contains("xmasportalentry")) {
                                _config.barriers.Add("xmasportalentry");
                            }
                        }
                        if (versionNumber.Patch < 7) {
                            if (!_config.barriers.Contains("stone-ore")) _config.barriers.Add("stone-ore");
                            if (!_config.barriers.Contains("metal-ore")) _config.barriers.Add("metal-ore");
                            if (!_config.barriers.Contains("sulfur-ore")) _config.barriers.Add("sulfur-ore");
                        }
                        if (versionNumber.Patch <= 9) {
                            _config.pveMode.scaleDamage.Add(new ScaleDamageConfig {
                                Type = "Helicopter", Scale = 1
                            }
                            );
                        }
                        versionNumber.Minor = 2;
                        versionNumber.Patch = 0;
                    }
                    if (versionNumber.Minor == 2) {
                    }
                }
                else {
                    PrintError("Delete the configuration file!");
                    NextTick(() => Server.Command($"o.unload {Name}"));
                    return;
                }
                _config.version = Version.ToString();
                SaveConfig();
            }
        }
        void Unsubscribes() {
            foreach (string hook in subscribeMetods) Unsubscribe(hook);
        }
        void Subscribes() {
            foreach (string hook in subscribeMetods) Subscribe(hook);
        }
        void CheckZeroCoord() {
            foreach (Collider collider in UnityEngine.Physics.OverlapSphere(Vector3.zero, 3f)) {
                BaseEntity entity = collider.ToBaseEntity();
                if (entity == null) continue;
                if (entity.PrefabName.Contains("modular") || entity.PrefabName.Contains("locked")) entity.Kill();
            }
        }
        void CreateConvoy(string presetName = "") {
            if (active) {
                Puts("This event is active now.To finish this event (convoystop), then to start the next one");
                return;
            }
            if (!plugins.Exists("NpcSpawn")) {
                PrintError("NpcSpawn plugin doesn`t exist! Please read the file ReadMe.txt");
                Server.Command($"o.unload {Name}");
                return;
            }
            if (pathCount == 0) {
                PrintError("No road detected");
                NextTick(() => Server.Command($"o.unload {Name}"));
                return;
            }
            destroyTime = ins._config.preFinishTime;
            if (presetName != "") convoySetting = _config.convoys.FirstOrDefault(x => x.name == presetName);
            else if (_config.convoys.Any(x => x.chance > 0 && x.on)) {
                while (convoySetting == null) {
                    foreach (ConvoySetting setting in _config.convoys) {
                        if (setting.on && UnityEngine.Random.Range(0.0f, 100.0f) <= setting.chance) convoySetting = setting;
                    }
                }
            }
            if (convoySetting == null) {
                PrintError("Event configuration not found!");
                Server.Command($"o.reload {Name}");
                return;
            }
            NotifyManager.SendMessageToAll("PreStart", _config.prefix, _config.preStartTime);
            active = true;
            timer.In(_config.preStartTime, () => {
                if (!active) return;
                Subscribes();
                bradleyConfig = _config.bradleyConfiguration.FirstOrDefault(x => x.presetName == convoySetting.bradleyConfigurationName);
                sedanConfig = _config.sedanConfiguration.FirstOrDefault(x => x.presetName == convoySetting.sedanConfigurationName);
                modularConfig = _config.modularConfiguration.FirstOrDefault(x => x.presetName == convoySetting.modularConfigurationName);
                heliConfig = _config.heliesConfiguration.FirstOrDefault(x => x.presetName == convoySetting.heliConfigurationName);
                supportModularConfig = _config.supportModularConfiguration.FirstOrDefault(x => x.presetName == convoySetting.supportodularConfigurationName);
                int totalVehicleCount = convoySetting.firstBradleyCount + convoySetting.firstSedanCount + convoySetting.endSedanCount + convoySetting.endBradleyCount;
                int startPoint = round ? UnityEngine.Random.Range(0, pathCount / 2) : 1;
                int count = 0;
                int totalCount = convoySetting.endBradleyCount;
                int delataPoint = _config.carDistance;
                int cycleCount = 0;
                while (cycleCount < 25 && Vector3.Distance(currentPath[0], currentPath[delataPoint]) < 10) {
                    delataPoint += 2;
                    cycleCount++;
                }
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoyBradley.CreateBradley(firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount += convoySetting.endModularCount;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoyModular.CreateModular(supportModularConfig, firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount += convoySetting.endSedanCount;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoySedan.CreateSedan(firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount++;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoyTruck.CreateTruck(modularConfig, firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount += convoySetting.firstSedanCount;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoySedan.CreateSedan(firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount += convoySetting.firstModularCount;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoyModular.CreateModular(supportModularConfig, firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                totalCount += convoySetting.firstBradleyCount;
                for (; count < totalCount; count++) {
                    int firstpoint = 0, secondpoint = 0;
                    DefineNextPathPoint(startPoint, pathCount, out firstpoint, out secondpoint);
                    ConvoyBradley.CreateBradley(firstpoint, secondpoint);
                    startPoint += delataPoint;
                }
                timer.In(1f, () => {
                    if (convoySetting.heliOn && convoyModular != null) ConvoyHeli.CreateHelicopter();
                }
                );
                convoyVehicles.Reverse();
                NotifyManager.SendMessageToAll("EventStart", _config.prefix);
                if (eventCoroutine != null) ServerMgr.Instance.StopCoroutine(eventCoroutine);
                eventCoroutine = ServerMgr.Instance.StartCoroutine(EventCounter());
                Puts("The event has begun");
                Interface.CallHook("OnConvoyStart");
            }
            );
        }
        void DefineNextPathPoint(int point, int pathCount, out int firstPoint, out int endPoint) {
            if (point > pathCount - 1) {
                if (round) firstPoint = point - pathCount;
                else {
                    PrintError("Insufficient route length!");
                    DeleteConvoy(true);
                    firstPoint = endPoint = 0;
                }
            }
            else firstPoint = point;
            int endpointClone = firstPoint++;
            if (endpointClone > pathCount - 1) {
                if (round) endPoint = endpointClone - pathCount;
                else {
                    PrintError("Insufficient route length!");
                    DeleteConvoy(true);
                    firstPoint = endPoint = 0;
                }
            }
            else endPoint = endpointClone;
        }
        void ReverseConvoy() {
            currentPath.Reverse();
            convoyVehicles.Reverse();
            foreach (ConvoyVehicle convoyVehicle in convoyVehicles) {
                if (convoyVehicle == null || convoyVehicle.baseEntity == null || convoyVehicle.baseEntity.IsDestroyed) continue;
                Transform transform = convoyVehicle.baseEntity.transform;
                convoyVehicle.rigidbody.velocity = Vector3.zero;
                transform.RotateAround(transform.position, transform.up, 180);
                convoyVehicle.Rotate();
                convoyVehicle.DefineFollowEntity();
            }
        }
        void DeleteConvoy(bool unload = false) {
            Unsubscribes();
            if (active) Interface.CallHook("OnConvoyStop");
            active = false;
            if (doorCloser != null && !doorCloser.IsDestroyed) doorCloser.Kill();
            foreach (BasePlayer player in ins.players) CuiHelper.DestroyUi(player, "TextMain");
            players.Clear();
            if (active) NotifyManager.SendMessageToAll("Finish", _config.prefix);
            destroying = false;
            foreach (ScientistNPC scientist in freeConvoyNpc) {
                if (scientist != null && !scientist.IsDestroyed) scientist.Kill();
            }
            foreach (ConvoyVehicle convoyVehicle in convoyVehicles) {
                if (convoyVehicle != null && convoyVehicle.baseEntity != null && !convoyVehicle.baseEntity.IsDestroyed) {
                    convoyVehicle.destroyAll = true;
                    convoyVehicle.baseEntity.Kill();
                }
            }
            if (convoyHeli != null && convoyHeli.baseHelicopter != null && !convoyHeli.baseHelicopter.IsDestroyed) convoyHeli.baseHelicopter.Kill();
            convoyVehicles.Clear();
            convoySummons.Clear();
            Puts("The event is over");
            if (stopCoroutine != null) ServerMgr.Instance.StopCoroutine(stopCoroutine);
            if (eventCoroutine != null) ServerMgr.Instance.StopCoroutine(eventCoroutine);
            if (destroyCoroutine != null) ServerMgr.Instance.StopCoroutine(destroyCoroutine);
            if (convoyModular != null && convoyModular.baseEntity != null && !convoyModular.baseEntity.IsDestroyed) convoyModular.baseEntity.Kill();
            if (_config.pveMode.pve && plugins.Exists("PveMode")) PveMode.Call("EventRemovePveMode", Name, true);
            EconomyManager.SendBalance();
            if (owners != null) owners.Clear();
            if (unload) Server.Command($"o.reload {Name}");
        }
        void ConvoyVehicleDie(BaseEntity entity) {
            if (entity == null) return;
            ConvoyVehicle convoyVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null && !x.baseEntity.IsDestroyed && x.baseEntity.net.ID == entity.net.ID);
            if (convoyVehicle != null) {
                if (convoyVehicle is ConvoyBradley) {
                    deathBradleyCoord = entity.transform.position;
                    if (_config.pveMode.pve && plugins.Exists("PveMode")) timer.In(1f, () => {
                        PveMode.Call("EventAddCrates", Name, bradleyContainers);
                        bradleyContainers.Clear();
                    }
                    );
                }
                DefineFollow(entity);
            }
            if (convoySummons.Count > 0 && convoySummons.Contains(entity)) {
                convoySummons.Remove(entity);
                if (convoySummons.Count == 0 && convoyModular != null) {
                    StopConvoy();
                    convoyModular.StopMoving(false, true);
                    NotifyManager.SendMessageToAll("SecurityKill", _config.prefix);
                }
            }
        }
        object ConvoyTakeDamage(BaseEntity entity, HitInfo info) {
            if (entity == null || !convoyVehicles.Any(x => x != null && x.baseEntity == entity)) return null;
            if (info == null || info.InitiatorPlayer == null) return true;
            BasePlayer initiator = info.InitiatorPlayer;
            if (!initiator.userID.IsSteamId()) return true;
            if (info.ProjectileDistance >= _config.maxDamageDistance) {
                NotifyManager.SendMessageToPlayer(initiator, "Distance", initiator.UserIDString, _config.prefix);
                return true;
            }
            StopConvoy(initiator);
            return null;
        }
        void StopConvoy(BasePlayer initiator = null, int time = 0) {
      
// ... [Code preview truncated due to length. Full source in attached file] ...

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