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

FREE Convoy : 2.4.1 2.4.1

Нет прав для скачивания
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;
using Time = UnityEngine.Time;
using System.Reflection;
using static BaseVehicle;
namespace Oxide.Plugins {
    [Info("Convoy", "Adem", "2.4.1")]
    class Convoy : RustPlugin {
        [PluginReference]
        Plugin NpcSpawn, GUIAnnouncements, DiscordMessages, PveMode, Economics, ServerRewards, IQEconomic, DynamicPVP;
#region Variables
        const bool en = false;
        static Convoy ins;
        HashSet<string> subscribeMetods = new HashSet<string> {
            "OnCustomNpcTarget", "OnEntitySpawned", "OnEntityTakeDamage", "OnEntityKill", "OnPlayerDeath", "OnEntityDeath", "CanHackCrate", "OnLootEntity", "CanMountEntity", "OnHelicopterRetire", "CanHelicopterTarget", "CanBradleyApcTarget", "OnTurretTarget", "OnExplosiveThrown", "OnCorpsePopulate", "OnCustomNpcTarget", "CanPopulateLoot", "OnCustomLootContainer", "CanEntityTakeDamage", "OnCreateDynamicPVP", "OnBotReSpawnCrateDropped", "CanBradleySpawnNpc", "CanHelicopterSpawnNpc",
        }
        ;
        ConvoyController convoyController;
        HashSet<ulong> bradleyOrHeliContainers = new HashSet<ulong>();
#endregion Variables
#region API
        private bool IsConvoyVehicle(BaseEntity entity) {
            if (entity == null || convoyController == null) return false;
            return convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value) != null;
        }
        private bool IsConvoyCrate(HackableLockedCrate crate) {
            if (crate == null || convoyController == null) return false;
            return convoyController.GetTruckByCrateNetID(crate.net.ID.Value) != null;
        }
        private bool IsConvoyHeli(PatrolHelicopter patrolHelicopter) {
            if (patrolHelicopter == null || patrolHelicopter.net == null) return false;
            return convoyController != null && convoyController.IsConvoyHeli(patrolHelicopter.net.ID.Value);
        }
#endregion API
#region Hooks
        void Init() {
            ins = this;
            UpdateConfig();
            Unsubscribes();
            LoadData();
        }
        void OnServerInitialized() {
            if (!NpcManager.CheckNPCSpawn()) {
                PrintError("NpcSpawn plugin doesn`t exist! Please read the file ReadMe.txt");
                NextTick(() => Server.Command($"o.unload {Name}"));
            }
            LoadDefaultMessages();
            CheckZeroCoord();
            ConvoyLauncher.AutoStartEvent();
        }
        void Unload() {
            ConvoyLauncher.StopEvent(true);
            RootCar.RootStop();
        }
        void OnEntitySpawned(LockedByEntCrate crate) {
            if (crate == null) return;
            if (crate.ShortPrefabName == "bradley_crate") {
                ConvoyBradley convoyBradley = convoyController.GetConvoyBradleyAtPosition(crate.transform.position);
                if (convoyBradley == null) return;
                NextTick(() => LootManager.UpdateConvoyLockedByEntCrate(crate, convoyBradley.bradleyConfig.offDelay, convoyBradley.bradleyConfig.typeLootTable, convoyBradley.bradleyConfig.lootTable));
                bradleyOrHeliContainers.Add(crate.net.ID.Value);
            }
            else if (crate.ShortPrefabName == "heli_crate") {
                ConvoyHeli convoyHeli = convoyController.GetCConvoyHeliAtPosition(crate.transform.position);
                if (convoyHeli == null) return;
                NextTick(() => LootManager.UpdateConvoyLockedByEntCrate(crate, convoyHeli.heliConfig.offDelay, convoyHeli.heliConfig.typeLootTable, convoyHeli.heliConfig.lootTable));
                bradleyOrHeliContainers.Add(crate.net.ID.Value);
            }
        }
        void OnEntitySpawned(HelicopterDebris entity) {
            if (!entity.IsExists()) return;
            if (convoyController.GetConvoyBradleyAtPosition(entity.transform.position) != null || convoyController.GetCConvoyHeliAtPosition(entity.transform.position) != null) {
                Rigidbody rigidbody = entity.gameObject.GetComponent<Rigidbody>();
                rigidbody.mass = 1;
            }
        }
        object OnTurretTarget(AutoTurret turret, ScientistNPC scientistNPC) {
            if (turret == null || scientistNPC == null) return null;
            if (NpcManager.IsConvoyNpc(scientistNPC.displayName)) {
                if (!_config.enablePlayerTurret) return true;
                else if(scientistNPC.isMounted) return true;
                else if (!convoyController.IsPlayerTurretCanAttackConvoy(turret)) return true;
            }
            return null;
        }
        object OnEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo info) {
            if (baseVehicleModule == null || info == null) return null;
            BaseModularVehicle modularVehicle = baseVehicleModule.Vehicle;
            if (modularVehicle == null || modularVehicle.net == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(modularVehicle.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (convoyController.CanConvoyEntityTakeDamage(info, baseVehicleModule)) {
                ConvoyModular convoyModular = convoyVehicle as ConvoyModular;
                modularVehicle.health -= convoyModular.supportModularConfig.damageMultiplier * info.damageTypes.Total() / 5;
                if (!modularVehicle.IsDestroyed && modularVehicle.health <= 0) modularVehicle.Kill(BaseNetworkable.DestroyMode.Gib);
                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);
                    }
                }
                if (info.InitiatorPlayer != null) convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                return null;
            }
            else return true;
        }
        object OnEntityTakeDamage(ModularCar entity, HitInfo info) {
            if (entity == null || info == null || entity.net == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (convoyController.CanConvoyEntityTakeDamage(info, entity)) {
                ConvoyModular convoyModular = convoyVehicle as ConvoyModular;
                info.damageTypes.ScaleAll(convoyModular.supportModularConfig.damageMultiplier);
                convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                return null;
            }
            else return true;
        }
        object OnEntityTakeDamage(BasicCar entity, HitInfo info) {
            if (entity == null || info == null || entity.net == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (convoyController.CanConvoyEntityTakeDamage(info, entity)) {
                convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                return null;
            }
            else return true;
        }
        object OnEntityTakeDamage(BradleyAPC entity, HitInfo info) {
            if (entity == null || info == null || entity.net == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (convoyController.CanConvoyEntityTakeDamage(info, entity)) {
                if (info.InitiatorPlayer.IsRealPlayer()) convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                return null;
            }
            else return true;
        }
        object OnEntityTakeDamage(ScientistNPC entity, HitInfo info) {
            if (info == null || entity == null || !info.InitiatorPlayer.IsRealPlayer()) return null;
            if (NpcManager.IsConvoyNpc(entity.displayName) && convoyController.CanConvoyNpcTakeDamage(info)) {
                BaseVehicle baseVehicle = entity.GetMountedVehicle();
                if (baseVehicle != null && baseVehicle.IsDriver(entity)) {
                    ins.NextTick(() => {
                        if (convoyController != null) convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                    }
                    );
                    return true;
                }
                ins.NextTick(() => {
                    if (convoyController != null) convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                }
                );
                return null;
            }
            return null;
        }
        object OnEntityTakeDamage(PatrolHelicopter entity, HitInfo info) {
            if (entity == null || info == null) return null;
            if (IsConvoyHeli(entity) && info.InitiatorPlayer != null) {
                if (!convoyController.CanConvoyEntityTakeDamage(info, entity)) {
                    info.damageTypes.ScaleAll(0);
                    return true;
                }
                else {
                    convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                }
            }
            return null;
        }
        void OnEntityTakeDamage(BuildingBlock buildingBlock, HitInfo info) {
            if (buildingBlock == null || info.PointStart == null) return;
            if (info.WeaponPrefab != null && info.WeaponPrefab.name == "MainCannonShell") {
                if (!convoyController.convoyVehicles.Any(x => x != null && Vector3.Distance(info.PointStart, x.baseEntity.transform.position) < _config.maxDamageDistance * 2)) return;
                info.damageTypes.ScaleAll(100 * _config.bradleyBuildingDamageScale);
                return;
            }
            if (info.Initiator == null || info.Initiator.net == null) return;
            BradleyAPC bradley = info.Initiator as BradleyAPC;
            if (bradley != null) {
                ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(bradley.net.ID.Value);
                if (convoyVehicle != null) info.damageTypes.ScaleAll(_config.bradleyBuildingDamageScale);
            }
        }
        void OnEntityKill(ModularCar entity) {
            if (entity == null || entity.net == null) return;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return;
            convoyController.OnConvoyVehicleDie(convoyVehicle);
            ConvoyTruck convoyTruck = convoyVehicle as ConvoyTruck;
            if (convoyTruck != null) {
                if (_config.dropCrateAfterKillTruck) convoyTruck.DropCrate();
                else NotifyManager.SendMessageToAll("Failed", ins._config.prefix);
                ins.NextTick(convoyController.CheckConvoyHasNoLootedTruck);
            }
        }
        void OnEntityKill(BradleyAPC entity) {
            if (entity == null || entity.net == null) return;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return;
            convoyController.OnConvoyVehicleDie(convoyVehicle);
            ConvoyBradley convoyBradley = convoyVehicle as ConvoyBradley;
            if (ins._config.pveMode.pve && ins.plugins.Exists("PveMode")) {
                timer.In(1f, () => {
                    ins.PveMode.Call("EventAddCrates", ins.Name, ins.bradleyOrHeliContainers);
                    ins.bradleyOrHeliContainers.Clear();
                }
                );
            }
        }
        void OnEntityKill(BasicCar entity) {
            if (entity == null || entity.net == null) return;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(entity.net.ID.Value);
            if (convoyVehicle == null) return;
            convoyController.OnConvoyVehicleDie(convoyVehicle);
        }
        void OnEntityKill(PatrolHelicopter entity) {
            if (entity == null) return;
            if (!IsConvoyHeli(entity)) return;
            if (_config.pveMode.pve && plugins.Exists("PveMode")) {
                timer.In(1f, () => {
                    PveMode.Call("EventAddCrates", Name, bradleyOrHeliContainers);
                    ins.bradleyOrHeliContainers.Clear();
                }
                );
            }
        }
        void OnEntityKill(ScientistNPC scientistNPC) {
            if (scientistNPC == null || scientistNPC.net == null || !NpcManager.IsConvoyNpc(scientistNPC.displayName) || scientistNPC.isMounted) return;
            if (ins._config.blockSpawnDieNpc) {
                ConvoyVehicle convoyVehicle = convoyController.convoyVehicles.FirstOrDefault(x => x != null && x.roamNpcsNetIDs.Any(y => y == scientistNPC.net.ID.Value));
                if (convoyVehicle != null) convoyVehicle.countDieNpc++;
            }
            if (convoyController.IsConvoyStop() && _config.needKillNpc) {
                convoyController.roamNpc.Remove(scientistNPC);
                if (convoyController.roamNpc.Count == 0) {
                    NotifyManager.SendMessageToAll("SecurityNpcKill", _config.prefix);
                }
            }
        }
        void OnPlayerDeath(BasePlayer player, HitInfo info) {
            if (player == null) return;
            if (ZoneController.IsPlayerInZone(player.userID)) ZoneController.OnPlayerLeaveZone(player);
        }
        void OnEntityDeath(ModularCar entity, HitInfo info) {
            if (entity == null || entity.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
            EconomyManager.CheckIfPlayerKillConvoyVehicle(entity.net.ID.Value, "Modular", info.InitiatorPlayer);
        }
        void OnEntityDeath(BradleyAPC entity, HitInfo info) {
            if (entity == null || entity.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
            EconomyManager.CheckIfPlayerKillConvoyVehicle(entity.net.ID.Value, "Bradley", info.InitiatorPlayer);
        }
        void OnEntityDeath(BasicCar entity, HitInfo info) {
            if (entity == null || entity.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
            EconomyManager.CheckIfPlayerKillConvoyVehicle(entity.net.ID.Value, "Sedan", info.InitiatorPlayer);
        }
        void OnEntityDeath(PatrolHelicopter entity, HitInfo info) {
            if (entity == null || info == null || info.InitiatorPlayer == null) return;
            if (IsConvoyHeli(entity)) EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Heli");
        }
        void OnEntityDeath(ScientistNPC scientistNPC, HitInfo info) {
            if (scientistNPC == null || scientistNPC.net == null || !NpcManager.IsConvoyNpc(scientistNPC.displayName)) return;
            if (info != null && info.InitiatorPlayer.IsRealPlayer()) EconomyManager.ActionEconomy(info.InitiatorPlayer.userID, "Npc");
        }
        object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
            if (crate == null || player == null) return null;
            ConvoyTruck convoyTruck = convoyController.GetTruckByCrateNetID(crate.net.ID.Value);
            if (convoyTruck == null) return null;
            if (player.InSafeZone()) return true;
            else if ((!_config.needStopConvoy || convoyController.IsConvoyStop()) && (!_config.needKillCars || !convoyController.ConvoyHaveAnySecurityVehivcle()) && (!_config.needKillNpc || !convoyController.roamNpc.Any(x => x.IsExists()))) {
                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);
                convoyController.OnConvoyAttacked(player);
                convoyTruck.UpdateCrateHackTimeWithDelay();
                return null;
            }
            else {
                NotifyManager.SendMessageToPlayer(player, "CantHackCrate", _config.prefix);
                return true;
            }
        }
        void OnLootEntity(BasePlayer player, HackableLockedCrate crate) {
            if (player == null || crate == null || crate.net == null) return;
            ConvoyTruck convoyTruck = convoyController.GetTruckByCrateNetID(crate.net.ID.Value);
            if (convoyTruck != null) convoyController.OnCrateLooted(crate.net.ID.Value);
        }
        object CanMountEntity(BasePlayer player, BaseMountable entity) {
            if (!player.IsRealPlayer() || entity == null) return null;
            BaseEntity vehicle = entity.VehicleParent();
            if (vehicle != null & IsConvoyVehicle(vehicle)) return true;
            return null;
        }
        object OnHelicopterRetire(PatrolHelicopterAI ai) {
            if (convoyController.convoyHeli != null && convoyController.convoyHeli.patrolHelicopterAI == ai) return true;
            return null;
        }
        object CanHelicopterTarget(PatrolHelicopterAI heli, BasePlayer player) {
            if (heli == null || heli.helicopterBase == null) return null;
            if (IsConvoyHeli(heli.helicopterBase)) {
                if (!player.IsRealPlayer() || player.IsSleeping()) return false;
                else if (!_config.isAggressive && !convoyController.IsConvoyStop() && !convoyController.IsAnyCrateHacking()) return false;
            }
            return null;
        }
        object CanBradleyApcTarget(BradleyAPC apc, BaseEntity entity) {
            if (apc == null || entity == null || apc.net == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(apc.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (!_config.isAggressive && !convoyController.IsConvoyStop() && !convoyController.IsAnyCrateHacking()) return false;
            BasePlayer player = entity as BasePlayer;
            if (!player.IsRealPlayer() || player.IsSleeping() || player.InSafeZone()) return false;
            return null;
        }
        void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon item) {
            if (!player.IsRealPlayer()) return;
            if (convoyController.convoyVehicles.Any(x => x != null && x.baseEntity != null && Vector3.Distance(player.transform.position, x.baseEntity.transform.position) < 25f)) convoyController.OnConvoyAttacked(player);
        }
        void OnCorpsePopulate(ScientistNPC scientistNPC, NPCPlayerCorpse corpse) {
            if (scientistNPC == null || corpse == null) return;
            NpcConfig npcConfig = NpcManager.GetNpcConfigByDisplayName(scientistNPC.displayName);
            if (npcConfig == null) return;
            NextTick(() => {
                if (corpse != null) LootManager.UpdateNpcLootContainer(corpse, npcConfig);
            }
            );
        }
#region OtherPLugins
        object OnCustomNpcTarget(ScientistNPC npc, BasePlayer player) {
            if (convoyController == null || npc == null) return null;
            if (!convoyController.IsConvoyStop() && !_config.isAggressive && NpcManager.IsConvoyNpc(npc.displayName)) return false;
            return null;
        }
        object CanPopulateLoot(LootContainer container) {
            if (convoyController == null || container == null) return null;
            if (container is HackableLockedCrate) {
                ConvoyTruck convoyTruck = convoyController.GetTruckByCrateNetID(container.net.ID.Value);
                if (convoyTruck == null) return null;
                if (convoyTruck.modularConfig.typeLootTable == 2) return null;
                else return true;
            }
            else if (container.ShortPrefabName == "bradley_crate") {
                ConvoyBradley convoyBradley = convoyController.GetConvoyBradleyAtPosition(container.transform.position);
                if (convoyBradley == null) return null;
                if (convoyBradley.bradleyConfig.typeLootTable == 2) return null;
                else return true;
            }
            else if (container.ShortPrefabName == "heli_crate") {
                ConvoyHeli convoyHeli = convoyController.GetCConvoyHeliAtPosition(container.transform.position);
                if (convoyHeli == null) return null;
                if (convoyHeli.heliConfig.typeLootTable == 2) return null;
                else return true;
            }
            else return null;
        }
        object CanPopulateLoot(ScientistNPC scientistNPC, NPCPlayerCorpse corpse) {
            if (convoyController == null || scientistNPC == null || corpse == null || convoyController.convoyVehicles.Count == 0) return null;
            if (convoyController.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;
        }
        object OnCustomLootContainer(NetworkableId netID) {
            if (convoyController == null || netID == null) return null;
            ConvoyTruck convoyTruck = convoyController.GetTruckByCrateNetID(netID.Value);
            if (convoyTruck == null) return null;
            if (convoyTruck.modularConfig.typeLootTable != 3) return true;
            return null;
        }
        object CanEntityBeTargeted(ScientistNPC scientistNPC, AutoTurret turret) {
            if (turret == null || scientistNPC == null) return null;
            if (NpcManager.IsConvoyNpc(scientistNPC.displayName)) {
                if (!_config.enablePlayerTurret) return false;
                if (scientistNPC.isMounted) return false;
                else if (!convoyController.IsPlayerTurretCanAttackConvoy(turret)) return false;
            }
            return null;
        }
        object CanEntityTakeDamage(BasePlayer victim, HitInfo hitinfo) {
            if (convoyController == null || !_config.eventZone.isCreateZonePVP || hitinfo == null || !victim.IsRealPlayer()) return null;
            if (ZoneController.IsPlayerInZone(victim.userID) && hitinfo.InitiatorPlayer.IsRealPlayer() && ZoneController.IsPlayerInZone(hitinfo.InitiatorPlayer.userID)) return true;
            else return null;
        }
        object CanEntityTakeDamage(ScientistNPC entity, HitInfo info) {
            if (info == null || entity == null || !info.InitiatorPlayer.IsRealPlayer()) return null;
            if (NpcManager.IsConvoyNpc(entity.displayName) && convoyController.CanConvoyNpcTakeDamage(info)) {
                BaseVehicle baseVehicle = entity.GetMountedVehicle();
                if (baseVehicle != null && baseVehicle.IsDriver(entity)) {
                    convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                    return false;
                }
                convoyController.OnConvoyAttacked(info.InitiatorPlayer);
                return null;
            }
            return null;
        }
        object CanEntityTakeDamage(BasicCar victim, HitInfo hitinfo) {
            if (convoyController == null || victim == null || hitinfo == null) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(victim.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (convoyController.CanConvoyEntityTakeDamage(hitinfo, victim)) return true;
            else return false;
        }
        object CanEntityTakeDamage(ModularCar victim, HitInfo hitinfo) {
            if (convoyController == null || victim == null || victim.net == null || hitinfo == null || !hitinfo.InitiatorPlayer.IsRealPlayer()) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(victim.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (!PveModeAllowAction(hitinfo.InitiatorPlayer)) return false;
            return true;
        }
        object CanEntityTakeDamage(CustomBradley victim, HitInfo hitinfo) {
            if (convoyController == null || victim == null || victim.net == null || hitinfo == null || !hitinfo.InitiatorPlayer.IsRealPlayer()) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(victim.net.ID.Value);
            if (convoyVehicle != null) return true;
            return null;
        }
        object CanEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo hitinfo) {
            if (convoyController == null || baseVehicleModule == null || baseVehicleModule.Vehicle == null || baseVehicleModule.Vehicle.net == null || hitinfo == null || !hitinfo.InitiatorPlayer.IsRealPlayer()) return null;
            ConvoyVehicle convoyVehicle = convoyController.GetConvoyVehicleByEntityNetId(baseVehicleModule.Vehicle.net.ID.Value);
            if (convoyVehicle == null) return null;
            if (!PveModeAllowAction(hitinfo.InitiatorPlayer)) return false;
            return true;
        }
        object CanEntityTakeDamage(PatrolHelicopter entity, HitInfo hitinfo) {
            if (entity == null || hitinfo == null) return null;
            if (IsConvoyHeli(entity) && hitinfo.InitiatorPlayer != null) {
                if (!convoyController.CanConvoyEntityTakeDamage(hitinfo, entity)) return false;
            }
            return null;
        }
        object OnCreateDynamicPVP(string eventName, BradleyAPC entity) {
            if (convoyController == null || entity == null) return null;
            if (IsConvoyVehicle(entity)) return true;
            return null;
        }
        object OnCreateDynamicPVP(string eventName, PatrolHelicopter entity) {
            if (convoyController == null || entity == null) return null;
            if (IsConvoyHeli(entity)) return true;
            return null;
        }
        object OnBotReSpawnCrateDropped(HackableLockedCrate crate) {
            if (convoyController == null || crate == null || crate.net == null) return null;
            if (IsConvoyCrate(crate)) return true;
            return null;
        }
        object CanBradleySpawnNpc(BradleyAPC bradley) {
            if (convoyController == null || _config.betterNpcConfig.bradleyNpc || bradley == null || bradley.net == null) return null;
            if (convoyController.GetConvoyVehicleByEntityNetId(bradley.net.ID.Value) != null) return true;
            return null;
        }
        object CanHelicopterSpawnNpc(PatrolHelicopter helicopter) {
            if (convoyController == null || _config.betterNpcConfig.heliNpc || helicopter == null) return null;
            if (IsConvoyHeli(helicopter)) return true;
            return null;
        }
        private object OnRestoreUponDeath(BasePlayer player) {
            if (player == null) return null;
            if (_config.eventZone.blockRestoreUponDeath && ZoneController.IsPlayerInZone(player.userID)) return false;
            return null;
        }
#endregion OtherPLugins
#endregion Hooks
#region Commands
        [ChatCommand("convoystart")]
        void StartCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            if (arg != null && arg.Length >= 1) ConvoyLauncher.StartEvent(player, arg[0]);
            else ConvoyLauncher.StartEvent(player);
        }
        [ChatCommand("convoystop")]
        void StopCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            ConvoyLauncher.StopEvent();
        }
        [ConsoleCommand("convoystart")]
        void ConsoleStartCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            if (arg.Args != null && arg.Args.Length > 0) ConvoyLauncher.StartEvent(null, arg.Args[0]);
            ConvoyLauncher.StartEvent();
            Puts("Event activated");
        }
        [ConsoleCommand("convoystop")]
        void ConsoleStopCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() == null) ConvoyLauncher.StopEvent();
        }
        [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;
                        }
                        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) {
                        if (versionNumber.Patch == 0) {
                            PrintWarning("Some parameters in the config have been changed due to the addition of new functions!\nRead the changelog!");
                            _config.roadLength = 300;
                            _config.killConvoyAfterLoot = true;
                            _config.bradleyBuildingDamageScale = 1f;
                            _config.killTimeConvoyAfterLoot = 300;
                            _config.isAggressive = true;
                            _config.timeNotifications = new HashSet<int> {
                                300, 60, 30, 5
                            }
                            ;
                            for (int i = 0; i < _config.convoys.Count; i++) {
                                ConvoySetting convoySetting = _config.convoys[i];
                                convoySetting.speed = 5f;
                                if (convoySetting.name.Contains("hard")) {
                                    convoySetting.vehiclesOrder = new List<string> {
                                        "bradley_1", "modular_1", "sedan_1", "truck_1", "sedan_1", "modular_1", "bradley_1"
                                    }
                                    ;
                                }
                                else {
                                    convoySetting.vehiclesOrder = new List<string> {
                                        "bradley_1", "sedan_1", "truck_1", "sedan_1", "bradley_1"
                                    }
                                    ;
                                }
                            }
                            for (int i = 0; i < _config.modularConfiguration.Count; i++) {
                                ModularConfig modularConfig = _config.modularConfiguration[i];
                                modularConfig.changeUnlockTime = true;
                            }
                            for (int i = 0; i < _config.NPC.Count; i++) {
                                NpcConfig npcConfig = _config.NPC[i];
                                npcConfig.turretDamageScale = 1;
                                for (int a = 0; a < npcConfig.beltItems.Count; a++) {
                                    NpcBelt npcBelt = npcConfig.beltItems[a];
                                    npcBelt.ammo = "";
                                }
                            }
                        }
                        if (versionNumber.Patch < 9) {
                            _config.marker.useRingMarker = true;
                            _config.marker.useShopMarker = true;
                        }
                        versionNumber.Minor = 3;
                        versionNumber.Patch = 0;
                    }
                    if (versionNumber.Minor == 3) {
                        if (versionNumber.Patch == 0) {
                            foreach (SupportModularConfig supportModularConfig in _config.supportModularConfiguration) supportModularConfig.frontVehicleDistance = 10;
                            foreach (SedanConfig sedanConfig in _config.sedanConfiguration) sedanConfig.frontVehicleDistance = 10;
                            foreach (ModularConfig modularConfig in _config.modularConfiguration) modularConfig.frontVehicleDistance = 10;
                            foreach (BradleyConfig bradleyConfig in _config.bradleyConfiguration) bradleyConfig.frontVehicleDistance = 10;
                            _config.pveMode.showEventOwnerNameOnMap = true;
                        }
                        if (versionNumber.Patch <= 4) {
                            foreach (SupportModularConfig supportModularConfig in _config.supportModularConfiguration) supportModularConfig.numberOfNpc = 4;
                            foreach (SedanConfig sedanConfig in _config.sedanConfiguration) sedanConfig.numberOfNpc = 4;
                            foreach (ModularConfig modularConfig in _config.modularConfiguration) modularConfig.numberOfNpc = 4;
                            foreach (BradleyConfig bradleyConfig in _config.bradleyConfiguration) bradleyConfig.numberOfNpc = 6;
                        }
                        if (versionNumber.Patch <= 7) {
                            foreach (HeliConfig heliConfig in _config.heliesConfiguration) {
                                heliConfig.outsideTime = 30;
                            }
                        }
                        versionNumber.Minor = 4;
                        versionNumber.Patch = 0;
                    }
                    if (versionNumber.Minor == 4) {
                        if (versionNumber.Patch == 0) {
                            _config.enablePlayerTurret = true;
                        }
                    }
                }
                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();
            }
        }
        bool PveModeAllowAction(BasePlayer player) {
            if (!ins.plugins.Exists("PveMode") || !plugins.Exists("PveMode")) return true;
            if (ins.PveMode.Call("CanActionEvent", ins.Name, player) != null) return false;
            return true;
        }
        void CopySerializableFields<T>(T src, T dst) {
            FieldInfo[] srcFields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo field in srcFields) {
                object value = field.GetValue(src);
                field.SetValue(dst, value);
            }
        }
#endregion Method
#region Classes
        static class ConvoyLauncher {
            static Coroutine autoEventCoroutine;
            internal static void AutoStartEvent() {
                if (!ins._config.autoEvent) return;
                if (autoEventCoroutine != null) return;
                autoEventCoroutine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
            }
            static IEnumerator AutoEventCorountine() {
                yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(ins._config.minTimeBetweenEvent, ins._config.maxTimeBetweenEvent));
                StartEvent();
            }
            internal static void StartEvent(BasePlayer initiator = null, string presetName = "") {
                if (ins.convoyController != null) {
                    NotifyManager.PrintError(initiator, "EventActive_Exeption");
                    return;
                }
                ConvoySetting convoysetting = DefineEventConfig(presetName);
                if (convoysetting == null) {
                    NotifyManager.PrintError(initiator, "СonfigurationNotFound_Exeption");
                    StopEvent();
                    return;
                }
                ConvoyPath convoyPath = ConvoyPath.DefineConvoyPath(convoysetting.vehiclesOrder.Count);
                if (convoyPath == null) {
                    NotifyManager.PrintError(initiator, "RootNotFound_Exeption", convoysetting.name);
                    StopEvent();
                    return;
                }
                if (autoEventCoroutine != null) {
                    ServerMgr.Instance.StopCoroutine(autoEventCoroutine);
                    autoEventCoroutine = null;
                }
                GameObject gameObject = new GameObject();
                ins.convoyController = gameObject.AddComponent<ConvoyController>();
                ins.convoyController.Init(convoysetting, convoyPath);
            }
            static ConvoySetting DefineEventConfig(string eventPresetName) {
                if (eventPresetName != "") {
                    return ins._config.convoys.FirstOrDefault(x => x.name == eventPresetName);
                }
                else {
                    if (!ins._config.convoys.Any(x => x.on && x.chance != 0)) return null;
                    float sumChance = 0;
                    foreach (ConvoySetting eventConfig in ins._config.convoys) {
                        if (eventConfig.on) sumChance += eventConfig.chance;
                    }
                    float random = UnityEngine.Random.Range(0, sumChance);
                    foreach (ConvoySetting eventConfig in ins._config.convoys) {
                        if (eventConfig.on) {
                            random -= eventConfig.chance;
                            if (random <= 0) return eventConfig;
                        }
                    }
                    return null;
                }
            }
            internal static void StopEvent(bool isPluginUnloading = false) {
                if (ins.convoyController != null) {
                    ins.Unsubscribes();
                    GameObject.Destroy(ins.convoyController.gameObject);
                    ZoneController.ClearZoneData();
                    EconomyManager.SendBalance();
                    NotifyManager.SendMessageToAll("Finish", ins._config.prefix);
                    Interface.CallHook("OnConvoyStop");
                    if (ins._config.enableStartStopLogs) NotifyManager.PrintLogMessage("EventStop_Log");
                }
                if (!isPluginUnloading) AutoStartEvent();
                else if (autoEventCoroutine != null) ServerMgr.Instance.StopCoroutine(autoEventCoroutine);
            }
        }
        sealed class ConvoyController : FacepunchBehaviour {
            internal ConvoySetting convoySetting;
            internal List<ConvoyVehicle> convoyVehicles = new List<ConvoyVehicle>();
            internal HashSet<ConvoyTruck> trucks = new HashSet<ConvoyTruck>();
            internal List<ScientistNPC> roamNpc = new List<ScientistNPC>();
            HashSet<ulong> lootedCrates = new HashSet<ulong>();
            internal ConvoyHeli convoyHeli;
            HashSet<ulong> convoyAttackersIds = new HashSet<ulong>();
            ConvoyPath convoyPath;
            ConvoyMarker convoyMarker;
            Coroutine stopCoroutine;
            Coroutine eventCoroutine;
            int eventTime;
            int stopTime;
#region API
            internal bool CanConvoyEntityTakeDamage(HitInfo info, BaseEntity entity) {
                if (info.Initiator != null && info.Initiator is AutoTurret) return true;
                if (!info.InitiatorPlayer.IsRealPlayer()) return false;
                if (!ins.PveModeAllowAction(info.InitiatorPlayer)) return false;
                if (entity is PatrolHelicopter) {
                    if (Vector3.Distance(info.InitiatorPlayer.transform.position, entity.transform.position) >= ins._config.maxDamageDistance * 2) {
                        NotifyManager.SendMessageToPlayer(info.InitiatorPlayer, "Distance", info.InitiatorPlayer.UserIDString, ins._config.prefix);
                        return false;
                    }
                }
                else if (Vector3.Distance(info.InitiatorPlayer.transform.position, entity.transform.position) >= ins._config.maxDamageDistance) {
                    NotifyManager.SendMessageToPlayer(info.InitiatorPlayer, "Distance", info.InitiatorPlayer.UserIDString, ins._config.prefix);
                    return false;
                }
                return true;
            }
            internal bool CanConvoyNpcTakeDamage(HitInfo info) {
                if (info.ProjectileDistance >= ins._config.maxDamageDistance) {
                    NotifyManager.SendMessageToPlayer(info.InitiatorPlayer, "Distance", info.InitiatorPlayer.UserIDString, ins._config.prefix);
                    return false;
                }
                return true;
            }
            internal void OnConvoyVehicleDie(ConvoyVehicle convoyVehicle) {
                DefineFollow(convoyVehicle);
                if (!ConvoyHaveAnySecurityVehivcle()) {
                    OnConvoyAttacked();
                    NotifyManager.SendMessageToAll("VehiclesKill", ins._config.prefix);
                }
                convoyVehicles.Remove(convoyVehicle);
            }
            internal ConvoyVehicle GetConvoyVehicleByEntityNetId(ulong netID) {
                return convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null && x.baseEntity.net.ID.Value == netID);
            }
            internal ConvoyTruck GetTruckByCrateNetID(ulong crateNetID) {
                return trucks.FirstOrDefault(x => x != null && x.IsOwnCrate(crateNetID));
            }
            internal Vector3 GetConvoyPosition() {
                if (convoyVehicles == null || convoyVehicles.Count == 0) return Vector3.zero;
                ConvoyVehicle frontVehicle = convoyVehicles.FirstOrDefault(x => x != null && x.baseEntity != null);
                ConvoyVehicle lastVehicle = convoyVehicles.Last();
                if (frontVehicle != null && lastVehicle != null && lastVehicle.baseEntity != null) return (frontVehicle.baseEntity.transform.position + lastVehicle.baseEntity.transform.position) / 2;
                else if (frontVehicle != null) return frontVehicle.baseEntity.transform.position;
                return Vector3.zero;
            }
            internal bool ConvoyHaveAnySecurityVehivcle() {
                return convoyVehicles.Any(x => x != null && x.baseEntity != null && x is ConvoyTruck == false);
            }
            internal bool IsAnyCrateHacking() {
                return trucks.Any(x => x != null && x.IsCrateHacking());
            }
            internal bool IsConvoyHeli(ulong heliNetId) {
                return convoyHeli != n
// ... [Code preview truncated due to length. Full source in attached file] ...

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