C#:
using System.Collections.Generic;
using Newtonsoft.Json;
using CompanionServer.Handlers;
using Oxide.Plugins.ArmoredTrainExtensionMethods;
using UnityEngine;
using System;
using Oxide.Core.Plugins;
using Network;
using Rust;
using System.Collections;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
///Скачано с дискорд сервера Rust Edit [PRO+]
///discord.gg/9vyTXsJyKR
namespace Oxide.Plugins {
[Info("ArmoredTrain", "discord.gg/9vyTXsJyKR", "1.2.4")]
class ArmoredTrain : RustPlugin {
[PluginReference]
Plugin NpcSpawn, PveMode, GUIAnnouncements, DiscordMessages;
#region Variables
const bool en = true;
static ArmoredTrain ins;
Coroutine autoEventCoroutine;
Train train;
bool isEventActive = false;
bool underGround = false;
internal List<Transform> railTransformList = new List<Transform>();
HashSet<string> subscribeMethods = new HashSet<string> {
"CanBradleyApcTarget", "OnEntityTakeDamage", "OnButtonPress", "OnTurretTarget", "CanLootEntity", "CanHackCrate", "OnLootEntity", "OnEntityDeath", "OnEntityKill", "OnLootEntity", "OnCorpsePopulate", "OnTrainCarUncouple", "OnEntitySpawned", "CanTrainCarCouple", "CanMountEntity", "OnSamSiteModeToggle"
}
;
Coroutine startEventCoroutine;
#endregion Variables
#region ExternalAPI
bool IsArmoredTrainActive() => isEventActive;
bool StopArmoredTrain() {
if (!isEventActive) return false;
train.StopTrain(null);
return true;
}
bool StartArmoredTrainEvent() {
if (isEventActive) return false;
StartEvent();
return true;
}
bool EndArmoredTrainEvent() {
if (!isEventActive) return false;
EndEvent();
return true;
}
Vector3 ArmoredTrainLocomotivePosition() {
if (!isEventActive) return Vector3.zero;
return train.locomotive.trainEngine.transform.position;
}
bool IsTrainBradley(uint netID) {
if (!isEventActive) return false;
return train.IsTrainBradley(netID);
}
bool IsTrainHeli(uint netID) {
if (!isEventActive) return false;
return train.IsTrainHeli(netID);
}
bool IsTrainCrate(uint netID) {
if (!isEventActive) return false;
return train.IsTrainCrate(netID);
}
bool IsTrainSamSite(uint netID) {
if (!isEventActive) return false;
return train.IsTrainSamSite(netID);
}
bool IsTrainWagon(uint netID) {
if (!isEventActive) return false;
return train.IsTrainWagon(netID);
}
bool IsTrainTurret(uint netID) {
if (!isEventActive) return false;
return train.IsTrainTurret(netID);
}
#endregion ExternalAPI
#region Hooks
void Init() => Unsubscribes();
void OnServerInitialized() {
ins = this;
UpdateConfig();
if (_config.mainConfig.isAutoEvent) autoEventCoroutine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
PostLoadCheck();
}
void OnButtonPress(PressButton button, BasePlayer player) {
if (!isEventActive || !button.IsExists() || player == null || button.net == null) return;
if (train.IsTrainButton(button.net.ID)) OnPlayerTryStopTrain(player);
}
object CanPickupEntity(BasePlayer player, PressButton entity) {
if (!isEventActive || !entity.IsExists() || player == null || entity.net == null) return null;
if (train.IsTrainButton(entity.net.ID)) return false;
return null;
}
object OnTrainCarUncouple(TrainCar trainCar, BasePlayer player) {
if (!isEventActive || trainCar == null || player == null || trainCar.net == null) return null;
if (train.IsTrainWagon(trainCar.net.ID)) return true;
return null;
}
object CanTrainCarCouple(TrainCar trainCar1, TrainCar trainCar2) {
if (!isEventActive || _config.mainConfig.allowConnectWagons || !trainCar1.IsExists() || !trainCar2.IsExists() || trainCar1.net == null || trainCar2.net == null) return null;
if (!train.IsTrainWagon(trainCar1.net.ID) && !train.IsTrainWagon(trainCar2.net.ID)) return null;
return false;
}
object CanMountEntity(BasePlayer player, BaseVehicleSeat entity) {
if (!isEventActive || !player.userID.IsSteamId() || entity == null || entity.VehicleParent() == null || entity.VehicleParent().net == null || !train.IsTrainWagon(entity.VehicleParent().net.ID)) return null;
return true;
}
object OnTurretTarget(AutoTurret turret, BaseCombatEntity entity) {
if (!isEventActive || !turret.IsExists() || !entity.IsExists() || turret.net == null) return null;
if (!train.IsTrainTurret(turret.net.ID)) return null;
BasePlayer player = entity as BasePlayer;
if (!player.IsRealPlayer()) return true;
if (!train.IsTrainCanAttack()) return true;
return null;
}
object CanBradleyApcTarget(BradleyAPC apc, BaseEntity entity) {
if (!isEventActive || !apc.IsExists() || !entity.IsExists() || apc.net == null) return null;
if (!train.IsTrainBradley(apc.net.ID)) return null;
BasePlayer player = entity as BasePlayer;
if (!player.IsRealPlayer()) return false;
if (!train.IsTrainCanAttack()) return false;
return null;
}
object CanSamSiteShoot(SamSite samSite) {
if (!isEventActive || samSite == null || samSite.net == null) return null;
if (!train.IsTrainSamSite(samSite.net.ID)) return null;
if (!train.IsTrainCanAttack()) return true;
return null;
}
object OnSamSiteModeToggle(SamSite samSite, BasePlayer player, bool flag) {
if (samSite == null || player == null || samSite.net == null) return null;
if (train.IsTrainSamSite(samSite.net.ID)) return true;
return null;
}
object CanHelicopterTarget(PatrolHelicopterAI heli, BasePlayer player) {
if (!isEventActive || !heli.helicopterBase.IsExists() || heli.helicopterBase.net == null) return null;
if (!train.IsTrainHeli(heli.helicopterBase.net.ID)) return null;
if (!train.IsTrainCanAttack()) return false;
return null;
}
void OnEntitySpawned(HelicopterDebris entity) {
if (!isEventActive || !entity.IsExists() || entity.transform == null || train == null) return;
if (Vector3.Distance(entity.transform.position, train.locomotive.baseWagonEntity.transform.position) < 20 || train.wagons.Any(x => Vector3.Distance(entity.transform.position, x.baseWagonEntity.transform.position) < 20)) entity.Kill();
}
object OnEntityTakeDamage(ScientistNPC scientistNPC, HitInfo info) {
if (!isEventActive || scientistNPC == null || scientistNPC.net == null) return null;
if (!_config.NPCConfigs.Any(x => x.name == scientistNPC.displayName) && !_config.driverConfigs.Any(x => x.name == scientistNPC.displayName)) return null;
OnTrainAttacked(info.InitiatorPlayer);
if (!_config.mainConfig.allowDriverDamage && train.IsTrainDriver(scientistNPC.net.ID)) return true;
return null;
}
object OnEntityTakeDamage(BradleyAPC bradley, HitInfo info) {
if (!isEventActive || bradley == null || bradley.net == null) return null;
if (!train.IsTrainBradley(bradley.net.ID)) return null;
return train.OnTrainAttacked(info);
}
object OnEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
if (!isEventActive || autoTurret == null || autoTurret.net == null) return null;
if (!train.IsTrainTurret(autoTurret.net.ID)) return null;
return train.OnTrainAttacked(info);
}
object OnEntityTakeDamage(SamSite samSite, HitInfo info) {
if (!isEventActive || samSite == null || samSite.net == null) return null;
if (!train.IsTrainSamSite(samSite.net.ID)) return null;
return train.OnTrainAttacked(info);
}
object OnEntityTakeDamage(TrainCar trainEngine, HitInfo info) {
if (train == null || trainEngine == null || trainEngine.net == null) return null;
if (!train.IsTrainWagon(trainEngine.net.ID)) return null;
return true;
}
object OnEntityTakeDamage(PressButton pressButton, HitInfo info) {
if (!isEventActive || pressButton == null || pressButton.net == null) return null;
if (train.IsTrainButton(pressButton.net.ID)) return true;
return null;
}
void OnEntityDeath(BradleyAPC entity, HitInfo info) {
if (!isEventActive || entity == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
BaseWagon baseWagon = train.locomotive.bradleys.Any(y => y != null && y.net != null && y.net.ID == entity.net.ID) ? train.locomotive : train.wagons.FirstOrDefault(x => x != null && x.bradleys.Any(y => y != null && y.net != null && y.net.ID == entity.net.ID));
if (baseWagon == null) return;
baseWagon.bradleys.Remove(entity);
ActionEconomy(info.InitiatorPlayer.userID, "Bradley");
}
void OnEntityDeath(ScientistNPC scientistNPC, HitInfo info) {
if (!isEventActive || scientistNPC == null || info == null) return;
if (info.InitiatorPlayer.IsRealPlayer() && _config.NPCConfigs.Any(x => x != null && x.name == scientistNPC.displayName)) ActionEconomy(info.InitiatorPlayer.userID, "Npc");
else if (_config.driverConfigs.Any(x => x != null && x.name == scientistNPC.displayName) && train.IsTrainDriver(scientistNPC.net.ID)) OnPlayerTryStopTrain(info.InitiatorPlayer);
}
void OnEntityDeath(AutoTurret entity, HitInfo info) {
if (!isEventActive || entity == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
BaseWagon baseWagon = train.locomotive.turrets.Any(y => y != null && y.net != null && y.net.ID == entity.net.ID) ? train.locomotive : train.wagons.FirstOrDefault(x => x != null && x.turrets.Any(y => y != null && y.net != null && y.net.ID == entity.net.ID));
if (baseWagon == null) return;
baseWagon.turrets.Remove(entity);
ActionEconomy(info.InitiatorPlayer.userID, "Turret");
}
void OnEntityDeath(BaseHelicopter entity, HitInfo info) {
if (!isEventActive || entity == null || info == null || !info.InitiatorPlayer.IsRealPlayer() || entity.net == null) return;
if (!train.IsTrainHeli(entity.net.ID)) return;
if (_config.supportedPluginsConfig.economy.enable) ActionEconomy(info.InitiatorPlayer.userID, "Heli");
}
void OnEntityKill(BasePlayer player) {
if (!isEventActive || !player.IsRealPlayer() || !train.playersInZone.Contains(player)) return;
train.playersInZone.Remove(player);
if (_config.guiConfig.IsGUI) CuiHelper.DestroyUi(player, "TextMain");
}
void OnEntityKill(TrainCar trainCar) {
if (!isEventActive || trainCar == null || trainCar.net == null) return;
if (!train.IsTrainWagon(trainCar.net.ID)) return;
train.DiconnectTrain();
}
object CanLootEntity(BasePlayer player, LootContainer container) {
if (!isEventActive || !_config.mainConfig.needStopTrain || player == null || container == null || container.net == null) return null;
if (!train.IsTrainCrate(container.net.ID) || train.CanLoot()) return null;
InformPlayer(player, "NeedStopTrain", _config.prefix);
return true;
}
object CanLootEntity(BasePlayer player, SamSite samSite) {
if (!isEventActive || samSite == null || samSite.net == null) return null;
if (train.IsTrainSamSite(samSite.net.ID)) return true;
return null;
}
object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
if (!isEventActive || !_config.mainConfig.needStopTrain || player == null || crate == null || crate.net == null) return null;
if (train.IsTrainLockedCrate(crate.net.ID)) {
if (!train.CanLoot()) {
InformPlayer(player, "NeedStopTrain", _config.prefix);
return true;
}
else {
ActionEconomy(player.userID, "LockedCrate");
}
}
return null;
}
private void OnLootEntity(BasePlayer player, LootContainer container) {
if (!isEventActive || player == null || container == null || container.net == null) return;
if (train.IsTrainCrate(container.net.ID) && !train.openedCrates.Contains(container.net.ID)) {
train.openedCrates.Add(container.net.ID);
ActionEconomy(player.userID, "Crates", container.PrefabName);
train.CheckAllCrates();
train.BecomeAgressive(player);
}
}
void OnCorpsePopulate(BasePlayer entity, NPCPlayerCorpse corpse) {
if (!isEventActive || entity == null || corpse == null) return;
if (entity is ScientistNPC) {
NpcConfig npcConfig = _config.NPCConfigs.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;
}
container.ClearItemsContainer();
if (npcConfig.typeLootTable == 1 && npcConfig.lootTable.minAmount > 0) AddToContainerItem(container, npcConfig.lootTable, npcConfig.typeLootTable);
if (npcConfig.deleteCorpse && corpse != null && !corpse.IsDestroyed) corpse.Kill();
}
);
}
}
void Unload() => EndEvent(true);
#region OtherPlugins
object CanBradleySpawnNpc(BradleyAPC bradley) {
if (!isEventActive || bradley == null || bradley.net == null) return null;
if (train.IsTrainBradley(bradley.net.ID)) return true;
return null;
}
object CanEntityTakeDamage(BasePlayer victim, HitInfo hitinfo) {
if (!isEventActive || victim == null || hitinfo == null || !victim.userID.IsSteamId()) return null;
BasePlayer attacker = hitinfo.InitiatorPlayer;
if (_config.zoneConfig.isCreateZonePVP && attacker != null) {
if (train.playersInZone.Contains(victim) && (attacker == null || (attacker != null && train.playersInZone.Contains(attacker)))) return true;
}
if (hitinfo.Initiator == null) return null;
AutoTurret autoTurret = hitinfo.Initiator as AutoTurret;
if (autoTurret != null && autoTurret.net != null && train.IsTrainTurret(autoTurret.net.ID)) return true;
SamSite samSite = hitinfo.Initiator as SamSite;
if (samSite != null && samSite.net != null && train.IsTrainSamSite(samSite.net.ID)) return true;
return null;
}
object CanEntityTakeDamage(BaseHelicopterVehicle victim, HitInfo hitinfo) {
if (!isEventActive || !victim.IsExists()) return null;
if (hitinfo.Initiator == null) return null;
SamSite samSite = hitinfo.Initiator as SamSite;
if (samSite != null && samSite.net != null && train.IsTrainSamSite(samSite.net.ID)) return true;
return null;
}
object OnCustomNpcTarget(ScientistNPC npc, BasePlayer player) {
if (!isEventActive || npc == null) return null;
if (!_config.NPCConfigs.Any(x => x.name == npc.displayName)) return null;
if (!train.IsTrainCanAttack()) return true;
return null;
}
object CanPopulateLoot(ScientistNPC entity, NPCPlayerCorpse corpse) {
if (!isEventActive || entity == null || corpse == null) return null;
NpcConfig npcConfig = _config.NPCConfigs.FirstOrDefault(x => x.name == entity.displayName);
if (npcConfig != null && npcConfig.typeLootTable != 2) return true;
return null;
}
object CanPopulateLoot(LootContainer container) {
if (!isEventActive || container == null) return null;
string cratePresetName = null;
if (container is HackableLockedCrate) {
if (train.locomotive.lockedCrates.Any(y => y.Key != null && y.Key.net != null && y.Key.net.ID == container.net.ID)) cratePresetName = train.locomotive.lockedCrates[container];
else {
BaseWagon baseWagon = train.wagons.FirstOrDefault(x => x.lockedCrates.Any(y => y.Key != null && y.Key.net != null && y.Key.net.ID == container.net.ID));
if (baseWagon != null) cratePresetName = baseWagon.lockedCrates[container];
}
return null;
}
if (train.locomotive.crates.Any(y => y.Key != null && y.Key.net != null && y.Key.net.ID == container.net.ID)) cratePresetName = train.locomotive.lockedCrates[container];
else {
BaseWagon baseWagon = train.wagons.FirstOrDefault(x => x.crates.Any(y => y.Key != null && y.Key.net != null && y.Key.net.ID == container.net.ID));
if (baseWagon != null) cratePresetName = baseWagon.lockedCrates[container];
}
CrateConfig crateConfig = _config.crateConfigs.FirstOrDefault(x => x.presetName == cratePresetName);
if (crateConfig != null && crateConfig.typeLootTable != 2) return true;
return null;
}
object CanEntityTakeDamage(AutoTurret autoTurret, HitInfo hitinfo) {
if (!isEventActive || autoTurret == null || autoTurret.net == null) return null;
if (!train.IsTrainTurret(autoTurret.net.ID)) return null;
if (!hitinfo.InitiatorPlayer.IsRealPlayer()) return false;
train.OnTrainAttacked(hitinfo);
return true;
}
object CanEntityTakeDamage(SamSite samSite, HitInfo hitinfo) {
if (!isEventActive || samSite == null || samSite.net == null) return null;
if (!train.IsTrainSamSite(samSite.net.ID)) return null;
if (!hitinfo.InitiatorPlayer.IsRealPlayer()) return false;
train.OnTrainAttacked(hitinfo);
return true;
}
object CanEntityBeTargeted(BasePlayer player, AutoTurret turret) {
if (!isEventActive || !turret.IsExists() || !player.IsExists() || turret.net == null) return null;
if (!train.IsTrainTurret(turret.net.ID)) return null;
if (!player.IsRealPlayer()) return false;
if (!train.IsTrainCanAttack()) return false;
return true;
}
object CanEntityBeTargeted(BasePlayer player, SamSite samSite) {
if (!isEventActive || samSite == null || samSite.net == null || !player.IsRealPlayer()) return null;
if (train.IsTrainSamSite(samSite.net.ID)) return true;
return null;
}
object OnCustomLootContainer(uint netID) {
if (!isEventActive) return null;
LootContainer lootContainer;
lootContainer = train.locomotive.lockedCrates.Keys.FirstOrDefault(y => y != null && y.net.ID == netID);
if (lootContainer != null) {
BaseWagon baseWagon = train.wagons.FirstOrDefault(x => x.lockedCrates.Any(y => y.Key != null && y.Key.net.ID == netID));
if (baseWagon != null) lootContainer = lootContainer = baseWagon.lockedCrates.Keys.FirstOrDefault(x => x != null && x.net.ID == netID);
if (lootContainer == null) {
if (lootContainer == null) lootContainer = train.locomotive.crates.Keys.FirstOrDefault(y => y != null && y.net.ID == netID);
if (lootContainer == null) {
BaseWagon baseWagon1 = train.wagons.FirstOrDefault(x => x.crates.Any(y => y.Key != null && y.Key.net.ID == netID));
if (baseWagon1 != null) lootContainer = lootContainer = baseWagon1.crates.Keys.FirstOrDefault(x => x != null && x.net.ID == netID);
}
}
}
return CanPopulateLoot(lootContainer);
}
#endregion OtherPlugins
#endregion Hooks
#region Commands
[ChatCommand("atrainstart")]
void ChatStartCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (isEventActive) {
InformPlayer(player, "EventActive", _config.prefix);
return;
}
if (arg != null && arg.Length >= 1) StartEvent(arg[0], player);
else StartEvent("", player);
}
[ChatCommand("atrainstartunderground")]
void ChatStarttUndergroundCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (isEventActive) {
InformPlayer(player, "EventActive", _config.prefix);
return;
}
if (arg != null && arg.Length >= 1) StartEvent(arg[0], player, 100);
else StartEvent("", player, 100);
}
[ChatCommand("atrainstartaboveground")]
void ChatStarttAbovegroundCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (isEventActive) {
InformPlayer(player, "EventActive", _config.prefix);
return;
}
if (arg != null && arg.Length >= 1) StartEvent(arg[0], player, 0);
else StartEvent("", player, 0);
}
[ChatCommand("atrainstop")]
void ChatStopCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (isEventActive) EndEvent();
}
[ConsoleCommand("atrainstart")]
void ConsoleStartCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
if (arg.Args != null && arg.Args.Length > 0) StartEvent(arg.Args[0]);
StartEvent();
Puts(_config.prefix + " Event activated");
}
[ConsoleCommand("atrainstartunderground")]
void ConsoleStartUndergroundCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
if (arg.Args != null && arg.Args.Length > 0) StartEvent(arg.Args[0]);
StartEvent(underGroundChance : 100);
Puts(_config.prefix + " Event activated");
}
[ConsoleCommand("atrainstartaboveground")]
void ConsoleStartAbovegroundCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
if (arg.Args != null && arg.Args.Length > 0) StartEvent(arg.Args[0]);
StartEvent(underGroundChance : 0);
Puts(_config.prefix + " Event activated");
}
[ConsoleCommand("atrainstop")]
void ConsoleStopCommand(ConsoleSystem.Arg arg) {
if (arg.Player() == null && isEventActive) EndEvent();
}
[ChatCommand("atrainpoint")]
void SpawnPointCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (CheckRailsInPosition(player.transform.position)) {
_config.mainConfig.customSpawnPoints.Add(player.transform.position.ToString());
PrintToChat(player, _config.prefix + " New spawn point <color=#738d43>successfully</color> added");
SaveConfig();
return;
}
PrintToChat(player, _config.prefix + " <color=#ce3f27>Couldn't</color> find the rails");
}
#endregion Commands
#region Actions
void OnPlayerTryStopTrain(BasePlayer player) {
train.StopTrain(player);
train.BecomeAgressive(player);
}
void OnTrainAttacked(BasePlayer attacker) => train.BecomeAgressive(attacker);
#endregion Actions
#region Methods
void UpdateConfig() {
if (_config.versionConfig == Version) return;
if (_config.versionConfig.Minor == 0) {
if (_config.versionConfig.Patch <= 1) {
_config.mainConfig.customSpawnPoints = new List<string>();
_config.mainConfig.isUnderGround = true;
}
if (_config.versionConfig.Patch <= 3) {
foreach (NpcConfig npcConfig in _config.NPCConfigs) {
npcConfig.kit = "";
foreach (NpcBelt npcBelt in npcConfig.beltItems) npcBelt.Mods = new HashSet<string>();
}
}
if (_config.versionConfig.Patch <= 5) {
_config.driverConfigs = new HashSet<DriverConfig> {
new DriverConfig {
name = "Train_Driver_1", health = 200f, wearItems = new List<NpcWear> {
new NpcWear {
shortName = "metal.plate.torso", skinID = 1988476232
}
, new NpcWear {
shortName = "riot.helmet", skinID = 1988478091
}
, new NpcWear {
shortName = "pants", skinID = 1582399729
}
, new NpcWear {
shortName = "tshirt", skinID = 1582403431
}
, new NpcWear {
shortName = "shoes.boots", skinID = 0
}
}
, kit = ""
}
}
;
foreach (LocomotiveConfig locomotiveConfig in _config.locomotiveConfigs) locomotiveConfig.driverName = "Train_Driver_1";
}
if (_config.versionConfig.Patch <= 6) {
_config.samsiteConfigs = new HashSet<SamSiteConfig> {
new SamSiteConfig {
presetName = "samsite_default", hp = 1000f, countAmmo = 100
}
}
;
foreach (BaseWagonConfig baseWagonConfig in _config.wagonConfigs) {
if (baseWagonConfig.prefabName == "assets/content/vehicles/trains/wagons/trainwagonc.entity.prefab") {
baseWagonConfig.samsites = new Dictionary<string, HashSet<LocationConfig>> {
["samsite_default"]
= new HashSet<LocationConfig> {
new LocationConfig {
position = "(0, 4.216, 0)", rotation = "(0, 180, 0)"
}
}
}
;
}
else baseWagonConfig.samsites = new Dictionary<string, HashSet<LocationConfig>>();
}
foreach (BaseWagonConfig baseWagonConfig in _config.locomotiveConfigs) {
baseWagonConfig.samsites = new Dictionary<string, HashSet<LocationConfig>>();
}
}
if (_config.versionConfig.Patch <= 7) {
foreach (NpcConfig npcConfig in _config.NPCConfigs) {
npcConfig.turretDamageScale = 1;
}
}
if (_config.versionConfig.Patch <= 8) {
_config.mainConfig.destroyEntities = new HashSet<string> {
"minicopter", "car"
}
;
}
_config.versionConfig = new VersionNumber(1, 1, 0);
foreach (BaseWagonConfig locomotiveConfig in _config.wagonConfigs) {
if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagond.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonc.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagonb.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonb.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagonc.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonunloadablefuel.entity.prefab";
}
}
if (_config.versionConfig.Minor == 1) {
if (_config.versionConfig.Patch < 3) {
foreach (BaseWagonConfig locomotiveConfig in _config.wagonConfigs) {
if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagond.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonc.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagonb.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonb.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/train/trainwagonc.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/train/trainwagonunloadablefuel.entity.prefab";
}
}
if (_config.versionConfig.Patch < 4) {
_config.locomotiveConfigs.Add(new LocomotiveConfig {
presetName = "locomotive_new", prefabName = "assets/content/vehicles/locomotive/locomotive.entity.prefab", engineForce = 500000f, maxSpeed = 14, driverName = "Train_Driver_1", brradleys = new Dictionary<string, HashSet<LocationConfig>> {
}
, turrets = new Dictionary<string, HashSet<LocationConfig>> {
["turret_m249"]
= new HashSet<LocationConfig> {
new LocationConfig {
position = "(-0.554, 1.546, -8.849)", rotation = "(0, 180, 0)"
}
, new LocationConfig {
position = "(0.554, 1.546, -8.849)", rotation = "(0, 180, 0)"
}
}
}
, NPCs = new Dictionary<string, HashSet<LocationConfig>> {
["TrainNPC"]
= new HashSet<LocationConfig> {
new LocationConfig {
position = "(-1.341, 1.546, 2)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(-1.341, 1.546, 0)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(-1.341, 1.546, -2)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(-1.341, 1.546, -4)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(-1.341, 1.546, -6)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(-1.341, 1.546, -8)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, 2)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, 0)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, -2)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, -4)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, -6)", rotation = "(0, 0, 0)"
}
, new LocationConfig {
position = "(1.341, 1.546, -8)", rotation = "(0, 0, 0)"
}
}
}
, crates = new Dictionary<string, HashSet<LocationConfig>> {
}
, samsites = new Dictionary<string, HashSet<LocationConfig>> {
}
, decors = new Dictionary<string, HashSet<LocationConfig>> {
}
}
);
_config.trainConfigs.Add(new TrainConfig {
presetName = "train_hard_new", trainName = "Giant Train", isUndergroundTrain = false, eventTime = 3600, stopTime = 120, automaticStart = false, chance = 20, locomotivePreset = "locomotive_new", wagonsPreset = new List<string> {
"wagon_bradley", "wagon_crate_2", "wagon_bradley", "wagon_samsite"
}
, heliPreset = "heli_1"
}
);
}
if (_config.versionConfig.Patch < 5) {
foreach (BaseWagonConfig wagonConfig in _config.wagonConfigs) {
if (wagonConfig.presetName == "wagon_crate_1") {
wagonConfig.prefabName = "assets/content/vehicles/train/trainwagonc.entity.prefab";
}
}
}
if (_config.versionConfig.Patch < 9) {
foreach (LocomotiveConfig locomotiveConfig in _config.locomotiveConfigs) {
if (locomotiveConfig.prefabName == "assets/content/vehicles/workcart/workcart_aboveground.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/trains/workcart/workcart_aboveground.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/workcart/workcart_aboveground2.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/trains/workcart/workcart_aboveground2.entity.prefab";
else if (locomotiveConfig.prefabName == "assets/content/vehicles/locomotive/locomotive.entity.prefab") locomotiveConfig.prefabName = "assets/content/vehicles/trains/locomotive/locomotive.entity.prefab";
}
foreach (BaseWagonConfig baseWagonConfig in _config.wagonConfigs) {
if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagona.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagona.entity.prefab";
else if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagonb.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagonb.entity.prefab";
else if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagonc.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagonc.entity.prefab";
else if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagonunloadable.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagonunloadable.entity.prefab";
else if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagonunloadablefuel.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagonunloadablefuel.entity.prefab";
else if (baseWagonConfig.prefabName == "assets/content/vehicles/train/trainwagonunloadableloot.entity.prefab") baseWagonConfig.prefabName = "assets/content/vehicles/trains/wagons/trainwagonunloadableloot.entity.prefab";
}
}
if (_config.versionConfig.Patch == 9) {
_config.wagonConfigs.Add(new BaseWagonConfig {
presetName = "caboose_wagon", prefabName = "assets/content/vehicles/trains/caboose/traincaboose.entity.prefab", brradleys = new Dictionary<string, HashSet<LocationConfig>>(), crates = new Dictionary<string, HashSet<LocationConfig>>(), samsites = new Dictionary<string, HashSet<LocationConfig>>(), decors = new Dictionary<string, HashSet<LocationConfig>>(), NPCs = new Dictionary<string, HashSet<LocationConfig>>(), turrets = new Dictionary<string, HashSet<LocationConfig>>()
}
);
_config.trainConfigs.Add(new TrainConfig {
presetName = "train_caboose", trainName = "Caboose", isUndergroundTrain = false, eventTime = 3600, stopTime = 0, automaticStart = false, chance = 20, locomotivePreset = _config.locomotiveConfigs.FirstOrDefault(x => true).presetName, wagonsPreset = new List<string> {
"caboose_wagon"
}
, heliPreset = ""
}
);
}
_config.versionConfig = new VersionNumber(1, 2, 0);
}
if (_config.versionConfig.Minor == 2) {
if (_config.versionConfig.Patch <= 3) {
_config.supportedPluginsConfig.pveMode.scaleDamage.Add(new ScaleDamageConfig {
Type = "Helicopter", Scale = 1
}
);
}
}
_config.versionConfig = Version;
SaveConfig();
}
bool CheckRailsInPosition(Vector3 position) {
foreach (Collider collider in UnityEngine.Physics.OverlapSphere(position, 2f)) {
if (collider.name.Contains("Rail Mesh") || collider.name.Contains("train_track") || collider.name.Contains("train_tunnel")) return true;
}
return false;
}
void PostLoadCheck() {
if (!plugins.Exists("NpcSpawn")) {
PrintError("NpcSpawn plugin doesn`t exist! Please read the file ReadMe.txt");
NextTick(() => Server.Command($"o.unload {Name}"));
return;
}
}
IEnumerator AutoEventCorountine() {
yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(_config.mainConfig.minTimeBetweenEvent, _config.mainConfig.maxTimeBetweenEvent));
StartEvent();
}
void StartEvent(string trainPresetName = "", BasePlayer player = null, float underGroundChance = -1) {
if (train != null) return;
if (autoEventCoroutine != null) ServerMgr.Instance.StopCoroutine(autoEventCoroutine);
FindRails(underGroundChance);
TrainConfig trainConfig = DefineTrainConfig(trainPresetName);
if (CanStartEvent(trainConfig, player)) startEventCoroutine = ServerMgr.Instance.StartCoroutine(StartEventCorountine(trainConfig));
}
void FindRails(float externalChance) {
railTransformList.Clear();
HashSet<TrainCar> trains = BaseNetworkable.serverEntities.OfType<TrainCar>().Where(x => x.IsExists() && (x.GetFuelSystem() == null || !x.GetFuelSystem().HasFuel()) && !x.AnyPlayersNearby(25));
underGround = false;
float undergroundChance = UnityEngine.Random.Range(0, 100);
float chance = externalChance < 0 ? _config.mainConfig.undergroundChance : externalChance;
if (undergroundChance < chance && ins._config.trainConfigs.Any(x => x.isUndergroundTrain)) {
foreach (TrainCar trainCar in trains) if (trainCar != null && trainCar.transform != null && trainCar.transform.position.y < 0) railTransformList.Add(trainCar.transform);
underGround = true;
}
else {
foreach (TrainCar trainCar in trains) if (trainCar != null && trainCar.transform != null && trainCar.transform.position.y > 0) railTransformList.Add(trainCar.transform);
if (trains.Count < 3 && _config.mainConfig.isUnderGround) {
foreach (TrainCar trainCar in trains) if (trainCar.transform.position.y < 0) railTransformList.Add(trainCar.transform);
underGround = true;
}
}
if (railTransformList.Count < 2 && (!_config.mainConfig.useCustomCoords || _config.mainConfig.customSpawnPoints.Count == 0)) {
PrintError("No rail detected");
NextTick(() => Server.Command($"o.unload {Name}"));
}
}
TrainConfig DefineTrainConfig(string trainPresetName = "") {
TrainConfig trainConfig = null;
if (trainPresetName == "") {
if (!_config.trainConfigs.Any(x => x.chance > 0 && x.automaticStart && (!underGround || x.isUndergroundTrain))) return null;
while (trainConfig == null) {
foreach (TrainConfig train in _config.trainConfigs) {
if ((!underGround || train.isUndergroundTrain) && train.automaticStart && UnityEngine.Random.Range(0.0f, 100.0f) <= train.chance) {
trainConfig = train;
break;
}
}
}
}
else trainConfig = ins._config.trainConfigs.FirstOrDefault(x => x.presetName == trainPresetName);
return trainConfig;
}
bool CanStartEvent(TrainConfig trainConfig, BasePlayer activator = null) {
if (trainConfig == null) {
SendErrorMessage("Train configuration not found!", activator);
return false;
}
if (isEventActive || startEventCoroutine != null) {
SendErrorMessage("The event has already been launched!", activator);
return false;
}
return true;
}
IEnumerator StartEventCorountine(TrainConfig trainConfig) {
if (_config.notifyConfig.chat) foreach (BasePlayer player in BasePlayer.activePlayerList) if (player != null) PrintToChat(player, GetMessage("PreStartTrain", player.UserIDString, _config.prefix, trainConfig.trainName, GetTimeMessage(player.UserIDString, _config.notifyConfig.preStartTime)));
SendDiscordMessage("PreStartTrain", _config.prefix, trainConfig.trainName, GetTimeMessage(null, _config.notifyConfig.preStartTime));
yield return CoroutineEx.waitForSeconds(_config.notifyConfig.preStartTime);
GameObject gameObject = new GameObject();
gameObject.layer = (int)Layer.Reserved1;
train = gameObject.AddComponent<Train>();
Subscribes();
train.CreateTrain(trainConfig);
startEventCoroutine = null;
}
private void AddToContainerItem(ItemContainer container, LootTableConfig lootTableConfig, int typeOfLootTable) {
if (typeOfLootTable == 1) container.ClearItemsContainer();
int CountLootInContainer = 0;
int countLoot = UnityEngine.Random.Range(lootTableConfig.minAmount, lootTableConfig.maxAmount);
container.capacity = countLoot;
for (; CountLootInContainer <= countLoot;) {
foreach (ItemConfig item in lootTableConfig.itemsConfig) {
if (UnityEngine.Random.Range(0.0f, 100.0f) <= item.chance) {
int amount = UnityEngine.Random.Range(item.minAmount, item.maxAmount + 1);
Item newItem = item.isBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.shortName, amount, item.skinID);
if (item.isBluePrint) newItem.blueprintTarget = ItemManager.FindItemDefinition(item.shortName).itemid;
if (item.name != "") newItem.name = item.name;
if (!newItem.MoveToContainer(container)) newItem.Remove();
if (CountLootInContainer == countLoot) return;
CountLootInContainer++;
}
}
}
}
void SendErrorMessage(string message, BasePlayer player = null) {
if (player != null) PrintToChat(player, message);
else PrintError(message);
}
void EndEvent(bool isUnloading = false) {
if (autoEventCoroutine != null) ServerMgr.Instance.StopCoroutine(autoEventCoroutine);
if (!isUnloading && _config.mainConfig.isAutoEvent) autoEventCoroutine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
Unsubscribes();
isEventActive = false;
if (train != null) {
InformAllPlayers("EndEvent", true, _config.prefix);
UnityEngine.Object.Destroy(train.ga
// ... [Code preview truncated due to length. Full source in attached file] ...