C#:
using Enumerable = System.Linq.Enumerable;
using Rust;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.SputnikExtensionMethods;
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.AI;
namespace Oxide.Plugins {
/*ПЛАГИН БЫЛ ПОФИКШЕН С ПОМОЩЬЮ ПРОГРАММЫ СКАЧАНОЙ С https://discord.gg/dNGbxafuJn */
/*ПЛАГИН БЫЛ ПОФИКШЕН С ПОМОЩЬЮ ПРОГРАММЫ СКАЧАНОЙ С https://discord.gg/dNGbxafuJn */
[Info("Sputnik", "https://discord.gg/dNGbxafuJn", "1.4.3")]
class Sputnik : RustPlugin {
#region Variables
const bool en = false;
static Sputnik ins;
[PluginReference]
Plugin NpcSpawn, PveMode, GUIAnnouncements, DiscordMessages, ZoneManager, RaidableBases, Economics, ServerRewards, IQEconomic, Notify, DynamicPVP;
HashSet<string> subscribeMethods = new HashSet<string> {
"OnEntitySpawned", "OnEntityTakeDamage", "OnEntityDeath", "OnCorpsePopulate", "OnPlayerSleep", "CanHelicopterTarget", "OnTrapTrigger", "OnCardSwipe", "OnLootSpawn", "CanHackCrate", "CanLootEntity", "OnLootEntity", "OnCustomNpcTarget", "CanEntityTakeDamage", "CanEntityTrapTrigger", "CanEntityBeTargeted", "CanPopulateLoot", "OnCustomLootContainer", "OnCustomLootNPC", "OnRestoreUponDeath", "SetOwnerPveMode", "ClearOwnerPveMode", "OnCreateDynamicPVP"
}
;
HashSet<string> permanentHooks = new HashSet<string> {
"OnLootSpawn"
}
;
EventController eventController;
#endregion Variables
#region Hooks
void Init() {
Unsubscribes(true);
}
void OnServerInitialized() {
ins = this;
if (!NpcSpawnManager.IsNpcSpawnReady()) return;
else if (!DataFileManager.TryLoadData()) return;
LoadDefaultMessages();
UpdateConfig();
UpdateLootTables();
UnsubscribesPermanentHooks();
GuiManager.LoadImages();
SpawnPositionFinder.InitialUpdate();
LootManager.InitialLootManagerUpdate();
EventLauncher.AutoStartEvent();
}
void Unload() {
EventLauncher.StopEvent(true);
SpawnPositionFinder.StopCachingSpawnPoints();
ins = null;
}
void OnEntitySpawned(LockedByEntCrate entity) {
if (!entity.IsExists()) return;
if (entity.ShortPrefabName == "heli_crate") LootManager.OnHeliCrateSpawned(entity);
}
object OnEntityTakeDamage(PatrolHelicopter patrolHelicopter, HitInfo info) {
if (patrolHelicopter == null || patrolHelicopter.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return null;
EventHeli eventHeli = EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value);
if (eventHeli == null) return null;
SputnikClass sputnikClass = eventHeli.sputnikClass;
if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, patrolHelicopter, true)) return true;
else eventHeli.OnHeliAttacked(info.InitiatorPlayer.userID);
return null;
}
object OnEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
if (autoTurret == null || autoTurret.net == null || info == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByTurretUid(autoTurret.net.ID.Value);
if (sputnikClass == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return true;
else if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, autoTurret, true)) return true;
else sputnikClass.OnSputnikAttacked();
return null;
}
object OnEntityTakeDamage(Landmine landmine, HitInfo info) {
if (landmine == null || landmine.net == null || info == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByLandmineUid(landmine.net.ID.Value);
if (sputnikClass == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return true;
else if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, landmine, true) || sputnikClass.IsPveModeBlockAction(info.InitiatorPlayer)) return true;
else sputnikClass.OnSputnikAttacked();
return null;
}
object OnEntityTakeDamage(ScientistNPC scientistNPC, HitInfo info) {
if (scientistNPC == null || scientistNPC.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByNpcUid(scientistNPC.net.ID.Value);
if (sputnikClass == null) return null;
if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, scientistNPC, true)) return true;
else sputnikClass.OnSputnikAttacked();
return null;
}
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);
}
void OnEntityDeath(AutoTurret autoTurret, HitInfo info) {
if (autoTurret == null || autoTurret.net == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
SputnikClass sputnikClass = SputnikClass.GetSputnikByTurretUid(autoTurret.net.ID.Value);
if (sputnikClass != null) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.supportedPluginsConfig.economicsConfig.turretPoint);
}
void OnEntityDeath(ScientistNPC scientistNPC, HitInfo info) {
if (scientistNPC == null || info == null || !info.InitiatorPlayer.IsRealPlayer()) return;
if (NpcSpawnManager.IsEventNpc(scientistNPC)) EconomyManager.AddBalance(info.InitiatorPlayer.userID, _config.supportedPluginsConfig.economicsConfig.npcPoint);
}
void OnPlayerDeath(BasePlayer player, HitInfo info) {
if (player == null) return;
ZoneController zoneController = ZoneController.GetZoneControllerByPlayerUserID(player.userID);
if (zoneController != null) zoneController.OnPlayerLeaveZone(player);
}
void OnCorpsePopulate(ScientistNPC scientistNPC, NPCPlayerCorpse corpse) {
if (scientistNPC == null) return;
NpcConfig npcConfig = NpcSpawnManager.GetNpcConfigByDisplayName(scientistNPC.displayName);
if (npcConfig == null) return;
ins.NextTick(() => {
if (corpse == null) return;
LootManager.UpdateItemContainer(corpse.containers[0], npcConfig.lootTableConfig, npcConfig.lootTableConfig.clearDefaultItemList);
if (npcConfig.deleteCorpse && !corpse.IsDestroyed) corpse.Kill();
}
);
}
void OnPlayerSleep(BasePlayer player) {
if (!player.IsRealPlayer()) return;
ZoneController zoneController = ZoneController.GetZoneControllerByPlayerUserID(player.userID);
if (zoneController != null) zoneController.OnPlayerLeaveZone(player);
}
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;
SputnikClass sputnikClass = SputnikClass.GetSputnikByTurretUid(autoTurret.net.ID.Value);
if (sputnikClass != null) return true;
return null;
}
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;
return null;
}
object OnTrapTrigger(Landmine landmine, GameObject gameObject) {
if (landmine == null) return null;
ScientistNPC scientistNPC = gameObject.ToBaseEntity() as ScientistNPC;
if (scientistNPC != null && NpcSpawnManager.GetNpcConfigByDisplayName(scientistNPC.displayName) != null) return true;
return null;
}
object OnCardSwipe(CardReader cardReader, Keycard keycard, BasePlayer player) {
if (player == null || cardReader == null || cardReader.net == null || keycard == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByCardReaderUid(cardReader.net.ID.Value);
if (sputnikClass == null) return null;
sputnikClass.OnCardSwipe(keycard, player);
return true;
}
void OnLootSpawn(LootContainer container) {
if (container == null || container.inventory == null) return;
if (_config.customCardConfig.enableSpawnInDefaultCrates && LootManager.GetContainerDataByNetId(container.net.ID.Value) == null) LootManager.SpawnSpaceCardInCrate(container);
}
object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
if (player == null || crate == null || crate.net == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByCrateUid(crate.net.ID.Value);
StorageContainerData storageContainerData = LootManager.GetContainerDataByNetId(crate.net.ID.Value);
if (sputnikClass == null || storageContainerData == null) return null;
CrateConfig crateConfig = LootManager.GetCrateConfigByPresetName(storageContainerData.presetName);
if (!sputnikClass.IsAgressive()) {
sputnikClass.OnSputnikAttacked();
return true;
}
if (sputnikClass.IsCardReaderExistAndClosed()) {
if (crateConfig.needSpaceCard) {
NotifyManager.SendMessageToPlayer(player, "NeedUseCard", _config.prefix);
return true;
}
}
if (sputnikClass.IsPveModeBlockAction(player)) return null;
EconomyManager.AddBalance(player.userID, _config.supportedPluginsConfig.economicsConfig.hackCratePoint);
crate.Invoke(() => LootManager.UpdateCrateHackTime(crate, crateConfig.hackTime), 1.1f);
return null;
}
object CanLootEntity(BasePlayer player, LootContainer container) {
if (player == null || container == null || container.net == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByCrateUid(container.net.ID.Value);
if (sputnikClass == null) return null;
if (!sputnikClass.IsAgressive()) {
sputnikClass.OnSputnikAttacked();
return true;
}
if (sputnikClass.IsCardReaderExistAndClosed()) {
StorageContainerData storageContainerData = LootManager.GetContainerDataByNetId(container.net.ID.Value);
if (storageContainerData != null) {
CrateConfig crateConfig = LootManager.GetCrateConfigByPresetName(storageContainerData.presetName);
if (crateConfig != null && crateConfig.needSpaceCard) {
NotifyManager.SendMessageToPlayer(player, "NeedUseCard", _config.prefix);
return true;
}
}
}
return null;
}
void OnLootEntity(BasePlayer player, LootContainer container) {
if (player == null || container == null || container.net == null) return;
SputnikClass sputnikClass = SputnikClass.GetSputnikByCrateUid(container.net.ID.Value);
if (sputnikClass == null) return;
sputnikClass.OnSputnikAttacked();
sputnikClass.CheckEventPassing();
LootManager.OnEventCrateLooted(container, player.userID);
}
#region OtherPlugins
object OnCustomNpcTarget(ScientistNPC scientistNPC, BasePlayer player) {
if (eventController == null || scientistNPC == null || scientistNPC.net == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByNpcUid(scientistNPC.net.ID.Value);
if (sputnikClass == null) return null;
if (!sputnikClass.IsAgressive() && !_config.agressiveConfig.npcAgressiveMode) return false;
return null;
}
object CanEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
if (eventController == null || autoTurret == null || autoTurret.net == null || info == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByTurretUid(autoTurret.net.ID.Value);
if (sputnikClass == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return false;
else if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, autoTurret, false) || sputnikClass.IsPveModeBlockAction(info.InitiatorPlayer)) return false;
return true;
}
object CanEntityTakeDamage(Landmine landmine, HitInfo info) {
if (eventController == null || landmine == null || landmine.net == null || info == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByLandmineUid(landmine.net.ID.Value);
if (sputnikClass == null) return null;
if (!info.InitiatorPlayer.IsRealPlayer()) return false;
else if (!sputnikClass.IsPlayerCanDealDamage(info.InitiatorPlayer, landmine, false) || sputnikClass.IsPveModeBlockAction(info.InitiatorPlayer)) return false;
return true;
}
object CanEntityTakeDamage(BasePlayer player, HitInfo hitinfo) {
if (eventController == null || !player.IsRealPlayer() || hitinfo == null) return null;
if (hitinfo.InitiatorPlayer.IsRealPlayer() && !_config.supportedPluginsConfig.pveMode.enable) {
ZoneController zoneController = ZoneController.GetZoneControllerByPlayerUserID(player.userID);
if (zoneController != null && zoneController.IsPvpZone() && ZoneController.GetZoneControllerByPlayerUserID(hitinfo.InitiatorPlayer.userID) != null) return true;
}
else if (hitinfo.Initiator != null && hitinfo.Initiator.net != null) {
if (hitinfo.Initiator is AutoTurret && SputnikClass.GetSputnikByTurretUid(hitinfo.Initiator.net.ID.Value) != null) return true;
else if (hitinfo.Initiator is Landmine && SputnikClass.GetSputnikByLandmineUid(hitinfo.Initiator.net.ID.Value) != null) return true;
}
return null;
}
object CanEntityTrapTrigger(Landmine landmine, BasePlayer player) {
if (eventController == null || landmine == null || !player.IsRealPlayer()) return null;
if (SputnikClass.GetSputnikByLandmineUid(landmine.net.ID.Value) != null) return true;
return null;
}
object CanEntityTrapTrigger(Landmine landmine, ScientistNPC scientistNPC) {
if (eventController == null || scientistNPC == null) return null;
if (NpcSpawnManager.GetNpcConfigByDisplayName(scientistNPC.displayName) != null) return false;
return null;
}
object CanEntityBeTargeted(BasePlayer player, AutoTurret turret) {
if (eventController == null || turret == null || turret.net == null) return null;
SputnikClass sputnikClass = SputnikClass.GetSputnikByTurretUid(turret.net.ID.Value);
if (sputnikClass == null) return null;
if (!player.IsRealPlayer()) return false;
else if (!sputnikClass.IsAgressive() && !_config.agressiveConfig.turretAgressiveMode) return false;
else if (!sputnikClass.IsPveModeBlockAction(player)) return true;
return null;
}
object CanPopulateLoot(ScientistNPC scientistNPC, NPCPlayerCorpse corpse) {
if (eventController == null || scientistNPC == null || scientistNPC.net == null) return null;
NpcConfig npcConfig = NpcSpawnManager.GetNpcConfigByDisplayName(scientistNPC.displayName);
if (npcConfig != null && !npcConfig.lootTableConfig.isAlphaLoot) return true;
return null;
}
object CanPopulateLoot(LootContainer lootContainer) {
if (eventController == null || lootContainer == null || lootContainer.net == null) return null;
StorageContainerData storageContainerData = LootManager.GetContainerDataByNetId(lootContainer.net.ID.Value);
if (storageContainerData == null) return null;
CrateConfig crateConfig = LootManager.GetCrateConfigByPresetName(storageContainerData.presetName);
if (!crateConfig.lootTableConfig.isAlphaLoot) return true;
return null;
}
object OnCustomLootContainer(NetworkableId netID) {
if (eventController == null || netID == null) return null;
StorageContainerData storageContainerData = LootManager.GetContainerDataByNetId(netID.Value);
if (storageContainerData == null) return null;
CrateConfig crateConfig = LootManager.GetCrateConfigByPresetName(storageContainerData.presetName);
if (!crateConfig.lootTableConfig.isCustomLoot) return true;
return null;
}
object OnCustomLootNPC(NetworkableId netID) {
if (eventController == null || netID == null) return null;
ScientistNPC scientistNPC = NpcSpawnManager.GetScientistByNetId(netID.Value);
if (scientistNPC == null) return null;
NpcConfig npcConfig = NpcSpawnManager.GetNpcConfigByDisplayName(scientistNPC.displayName);
if (npcConfig != null && !npcConfig.lootTableConfig.isCustomLoot) return true;
return null;
}
object OnRestoreUponDeath(BasePlayer player) {
if (player == null || eventController == null) return null;
if (_config.supportedPluginsConfig.restoreUponDeath.disableRestore) {
ZoneController zoneController = ZoneController.GetZoneControllerByPlayerUserID(player.userID);
if (zoneController != null) return true;
}
return null;
}
void SetOwnerPveMode(string eventName, BasePlayer owner) {
if (eventController == null) return;
PveModeController pveModeController = PveModeController.GetPveControllerByZoneName(eventName);
if (pveModeController != null) pveModeController.OnNewOwnerSet(owner);
}
void ClearOwnerPveMode(string eventName) {
if (eventController == null) return;
PveModeController pveModeController = PveModeController.GetPveControllerByZoneName(eventName);
if (pveModeController != null) pveModeController.OnOwnerDeleted();
}
object OnCreateDynamicPVP(string eventName, PatrolHelicopter patrolHelicopter) {
if (eventController == null || patrolHelicopter == null || patrolHelicopter.net == null) return null;
if (ins._config.supportedPluginsConfig.betterNpcConfig.isHeliNpc) return null;
EventHeli eventHeli = EventHeli.GetEventHeliByNetId(patrolHelicopter.net.ID.Value);
if (eventHeli != null) return true;
return null;
}
#endregion OtherPlugins
#endregion Hooks
#region Commands
[ChatCommand("sputnikstart")]
void ChatStartCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (arg != null && arg.Length >= 1) EventLauncher.DelayStartEvent(false, player, arg[0]);
else EventLauncher.DelayStartEvent(false, player);
}
[ChatCommand("sputnikstop")]
void ChatStopCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
EventLauncher.StopEvent();
}
[ConsoleCommand("sputnikstart")]
void ConsoleStartCommand(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
if (arg.Args != null && arg.Args.Length > 0) EventLauncher.DelayStartEvent(false, null, arg.Args[0]);
else EventLauncher.DelayStartEvent(false);
}
[ConsoleCommand("sputnikstop")]
void ConsoleStopCommand(ConsoleSystem.Arg arg) {
if (arg.Player() == null) EventLauncher.StopEvent();
}
[ChatCommand("givespacecard")]
void GiveCustomItemChatCommand(BasePlayer player, string command, string[] arg) {
if (player == null || !player.IsAdmin || arg == null) return;
LootManager.GiveSpaceCardToPlayer(player);
PrintToChat(player, GetMessage("GetSpaceCard", player.UserIDString, _config.prefix));
}
[ConsoleCommand("givespacecard")]
void GiveCustomItemCommand(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
BasePlayer target = null;
if (arg.Args.Length >= 1) {
ulong userId = Convert.ToUInt64(arg.Args[0]);
target = BasePlayer.FindByID(userId);
}
if (target == null) {
PrintToConsole(player, "Player not found");
return;
}
LootManager.GiveSpaceCardToPlayer(target);
PrintToChat(target, GetMessage("GetSpaceCard", target.UserIDString, _config.prefix));
Puts($"A space card was given to {target.displayName}");
}
[ChatCommand("sputnikspawnpoint")]
void SpawnPointCommand(BasePlayer player, string command, string[] arg) {
if (!player.IsAdmin) return;
if (arg.Length <= 0) {
PrintToChat(player, _config.prefix + " Use the command: /sputnikspawnpoint <DebrisPresetName>");
return;
}
string sputnikPresetName = arg[0];
SputnikDebrisConfig sputnikDebrisConfig = _config.sputnikDebrisConfigs.FirstOrDefault(x => x.presetName == sputnikPresetName);
if (sputnikDebrisConfig == null) {
PrintToChat(player, _config.prefix + " <color=#ce3f27>Couldn't</color> find the preset");
return;
}
sputnikDebrisConfig.customSpawnPoints.Add(player.transform.position.ToString());
SaveConfig();
PrintToChat(player, _config.prefix + " New spawn point <color=#738d43>successfully</color> added");
}
#endregion Commands
#region Methods
void Unsubscribes(bool includePermanentHooks) {
foreach (string hook in subscribeMethods) if (includePermanentHooks || !permanentHooks.Contains(hook)) Unsubscribe(hook);
}
void UnsubscribesPermanentHooks() {
foreach (string hook in permanentHooks) Unsubscribe(hook);
}
void Subscribes(bool includePermanentHooks) {
foreach (string hook in subscribeMethods) if (includePermanentHooks || !permanentHooks.Contains(hook)) Subscribe(hook);
}
void UpdateConfig() {
PluginConfig defaultConfig = PluginConfig.DefaultConfig();
if (_config.version == Version) return;
if (_config.version.Minor == 0) {
if (_config.version.Patch <= 2) {
_config.supportedPluginsConfig.zoneManager = new ZoneManagerConfig {
enable = false, blockFlags = new HashSet<string> {
"eject", "pvegod"
}
}
;
}
if (_config.version.Patch <= 3) {
_config.supportedPluginsConfig.raidableBases = new RaidableBasesConfig();
_config.mainConfig.destroyAfterLootingTime = 300;
}
_config.version = new VersionNumber(1, 1, 0);
}
if (_config.version.Minor == 1) {
if (_config.version.Patch <= 2) {
_config.agressiveConfig = new AgressiveConfig {
agressiveSecurityMode = true, agressiveTime = 120, npcAgressiveMode = true, turretAgressiveMode = true, heliAgressiveMode = false,
}
;
foreach (SputnikDebrisConfig sputnikDebrisConfig in _config.sputnikDebrisConfigs) {
sputnikDebrisConfig.useCustomSpawnPoints = false;
sputnikDebrisConfig.customSpawnPoints = new List<string>();
}
}
_config.version = new VersionNumber(1, 2, 0);
}
if (_config.version.Minor == 2) {
if (_config.version.Patch == 0) {
foreach (HeliConfig heliConfig in _config.heliConfigs) {
heliConfig.outsideTime = 60;
}
}
if (_config.version.Patch <= 1) {
foreach (SputnikDebrisConfig sputnikDebrisConfig in _config.sputnikDebrisConfigs) {
sputnikDebrisConfig.markerConfig.isRingMarker = true;
sputnikDebrisConfig.markerConfig.isShopMarker = true;
}
}
if (_config.version.Patch <= 5) {
_config.supportedPluginsConfig.zoneManager.blockIDs = new HashSet<string> {
"Example"
}
;
_config.supportedPluginsConfig.restoreUponDeath = new RestoreUponDeathConfig {
disableRestore = false
}
;
}
_config.version = new VersionNumber(1, 3, 0);
}
if (_config.version.Minor == 3) {
if (_config.version.Patch == 0) {
_config.supportedPluginsConfig.pveMode.scaleDamage = new Dictionary<string, float> {
["Npc"]
= 1f, ["Helicopter"] = 2f, ["Turret"] = 2f,
}
;
}
if (_config.version.Patch <= 1) {
PrefabLootTableConfigs prefabConfigs = new PrefabLootTableConfigs {
isEnable = false, prefabs = new List<PrefabConfig> {
new PrefabConfig {
minLootScale = 1, maxLootScale = 1, prefabName = "assets/bundled/prefabs/radtown/underwater_labs/crate_food_1.prefab"
}
}
}
;
_config.notifyConfig.gameTipConfig = defaultConfig.notifyConfig.gameTipConfig;
foreach (CrateConfig crateConfig in _config.crateConfigs) {
if (crateConfig.lootTableConfig.items.Any(x => x.shortname == _config.customCardConfig.shortName)) crateConfig.lootTableConfig.isRandomItemsEnable = true;
crateConfig.lootTableConfig.prefabConfigs = prefabConfigs;
}
foreach (NpcConfig npcConfig in _config.npcConfigs) npcConfig.lootTableConfig.prefabConfigs = prefabConfigs;
foreach (EventConfig eventConfig in _config.eventConfigs) {
eventConfig.minTimeAfterWipe = 0;
eventConfig.maxTimeAfterWipe = -1;
}
_config.guiConfig.offsetMinY = defaultConfig.guiConfig.offsetMinY;
_config.supportedPluginsConfig.pveMode.cooldownOwner = defaultConfig.supportedPluginsConfig.pveMode.cooldownOwner;
_config.mainConfig.maxGroundDamageDistance = defaultConfig.mainConfig.maxGroundDamageDistance;
_config.mainConfig.maxHeliDamageDistance = defaultConfig.mainConfig.maxHeliDamageDistance;
_config.spawnConfig.isRiverDisbled = true;
_config.spawnConfig.isBeachDisbled = true;
_config.spawnConfig.isMonumentsDisbled = true;
_config.spawnConfig.isNearestPoint = true;
}
if (_config.version.Patch <= 4) {
ins._config.notifyConfig.isChatEnable = true;
}
if (_config.version.Patch <= 5) {
foreach (CrateConfig crateConfig in _config.crateConfigs) foreach (LootItemConfig lootItemConfig in crateConfig.lootTableConfig.items) lootItemConfig.genomes = new List<string>();
foreach (NpcConfig npcConfig in _config.npcConfigs) foreach (LootItemConfig lootItemConfig in npcConfig.lootTableConfig.items) lootItemConfig.genomes = new List<string>();
}
if (_config.version.Patch <= 7) {
ins._config.supportedPluginsConfig.pveMode.showEventOwnerNameOnMap = true;
}
_config.version = new VersionNumber(1, 4, 0);
}
if (_config.version.Minor == 4) {
if (_config.version.Patch == 0) {
LootTableConfig defaultLootTable = new LootTableConfig {
clearDefaultItemList = false, isAlphaLoot = false, isCustomLoot = false, prefabConfigs = new PrefabLootTableConfigs {
isEnable = false, prefabs = new List<PrefabConfig> {
new PrefabConfig {
minLootScale = 1, maxLootScale = 1, prefabName = "assets/bundled/prefabs/radtown/underwater_labs/crate_food_1.prefab"
}
}
}
, isRandomItemsEnable = false, maxItemsAmount = 1, minItemsAmount = 2, items = new List<LootItemConfig> {
new LootItemConfig {
shortname = "scrap", minAmount = 100, maxAmount = 200, chance = 100f, isBluePrint = false, skin = 0, name = "", genomes = new List<string>()
}
}
}
;
foreach (HeliConfig heliConfig in ins._config.heliConfigs) heliConfig.lootTableConfig = defaultLootTable;
_config.supportedPluginsConfig.betterNpcConfig = new BetterNpcConfig {
isHeliNpc = false,
}
;
}
if (_config.version.Patch <= 1) {
foreach (SputnikDebrisConfig sputnikDebrisConfig in _config.sputnikDebrisConfigs) {
sputnikDebrisConfig.zoneConfig.isColoredBorder = sputnikDebrisConfig.zoneConfig.isDome;
sputnikDebrisConfig.zoneConfig.brightness = 5;
sputnikDebrisConfig.zoneConfig.borderColor = 2;
}
}
}
_config.version = Version;
SaveConfig();
}
void UpdateLootTables() {
foreach (CrateConfig crateConfig in _config.crateConfigs) UpdateBaseLootTable(crateConfig.lootTableConfig);
foreach (NpcConfig npcConfig in _config.npcConfigs) UpdateBaseLootTable(npcConfig.lootTableConfig);
}
void UpdateBaseLootTable(LootTableConfig lootTableConfig) {
for (int i = 0; i < lootTableConfig.items.Count; i++) {
LootItemConfig lootItemConfig = lootTableConfig.items[i];
if (lootItemConfig.chance <= 0) lootTableConfig.items.RemoveAt(i);
}
lootTableConfig.items = lootTableConfig.items.OrderByQuickSort(x => x.chance);
if (lootTableConfig.maxItemsAmount > lootTableConfig.items.Count) lootTableConfig.maxItemsAmount = lootTableConfig.items.Count;
if (lootTableConfig.minItemsAmount > lootTableConfig.maxItemsAmount) lootTableConfig.minItemsAmount = lootTableConfig.maxItemsAmount;
}
#endregion Methods
#region Classes
static class EventLauncher {
static Coroutine autoEventCoroutine;
static Coroutine delayedEventStartCorountine;
internal static bool IsEventActive() {
return ins != null && ins.eventController != null;
}
internal static void AutoStartEvent() {
if (!ins._config.mainConfig.isAutoEvent) return;
if (autoEventCoroutine != null) return;
autoEventCoroutine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
}
static IEnumerator AutoEventCorountine() {
yield return CoroutineEx.waitForSeconds(5f);
yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(ins._config.mainConfig.minTimeBetweenEvents, ins._config.mainConfig.maxTimeBetweenEvents));
DelayStartEvent(true);
autoEventCoroutine = null;
}
internal static void DelayStartEvent(bool isAutoActivated = false, BasePlayer activator = null, string presetName = "") {
if (IsEventActive() || delayedEventStartCorountine != null) {
NotifyManager.PrintError(activator, "EventActive_Exeption");
return;
}
if (autoEventCoroutine != null) ServerMgr.Instance.StopCoroutine(autoEventCoroutine);
EventConfig eventConfig = DefineEventConfig(presetName);
if (eventConfig == null) {
NotifyManager.PrintError(activator, "ConfigurationNotFound_Exeption");
StopEvent(shoudSendEndMessage : false);
return;
}
delayedEventStartCorountine = ServerMgr.Instance.StartCoroutine(DelayedStartEventCorountine(eventConfig));
if (!isAutoActivated && ins._config.notifyConfig.preStartTime > 0) NotifyManager.PrintInfoMessage(activator, "SuccessfullyLaunched");
}
static EventConfig DefineEventConfig(string eventPresetName = "") {
if (eventPresetName != "") return ins._config.eventConfigs.FirstOrDefault(x => x.presetName == eventPresetName);
HashSet<EventConfig> suitableEventConfigs = ins._config.eventConfigs.Where(x => x.chance > 0 && IsEventConfigSuitableByTime(x));
if (suitableEventConfigs == null || suitableEventConfigs.Count == 0) return null;
float sumChance = 0;
foreach (EventConfig eventConfig in suitableEventConfigs) sumChance += eventConfig.chance;
float random = UnityEngine.Random.Range(0, sumChance);
foreach (EventConfig eventConfig in suitableEventConfigs) {
random -= eventConfig.chance;
if (random <= 0) return eventConfig;
}
return null;
}
static IEnumerator DelayedStartEventCorountine(EventConfig eventConfig) {
if (ins._config.notifyConfig.preStartTime > 0) NotifyManager.SendMessageToAll("PreStartEvent", ins._config.prefix, eventConfig.displayName, ins._config.notifyConfig.preStartTime);
yield return CoroutineEx.waitForSeconds(ins._config.notifyConfig.preStartTime);
StartEvent(eventConfig);
}
static void StartEvent(EventConfig eventConfig) {
GameObject gameObject = new GameObject();
ins.eventController = gameObject.AddComponent<EventController>();
ins.eventController.Init(eventConfig);
if (ins._config.mainConfig.enableStartStopLogs) NotifyManager.PrintLogMessage("EventStart_Log", eventConfig.presetName);
Interface.CallHook("OnSputnikEventStart");
}
static bool IsEventConfigSuitableByTime(EventConfig eventConfig) {
if (eventConfig.minTimeAfterWipe <= 0 && eventConfig.maxTimeAfterWipe <= 0) return true;
int timeScienceWipe = GetTimeScienceLastWipe();
if (timeScienceWipe < eventConfig.minTimeAfterWipe) return false;
if (eventConfig.maxTimeAfterWipe > 0 && timeScienceWipe > eventConfig.maxTimeAfterWipe) return false;
return true;
}
static int GetTimeScienceLastWipe() {
DateTime startTime = new DateTime(2019, 1, 1, 0, 0, 0);
double realTime = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
double wipeTime = SaveRestore.SaveCreatedTime.Subtract(startTime).TotalSeconds;
return Convert.ToInt32(realTime - wipeTime);
}
internal static void StopEvent(bool isPluginUnloading = false, bool shoudSendEndMessage = true) {
if (IsEventActive()) {
ins.Unsubscribes(false);
ins.eventController.KillController();
SputnikClass.KillAllSputniks();
Interface.CallHook("OnSputnikEventStop");
if (shoudSendEndMessage) NotifyManager.SendMessageToAll("EndEvent", ins._config.prefix);
if (ins._config.mainConfig.enableStartStopLogs) NotifyManager.PrintLogMessage("EventStop_Log");
LootManager.ClearLootData();
EconomyManager.OnEventEnd();
NpcSpawnManager.ClearData();
PveModeController.SendCooldownAndClearData();
EventHeli.ClearData();
if (!isPluginUnloading) AutoStartEvent();
}
ZoneController.ClearData();
if (delayedEventStartCorountine != null) {
ServerMgr.Instance.StopCoroutine(delayedEventStartCorountine);
delayedEventStartCorountine = null;
}
}
}
class EventController : FacepunchBehaviour {
EventConfig eventConfig;
Coroutine eventCorountine;
int eventTime;
internal int GetEventTime() {
return eventTime;
}
internal void Init(EventConfig eventConfig) {
this.eventConfig = eventConfig;
eventTime = eventConfig.eventTime;
SpawnPositionFinder.UpdateCachedPoints();
if (TrySpawnSputniks()) {
NotifyManager.SendMessageToAll("StartEvent", ins._config.prefix, eventConfig.displayName);
SputnikClass.StartAllSputniksFalling();
SpawnPositionFinder.StartCachingSpawnPoints();
eventCorountine = ServerMgr.Instance.StartCoroutine(EventCorountine());
ins.Subscribes(true);
}
else {
EventLauncher.StopEvent(shoudSendEndMessage : false);
}
}
bool TrySpawnSputniks() {
if (eventConfig.fixedSputniksPresets != null && eventConfig.fixedSputniksPresets.Count > 0) {
if (SpawnPositionFinder.GetCountSpawnPoints() < eventConfig.fixedSputniksPresets.Count) return false;
Vector3 lastSputnikPosition = Vector3.zero;
foreach (string sputnikDebrisPresetName in eventConfig.fixedSputniksPresets) {
SputnikDebrisConfig sputnikDebrisConfig = ins._config.sputnikDebrisConfigs.FirstOrDefault(x => x.presetName == sputnikDebrisPresetName);
if (sputnikDebrisConfig == null) {
ins.PrintError($"Sputnik debris preset not found! (PresetName - {sputnikDebrisPresetName})");
continue;
}
Vector3 sputnikPosition = SpawnPositionFinder.GetSpawnPosition(sputnikDebrisConfig, lastSputnikPosition);
if (sputnikPosition == null || sputnikPosition == Vector3.zero) {
ins.PrintError("The event could not be started! Increase the number of cached spawn points!");
return false;
}
SputnikClass.CreateSputnik(sputnikDebrisConfig, sputnikPosition);
lastSputnikPosition = sputnikPosition;
}
}
if (SputnikClass.IsAnySputnikAlive()) return true;
else return false;
}
IEnumerator EventCorountine() {
while (eventTime > 0 && SputnikClass.IsAnySputnikAlive()) {
eventTime -= 1;
if (ins._config.notifyConfig.timeNotifications.Contains(eventTime)) NotifyManager.SendMessageToAll("RemainTime", ins._config.prefix, eventConfig.displayName, eventTime);
yield return CoroutineEx.waitForSeconds(1);
}
EventLauncher.StopEvent();
}
internal void KillController() {
if (eventCorountine != null) ServerMgr.Instance.StopCoroutine(eventCorountine);
GameObject.Destroy(this);
ins.eventController = null;
}
}
class SputnikClass : FacepunchBehaviour {
static HashSet<SputnikClass> sputnikClasses = new HashSet<SputnikClass>();
internal SputnikDebrisConfig sputnikDebrisConfig;
internal PveModeController pveModeController;
EventHeli eventHeli;
ZoneController zoneController;
Coroutine sputnikCorountine;
FallingSputnikEffect fallingSputnikEffect;
EventMapMarker eventMapMarker;
CardReader cardReader;
HashSet<ScientistNPC> npcs = new HashSet<ScientistNPC>();
HashSet<LootContainer> crates = new HashSet<LootContainer>();
HashSet<AutoTurret> turrets = new HashSet<AutoTurret>();
HashSet<Landmine> mines = new HashSet<Landmine>();
HashSet<BaseEntity> decorEntities = new HashSet<BaseEntity>();
bool cardReaderOpen = true;
int destroyTime = 0;
int agressiveTime = 0;
bool isEventLooted;
internal static bool IsAnySputnikAlive() {
return sputnikClasses.Any(x => x != null);
}
internal static SputnikClass GetSputnikByCrateUid(ulong netID) {
return sputnikClasses.FirstOrDefault(x => x != null && x.crates.Any(y => y.IsExists() && y.net != null && y.net.ID.Value == netID));
}
internal static SputnikClass GetSputnikByCardReaderUid(ulong netID) {
return sputnikClasses.FirstOrDefault(x => x != null && x.cardReader != null && x.cardReader.net.ID.Value == netID);
}
internal static SputnikClass GetSputnikByTurretUid(ulong netID) {
return sputnikClasses.FirstOrDefault(x => x != null && x.turrets.Any(y => y.IsExists() && y.net.ID.Value == netID));
}
internal static SputnikClass GetSputnikByLandmineUid(ulong netID) {
return sputnikClasses.FirstOrDefault(x => x != null && x.mines.Any(y => y.IsExists() && y.net.ID.Value == netID));
}
internal static SputnikClass GetSputnikByNpcUid(ulong netID) {
return sputnikClasses.FirstOrDefault(x => x != null && x.npcs.Any(y => y.IsExists() && y.net.ID.Value == netID));
}
internal static void CreateSputnik(SputnikDebrisConfig sputnikDebrisConfig, Vector3 position) {
GameObject gameObject = new GameObject();
gameObject.layer = (int)Layer.Reserved1;
gameObject.transform.position = position;
SputnikClass sputnik = gameObject.AddComponent<SputnikClass>();
sputnik.Init(sputnikDebrisConfig);
sputnikClasses.Add(sputnik);
}
internal Vector3 GetEventPosition() {
return transform.position;
}
internal static void StartAllSputniksFalling() {
foreach (SputnikClass sputnikClass in sputnikClasses) if (sputnikClass != null) sputnikClass.StartFalling();
}
internal int GetCountOfUnlootedCrates() {
return crates.Where(x => x.IsExists() && x.FirstLooterId == 0).Count;
}
internal int GetCountOfAliveNpc() {
return npcs.Where(x => x.IsExists()).Count;
}
internal int GetEventTime() {
return destroyTime;
}
internal bool IsPlayerCanDealDamage(BasePlayer player, BaseCombatEntity sputnikEntity, bool shoudSendMessages) {
Vector3 playerGroundPosition = new Vector3(player.transform.position.x, 0, player.transform.position.z);
Vector3 entityGroundPosition = new Vector3(sputnikEntity.transform.position.x, 0, sputnikEntity.transform.position.z);
float distance = Vector3.Distance(playerGroundPosition, entityGroundPosition);
float maxDamageDistance = sputnikEntity is PatrolHelicopter ? ins._config.mainConfig.maxHeliDamageDistance : ins._config.mainConfig.maxGroundDamageDistance;
if (maxDamageDistance > 0 && distance > maxDamageDistance) {
if (shoudSendMessages) NotifyManager.SendMessageToPlayer(player, "DamageDistance", ins._config.prefix);
return false;
}
return true;
}
internal bool IsPveModeBlockAction(BasePlayer player) {
return pveModeController != null && pveModeController.IsPveModeBlockAction(player);
}
internal bool IsAgressive() {
return ins._config.agressiveConfig.agressiveSecurityMode || agressiveTime > 0;
}
internal void OnSputnikAttacked() {
if (ins._config.agressiveConfig.agressiveSecurityMode) return;
if (!ins._config.agressiveConfig.makeAllSputniksAgressive) UpdateAgressive();
else foreach (SputnikClass sputnikClass in sputnikClasses) if (sputnikClass != null) sputnikClass.UpdateAgressive();
}
void UpdateAgressive() {
if (agressiveTime <= 0) MakeSputnikAgressive();
agressiveTime = ins._config.agressiveConfig.agressiveTime;
}
internal bool IsCardReaderExistAndClosed() {
return cardReader.IsExists() && !cardReaderOpen;
}
internal void CheckEventPassing() {
// ... [Code preview truncated due to length. Full source in attached file] ...