Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalWorkingConditions v0.1.5
LethalWorkingConditions.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib; using LethalLib.Modules; using LethalWorkingConditions.Classes.ChatCommand; using LethalWorkingConditions.Classes.ChatCommand.Commands; using LethalWorkingConditions.Classes.LightAnomaly; using LethalWorkingConditions.Classes.MonsterEvent; using LethalWorkingConditions.Classes.MonsterEvent.Events; using LethalWorkingConditions.Helpers; using LethalWorkingConditions.MonoBehaviours; using LethalWorkingConditions.Patches; using Unity.Netcode; using Unity.Netcode.Components; using UnityEngine; using UnityEngine.EventSystems; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LethalWorkingCondition")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LethalWorkingCondition")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6efab151-7ff3-4bb1-a345-7f43604d9c10")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace LethalWorkingConditions { internal class AssetBundleStuff { public class CustomEnemy { public string name; public string enemyPath; public int rarity; public LevelTypes levelFlags; public SpawnType spawnType; public string infoKeyword; public string infoNode; public bool enabled = true; public CustomEnemy(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) this.name = name; this.enemyPath = enemyPath; this.rarity = rarity; this.levelFlags = levelFlags; this.spawnType = spawnType; this.infoKeyword = infoKeyword; this.infoNode = infoNode; } public static CustomEnemy Add(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode, bool enabled = true) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) CustomEnemy customEnemy = new CustomEnemy(name, enemyPath, rarity, levelFlags, spawnType, infoKeyword, infoNode); customEnemy.enabled = enabled; return customEnemy; } } public class CustomItem { public string name = ""; public string itemPath = ""; public string infoPath = ""; public Action<Item> itemAction = delegate { }; public bool enabled = true; public CustomItem(string name, string itemPath, string infoPath, Action<Item> action = null) { this.name = name; this.itemPath = itemPath; this.infoPath = infoPath; if (action != null) { itemAction = action; } } public static CustomItem Add(string name, string itemPath, string infoPath = null, Action<Item> action = null) { return new CustomItem(name, itemPath, infoPath, action); } } public class CustomScrap : CustomItem { public LevelTypes levelType = (LevelTypes)(-1); public int rarity = 0; public CustomScrap(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null) : base(name, itemPath, null, action) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) this.levelType = levelType; this.rarity = rarity; } public static CustomScrap Add(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return new CustomScrap(name, itemPath, levelType, rarity, action); } } public class CustomShopItem : CustomItem { public int itemPrice = 0; public CustomShopItem(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null) : base(name, itemPath, infoPath, action) { this.itemPrice = itemPrice; } public static CustomShopItem Add(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null, bool enabled = true) { CustomShopItem customShopItem = new CustomShopItem(name, itemPath, infoPath, itemPrice, action); customShopItem.enabled = enabled; return customShopItem; } } } public class LWCConfig { public readonly string Name = "LethalWorkingConditions"; public static readonly string TerminalCommandPrefixDefault = "/"; public static ConfigEntry<string> TerminalCommandPrefix; public static readonly bool TerminalCommandDisableChatDefault = false; public static ConfigEntry<bool> TerminalCommandDisableChat; public static readonly bool MonsterEventsEnabledDefault = true; public static ConfigEntry<bool> MonsterEventsEnabled; public LWCConfig(ConfigFile cfg) { TerminalCommandPrefix = cfg.Bind<string>(Name, "TerminalCommandPrefix", TerminalCommandPrefixDefault, "Prefix for chat commands"); TerminalCommandDisableChat = cfg.Bind<bool>(Name, "TerminalCommandDisableChat", TerminalCommandDisableChatDefault, "If enabled, your chat messages will not be sent to other clients"); MonsterEventsEnabled = cfg.Bind<bool>(Name, "MonsterEventsEnabled", MonsterEventsEnabledDefault, "If enabled, monster events can occure"); } } internal class Content { private static LWCLogger logger = new LWCLogger("Content"); public static AssetBundle MainAssetsBundle; private static readonly string mainAssetBundleName = "lethalworkingconditions"; public static Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>(); public static List<AssetBundleStuff.CustomEnemy> customEnemies; public static List<AssetBundleStuff.CustomItem> customItems = new List<AssetBundleStuff.CustomItem>(); private static void TryLoadAssets() { MainAssetsBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), mainAssetBundleName)); if ((Object)(object)MainAssetsBundle != (Object)null) { logger.LogInfo("AssetBundle loaded"); } else { logger.LogError("Could not load AssetBundle from " + mainAssetBundleName); } } private static void LoadPatches() { LethalWorkingConditions.harmony.PatchAll(typeof(RoundManagerBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(HUDManagerBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(BridgeTriggerBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(QuicksandTriggerBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(SprayPaintItemBPatch)); LethalWorkingConditions.harmony.PatchAll(typeof(TimeOfDayBPatch)); logger.LogInfo("Patches loaded"); } private static void RegisterCustomScrapItems() { //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MainAssetsBundle == (Object)null) { logger.LogError("Cannot register custom items because AssetBundle is empty"); return; } foreach (AssetBundleStuff.CustomItem customItem in customItems) { if (customItem.enabled) { Item val = MainAssetsBundle.LoadAsset<Item>(customItem.itemPath); if ((Object)(object)val.spawnPrefab.GetComponent<NetworkTransform>() == (Object)null && (Object)(object)val.spawnPrefab.GetComponent<CustomNetworkTransform>() == (Object)null) { NetworkTransform val2 = val.spawnPrefab.AddComponent<NetworkTransform>(); val2.SlerpPosition = false; val2.Interpolate = false; val2.SyncPositionX = false; val2.SyncPositionY = false; val2.SyncPositionZ = false; val2.SyncScaleX = false; val2.SyncScaleY = false; val2.SyncScaleZ = false; val2.UseHalfFloatPrecision = true; } Prefabs.Add(customItem.name, val.spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); customItem.itemAction(val); if (customItem is AssetBundleStuff.CustomShopItem customShopItem) { TerminalNode val3 = MainAssetsBundle.LoadAsset<TerminalNode>(customShopItem.infoPath); Plugin.logger.LogInfo((object)$"Registering shop item {customItem.name} with price {customShopItem.itemPrice}"); Items.RegisterShopItem(val, (TerminalNode)null, (TerminalNode)null, val3, customShopItem.itemPrice); } else if (customItem is AssetBundleStuff.CustomScrap customScrap) { Plugin.logger.LogInfo((object)$"Registering scrap item {customScrap.name} with price rarity:{customScrap.rarity} and leveltype:{customScrap.levelType}"); Items.RegisterScrap(val, customScrap.rarity, customScrap.levelType); } } } logger.LogInfo("CustomItems loaded"); } public static void Load() { LethalWorkingConditions.harmony.PatchAll(typeof(LethalWorkingConditions)); LoadPatches(); TryLoadAssets(); RegisterCustomScrapItems(); foreach (KeyValuePair<string, GameObject> prefab in Prefabs) { GameObject value = prefab.Value; string key = prefab.Key; AudioSource[] componentsInChildren = value.GetComponentsInChildren<AudioSource>(); if (componentsInChildren.Length != 0) { AudioSource[] array = componentsInChildren; foreach (AudioSource val in array) { val.volume *= 1f; } } } logger.LogInfo("Mod content loaded"); } } [BepInPlugin("Trebossa.LethalWorkingConditions", "Lethal Working Conditions", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LethalWorkingConditions : BaseUnityPlugin { public const string modGUID = "Trebossa.LethalWorkingConditions"; public const string modName = "Lethal Working Conditions"; public const string modVersion = "0.1.4"; public static readonly Harmony harmony = new Harmony("Trebossa.LethalWorkingConditions"); public static LethalWorkingConditions Instance; private static LWCLogger logger; public static LWCConfig Config { get; internal set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Config = new LWCConfig(((BaseUnityPlugin)this).Config); LWCLogger.Init(); logger = new LWCLogger("LWC"); Content.Load(); logger.LogInfo("Done loading config"); } } } namespace LethalWorkingConditions.Patches { [HarmonyPatch(typeof(BridgeTrigger))] internal class BridgeTriggerBPatch { [HarmonyPatch("OnEnable")] [HarmonyPrefix] private static void BridgeTriggerBPatch_OnEnable_Prefix(ref float ___bridgeDurability) { ___bridgeDurability = 0.6f; } } [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerBPatch { private static bool chatDisabled = LWCConfig.TerminalCommandDisableChat.Value; [HarmonyPatch("SubmitChat_performed")] [HarmonyPrefix] private static bool HUDManager_SubmitChat_performed_Prefix(ref HUDManager __instance) { string text = __instance.chatTextField.text; if (!text.ToLower().StartsWith(ChatCommand.CommandPrefix) && !chatDisabled) { return true; } CommandStatus commandStatus = HandleCommandLogic(text, ref __instance); CleanupGUI(ref __instance); if (commandStatus == CommandStatus.NOT_SET && !chatDisabled) { return true; } return false; } private static CommandStatus HandleCommandLogic(string text, ref HUDManager __instance) { CommandStatus result = CommandStatus.NOT_SET; if (text.ToLower().StartsWith(ChatCommand.CommandPrefix + "spawn")) { SpawnCommand spawnCommand = new SpawnCommand(ref __instance); result = spawnCommand.ExecuteCommand(); } return result; } private static void CleanupGUI(ref HUDManager __instance) { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; localPlayerController.isTypingChat = false; __instance.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); __instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f); ((Behaviour)__instance.typingIndicator).enabled = false; } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch { } [HarmonyPatch(typeof(QuicksandTrigger))] internal class QuicksandTriggerBPatch { [HarmonyPatch("OnTriggerStay")] [HarmonyPrefix] private static void QuicksandTriggerBPatch_OnTriggerStay_Prefix(ref float ___movementHinderance, ref float ___sinkingSpeedMultiplier) { ___movementHinderance = 3f; ___sinkingSpeedMultiplier = 0.5f; } } [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerBPatch { internal static bool isHost; internal static RoundManager currentRound; internal static SelectableLevel currentLevel; internal static EnemyVent[] currentLevelVents; [HarmonyPatch("Start")] [HarmonyPrefix] private static void RoundManagerBPatch_Start_Prefix(ref float ___mapSizeMultiplier) { ___mapSizeMultiplier = 1.5f; isHost = ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost; } [HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPrefix] private static void RoundManagerBPatch_AdvanceHourAndSpawnNewBatchOfEnemies_Prefix(ref EnemyVent[] ___allEnemyVents, ref SelectableLevel ___currentLevel) { currentLevel = ___currentLevel; currentLevelVents = ___allEnemyVents; MonsterEventManager.activeEvent?.Bind_AdvanceHourAndSpawnNewBatchOfEnemies(); } [HarmonyPatch("LoadNewLevel")] [HarmonyPrefix] private static void RoundManagerBPatch_LoadNewLevel_Prefix(ref SelectableLevel newLevel) { currentRound = RoundManager.Instance; MonsterEventManager.activeEvent?.Bind_On_LoadNewLevel(); } } [HarmonyPatch(typeof(SprayPaintItem))] internal class SprayPaintItemBPatch { [HarmonyPatch("Start")] [HarmonyPrefix] private static void SprayPaintItemBPatch_Start_Prefix(ref float ___sprayCanTank) { ___sprayCanTank = 4f; } } [HarmonyPatch(typeof(TimeOfDay))] internal class TimeOfDayBPatch { } } namespace LethalWorkingConditions.MonoBehaviours { public class CustomNetworkTransform : NetworkBehaviour { public bool syncPosition = true; public bool syncRotation = true; public bool syncScale = true; public float positionDiffLimit = 0.1f; public float rotationDiffLimit = 0.1f; public float scaleDiffLimit = 0.1f; public bool lerpPosition = true; public bool lerpRotation = true; public bool lerpScale = true; public float positionLerpSpeed = 10f; public float rotationLerpSpeed = 10f; public float scaleLerpSpeed = 10f; private Vector3 _lastPosition; private Vector3 _lastRotation; private Vector3 _lastScale; private Vector3 _targetPosition; private Quaternion _targetRotation; private Vector3 _targetScale; public void FixedUpdate() { //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer) { if (syncPosition && Vector3.Distance(((Component)this).transform.position, _lastPosition) > positionDiffLimit) { _lastPosition = ((Component)this).transform.position; UpdatePositionClientRpc(((Component)this).transform.position); } if (syncRotation && Quaternion.Angle(Quaternion.Euler(((Component)this).transform.eulerAngles), Quaternion.Euler(_lastRotation)) > rotationDiffLimit) { _lastRotation = ((Component)this).transform.eulerAngles; UpdateRotationClientRpc(((Component)this).transform.eulerAngles); } if (syncScale && Vector3.Distance(((Component)this).transform.localScale, _lastScale) > scaleDiffLimit) { _lastScale = ((Component)this).transform.localScale; UpdateScaleClientRpc(((Component)this).transform.localScale); } } else { if (lerpPosition) { ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, _targetPosition, Time.fixedDeltaTime * positionLerpSpeed); } if (lerpRotation) { ((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, _targetRotation, Time.fixedDeltaTime * rotationLerpSpeed); } if (lerpScale) { ((Component)this).transform.localScale = Vector3.Lerp(((Component)this).transform.localScale, _targetScale, Time.fixedDeltaTime * scaleLerpSpeed); } } } [ClientRpc] public void UpdatePositionClientRpc(Vector3 position) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer && syncPosition) { if (lerpPosition) { _targetPosition = position; } else { ((Component)this).transform.position = position; } } } [ClientRpc] public void UpdateRotationClientRpc(Vector3 rotation) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer && syncRotation) { if (lerpRotation) { _targetRotation = Quaternion.Euler(rotation); } else { ((Component)this).transform.rotation = Quaternion.Euler(rotation); } } } [ClientRpc] public void UpdateScaleClientRpc(Vector3 scale) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer && syncScale) { if (lerpScale) { _targetScale = scale; } else { ((Component)this).transform.localScale = scale; } } } } internal class LethalGigaAI : CrawlerAI { } } namespace LethalWorkingConditions.Helpers { internal class CoroutineHelper : MonoBehaviour { private static LWCLogger logger = new LWCLogger("CoroutineHelper"); private static CoroutineHelper instance; public CoroutineHelper() { if ((Object)(object)instance == (Object)null) { instance = this; } } public static void Sleep(float seconds) { if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(SleepCoroutine(seconds)); } else { logger.LogError("CoroutineHelper instance is null. Make sure its constructed somwhere."); } } private static IEnumerator SleepCoroutine(float durationSeconds) { yield return (object)new WaitForSecondsRealtime(durationSeconds); } } internal class LWCLogger { public static ManualLogSource pluginMls; public readonly string source; public LWCLogger(string source) { this.source = source; } public static void Init() { pluginMls = Logger.CreateLogSource("Trebossa.LethalWorkingConditions"); } public void LogInfo(string message) { if (pluginMls != null) { pluginMls.LogInfo((object)("[" + source + "] " + message)); } } public void LogWarning(string message) { if (pluginMls != null) { pluginMls.LogWarning((object)("[" + source + "] " + message)); } } public void LogError(string message) { if (pluginMls != null) { pluginMls.LogError((object)("[" + source + "] " + message)); } } } } namespace LethalWorkingConditions.Classes { [HarmonyPatch(typeof(RoundManager))] internal class FlickerLightsBClass { private LWCLogger logger = new LWCLogger("FlickerLightsBClass"); private static LightAnomalyEventManager lightFlickerEventManager; private static bool initaliedYet; [HarmonyPatch("SetPowerOffAtStart")] [HarmonyPrefix] private static void LoadLightAnomalyEventManager(ref RoundManager __instance) { if (!initaliedYet) { lightFlickerEventManager = new LightAnomalyEventManager(ref __instance); lightFlickerEventManager.Awake(); initaliedYet = true; } } } internal class LightAnomalyEventManager { private LWCLogger logger = new LWCLogger("LightAnomalyEventManager"); private readonly int lightAnomalyEventIntervalMS = 60000; private RoundManager roundManager; private Random randomGenerator = new Random(); private Timer lightFlickTimer; private readonly UncommonLightAnomaly uncommonLightAnomaly; public LightAnomalyEventManager(ref RoundManager instance) { roundManager = instance; uncommonLightAnomaly = new UncommonLightAnomaly(ref instance); } public void Awake() { logger.LogInfo("LightAnomalyEventManager::Awake()"); lightFlickTimer = new Timer(Tick, null, 0, lightAnomalyEventIntervalMS); } public void Unload() { uncommonLightAnomaly.Dispose(); lightFlickTimer.Dispose(); } private void Tick(object state) { int num = randomGenerator.Next(0, 100); logger.LogInfo($"LightAnomalyEventManager::Tick() - {num}"); roundManager.FlickerLights(true, true); uncommonLightAnomaly.InitalizeVariables(); uncommonLightAnomaly.Start(); } } internal class EnemySpawner { private static LWCLogger logger = new LWCLogger("EnemySpawner"); public static List<SpawnableEnemyWithRarity> EnemiesInside => RoundManagerBPatch.currentLevel.Enemies; public static List<SpawnableEnemyWithRarity> EnemiesOutside => RoundManagerBPatch.currentLevel.OutsideEnemies; public static void SpawnEnemy(SpawnableEnemyWithRarity enemy, int amount, bool inside) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!RoundManagerBPatch.isHost) { logger.LogInfo("Could not spawn enemies because user is not host"); return; } if (inside) { try { for (int i = 0; i < amount; i++) { RoundManagerBPatch.currentRound.SpawnEnemyOnServer(RoundManagerBPatch.currentRound.allEnemyVents[Random.Range(0, RoundManagerBPatch.currentRound.allEnemyVents.Length)].floorNode.position, RoundManagerBPatch.currentRound.allEnemyVents[i].floorNode.eulerAngles.y, RoundManagerBPatch.currentLevel.Enemies.IndexOf(enemy)); } return; } catch { logger.LogWarning("Failed to spawn enemies, check your command."); return; } } try { for (int j = 0; j < amount; j++) { GameObject val = Object.Instantiate<GameObject>(RoundManagerBPatch.currentLevel.OutsideEnemies[RoundManagerBPatch.currentLevel.OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length - 1)].transform.position, Quaternion.Euler(Vector3.zero)); val.gameObject.GetComponentInChildren<NetworkObject>().Spawn(true); } } catch { logger.LogWarning("Failed to spawn enemies, check your command."); } } public static SpawnableEnemyWithRarity FindEnemy(List<SpawnableEnemyWithRarity> list, string search) { return list.Find((SpawnableEnemyWithRarity e) => e.enemyType.enemyName.ToLower().Contains(search.ToLower())); } } } namespace LethalWorkingConditions.Classes.MonsterEvent { internal abstract class MonsterEvent { private LWCLogger logger; public readonly string eventName; private string noticeTitle => "Monster Event: " + eventName; protected abstract void On_LoadNewLevel(); protected abstract void On_AdvanceHourAndSpawnNewBatchOfEnemies(); public MonsterEvent(string eventName) { this.eventName = eventName; logger = new LWCLogger("MonsterEvent::" + eventName); } protected void IssueNotification(string text) { HUDManager.Instance.DisplayTip(noticeTitle, text, false, false, "LC_Tip1"); logger.LogInfo(noticeTitle + ": " + text); } public void Bind_On_LoadNewLevel() { logger.LogInfo("On_LoadNewLevel()"); On_LoadNewLevel(); } public void Bind_AdvanceHourAndSpawnNewBatchOfEnemies() { logger.LogInfo("On_PlotOutEnemiesForNextHour()"); On_AdvanceHourAndSpawnNewBatchOfEnemies(); } } internal class MonsterEventManager { internal static LWCLogger logger = new LWCLogger("MonsterEventManager"); internal static MonsterEvent activeEvent = null; internal static Random randomGenerator = new Random(); internal static void IssueNotification(string title, string message) { if (activeEvent != null) { HUDManager.Instance.DisplayTip(title, message, false, false, "LC_Tip1"); logger.LogInfo(title + ": " + message); } } private static MonsterEvent GetRandomEvent() { int num = randomGenerator.Next(0, 100); if (num >= 50) { return new SpiderEvent(); } return new HoardingBugEvent(); } internal static void GenerateNewEvent() { activeEvent = GetRandomEvent(); logger.LogInfo("GenerateNewEvent()"); IssueNotification("Monster Event", activeEvent.eventName); } } } namespace LethalWorkingConditions.Classes.MonsterEvent.Events { internal class HoardingBugEvent : MonsterEvent { private readonly Random randomGenerator = new Random(); private readonly int initialSpawnAmount; private int multiplier; protected SpawnableEnemyWithRarity hoardingBugEnemy = EnemySpawner.FindEnemy(EnemySpawner.EnemiesInside, "hoarding"); public HoardingBugEvent() : base("Smaug") { initialSpawnAmount = randomGenerator.Next(4, 10); multiplier = 1; } protected override void On_LoadNewLevel() { EnemySpawner.SpawnEnemy(hoardingBugEnemy, initialSpawnAmount, inside: true); } protected override void On_AdvanceHourAndSpawnNewBatchOfEnemies() { int num = 2 * multiplier; multiplier *= 3; EnemySpawner.SpawnEnemy(hoardingBugEnemy, num, inside: true); IssueNotification($"Spawned {num} of {hoardingBugEnemy.enemyType.enemyName}"); } } internal class SpiderEvent : MonsterEvent { private readonly Random randomGenerator = new Random(); private readonly int initialSpawnAmount; private int multiplier; protected SpawnableEnemyWithRarity spiderEnemy = EnemySpawner.FindEnemy(EnemySpawner.EnemiesInside, "spider"); public SpiderEvent() : base("Spider cocoon") { initialSpawnAmount = randomGenerator.Next(2, 5); multiplier = 1; } protected override void On_LoadNewLevel() { EnemySpawner.SpawnEnemy(spiderEnemy, initialSpawnAmount, inside: true); } protected override void On_AdvanceHourAndSpawnNewBatchOfEnemies() { int num = 2 * multiplier; multiplier *= 2; EnemySpawner.SpawnEnemy(spiderEnemy, num, inside: true); IssueNotification($"Spawned {num} of {spiderEnemy.enemyType.enemyName}"); } } } namespace LethalWorkingConditions.Classes.LightAnomaly { internal class BaseLightAnomaly { private protected Random randomGenerator = new Random(); private protected RoundManager roundManager; public BaseLightAnomaly(ref RoundManager manager) { roundManager = manager; } private protected void FlickerLights() { roundManager.FlickerLights(true, true); } } internal class UncommonLightAnomaly : BaseLightAnomaly { private static LWCLogger logger = new LWCLogger("UncommonLightAnomaly"); private bool initalized = false; private int executionIndex = 0; private int maxExecutions; private int intervalInSeconds; private Timer timer; public UncommonLightAnomaly(ref RoundManager manager) : base(ref manager) { roundManager = manager; } public void InitalizeVariables() { maxExecutions = randomGenerator.Next(5, 6); intervalInSeconds = randomGenerator.Next(5, 6); initalized = true; } public void Start() { if (!initalized) { logger.LogWarning("UncommonLightAnomaly::Start() - Could not start because Instance is not initalized"); return; } logger.LogInfo($"UncommonLightAnomaly::Start() - {maxExecutions}/{intervalInSeconds}"); timer = new Timer(Tick, null, 0, intervalInSeconds * 1000); } public void Dispose() { logger.LogInfo("UncommonLightAnomaly::Dispose()"); timer.Dispose(); } private void Tick(object sender) { logger.LogInfo("UncommonLightAnomaly::Tick()"); if (executionIndex >= maxExecutions) { logger.LogInfo("UncommonLightAnomaly::Tick() - Cleanup"); timer.Dispose(); } else { executionIndex++; roundManager.FlickerLights(true, true); } } } } namespace LethalWorkingConditions.Classes.ChatCommand { public enum CommandStatus { NOT_SET, PREQUISITES_NOT_MET, PARAMS_INCOMPLETE, OK } internal abstract class ChatCommand { protected LWCLogger logger; public static string CommandPrefix = LWCConfig.TerminalCommandPrefix.Value ?? LWCConfig.TerminalCommandPrefixDefault; protected HUDManager hudManager; protected readonly string text; protected string[] parameters; protected string commandName = "N/A"; protected string noticeTitle => "Command: " + CommandPrefix + commandName; protected virtual string GetFullCommandSyntax() { return CommandPrefix + commandName; } protected virtual void OnInterception() { } protected abstract bool CanBeCalled(); protected abstract bool ParseParameters(); protected abstract void Execute(); public ChatCommand(string commandname, ref HUDManager hudManager) { this.hudManager = hudManager; commandName = commandname; logger = new LWCLogger(commandName ?? ""); text = hudManager.chatTextField.text; parameters = text.Split(new char[1] { ' ' }).Skip(1).ToArray(); } protected void IssueNotification(string message, bool isWarning = false) { HUDManager.Instance.DisplayTip(noticeTitle, message, isWarning, false, "LC_Tip1"); logger.LogInfo(noticeTitle + ": " + message); } protected void IssueCommandSyntax() { IssueNotification("Wrong Syntax: " + GetFullCommandSyntax()); } public CommandStatus ExecuteCommand() { if (!CanBeCalled()) { return CommandStatus.PREQUISITES_NOT_MET; } if (!ParseParameters()) { IssueCommandSyntax(); return CommandStatus.PARAMS_INCOMPLETE; } Execute(); return CommandStatus.OK; } } } namespace LethalWorkingConditions.Classes.ChatCommand.Commands { internal class SpawnCommand : ChatCommand { private string targetEnemyNameParam = ""; private int targetEnemyAmountParam = 1; private bool targetEnemyFound = false; private string targetEnemyName; private string creaturesAvailableString => string.Join("|", RoundManagerBPatch.currentLevel.Enemies.Select((SpawnableEnemyWithRarity e) => e.enemyType.enemyName).ToArray()) + "|" + string.Join("|", RoundManagerBPatch.currentLevel.OutsideEnemies.Select((SpawnableEnemyWithRarity e) => e.enemyType.enemyName).ToArray()); public SpawnCommand(ref HUDManager hudManager) : base("Spawn", ref hudManager) { } protected override string GetFullCommandSyntax() { return base.GetFullCommandSyntax() + " <" + creaturesAvailableString + "> [amount=1]"; } protected override bool CanBeCalled() { if (!RoundManagerBPatch.isHost) { IssueNotification("Only the host is allowed to use this comand"); return false; } try { List<SpawnableEnemyWithRarity> outsideEnemies = RoundManagerBPatch.currentLevel.OutsideEnemies; List<SpawnableEnemyWithRarity> enemies = RoundManagerBPatch.currentLevel.Enemies; if (outsideEnemies.Count <= 0 || enemies.Count <= 0) { throw new Exception(); } } catch { IssueNotification("You need to start the game before spawning enemies"); return false; } return true; } protected override bool ParseParameters() { if (parameters.Length < 1) { return false; } targetEnemyNameParam = parameters[0].ToLower(); if (parameters.Length > 1) { int.TryParse(parameters[1], out targetEnemyAmountParam); } return true; } protected override void Execute() { List<SpawnableEnemyWithRarity> outsideEnemies = RoundManagerBPatch.currentLevel.OutsideEnemies; List<SpawnableEnemyWithRarity> enemies = RoundManagerBPatch.currentLevel.Enemies; HandleSpawnEnemies(outsideEnemies, inside: false); HandleSpawnEnemies(enemies, inside: true); if (!targetEnemyFound) { IssueCommandSyntax(); } } private void HandleSpawnEnemies(List<SpawnableEnemyWithRarity> list, bool inside) { foreach (SpawnableEnemyWithRarity item in list) { if (!targetEnemyFound && item.enemyType.enemyName.ToLower().Contains(targetEnemyNameParam)) { targetEnemyFound = true; targetEnemyName = item.enemyType.enemyName; try { EnemySpawner.SpawnEnemy(item, targetEnemyAmountParam, inside); IssueNotification($"Spawned {targetEnemyAmountParam} {targetEnemyName}"); } catch { IssueNotification("Could not spawn enemies"); } } } } } internal enum RussianRouletteState { NOT_PLAYING, PLAYING } internal class RussianRoulette : ChatCommand { private Random randomGenerator; public RussianRouletteState state; public RussianRoulette(ref HUDManager hudManager) : base("rr", ref hudManager) { state = RussianRouletteState.NOT_PLAYING; randomGenerator = new Random(); } protected override bool CanBeCalled() { return true; } protected override bool ParseParameters() { return true; } protected override void Execute() { switch (state) { case RussianRouletteState.NOT_PLAYING: HandleNotPlaying(); break; case RussianRouletteState.PLAYING: HandlePlaying(); break; } } private void HandleNotPlaying() { } private void HandlePlaying() { } } }