C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.ConvoyExtensionMethods;
using Rust;
using Rust.Modular;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Facepunch;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Networking;
using static BaseVehicle;
using Random = UnityEngine.Random;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
[Info("Convoy", "Adem", "2.9.6")]
internal class Convoy : RustPlugin {
#region Variables
private const bool En = false;
private static Convoy _ins;
private EventController _eventController;
[PluginReference]
Plugin ArmoredTrain, NpcSpawn, GUIAnnouncements, DiscordMessages, Notify, PveMode, Economics, ServerRewards, IQEconomic, DynamicPVP, AlphaLoot, CustomLoot, Loottable;
private ProtectionProperties _protection;
private EventHeli _eventHeli;
private readonly HashSet<string> _subscribeMethods = new HashSet<string> {
"OnEntitySpawned", "OnExplosiveThrown", "CanExplosiveStick", "CanMountEntity", "CanDismountEntity", "OnPlayerSleep", "CanPickupEntity", "OnEntityTakeDamage", "OnEntityDeath", "OnEntityKill", "CanHelicopterTarget", "OnCustomNpcTarget", "CanBradleyApcTarget", "CanHackCrate", "CanLootEntity", "OnLootEntity", "OnLootEntityEnd", "OnEntityEnter", "OnCorpsePopulate", "OnCrateSpawned", "OnContainerPopulate", "CanPopulateLoot", "OnCustomLootContainer", "OnCustomLootNPC", "CanEntityBeTargeted", "CanEntityTakeDamage", "CanBradleySpawnNpc", "CanHelicopterSpawnNpc", "OnCreateDynamicPVP", "SetOwnerPveMode", "ClearOwnerPveMode", "OnSetupTurret", "OnLifeSupportSavingLife"
}
;
#endregion Variables
#region API
private bool IsConvoyVehicle(BaseEntity entity) {
if (_eventController == null || entity == null || entity.net == null) return false;
if (ConvoyPathVehicle.GetVehicleByNetId(entity.net.ID.Value) != null) return true;
BaseVehicleModule baseVehicleModule = entity as BaseVehicleModule;
if (baseVehicleModule != null) {
BaseVehicle baseVehicle = baseVehicleModule.Vehicle;
if (baseVehicle != null && baseVehicle.net != null) return ConvoyPathVehicle.GetVehicleByNetId(baseVehicle.net.ID.Value) != null;
}
return false;
}
private bool IsConvoyCrate(BaseEntity crate) {
if (_eventController == null || crate == null || crate.net == null) return false;
return _eventController.IsEventCrate(crate.net.ID.Value);
}
private bool IsConvoyHeli(PatrolHelicopter patrolHelicopter) {
if (_eventController == null || patrolHelicopter == null || patrolHelicopter.net == null) return false;
return EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value) != null;
}
private bool IsConvoyNpc(ScientistNPC scientistNpc) {
if (_eventController == null || scientistNpc == null || scientistNpc.net == null) return false;
return NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) != null;
}
#endregion API
#region Hooks
private void Init() {
Unsubscribes();
}
private void OnServerInitialized() {
_ins = this;
if (!NpcSpawnManager.IsNpcSpawnReady()) return;
UpdateConfig();
LoadDefaultMessages();
LoadData();
_protection = ScriptableObject.CreateInstance<ProtectionProperties>();
_protection.Add(1);
PrefabController.CachePrefabs();
GuiManager.LoadImages();
PathManager.StartCachingRouts();
EventLauncher.AutoStartEvent();
}
private void Unload() {
EventLauncher.StopEvent(true);
PathManager.OnPluginUnloaded();
_ins = null;
}
private void OnEntitySpawned(TimedExplosive timedExplosive) {
if (timedExplosive == null) return;
if (timedExplosive.ShortPrefabName == "maincannonshell") {
BradleyVehicle bradleyVehicle = ConvoyPathVehicle.GetClosestVehicle<BradleyVehicle>(timedExplosive.transform.position) as BradleyVehicle;
if (bradleyVehicle == null) return;
if (Vector3.Distance(bradleyVehicle.transform.position, timedExplosive.transform.position) < 5f) timedExplosive.SetCreatorEntity(bradleyVehicle.bradley);
}
}
private void OnExplosiveThrown(BasePlayer player, BaseEntity entity, ThrownWeapon item) {
if (!player.IsRealPlayer()) return;
ConvoyPathVehicle convoyPathVehicle = ConvoyPathVehicle.GetClosestVehicle<ConvoyPathVehicle>(player.transform.position);
if (convoyPathVehicle != null && Vector3.Distance(convoyPathVehicle.transform.position, player.transform.position) < 20f) _eventController.OnEventAttacked(player);
}
private object CanExplosiveStick(RFTimedExplosive rfTimedExplosive, BaseEntity entity) {
if (rfTimedExplosive == null || entity == null || entity.net == null) return null;
ConvoyPathVehicle convoyPathVehicle = ConvoyPathVehicle.GetVehicleByNetId(entity.net.ID.Value);
if (convoyPathVehicle != null && rfTimedExplosive.GetFrequency() > 0) return false;
return null;
}
private object CanMountEntity(BasePlayer player, BaseMountable entity) {
if (!player.IsRealPlayer() || entity == null) return null;
BaseEntity vehicle = entity.VehicleParent();
if (vehicle != null && ConvoyPathVehicle.GetVehicleByNetId(vehicle.net.ID.Value) != null) return true;
return null;
}
private object CanDismountEntity(BasePlayer player, BaseMountable baseMountable) {
if (baseMountable == null || player == null || player.userID.IsSteamId()) return null;
BaseVehicle baseVehicle = baseMountable.VehicleParent();
if (baseVehicle == null || baseVehicle.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(baseVehicle.net.ID.Value) != null) return true;
return null;
}
private void OnPlayerSleep(BasePlayer player) {
if (!player.IsRealPlayer()) return;
ZoneController.OnPlayerLeaveZone(player);
}
private object CanPickupEntity(BasePlayer player, Door door) {
if (door == null || door.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(door.net.ID.Value) == null) return null;
return false;
}
private object OnEntityTakeDamage(BaseVehicle baseVehicle, HitInfo info) {
if (baseVehicle == null || baseVehicle.net == null || info == null) return null;
return CheckIfVehicleAttacked(baseVehicle, info);
}
private object OnEntityTakeDamage(BradleyAPC bradley, HitInfo info) {
if (bradley == null || bradley.net == null || info == null) return null;
return CheckIfVehicleAttacked(bradley, info);
}
private object OnEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo info) {
if (!baseVehicleModule.IsExists()) return null;
BaseModularVehicle modularCar = baseVehicleModule.Vehicle;
if (modularCar == null || modularCar.net == null) return null;
ModularCarVehicle modularCarVehicle = ConvoyPathVehicle.GetVehicleByNetId(modularCar.net.ID.Value) as ModularCarVehicle;
if (modularCarVehicle == null) return null;
if (CheckIfVehicleAttacked(modularCar, info) == null) {
modularCar.health -= info.damageTypes.Total() * modularCarVehicle.ModularCarConfig.DamageScale / 5;
if (!modularCar.IsDestroyed && modularCar.health <= 0) modularCar.Kill(BaseNetworkable.DestroyMode.Gib);
for (int i = 0; i <= modularCar.moduleSockets.Count; i++) {
if (modularCar.TryGetModuleAt(i, out BaseVehicleModule module)) module.SetHealth(module._maxHealth * modularCar.health / modularCar._maxHealth);
}
}
return true;
}
private object CheckIfVehicleAttacked(BaseCombatEntity entity, HitInfo info) {
if (ConvoyPathVehicle.GetVehicleByNetId(entity.net.ID.Value) == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return true;
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, entity, true)) return true;
_eventController.OnEventAttacked(info.InitiatorPlayer);
return null;
}
private object OnEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
if (autoTurret == null || autoTurret.net == null || info == null) return null;
return CheckIfConvoyChildAttacked(autoTurret, info);
}
private object OnEntityTakeDamage(Door door, HitInfo info) {
if (door == null || door.net == null || info == null) return null;
return CheckIfConvoyChildAttacked(door, info);
}
private object OnEntityTakeDamage(SamSite samSite, HitInfo info) {
if (samSite == null || samSite.net == null || info == null) return null;
return CheckIfConvoyChildAttacked(samSite, info);
}
private object CheckIfConvoyChildAttacked(BaseCombatEntity entity, HitInfo info) {
if (ConvoyPathVehicle.GetVehicleByChildNetId(entity.net.ID.Value) == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return true;
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, entity, true)) return true;
_eventController.OnEventAttacked(info.InitiatorPlayer);
return null;
}
private object OnEntityTakeDamage(ScientistNPC scientistNpc, HitInfo info) {
if (scientistNpc == null || scientistNpc.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return null;
if (NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) == null) return null;
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, scientistNpc, true)) {
info.damageTypes.ScaleAll(0f);
return true;
}
if (scientistNpc.isMounted) info.damageTypes.ScaleAll(10f);
_eventController.OnEventAttacked(info.InitiatorPlayer);
if (info.WeaponPrefab != null && _eventController.EventConfig.WeaponToScaleDamageNpc.TryGetValue(info.WeaponPrefab.ShortPrefabName, out float weaponDamageScale)) info.damageTypes.ScaleAll(weaponDamageScale);
return null;
}
private object OnEntityTakeDamage(StorageContainer storageContainer, HitInfo info) {
if (storageContainer == null || storageContainer.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(storageContainer.net.ID.Value) != null) return true;
return null;
}
private object OnEntityTakeDamage(Fridge fridge, HitInfo info) {
if (fridge == null || fridge.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(fridge.net.ID.Value) != null) return true;
return null;
}
private object OnEntityTakeDamage(PatrolHelicopter patrolHelicopter, HitInfo info) {
if (patrolHelicopter == null || patrolHelicopter.net == null || info == null) return null;
EventHeli eventHeli = EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value);
if (eventHeli == null) return null;
if (info.InitiatorPlayer.IsRealPlayer()) {
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, patrolHelicopter, true)) return true;
else {
eventHeli.OnHeliAttacked(info.InitiatorPlayer.userID);
_eventController.OnEventAttacked(info.InitiatorPlayer);
}
}
return null;
}
private void OnEntityTakeDamage(BuildingBlock buildingBlock, HitInfo info) {
if (buildingBlock == null || info == null) return;
CustomBradley customBradley = info.Initiator as CustomBradley;
if (customBradley == null) return;
if (customBradley.BradleyConfig.BradleyBuildingDamageScale >= 0) info.damageTypes.ScaleAll(customBradley.BradleyConfig.BradleyBuildingDamageScale);
}
private void OnEntityDeath(BradleyAPC bradleyApc, HitInfo info) {
if (bradleyApc == null || bradleyApc.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
ConvoyPathVehicle convoyPathVehicle = ConvoyPathVehicle.GetVehicleByNetId(bradleyApc.net.ID.Value);
if (convoyPathVehicle != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.BradleyPoint);
}
private void OnEntityDeath(BasicCar basicCar, HitInfo info) {
if (basicCar == null || basicCar.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (ConvoyPathVehicle.GetVehicleByNetId(basicCar.net.ID.Value) != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.SedanPoint);
}
private void OnEntityDeath(ModularCar modularCar, HitInfo info) {
if (modularCar == null || modularCar.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (ConvoyPathVehicle.GetVehicleByNetId(modularCar.net.ID.Value) != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.ModularCarPoint);
}
private void OnEntityDeath(PatrolHelicopter patrolHelicopter, HitInfo info) {
if (patrolHelicopter == null || patrolHelicopter.net == null) return;
EventHeli eventHeli = EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value);
if (eventHeli != null && eventHeli.lastAttackedPlayer != 0) EconomyManager.AddBalance(eventHeli.lastAttackedPlayer, _config.SupportedPluginsConfig.EconomicsConfig.HeliPoint);
}
private void OnEntityDeath(AutoTurret autoTurret, HitInfo info) {
if (autoTurret == null || autoTurret.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (ConvoyPathVehicle.GetVehicleByChildNetId(autoTurret.net.ID.Value) != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.TurretPoint);
}
private void OnEntityDeath(SamSite samSite, HitInfo info) {
if (samSite == null || samSite.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (ConvoyPathVehicle.GetVehicleByChildNetId(samSite.net.ID.Value) != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.SamsitePoint);
}
private void OnEntityDeath(ScientistNPC scientistNpc, HitInfo info) {
if (scientistNpc == null || scientistNpc.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.SupportedPluginsConfig.EconomicsConfig.NpcPoint);
}
private void OnEntityKill(BaseMountable baseMountable) {
if (baseMountable == null || baseMountable.net == null) return;
BaseVehicle baseVehicle = baseMountable as BaseVehicle;
if (baseVehicle != null) {
ConvoyPathVehicle convoyPathVehicle = ConvoyPathVehicle.GetVehicleByNetId(baseVehicle.net.ID.Value);
if (convoyPathVehicle == null) return;
foreach (MountPointInfo mountPointInfo in baseVehicle.allMountPoints) {
if (mountPointInfo == null || mountPointInfo.mountable == null) continue;
BasePlayer mountedPlayer = mountPointInfo.mountable.GetMounted();
if (mountedPlayer.IsExists() && !mountedPlayer.userID.IsSteamId()) mountedPlayer.Kill();
}
if (EventLauncher.IsEventActive() && _ins._eventController.IsFullySpawned()) convoyPathVehicle.DropCrates();
}
if (ConvoyPathVehicle.GetVehicleByChildNetId(baseMountable.net.ID.Value) != null) {
if (baseMountable._mounted.IsExists()) baseMountable._mounted.Kill();
}
}
private void OnEntityKill(BradleyAPC bradleyApc) {
if (bradleyApc == null || bradleyApc.net == null) return;
ConvoyPathVehicle convoyPathVehicle = ConvoyPathVehicle.GetVehicleByNetId(bradleyApc.net.ID.Value);
if (convoyPathVehicle != null && EventLauncher.IsEventActive() && _ins._eventController.IsFullySpawned()) convoyPathVehicle.DropCrates();
}
private object CanHelicopterTarget(PatrolHelicopterAI heli, BasePlayer player) {
if (heli == null || heli.helicopterBase == null || heli.helicopterBase.net == null) return null;
EventHeli eventHeli = EventHeli.GetEventHeliByNetId(heli.helicopterBase.net.ID.Value);
if (eventHeli != null && !eventHeli.IsHeliCanTarget()) return false;
if (player.IsSleeping() || player.InSafeZone()) return false;
return null;
}
private object OnCustomNpcTarget(ScientistNPC scientistNpc, BasePlayer player) {
if (_eventController == null || scientistNpc == null || scientistNpc.net == null) return null;
if (NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) == null) return null;
if (!_eventController.IsAggressive()) return false;
else if (player.IsSleeping() || (player.InSafeZone() && !player.IsHostile())) return false;
return null;
}
private object CanBradleyApcTarget(BradleyAPC bradley, BaseEntity entity) {
if (bradley == null || bradley.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(bradley.net.ID.Value) == null) return null;
BasePlayer targetPlayer = entity as BasePlayer;
if (!targetPlayer.IsRealPlayer()) return false;
if (targetPlayer.IsSleeping() || (targetPlayer.InSafeZone() && !targetPlayer.IsHostile())) return false;
return null;
}
private object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
if (player == null || crate == null || crate.net == null) return null;
if (_eventController.IsEventCrate(crate.net.ID.Value)) {
if (!_eventController.IsPlayerCanLoot(player, true)) {
_eventController.SwitchAggressive(true);
return true;
}
EconomyManager.AddBalance(player.userID, _config.SupportedPluginsConfig.EconomicsConfig.LockedCratePoint);
}
return null;
}
private object CanLootEntity(BasePlayer player, StorageContainer storageContainer) {
return CanLootEventEntity(player, storageContainer);
}
private object CanLootEntity(BasePlayer player, Fridge fridge) {
return CanLootEventEntity(player, fridge);
}
private object CanLootEventEntity(BasePlayer player, BaseEntity entity) {
if (player == null || entity == null || entity.net == null) return null;
if (_eventController.IsEventCrate(entity.net.ID.Value)) {
if (_eventController.IsPlayerCanLoot(player, true)) return null;
_eventController.SwitchAggressive(true);
return true;
}
else {
BaseVehicleModule baseVehicleModule = entity.GetParentEntity() as BaseVehicleModule;
if (baseVehicleModule == null || baseVehicleModule.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(baseVehicleModule.net.ID.Value) != null) return true;
}
return null;
}
private void OnLootEntity(BasePlayer player, StorageContainer storageContainer) {
if (player == null || storageContainer == null || storageContainer.net == null) return;
if (_eventController.IsEventCrate(storageContainer.net.ID.Value)) _eventController.OnEventCrateLooted(storageContainer, player.userID);
}
private void OnLootEntity(BasePlayer player, Fridge fridge) {
if (player == null || fridge == null || fridge.net == null) return;
if (_eventController.IsEventCrate(fridge.net.ID.Value)) _eventController.OnEventCrateLooted(fridge, player.userID);
}
private void OnLootEntityEnd(BasePlayer player, StorageContainer storageContainer) {
if (storageContainer == null || storageContainer.net == null || !player.IsRealPlayer()) return;
if (storageContainer is not LootContainer && _eventController.IsEventCrate(storageContainer.net.ID.Value)) if (storageContainer.inventory.IsEmpty()) storageContainer.Kill();
}
private void OnLootEntityEnd(BasePlayer player, Fridge fridge) {
if (fridge == null || fridge.net == null || !player.IsRealPlayer()) return;
if (_eventController.IsEventCrate(fridge.net.ID.Value)) if (fridge.inventory.IsEmpty()) fridge.Kill();
}
private object OnEntityEnter(TriggerVehiclePush trigger, BaseCombatEntity entity) {
if (trigger == null || entity == null || entity.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(entity.net.ID.Value) != null) return true;
return null;
}
private object OnEntityEnter(TriggerPath trigger, BradleyAPC bradleyApc) {
if (bradleyApc == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(bradleyApc.net.ID.Value) == null) return null;
NextTick(() => bradleyApc.myRigidBody.isKinematic = false);
return null;
}
private object OnEntityEnter(TriggerPath trigger, TravellingVendor travellingVendor) {
if (travellingVendor == null || travellingVendor.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(travellingVendor.net.ID.Value) == null) return null;
Rigidbody rigidbody = travellingVendor.GetComponentInChildren<Rigidbody>();
NextTick(() => {
rigidbody.isKinematic = false;
}
);
return true;
}
private object OnEntityEnter(TargetTrigger trigger, ScientistNPC scientistNpc) {
if (trigger == null || scientistNpc == null || scientistNpc.net == null) return null;
AutoTurret autoTurret = trigger.GetComponentInParent<AutoTurret>();
if (autoTurret == null || autoTurret.net == null) return null;
if (NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) == null) return null;
if (scientistNpc.isMounted || !_config.BehaviorConfig.IsPlayerTurretEnable) return true;
return null;
}
private object OnEntityEnter(TriggerVehiclePush trigger, TravellingVendor travellingVendor) {
if (trigger == null || travellingVendor == null || travellingVendor.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(travellingVendor.net.ID.Value)) return true;
return null;
}
#region Loot
private void OnCorpsePopulate(ScientistNPC scientistNpc, NPCPlayerCorpse corpse) {
if (scientistNpc == null || scientistNpc.net == null || corpse == null) return;
EntityPresetInfo entityPresetInfo = scientistNpc.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return;
NpcConfig npcConfig = NpcSpawnManager.GetNpcConfigByPresetName(entityPresetInfo.presetName);
if (npcConfig == null) return;
LootController.UpdateNpcCorpse(corpse, npcConfig);
}
private void OnCrateSpawned(BradleyAPC bradleyApc, LockedByEntCrate crate) {
if (bradleyApc == null || crate == null) return;
EntityPresetInfo entityPresetInfo = bradleyApc.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return;
BradleyConfig bradleyConfig = _config.BradleyConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (bradleyConfig == null) return;
if (bradleyConfig.InstCrateOpen) {
crate.SetLockingEnt(null);
crate.SetLocked(false);
}
PveModeManager.AddCrate(crate.net.ID.Value);
_eventController.AddEventCrate(crate);
LootController.UpdateHeliOrBradleyCrate(crate, bradleyConfig.LootTableConfig, bradleyConfig.PresetName);
}
private void OnCrateSpawned(PatrolHelicopter patrolHelicopter, LockedByEntCrate crate) {
if (patrolHelicopter == null || crate == null) return;
EntityPresetInfo entityPresetInfo = patrolHelicopter.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return;
HeliConfig heliConfig = _config.HeliConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (heliConfig == null) return;
if (heliConfig.InstCrateOpen) {
crate.SetLockingEnt(null);
crate.SetLocked(false);
}
PveModeManager.AddCrate(crate.net.ID.Value);
_eventController.AddEventCrate(crate);
LootController.UpdateHeliOrBradleyCrate(crate, heliConfig.LootTableConfig, heliConfig.PresetName);
}
#region LootTablePlugin
private object OnContainerPopulate(LootContainer lootContainer) {
if (lootContainer == null) return null;
LockedByEntCrate lockedByEntCrate = lootContainer as LockedByEntCrate;
if (lockedByEntCrate != null) {
LootTableConfig lootTableConfig = null;
if (_eventHeli != null && Vector3.Distance(_eventHeli.transform.position, lockedByEntCrate.transform.position) < 15f) lootTableConfig = _eventHeli.HeliConfig.LootTableConfig;
if (lootTableConfig == null) {
ConvoyPathVehicle closestVehicle = ConvoyPathVehicle.GetClosestVehicle<BradleyVehicle>(lockedByEntCrate.transform.position);
if (closestVehicle == null) return null;
BradleyVehicle bradleyVehicle = closestVehicle as BradleyVehicle;
if (bradleyVehicle == null) return null;
if (Vector3.Distance(bradleyVehicle.transform.position, lockedByEntCrate.transform.position) > 15f) return null;
lootTableConfig = bradleyVehicle.BradleyConfig.LootTableConfig;
}
if (lootTableConfig == null) return null;
if (!lootTableConfig.IsLoottablePlugin) return true;
return null;
}
EntityPresetInfo entityPresetInfo = lootContainer.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
CrateConfig crateConfig = _config.CrateConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (crateConfig == null) return null;
if (!crateConfig.LootTableConfig.IsLoottablePlugin) return true;
return null;
}
private object OnCorpsePopulate(NPCPlayerCorpse corpse) {
if (corpse == null) return null;
EntityPresetInfo entityPresetInfo = corpse.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
NpcConfig npcConfig = _config.NpcConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (npcConfig == null) return null;
if (!npcConfig.LootTableConfig.IsLoottablePlugin) return true;
return null;
}
#endregion LootTablePlugin
#region AlphaLoot
private object CanPopulateLoot(LootContainer lootContainer) {
if (lootContainer == null) return null;
EntityPresetInfo entityPresetInfo = lootContainer.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
LockedByEntCrate lockedByEntCrate = lootContainer as LockedByEntCrate;
if (lockedByEntCrate != null) {
LootTableConfig lootTableConfig = null;
BradleyConfig bradleyConfig = _config.BradleyConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (bradleyConfig != null) lootTableConfig = bradleyConfig.LootTableConfig;
if (lootTableConfig == null) {
HeliConfig heliConfig = _config.HeliConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (heliConfig != null) lootTableConfig = heliConfig.LootTableConfig;
}
if (lootTableConfig == null) return null;
if (!lootTableConfig.IsAlphaLoot) return true;
return null;
}
CrateConfig crateConfig = _config.CrateConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (crateConfig == null) return null;
if (!crateConfig.LootTableConfig.IsAlphaLoot) return true;
return null;
}
private object CanPopulateLoot(ScientistNPC scientistNpc, NPCPlayerCorpse corpse) {
if (corpse == null) return null;
EntityPresetInfo entityPresetInfo = corpse.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
NpcConfig npcConfig = _config.NpcConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (npcConfig == null) return null;
if (!npcConfig.LootTableConfig.IsAlphaLoot) return true;
return null;
}
#endregion AlphaLoot
#region CustomLoot
private object OnCustomLootContainer(NetworkableId net) {
BaseEntity crateEntity = _eventController.GetCrateByNetId(net.Value);
if (crateEntity == null) return null;
EntityPresetInfo entityPresetInfo = crateEntity.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
LockedByEntCrate lockedByEntCrate = crateEntity as LockedByEntCrate;
if (lockedByEntCrate != null) {
LootTableConfig lootTableConfig = null;
BradleyConfig bradleyConfig = _config.BradleyConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (bradleyConfig != null) lootTableConfig = bradleyConfig.LootTableConfig;
if (lootTableConfig == null) {
HeliConfig heliConfig = _config.HeliConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (heliConfig != null) lootTableConfig = heliConfig.LootTableConfig;
}
if (lootTableConfig == null) return null;
if (!lootTableConfig.IsCustomLootPlugin) return true;
return null;
}
CrateConfig crateConfig = _config.CrateConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (crateConfig == null) return null;
if (!crateConfig.LootTableConfig.IsCustomLootPlugin) return true;
return null;
}
private object OnCustomLootNPC(NetworkableId net) {
ScientistNPC scientistNpc = NpcSpawnManager.GetScientistByNetId(net.Value);
if (scientistNpc == null) return null;
EntityPresetInfo entityPresetInfo = scientistNpc.GetComponent<EntityPresetInfo>();
if (entityPresetInfo == null) return null;
NpcConfig npcConfig = _config.NpcConfigs.FirstOrDefault(x => x.PresetName == entityPresetInfo.presetName);
if (npcConfig == null) return null;
if (!npcConfig.LootTableConfig.IsCustomLootPlugin) return true;
return null;
}
#endregion CustomLoot
#endregion Loot
#region OtherPlugins
private object CanPveModeAllowDamage(AutoTurret autoTurret, HitInfo info) {
if (_eventController == null || autoTurret == null || autoTurret.net == null || info == null || info.InitiatorPlayer == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(autoTurret.net.ID.Value) == null) return null;
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, autoTurret, true)) return true;
return null;
}
private object CanPveModeAllowDamage(SamSite samSite, HitInfo info) {
if (_eventController == null || samSite == null || samSite.net == null || info == null || info.InitiatorPlayer == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(samSite.net.ID.Value) == null) return null;
if (!_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, samSite, true)) return true;
return null;
}
private object CanEntityBeTargeted(BasePlayer player, AutoTurret turret) {
if (_eventController == null || turret == null || turret.net == null || turret.OwnerID != 0) return null;
if (!_eventController.IsEventTurret(turret.net.ID.Value)) return null;
if (!player.IsRealPlayer()) return false;
else if (!_eventController.IsAggressive()) return false;
else if (!PveModeManager.IsPveModDefaultBlockAction(player)) return true;
return null;
}
private object CanEntityBeTargeted(PlayerHelicopter playerHelicopter, SamSite samSite) {
if (_eventController == null || samSite == null || samSite.net == null || samSite.OwnerID != 0) return null;
if (!_eventController.IsEventSamSite(samSite.net.ID.Value)) return null;
if (!_eventController.IsAggressive()) return false;
return true;
}
private object CanEntityTakeDamage(Bike bike, HitInfo info) {
if (_eventController == null || info == null || !bike.IsExists() || bike.net == null) return null;
return CanConvoyVehicleTakeDamage(bike, info);
}
private object CanEntityTakeDamage(ModularCar modularCar, HitInfo info) {
if (_eventController == null || info == null || !modularCar.IsExists() || modularCar.net == null) return null;
return CanConvoyVehicleTakeDamage(modularCar, info);
}
private object CanEntityTakeDamage(BaseVehicleModule baseVehicleModule, HitInfo info) {
if (_eventController == null || info == null || !baseVehicleModule.IsExists() || baseVehicleModule.net == null) return null;
BaseModularVehicle modularCar = baseVehicleModule.Vehicle;
if (modularCar == null || modularCar.net == null) return null;
return CanConvoyVehicleTakeDamage(modularCar, info);
}
private object CanEntityTakeDamage(BradleyAPC bradleyApc, HitInfo info) {
if (_eventController == null || info == null || !bradleyApc.IsExists() || bradleyApc.net == null) return null;
return CanConvoyVehicleTakeDamage(bradleyApc, info);
}
private object CanEntityTakeDamage(BasicCar basicCar, HitInfo info) {
if (_eventController == null || info == null || !basicCar.IsExists() || basicCar.net == null) return null;
return CanConvoyVehicleTakeDamage(basicCar, info);
}
private object CanConvoyVehicleTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (ConvoyPathVehicle.GetVehicleByNetId(entity.net.ID.Value) == null) return null;
if (info.InitiatorPlayer.IsRealPlayer()) {
if (_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, entity, shouldSendMessages : false) && !PveModeManager.IsPveModDefaultBlockAction(info.InitiatorPlayer)) return true;
}
return false;
}
private object CanEntityTakeDamage(SamSite samSite, HitInfo info) {
if (_eventController == null || info == null || !samSite.IsExists() || samSite.net == null) return null;
return CheckTruePveDamageToConvoyChild(samSite, info);
}
private object CanEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
if (_eventController == null || info == null || !autoTurret.IsExists() || autoTurret.net == null) return null;
return CheckTruePveDamageToConvoyChild(autoTurret, info);
}
private object CanEntityTakeDamage(Door door, HitInfo info) {
if (door == null || door.net == null || info == null) return null;
return CheckTruePveDamageToConvoyChild(door, info);
}
private object CheckTruePveDamageToConvoyChild(BaseCombatEntity entity, HitInfo info) {
if (ConvoyPathVehicle.GetVehicleByChildNetId(entity.net.ID.Value) == null) return null;
if (info.InitiatorPlayer.IsRealPlayer()) {
if (_eventController.IsPlayerCanDealDamage(info.InitiatorPlayer, entity, shouldSendMessages : true) && !PveModeManager.IsPveModDefaultBlockAction(info.InitiatorPlayer)) return true;
else return false;
}
else return false;
}
private object CanEntityTakeDamage(BasePlayer victim, HitInfo info) {
if (info == null || info.Initiator == null || info.Initiator.net == null) return null;
if (victim.IsRealPlayer()) {
if (_config.ZoneConfig.IsPvpZone && !_config.SupportedPluginsConfig.PveMode.Enable) {
if (info.InitiatorPlayer.IsRealPlayer() && ZoneController.IsPlayerInZone(info.InitiatorPlayer.userID) && ZoneController.IsPlayerInZone(victim.userID)) return true;
}
if (info.Initiator is AutoTurret or SamSite) {
if (ConvoyPathVehicle.GetVehicleByChildNetId(info.Initiator.net.ID.Value) != null) return true;
}
}
ScientistNPC scientistNpc = victim as ScientistNPC;
if (scientistNpc != null && scientistNpc.net != null && NpcSpawnManager.GetScientistByNetId(scientistNpc.net.ID.Value) != null) {
AutoTurret autoTurret = info.Initiator as AutoTurret;
if (autoTurret != null && autoTurret.net != null && !_eventController.IsEventTurret(autoTurret.net.ID.Value)) {
if (_config.SupportedPluginsConfig.PveMode.Enable) return null;
return true;
}
}
return null;
}
private object CanEntityTakeDamage(PlayerHelicopter playerHelicopter, HitInfo info) {
if (info == null || info.Initiator == null || info.Initiator.net == null) return null;
if (info.Initiator is SamSite) {
if (ConvoyPathVehicle.GetVehicleByChildNetId(info.Initiator.net.ID.Value) != null) return true;
}
return null;
}
private object CanBradleySpawnNpc(BradleyAPC bradley) {
if (_eventController == null || bradley == null || bradley.net == null) return null;
if (!_config.SupportedPluginsConfig.BetterNpcConfig.BradleyNpc && ConvoyPathVehicle.GetVehicleByNetId(bradley.net.ID.Value) != null) return true;
return null;
}
private object CanHelicopterSpawnNpc(PatrolHelicopter helicopter) {
if (_eventController == null || helicopter == null || helicopter.net == null) return null;
if (!_config.SupportedPluginsConfig.BetterNpcConfig.HeliNpc && EventHeli.GetEventHeliByNetId(helicopter.net.ID.Value) != null) return true;
return null;
}
private object OnCreateDynamicPVP(string eventName, PatrolHelicopter patrolHelicopter) {
if (_eventController == null || patrolHelicopter == null || patrolHelicopter.net == null) return null;
if (EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value) != null) return true;
return null;
}
private object OnCreateDynamicPVP(string eventName, BradleyAPC bradleyApc) {
if (_eventController == null || bradleyApc == null || bradleyApc.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByNetId(bradleyApc.net.ID.Value)) return true;
return null;
}
private void SetOwnerPveMode(string shortname, BasePlayer player) {
if (_eventController == null || string.IsNullOrEmpty(shortname) || shortname != Name || !player.IsRealPlayer()) return;
if (shortname == Name) PveModeManager.OnNewOwnerSet(player);
}
private void ClearOwnerPveMode(string shortname) {
if (_eventController == null || string.IsNullOrEmpty(shortname)) return;
if (shortname == Name) PveModeManager.OnOwnerDeleted();
}
private object OnSetupTurret(AutoTurret autoTurret) {
if (autoTurret == null || autoTurret.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(autoTurret.net.ID.Value) != null) return true;
return null;
}
private object OnSetupTurret(SamSite samSite) {
if (samSite == null || samSite.net == null) return null;
if (ConvoyPathVehicle.GetVehicleByChildNetId(samSite.net.ID.Value) != null) return true;
return null;
}
private object OnLifeSupportSavingLife(BasePlayer player) {
if (player == null) return null;
if (!_config.SupportedPluginsConfig.LifeSupportConfig.IsDisabled) return null;
if (ZoneController.IsPlayerInZone(player.userID)) return true;
return null;
}
#endregion OtherPlugins
#endregion Hooks
#region Commands
[ChatCommand("convoystart")]
private void ChatStartCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (arg == null || arg.Length == 0) EventLauncher.DelayStartEvent(false, player);
else {
string eventPresetName = arg[0];
EventLauncher.DelayStartEvent(false, player, eventPresetName);
}
}
[ConsoleCommand("convoystart")]
private void ConsoleStartEventCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
if (arg == null || arg.Args == null || arg.Args.Length == 0) {
EventLauncher.DelayStartEvent();
}
else {
string eventPresetName = arg.Args[0];
EventLauncher.DelayStartEvent(presetName : eventPresetName);
}
}
[ChatCommand("convoystop")]
private void ChatStopCommand(BasePlayer player, string command, string[] arg) {
if (player.IsAdmin) EventLauncher.StopEvent();
}
[ConsoleCommand("convoystop")]
private void ConsoleStopEventCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
EventLauncher.StopEvent();
}
[ChatCommand("convoyroadblock")]
private void ChatRoadBlockCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) 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 <color=#ce3f27>not found</color>.Step onto the required road and enter the command again.");
return;
}
int index = TerrainMeta.Path.Roads.IndexOf(blockRoad);
if (!_config.PathConfig.BlockRoads.Add(index)) {
NotifyManager.SendMessageToPlayer(player, $"{_config.Prefix} The road is already <color=#ce3f27>blocked</color>");
return;
}
SaveConfig();
NotifyManager.SendMessageToPlayer(player, $"{_config.Prefix} The road with the index <color=#738d43>{index}</color> is <color=#ce3f27>blocked</color>");
}
[ChatCommand("convoyshowpath")]
private void ChatShowPathCommand(BasePlayer player, string command, string[] arg) {
if (player.IsAdmin) PathManager.DrawPath(PathManager.CurrentPath, player);
}
[ChatCommand("convoypathstart")]
private void ChatPathStartCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
PathRecorder.StartRecordingRoute(player);
}
[ChatCommand("convoypathsave")]
private void ChatPathSaveCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (arg.Length == 0) {
NotifyManager.SendMessageToPlayer(player, "CustomRouteDescription", _ins._config.Prefix);
return;
}
string pathName = arg[0];
PathRecorder.TrySaveRoute(player.userID, pathName);
}
[ChatCommand("convoypathcancel")]
private void ChatPathCancelCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
PathRecorder.TryCancelRoute(player.userID);
}
[ChatCommand("convoystartmoving")]
private void ChatStartMovingCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
_ins._eventController.SwitchMoving(true);
}
[ChatCommand("convoystopmoving")]
private void ChatStopMovingCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
_ins._eventController.SwitchMoving(false);
}
#endregion Commands
#region Methods
private void Unsubscribes() {
foreach (string hook in _subscribeMethods) Unsubscribe(hook);
}
private void Subscribes() {
foreach (string hook in _subscribeMethods) Subscribe(hook);
}
private static void Debug(params object[] arg) {
string result = "";
foreach (object obj in arg) if (obj != null) result += obj.ToString() + " ";
_ins.Puts(result);
}
#endregion Methods
#region Classes
private static class EventLauncher {
private static Coroutine _autoEventCoroutine;
private static Coroutine _delayedEventStartCoroutine;
public static bool IsEventActive() {
return _ins != null && _ins._eventController != null;
// ... [Code preview truncated due to length. Full source in attached file] ...