using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using AIGraph; using AK; using Agents; using AmorLib.API; using AmorLib.Dependencies; using AmorLib.Events; using AmorLib.Networking; using AmorLib.Networking.StateReplicators; using AmorLib.Utils; using AmorLib.Utils.Extensions; using AmorLib.Utils.JsonElementConverters; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils; using BepInEx.Unity.IL2CPP.Utils.Collections; using CellMenu; using ChainedPuzzles; using EOS.BaseClasses; using EOS.BaseClasses.CustomTerminalDefinition; using EOS.JSON; using EOS.Modules.Expedition; using EOS.Modules.Expedition.Gears; using EOS.Modules.Expedition.IndividualGeneratorGroup; using EOS.Modules.Expedition.ThermalSights; using EOS.Modules.Instances; using EOS.Modules.Objectives.ActivateSmallHSU; using EOS.Modules.Objectives.GeneratorCluster; using EOS.Modules.Objectives.IndividualGenerator; using EOS.Modules.Objectives.Reactor; using EOS.Modules.Objectives.TerminalUplink; using EOS.Modules.Tweaks.BossEvents; using EOS.Modules.Tweaks.ScoutEvents; using EOS.Modules.Tweaks.SecDoorIntText; using EOS.Modules.Tweaks.TerminalPosition; using EOS.Modules.Tweaks.TerminalTweak; using EOS.Modules.World.EMP; using EOS.Modules.World.EMP.Handlers; using EOS.Modules.World.SecuritySensor; using EOS.Utils; using Enemies; using FirstPersonItem; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using StateMachines; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ExcellentObjectiveSetup")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ebfa3a18ca4d8d286e0360c69f2c74399baeb1b0")] [assembly: AssemblyProduct("ExcellentObjectiveSetup")] [assembly: AssemblyTitle("ExcellentObjectiveSetup")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace EOS { [BepInPlugin("Amor.ExcellentObjectiveSetup", "ExcellentObjectiveSetup", "1.1.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class EntryPoint : BasePlugin { private readonly List _callbackAssemblyTypes = new List { AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly()) }; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) new Harmony("ExcellentObjectiveSetup").PatchAll(); InteropAPI.RegisterCall("EOS.Managers", (Func)delegate(object[] args) { if (args != null && args.Length != 0 && args[0] is Type[] item) { _callbackAssemblyTypes.Add(item); } return (object)null; }); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); AssetAPI.OnStartupAssetsLoaded += SetupManagers; EOSLogger.Log("EOS is done loading!"); } private void SetupManagers() { IEnumerable managers = _callbackAssemblyTypes.SelectMany((Type[] types) => from t in types where typeof(BaseManager).IsAssignableFrom(t) && !t.IsAbstract select (BaseManager)Activator.CreateInstance(t, nonPublic: true) into m orderby m.ChainedPuzzleLoadOrder select m); BaseManager.SetupManagers(managers); } } public static class EOSNetworking { public const uint INVALID_ID = 0u; public const uint FOREVER_REPLICATOR_ID_START = 1000u; public const uint REPLICATOR_ID_START = 10000u; private static readonly HashSet _foreverUsedIDs; private static readonly HashSet _usedIDs; private static uint _currentForeverID; private static uint _currentID; static EOSNetworking() { _foreverUsedIDs = new HashSet(); _usedIDs = new HashSet(); _currentForeverID = 1000u; _currentID = 10000u; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } public static uint AllotReplicatorID() { while (_currentID >= 10000 && _usedIDs.Contains(_currentID)) { _currentID++; } if (_currentID < 10000) { EOSLogger.Error("Replicator IDs depleted. How?"); return 0u; } uint currentID = _currentID; _usedIDs.Add(currentID); _currentID++; return currentID; } public static bool TryAllotID(uint id) { return _usedIDs.Add(id); } public static uint AllotForeverReplicatorID() { while (_currentForeverID < 10000 && _foreverUsedIDs.Contains(_currentForeverID)) { _currentForeverID++; } if (_currentForeverID >= 10000) { EOSLogger.Error("Forever Replicator ID depleted."); return 0u; } uint currentForeverID = _currentForeverID; _foreverUsedIDs.Add(currentForeverID); _currentForeverID++; return currentForeverID; } private static void Clear() { _usedIDs.Clear(); _currentID = 10000u; } public static void ClearForever() { _foreverUsedIDs.Clear(); _currentForeverID = 1000u; } } public static class EOSWardenEventManager { public const uint AWOEventIDsStart = 10000u; private static readonly Dictionary> _eventDefinitions = new Dictionary>(); private static readonly Dictionary _eventIDNameMap = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly ImmutableHashSet _vanillaEventIDs = Enum.GetValues().ToImmutableHashSet(); public static bool IsVanillaEventID(uint eventID) { return _vanillaEventIDs.Contains((eWardenObjectiveEventType)eventID); } public static bool IsAWOEventID(uint eventID) { return eventID >= 10000; } public static bool HasEventDefinition(string eventName) { return _eventIDNameMap.ContainsKey(eventName); } public static bool HasEventDefinition(uint eventID) { return _eventDefinitions.ContainsKey(eventID); } public static bool AddEventDefinition(string eventName, uint eventID, Action definition) { if (IsAWOEventID(eventID)) { EOSLogger.Error($"EventID {eventID} is already used by AWO"); return false; } if (IsVanillaEventID(eventID)) { EOSLogger.Warning($"EventID {eventID}: overriding vanilla event!"); } if (_eventIDNameMap.ContainsKey(eventName)) { EOSLogger.Error($"AddEventDefinition: duplicate event name '{eventName}' or id '{eventID}'"); return false; } _eventIDNameMap[eventName] = eventID; _eventDefinitions[eventID] = definition; EOSLogger.Debug($"EOSWardenEventManager: added event with name '{eventName}', id '{eventID}'"); return true; } public static void ExecuteWardenEvent(WardenObjectiveEventData events, eWardenObjectiveEventTrigger trigger = (eWardenObjectiveEventTrigger)0, bool ignoreTrigger = true) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, trigger, ignoreTrigger, 0f); } public static void ExecuteWardenEvents(List events, eWardenObjectiveEventTrigger trigger = (eWardenObjectiveEventTrigger)0, bool ignoreTrigger = true) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp(events), trigger, ignoreTrigger, 0f, (Il2CppStructArray)null); } internal static void HandleEvent(WardenObjectiveEventData e, float currentDuration) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected I4, but got Unknown uint num = (uint)(int)e.Type; if (!_eventDefinitions.ContainsKey(num)) { EOSLogger.Error($"ExecuteEvent: event ID {num} doesn't have a definition"); } else { Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(e, currentDuration)), (Action)null); WorldEventManager.m_worldEventEventCoroutines.Add(val); } } private static IEnumerator Handle(WardenObjectiveEventData e, float currentDuration) { uint eventID = (uint)(int)e.Type; float delay = Mathf.Max(e.Delay - currentDuration, 0f); if (delay > 0f) { int reloadCount = CheckpointManager.CheckpointUsage; yield return (object)new WaitForSeconds(delay); if (reloadCount < CheckpointManager.CheckpointUsage) { EOSLogger.Warning($"Delayed event ID {eventID} aborted due to checkpoint reload"); yield break; } } if (WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue) { yield break; } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); string line = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(line)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(line); } } SafeInvoke.Invoke(_eventDefinitions[eventID], e); } } } namespace EOS.Utils { public static class ChainedPuzzleInstanceManagerHelper { public static void Add_OnStateChange(this ChainedPuzzleInstance instance, Action action) { BaseManager.Current.Add_OnStateChange(instance, action); } public static void Remove_OnStateChange(this ChainedPuzzleInstance instance, Action action) { BaseManager.Current.Remove_OnStateChange(instance, action); } public static void ResetProgress(this ChainedPuzzleInstance chainedPuzzle) { //IL_0018: 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) //IL_0027: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (chainedPuzzle.Data.DisableSurvivalWaveOnComplete) { chainedPuzzle.m_sound = new CellSoundPlayer(chainedPuzzle.m_parent.position); } foreach (iChainedPuzzleCore item in (Il2CppArrayBase)(object)chainedPuzzle.m_chainedPuzzleCores) { ResetChild(item); } if (SNet.IsMaster) { pChainedPuzzleState state = chainedPuzzle.m_stateReplicator.State; pChainedPuzzleState val = new pChainedPuzzleState { status = (eChainedPuzzleStatus)0, currentSurvivalWave_EventID = state.currentSurvivalWave_EventID, isSolved = false, isActive = false }; chainedPuzzle.m_stateReplicator.InteractWithState(val, new pChainedPuzzleInteraction { type = (eChainedPuzzleInteraction)2 }); } static void ResetChild(iChainedPuzzleCore iCore) { CP_Bioscan_Core val2 = ((Il2CppObjectBase)iCore).TryCast(); if ((Object)(object)val2 != (Object)null) { val2.m_spline.SetVisible(false); CP_PlayerScanner val3 = ((Il2CppObjectBase)val2.PlayerScanner).Cast(); val3.ResetScanProgression(0f); val2.Deactivate(); } else { CP_Cluster_Core val4 = ((Il2CppObjectBase)iCore).TryCast(); if ((Object)(object)val4 == (Object)null) { EOSLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core..."); } else { val4.m_spline.SetVisible(false); foreach (iChainedPuzzleCore item2 in (Il2CppArrayBase)(object)val4.m_childCores) { ResetChild(item2); } val4.Deactivate(); } } } } } public static class EOSLogger { private static readonly ManualLogSource _logger = Logger.CreateLogSource("EOS"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (_logger != null) { _logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (_logger != null) { _logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (_logger != null) { _logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (_logger != null) { _logger.Log((LogLevel)32, (object)str); } } } public static class EOSTerminalUtil { public static List FindTerminals((int dim, int layer, int zone) gIndex, Predicate predicate) { return FindTerminals((eDimensionIndex)gIndex.dim, (LG_LayerType)(byte)gIndex.layer, (eLocalZoneIndex)gIndex.zone, predicate); } public static List FindTerminals(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, Predicate predicate) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"SelectTerminal: Could NOT find zone {(dimensionIndex, layerType, localIndex)}"); return null; } if (val.TerminalsSpawnedInZone.Count == 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals in zone {(dimensionIndex, layerType, localIndex)}"); return null; } List list = new List(); Enumerator enumerator = val.TerminalsSpawnedInZone.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current = enumerator.Current; if (predicate != null) { if (predicate(current)) { list.Add(current); } } else { list.Add(current); } } return list; } public static TerminalLogFileData? GetLocalLog(this LG_ComputerTerminal terminal, string logName) { Dictionary localLogs = terminal.GetLocalLogs(); logName = logName.ToUpperInvariant(); return localLogs.ContainsKey(logName) ? localLogs[logName] : null; } public static void ResetInitialOutput(this LG_ComputerTerminal terminal) { terminal.m_command.ClearOutputQueueAndScreenBuffer(); terminal.m_command.AddInitialTerminalOutput(); if (terminal.IsPasswordProtected) { terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null); } } public static List GetUniqueCommandEvents(this LG_ComputerTerminal terminal, string command) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode val = terminal.SpawnNode; if (val == null) { val = CourseNodeUtil.GetCourseNode(terminal.m_position); } if (val == null) { EOSLogger.Error("GetCommandEvents: Cannot find a terminal spawn node"); return new List(); } LG_ZoneSettings settings = val.m_zone.m_settings; ExpeditionZoneData val2 = ((settings != null) ? settings.m_zoneData : null); if (val2 == null) { EOSLogger.Error("GetCommandEvents: Cannot find terminal zone data"); return new List(); } List terminalsSpawnedInZone = val.m_zone.TerminalsSpawnedInZone; int num = terminalsSpawnedInZone.IndexOf(terminal); if (num < 0) { EOSLogger.Warning("GetCommandEvents: terminal not found in TerminalsSpawnedInZone"); return new List(); } List val3 = val2.TerminalPlacements ?? new List(); List val4 = val2.SpecificTerminalSpawnDatas ?? new List(); List list = new List(); if ((Object)(object)terminal.ConnectedReactor != (Object)null) { if (BaseManager.Current.TryGetDefinition(terminal.ConnectedReactor, out ReactorShutdownDefinition definition)) { list = definition.ReactorTerminal.UniqueCommands.ConvertAll((CustomCommand cmd) => cmd.ToVanillaDataType()); } else { if (!BaseManager.Current.TryGetDefinition(terminal.ConnectedReactor, out ReactorStartupOverride definition2)) { return new List(); } list = definition2.ReactorTerminal.UniqueCommands.ConvertAll((CustomCommand cmd) => cmd.ToVanillaDataType()); } } else if (num >= val3.Count && num - val3.Count < val4.Count) { list = ListExtensions.ToManaged(val4[num - val3.Count].UniqueCommands); } else { if (num >= val3.Count) { EOSLogger.Warning($"GetCommandEvents: skipped! Terminal_{terminal.PublicName}, TerminalDataIndex({num})"); return new List(); } list = ListExtensions.ToManaged(val3[num].UniqueCommands); } foreach (CustomTerminalCommand item in list) { if (string.Equals(item.Command, command, StringComparison.InvariantCultureIgnoreCase)) { return ListExtensions.ToManaged(item.CommandEvents); } } EOSLogger.Warning("GetCommandEvents: command '" + command + "' not found on " + terminal.ItemKey); return new List(); } public static LG_ComputerTerminal SelectPasswordTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, eSeedType seedType, int staticSeed = 1) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected I4, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_011a: Unknown result type (might be due to invalid IL or missing references) if ((int)seedType == 0) { EOSLogger.Error($"SelectTerminal: unsupported seed type {seedType}"); return null; } List list = FindTerminals(dimensionIndex, layerType, localIndex, (LG_ComputerTerminal x) => !x.HasPasswordPart); if (list == null) { EOSLogger.Error($"SelectTerminal: Could not find zone {(dimensionIndex, layerType, localIndex)}!"); return null; } if (list.Count <= 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals without a password part in zone {(dimensionIndex, layerType, localIndex)}, putting the password on random (session) already used terminal."); LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val); return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")]; } switch (seedType - 1) { case 0: return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")]; case 1: return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")]; case 2: Random.InitState(staticSeed); return list[Random.Range(0, list.Count)]; default: EOSLogger.Error("SelectTerminal: did not have a valid SeedType!!"); return null; } } public static void BuildPassword(LG_ComputerTerminal terminal, TerminalPasswordData data) { //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Invalid comparison between Unknown and I4 //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Expected O, but got Unknown //IL_0580: Expected O, but got Unknown if ((Object)(object)terminal == (Object)null || data == null || !data.PasswordProtected) { return; } if (terminal.IsPasswordProtected) { EOSLogger.Error("EOSTerminalUtils.BuildPassword: " + terminal.PublicName + " is already password-protected!"); return; } if (!data.GeneratePassword) { terminal.LockWithPassword(data.Password, new string[1] { data.PasswordHintText }); return; } if (data.TerminalZoneSelectionDatas.Count <= 0) { EOSLogger.Error($"Tried to generate a password for terminal {terminal.PublicName} with no {typeof(TerminalZoneSelectionData).Name}!! This is not allowed."); return; } string codeWord = SerialGeneratorManager.GetCodeWord(data.PasswordWordLength); string passwordHintText = data.PasswordHintText; string text = "[Forgot your password?] Backup security key(s) located in logs on "; int num = data.PasswordPartCount; if (codeWord.Length % num != 0) { EOSLogger.Error($"BuildPassword: length ({codeWord.Length}) not divisible by passwordParts ({num}). Defaulting to 1."); num = 1; } string[] array = ((num > 1) ? Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord }); string text2 = ""; if (data.ShowPasswordPartPositions) { for (int i = 0; i < array[0].Length; i++) { text2 += "-"; } } HashSet hashSet = new HashSet(); for (int j = 0; j < num; j++) { int index = j % data.TerminalZoneSelectionDatas.Count; List list = data.TerminalZoneSelectionDatas[index]; int index2 = Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG"); CustomTerminalZoneSelectionData customTerminalZoneSelectionData = list[index2]; LG_ComputerTerminal val; if ((int)customTerminalZoneSelectionData.SeedType == 0) { LG_Zone zone = ((GlobalBase)customTerminalZoneSelectionData).Zone; if ((Object)(object)zone == (Object)null) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find zone {customTerminalZoneSelectionData}"); continue; } if (zone.TerminalsSpawnedInZone.Count == 0) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find terminal zone {customTerminalZoneSelectionData}"); continue; } val = zone.TerminalsSpawnedInZone[customTerminalZoneSelectionData.TerminalIndex]; } else { val = SelectPasswordTerminal(((GlobalBase)customTerminalZoneSelectionData).DimensionIndex, ((GlobalBase)customTerminalZoneSelectionData).Layer, ((GlobalBase)customTerminalZoneSelectionData).LocalIndex, customTerminalZoneSelectionData.SeedType); } if ((Object)(object)val == (Object)null) { EOSLogger.Error($"BuildPassword: CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log"); continue; } string text3 = ""; string text4; if (data.ShowPasswordPartPositions) { for (int k = 0; k < j; k++) { text3 += text2; } text4 = text3 + array[j]; for (int l = j; l < num - 1; l++) { text4 += text2; } } else { text4 = array[j]; } string value = (data.ShowPasswordPartPositions ? $"0{j + 1}" : $"0{Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")}"); TerminalLogFileData val2 = new TerminalLogFileData { FileName = $"key{value}_{LG_TerminalPasswordLinkerJob.GetTerminalNumber(terminal)}{(val.HasPasswordPart ? "_1" : "")}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get((num > 1) ? 1431221909u : 2260297836u), text4), Id = 0u } }; val.AddLocalLog(val2, true); if (!hashSet.Contains(val.SyncID)) { if (j > 0) { text += ", "; } string text5 = text; string publicName = val.PublicName; AIG_CourseNode spawnNode = val.SpawnNode; text = text5 + publicName + " in " + (((spawnNode != null) ? spawnNode.m_zone.AliasName : null) ?? "???"); } hashSet.Add(val.SyncID); val.HasPasswordPart = true; } string text6 = text + "."; try { if (data.ShowPasswordLength) { terminal.LockWithPassword(codeWord, new string[3] { passwordHintText, text6, "Char[" + codeWord.Length + "]" }); } else { terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text6 }); } } catch (Exception value2) { EOSLogger.Error($"Something went wrong while setting up {terminal.PublicName}'s password!\n{value2}"); } } public static void AddUniqueCommand(LG_ComputerTerminal terminal, CustomCommand cmd) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0081: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) if (terminal.m_command.m_commandsPerString.ContainsKey(cmd.Command)) { EOSLogger.Error("Duplicate command name: '" + cmd.Command + "', cannot add command"); return; } TERM_Command val = default(TERM_Command); if (!terminal.m_command.TryGetUniqueCommandSlot(ref val)) { EOSLogger.Error("Cannot get more unique command slot, max: 5"); return; } LocalizedText val2 = new LocalizedText { UntranslatedText = cmd.CommandDesc.ParseTextFragments(), Id = 0u }; terminal.m_command.AddCommand(val, cmd.Command, val2, cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp(cmd.CommandEvents), ListExtensions.ToIl2Cpp(cmd.PostCommandOutputs.ConvertAll((CustomCommand.LocaleTerminalOutput x) => x.ToTerminalOutput()))); ChainedPuzzleDataBlock val4 = default(ChainedPuzzleDataBlock); for (int num = 0; num < cmd.CommandEvents.Count; num++) { WardenObjectiveEventData val3 = cmd.CommandEvents[num]; if (val3.ChainPuzzle == 0) { continue; } if (!DataBlockUtil.TryGetBlock(val3.ChainPuzzle, ref val4)) { continue; } LG_Area val5; Transform val6; if ((Object)(object)terminal.ConnectedReactor == (Object)null) { val5 = terminal.SpawnNode.m_area; val6 = terminal.m_wardenObjectiveSecurityScanAlign; } else { LG_WardenObjective_Reactor connectedReactor = terminal.ConnectedReactor; object obj; if (connectedReactor == null) { obj = null; } else { AIG_CourseNode spawnNode = connectedReactor.SpawnNode; obj = ((spawnNode != null) ? spawnNode.m_area : null); } if (obj == null) { obj = null; } val5 = (LG_Area)obj; LG_WardenObjective_Reactor connectedReactor2 = terminal.ConnectedReactor; val6 = ((connectedReactor2 != null) ? connectedReactor2.m_chainedPuzzleAlign : null) ?? null; } if ((Object)(object)val5 == (Object)null) { EOSLogger.Error("Terminal source area is not found! Cannot create chained puzzle for command " + cmd.Command + "!"); continue; } ChainedPuzzleInstance val7 = ChainedPuzzleManager.CreatePuzzleInstance(val4, val5, val6.position, val6, val3.UseStaticBioscanPoints); List events = cmd.CommandEvents.GetRange(num, cmd.CommandEvents.Count - num); val7.OnPuzzleSolved += Action.op_Implicit((Action)delegate { EOSWardenEventManager.ExecuteWardenEvents(events, (eWardenObjectiveEventTrigger)0); }); terminal.SetChainPuzzleForCommand(val, num, val7); } } } public static class TSL_Wrapper { public unsafe static string ParseTextFragments(this LocaleText input) { return ((object)(*(LocaleText*)(&input))/*cast due to .constrained prefix*/).ToString().ParseTextFragments(); } public static string ParseTextFragments(this string input) { return (InteropAPI.Call("TSL.ParseTextFragments", new object[1] { input }) as string) ?? input; } } public class Vec3 { [JsonPropertyOrder(-10)] public float x { get; set; } [JsonPropertyOrder(-10)] public float y { get; set; } [JsonPropertyOrder(-10)] public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } public Quaternion ToQuaternion() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(x, y, z); } public static implicit operator Vector3(Vec3 v3) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v3.x, v3.y, v3.z); } public static implicit operator Quaternion(Vec3 v3) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(v3.x, v3.y, v3.z); } } public class Vec4 : Vec3 { [JsonPropertyOrder(-9)] public float w { get; set; } = 0f; public Vector4 ToVector4() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector4(base.x, base.y, base.z, w); } public static implicit operator Vector4(Vec4 v4) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector4(v4.x, v4.y, v4.z, v4.w); } } } namespace EOS.Patches { [HarmonyPatch] internal class Patch_CheckAndExecuteEventsOnTrigger { [HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[] { typeof(WardenObjectiveEventData), typeof(eWardenObjectiveEventTrigger), typeof(bool), typeof(float) })] [HarmonyPrefix] [HarmonyPriority(500)] [HarmonyWrapSafe] private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration)) { return true; } uint num = (uint)(int)eventToTrigger.Type; if (!EOSWardenEventManager.HasEventDefinition(num)) { return true; } string value = (EOSWardenEventManager.IsVanillaEventID(num) ? "overriding vanilla event implementation..." : "executing..."); EOSLogger.Debug($"EOSWardenEvent: found definition for event ID {num}, {value}"); EOSWardenEventManager.HandleEvent(eventToTrigger, currentDuration); return false; } } [HarmonyPatch] internal static class Patch_EventsOnBossDeath { private static readonly HashSet _executedForInstances; static Patch_EventsOnBossDeath() { _executedForInstances = new HashSet(); LevelAPI.OnLevelCleanup += _executedForInstances.Clear; } [HarmonyPatch(typeof(EnemySync), "OnSpawn")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_SpawnEnemy(EnemySync __instance, pEnemySpawnData spawnData) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Invalid comparison between Unknown and I4 //IL_014e: 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) AIG_CourseNode val = default(AIG_CourseNode); if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref val) || val == null) { EOSLogger.Error("Failed to get node for a boss! Skipped EventsOnBossDeath for it"); } else { if (!BaseManager.Current.TryGetDefinition(GlobalIndexUtil.ToIntTuple(val.m_zone), out EventsOnZoneBossDeath def)) { return; } EnemyAgent agent = __instance.m_agent; if (!def.BossIDs.Contains(((GameDataBlockBase)(object)agent.EnemyData).persistentID)) { return; } bool flag = ((int)spawnData.mode == 4 || (int)spawnData.mode == 3) && def.ApplyToHibernate; bool flag2 = (int)spawnData.mode == 1 && def.ApplyToWave; if (!flag && !flag2) { return; } BossDeathEventManager.Mode mode = (((int)spawnData.mode != 4) ? BossDeathEventManager.Mode.WAVE : BossDeathEventManager.Mode.HIBERNATE); ushort enemyID = ((Agent)agent).GlobalID; agent.OnDeadCallback += Action.op_Implicit((Action)delegate { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName == 10) { if (!BaseManager.Current.TryConsumeBDEventsExecutionTimes(def, mode)) { EOSLogger.Debug($"EventsOnBossDeath: execution times depleted for {def}, {mode}"); } else if (_executedForInstances.Contains(enemyID)) { _executedForInstances.Remove(enemyID); } else { EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnBossDeath, (eWardenObjectiveEventTrigger)0); _executedForInstances.Add(enemyID); } } }); EOSLogger.Debug($"EventsOnBossDeath: added for enemy with id {((GameDataBlockBase)(object)agent.EnemyData).persistentID}, mode: {spawnData.mode}"); } } } [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] internal static class Patch_EventsOnZoneScoutScream { private static uint ScoutWaveSettings => RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings; private static uint ScoutWavePopulation => RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation; [HarmonyPrefix] private static bool Pre_ES_ScoutScream_CommonUpdate(ES_ScoutScream __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((int)__instance.m_state != 3 || __instance.m_stateDoneTimer >= Clock.Time) { return true; } EnemyAgent enemyAgent = ((ES_Base)__instance).m_enemyAgent; AIG_CourseNode courseNode = ((Agent)enemyAgent).CourseNode; if (!BaseManager.Current.TryGetDefinition(GlobalIndexUtil.ToIntTuple(courseNode.m_zone), out EventsOnZoneScoutScream definition)) { return true; } if (definition.EventsOnScoutScream != null && definition.EventsOnScoutScream.Count > 0) { EOSLogger.Debug($"EventsOnZoneScoutScream: found config for {definition}, executing events."); EOSWardenEventManager.ExecuteWardenEvents(definition.EventsOnScoutScream, (eWardenObjectiveEventTrigger)0); } if (SNet.IsMaster) { if (!definition.SuppressVanillaScoutWave) { if (courseNode != null && ScoutWaveSettings != 0 && ScoutWavePopulation != 0) { ushort num = default(ushort); Mastermind.Current.TriggerSurvivalWave(courseNode, ScoutWaveSettings, ScoutWavePopulation, ref num, (SurvivalWaveSpawnType)0, 0f, 2f, true, false, default(Vector3), ""); } else { EOSLogger.Error($"ES_ScoutScream, a scout is screaming but we can't spawn a wave because the the scout settings are not set for this expedition, or null node! ScoutWaveSettings: {ScoutWaveSettings} ScoutWavePopulation: {ScoutWavePopulation}"); } } ((ES_Base)__instance).m_enemyAgent.AI.m_behaviour.ChangeState((EB_States)5); } ((MachineState)(object)__instance).m_machine.ChangeState(2); __instance.m_state = (ScoutScreamState)4; return false; } } } namespace EOS.Patches.Uplink { [HarmonyPatch] internal static class ComputerTerminalSetup { [HarmonyPatch(typeof(LG_ComputerTerminal), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_ComputerTerminal_Setup(LG_ComputerTerminal __instance) { BaseManager.Current.Register(__instance); if (__instance.SpawnNode != null) { BaseManager.Current.Setup(__instance); } } [HarmonyPatch(typeof(LG_ComputerTerminal), "SetupAsWardenObjectiveTerminalUplink")] [HarmonyPatch(typeof(LG_ComputerTerminal), "SetupAsWardenObjectiveCorruptedTerminalUplink")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_ComputerTerminal_UplinkSetup(LG_ComputerTerminal __instance) { BaseManager.Current.RegisterWardenUplink(__instance); } [HarmonyPatch(typeof(TerminalUplinkPuzzle), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_ComputerTerminal_SyncedPuzzle(TerminalUplinkPuzzle __instance, LG_ComputerTerminal terminal) { if (!terminal.m_isWardenObjective) { return; } UplinkDefinition def = BaseManager.Current.GetWardenDefinition(terminal); if (def == null) { return; } __instance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (def.EventsOnComplete != null) { EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnComplete, (eWardenObjectiveEventTrigger)0); } }); } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConfirm")] internal static class CorruptedUplinkConfirm { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConfirm(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal receiver = __instance.m_terminal; LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver; if ((Object)(object)sender == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConfirm: critical failure because terminal does not have a CorruptedUplinkReceiver (sender)."); __result = false; return false; } if (sender.m_isWardenObjective) { return true; } receiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(2816126705u), sender.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); if ((Object)(object)sender.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = sender.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); BaseManager.Current.ChangeState(sender, new UplinkState { status = UplinkStatus.InProgress }); }); sender.m_command.AddOutput(string.Empty, true); sender.m_command.AddOutput(Text.Get(3268596368u), true); sender.m_command.AddOutput(Text.Get(2277987284u), true); receiver.m_command.AddOutput(string.Empty, true); receiver.m_command.AddOutput(Text.Get(3268596368u), true); receiver.m_command.AddOutput(Text.Get(2277987284u), true); if (SNet.IsMaster) { sender.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); BaseManager.Current.ChangeState(sender, new UplinkState { status = UplinkStatus.InProgress }); } __result = true; return false; } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConnect")] internal static class CorruptedUplinkConnect { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } __result = false; LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver; if ((Object)(object)corruptedUplinkReceiver == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConnect: critical failure because terminal does not have a CorruptedUplinkReceiver."); return false; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); __result = false; return false; } LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = terminal.SyncID; if (!BaseManager.Current.TryGetDefinition(terminal, out UplinkDefinition definition)) { return true; } if (definition.UseUplinkAddress) { param1 = param1.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, param1: " + param1 + ", TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } else { param1 = terminal.UplinkPuzzle.TerminalUplinkIP.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, not using uplink address, TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } if (!definition.UseUplinkAddress || string.Equals(param1, terminal.UplinkPuzzle.TerminalUplinkIP, StringComparison.InvariantCultureIgnoreCase)) { if (corruptedUplinkReceiver.m_command.HasRegisteredCommand((TERM_Command)27)) { terminal.m_command.AddUplinkCorruptedOutput(); } else { terminal.m_command.AddUplinkCorruptedOutput(); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(3492863045u), corruptedUplinkReceiver.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(2761366063u), 0.6f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(3435969025u), 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); corruptedUplinkReceiver.m_command.AddCommand((TERM_Command)27, "UPLINK_CONFIRM", new LocalizedText { UntranslatedText = Text.Get(112719254u), Id = 0u }, (TERM_CommandRule)2); corruptedUplinkReceiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(1173595354u), terminal.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } } else { terminal.m_command.AddUplinkWrongAddressError(param1); } return false; } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "StartTerminalUplinkSequence")] internal static class StartTerminalUplinkSequence { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_StartTerminalUplinkSequence(LG_ComputerTerminalCommandInterpreter __instance, string uplinkIp, bool corrupted) { LG_ComputerTerminal terminal = __instance.m_terminal; LG_ComputerTerminal terminal2 = (corrupted ? terminal.CorruptedUplinkReceiver : terminal); if (terminal2.m_isWardenObjective || !BaseManager.Current.TryGetDefinition(terminal2, out UplinkDefinition uplinkConfig)) { return true; } if (uplinkConfig.FirstRoundOutputted(terminal.UplinkPuzzle.m_roundIndex)) { if (!corrupted) { terminal2.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2583360288u), uplinkIp), 3f, (TerminalSoundType)0, (TerminalSoundType)0); UplinkSequenceOutputs(terminal2, corrupted: false); } else { terminal2.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), terminal2.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal2.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), terminal2.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); UplinkSequenceOutputs(terminal2, corrupted: false); UplinkSequenceOutputs(terminal, corrupted: true); } } terminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Log("UPLINK CONNECTED, VERIFICATION START!"); BaseManager.Current.ChangeState(terminal2, new UplinkState { status = UplinkStatus.InProgress }); terminal2.UplinkPuzzle.OnStartSequence(); EOSWardenEventManager.ExecuteWardenEvents(uplinkConfig.EventsOnCommence, (eWardenObjectiveEventTrigger)0); int num = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); UplinkRound uplinkRound = ((num != -1) ? uplinkConfig.RoundOverrides[num] : null); if (uplinkRound != null) { EOSWardenEventManager.ExecuteWardenEvents(uplinkRound.EventsOnRound, (eWardenObjectiveEventTrigger)1, ignoreTrigger: false); } }); return false; void UplinkSequenceOutputs(LG_ComputerTerminal outputTerminal, bool flag) { outputTerminal.m_command.AddOutput((TerminalLineType)3, Text.Get(3418104670u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); outputTerminal.m_command.AddOutput("", true); if (uplinkConfig.DisplayUplinkWarning) { outputTerminal.m_command.AddOutput((TerminalLineType)5, "WARNING! Breach detected!", 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); outputTerminal.m_command.AddOutput((TerminalLineType)5, "WARNING! Breach detected!", 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); outputTerminal.m_command.AddOutput((TerminalLineType)5, "WARNING! Breach detected!", 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); outputTerminal.m_command.AddOutput("", true); } if (!flag) { outputTerminal.m_command.AddOutput(string.Format(Text.Get(947485599u), outputTerminal.UplinkPuzzle.CurrentRound.CorrectPrefix), true); } } } [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_ComputerTerminalCommandInterpreter_StartTerminalUplinkSequence(LG_ComputerTerminalCommandInterpreter __instance, bool corrupted) { LG_ComputerTerminal terminal = __instance.m_terminal; LG_ComputerTerminal val = (corrupted ? terminal.CorruptedUplinkReceiver : terminal); if (!val.m_isWardenObjective) { return; } UplinkDefinition uplinkConfig = BaseManager.Current.GetWardenDefinition(val); if (uplinkConfig == null) { return; } LG_ComputerTerminalCommandInterpreter command = terminal.m_command; command.OnEndOfQueue += Action.op_Implicit((Action)delegate { EOSWardenEventManager.ExecuteWardenEvents(uplinkConfig.EventsOnCommence, (eWardenObjectiveEventTrigger)0); int num = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); UplinkRound uplinkRound = ((num != -1) ? uplinkConfig.RoundOverrides[num] : null); if (uplinkRound != null) { EOSWardenEventManager.ExecuteWardenEvents(uplinkConfig.RoundOverrides[num].EventsOnRound, (eWardenObjectiveEventTrigger)1, ignoreTrigger: false); } }); } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkConnect")] internal static class TerminalUplinkConnect { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); return false; } if (!BaseManager.Current.TryGetDefinition(terminal, out UplinkDefinition definition)) { return true; } if (!definition.UseUplinkAddress) { param1 = __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP; } if (!definition.UseUplinkAddress || string.Equals(param1, __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP, StringComparison.InvariantCultureIgnoreCase)) { __instance.m_terminal.TrySyncSetCommandRule((TERM_Command)25, (TERM_CommandRule)1); if ((Object)(object)__instance.m_terminal.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = __instance.m_terminal.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.StartTerminalUplinkSequence(param1, false); }); __instance.AddOutput("", true); __instance.AddOutput(Text.Get(3268596368u), true); if (SNet.IsMaster) { __instance.m_terminal.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.StartTerminalUplinkSequence(param1, false); } __result = true; } else { __instance.AddUplinkWrongAddressError(param1); __result = false; } return false; } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkVerify")] internal static class TerminalUplinkVerify { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result, out List? __state) { __state = null; if (__instance.m_terminal.m_isWardenObjective) { UplinkDefinition wardenDefinition = BaseManager.Current.GetWardenDefinition(__instance.m_terminal); if (wardenDefinition == null) { return true; } TerminalUplinkPuzzle wardenPuzzle = __instance.m_terminal.UplinkPuzzle; if (wardenPuzzle.Connected && !wardenPuzzle.Solved && wardenPuzzle.CurrentRound.CorrectCode.Equals(param1, StringComparison.InvariantCultureIgnoreCase)) { __state = wardenDefinition.RoundOverrides.Find((UplinkRound round) => round.RoundIndex == wardenPuzzle.m_roundIndex + 1)?.EventsOnRound; UplinkRound uplinkRound = wardenDefinition.RoundOverrides.Find((UplinkRound round) => round.RoundIndex == wardenPuzzle.m_roundIndex); if (uplinkRound != null) { EOSWardenEventManager.ExecuteWardenEvents(uplinkRound.EventsOnRound, (eWardenObjectiveEventTrigger)2, ignoreTrigger: false); } } return true; } if (!BaseManager.Current.TryGetDefinition(__instance.m_terminal, out UplinkDefinition uplinkConfig)) { return true; } TerminalUplinkPuzzle uplinkPuzzle = __instance.m_terminal.UplinkPuzzle; int roundIndex = uplinkPuzzle.m_roundIndex; UplinkRound roundOverride = GetRoundOverride(roundIndex); TimeSettings timeSettings = ((roundOverride != null) ? roundOverride.OverrideTimeSettings : uplinkConfig.DefaultTimeSettings); float num = ((timeSettings.TimeToStartVerify >= 0f) ? timeSettings.TimeToStartVerify : uplinkConfig.DefaultTimeSettings.TimeToStartVerify); float timeToCompleteVerify = ((timeSettings.TimeToCompleteVerify >= 0f) ? timeSettings.TimeToCompleteVerify : uplinkConfig.DefaultTimeSettings.TimeToCompleteVerify); float num2 = ((timeSettings.TimeToRestoreFromFail >= 0f) ? timeSettings.TimeToRestoreFromFail : uplinkConfig.DefaultTimeSettings.TimeToRestoreFromFail); if (!uplinkPuzzle.Connected) { __instance.AddOutput("", true); __instance.AddOutput(Text.Get(403360908u), true); __result = false; return false; } __instance.AddOutput((TerminalLineType)3, Text.Get(2734004688u), num, (TerminalSoundType)0, (TerminalSoundType)0); if (!uplinkPuzzle.Solved && string.Equals(uplinkPuzzle.CurrentRound.CorrectCode, param1, StringComparison.InvariantCultureIgnoreCase)) { __instance.AddOutput(string.Format(Text.Get(1221800228u), uplinkPuzzle.CurrentProgress), true); if (uplinkPuzzle.TryGoToNextRound()) { int roundIndex2 = uplinkPuzzle.m_roundIndex; UplinkRound newRoundOverride = GetRoundOverride(roundIndex2); if (roundOverride != null) { EOSWardenEventManager.ExecuteWardenEvents(roundOverride.EventsOnRound, (eWardenObjectiveEventTrigger)2, ignoreTrigger: false); } if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { TextDataBlock val = default(TextDataBlock); if (DataBlockUtil.TryGetBlock("InGame.UplinkTerminal.ScanRequiredToProgress", ref val)) { __instance.AddOutput((TerminalLineType)4, Text.Get(((GameDataBlockBase)(object)val).persistentID), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } ChainedPuzzleInstance chainedPuzzleToEndRoundInstance = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit(CreateNextRoundOnEndAction(newRoundOverride)); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit(CreateNextRoundOnEndAction(newRoundOverride)); } } else { __instance.AddOutput((TerminalLineType)3, Text.Get(1780488547u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { if (roundOverride != null) { EOSWardenEventManager.ExecuteWardenEvents(roundOverride.EventsOnRound, (eWardenObjectiveEventTrigger)2, ignoreTrigger: false); } uplinkPuzzle.CurrentRound.ShowGui = false; if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { ChainedPuzzleInstance chainedPuzzleToEndRoundInstance2 = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance2.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit(FinalUplinkVerification()); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); FinalUplinkVerification()(); } }); } } else if (uplinkPuzzle.Solved) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, Text.Get(4080876165u), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), 6f, (TerminalSoundType)0, (TerminalSoundType)0); } else { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, string.Format(Text.Get(507647514u), uplinkPuzzle.CurrentRound.CorrectPrefix), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), num2, (TerminalSoundType)0, (TerminalSoundType)0); } __result = false; return false; Action CreateNextRoundOnEndAction(UplinkRound? uplinkRound2) { return delegate { EOSLogger.Log("UPLINK VERIFICATION, GO TO NEXT ROUND!"); uplinkPuzzle.CurrentRound.ShowGui = true; if (uplinkRound2 != null) { EOSWardenEventManager.ExecuteWardenEvents(uplinkRound2.EventsOnRound, (eWardenObjectiveEventTrigger)1, ignoreTrigger: false); } BaseManager.Current.ChangeState(__instance.m_terminal, new UplinkState { status = UplinkStatus.InProgress, currentRoundIndex = uplinkPuzzle.m_roundIndex }); }; } Action FinalUplinkVerification() { return delegate { EOSLogger.Log("UPLINK VERIFICATION SEQUENCE DONE!"); LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u; uplinkPuzzle.CurrentRound.ShowGui = false; uplinkPuzzle.Solved = true; Action onPuzzleSolved = uplinkPuzzle.OnPuzzleSolved; if (onPuzzleSolved != null) { onPuzzleSolved.Invoke(); } BaseManager.Current.ChangeState(__instance.m_terminal, new UplinkState { status = UplinkStatus.Finished, currentRoundIndex = uplinkPuzzle.m_roundIndex }); }; } UplinkRound? GetRoundOverride(int num4) { int num3 = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == num4); return (num3 != -1) ? uplinkConfig.RoundOverrides[num3] : null; } } [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_ComputerTerminalCommandInterpreter_TerminalUplinkVerify(LG_ComputerTerminalCommandInterpreter __instance, List? __state) { if (__state != null) { __instance.OnEndOfQueue += Action.op_Implicit((Action)delegate { EOSWardenEventManager.ExecuteWardenEvents(__state, (eWardenObjectiveEventTrigger)1, ignoreTrigger: false); }); } } } [HarmonyPatch(typeof(LG_ComputerTerminal), "Update")] internal static class UplinkGUI_Update { [HarmonyPostfix] private static void Post_LG_ComputerTerminal_Update(LG_ComputerTerminal __instance) { if (!__instance.m_isWardenObjective && __instance.UplinkPuzzle != null) { __instance.UplinkPuzzle.UpdateGUI(false); } } } [HarmonyPatch] internal static class UplinkPuzzleCodesString { public const string AUTOGEN_GUID = "000-the_tavern-AutogenRundown"; public const string LONGERCODES_GUID = "com.Brandont.LongerCodes"; [HarmonyPrepare] private static bool PreparePatches() { return !((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("000-the_tavern-AutogenRundown") && !((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.Brandont.LongerCodes"); } [HarmonyPatch(typeof(TerminalUplinkPuzzle), "GetCodesString")] [HarmonyPrefix] [HarmonyPriority(500)] [HarmonyWrapSafe] public static bool TerminalUplinkPuzzle_GetCodesString(ref string __result, TerminalUplinkPuzzleRound round, bool newLine = false) { int count = ((Il2CppArrayBase)(object)round.Codes).Count; int length = ((Il2CppArrayBase)(object)round.Codes)[0].Length; bool flag = count > 6 || length > 4; string text = (((Il2CppArrayBase)(object)round.Prefixes)[0].Contains('-') ? " | " : " - "); string text2 = ((flag && !newLine) ? "\n" : ""); int num = 3; int num2 = 3; if (flag) { int num3 = ((Il2CppArrayBase)(object)round.Prefixes)[0].Length + 1 + length; int max = 71 / (num3 + 3); int max2 = 44 / (num3 + 2); num = FitEntries(count, max); num2 = FitEntries(count, max2); } for (int i = 0; i < ((Il2CppArrayBase)(object)round.Codes).Length; i++) { text2 = text2 + "" + ((Il2CppArrayBase)(object)round.Prefixes)[i] + ":" + ((Il2CppArrayBase)(object)round.Codes)[i]; if (i < ((Il2CppArrayBase)(object)round.Codes).Length - 1) { text2 = ((!newLine) ? (text2 + (((i + 1) % num != 0) ? text : "\n")) : (text2 + (((i + 1) % num2 != 0) ? " " : "\n"))); } } __result = text2; return false; } private static int FitEntries(int count, int max) { if (max < 3) { return Math.Max(1, max); } for (int num = Math.Min(max, count - 1); num > 3; num--) { if (count % num == 0) { return num; } } return 3; } [HarmonyPatch(typeof(LG_TerminalPasswordLinkerJob), "Build")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_TerminalPasswordLinkerBuild(LG_TerminalPasswordLinkerJob __instance, ref bool __result) { if (!BaseManager.Current.TryGetTerminalDefinitionFromInstance(__instance.m_lockedTerminal, out ExpeditionTerminalsDefinition def)) { return true; } TerminalPasswordData obj = new TerminalPasswordData { PasswordProtected = true, Password = string.Empty }; TerminalStartStateData startStateData = __instance.m_lockedTerminal.StartStateData; obj.PasswordHintText = ((startStateData != null) ? startStateData.PasswordHintText : null) ?? "Password Required."; obj.GeneratePassword = true; obj.PasswordPartCount = __instance.m_passwordParts; obj.ShowPasswordLength = __instance.m_showPasswordLength; obj.ShowPasswordPartPositions = __instance.m_showPasswordPartPositions; obj.PasswordWordLength = def.PasswordWordLength; obj.TerminalZoneSelectionDatas = (from list in ListExtensions.ToManaged>(__instance.m_zoneSelectionDatas) select ListExtensions.ToManaged(list).Select(delegate(TerminalZoneSelectionData nested) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) CustomTerminalZoneSelectionData customTerminalZoneSelectionData = new CustomTerminalZoneSelectionData(); ((GlobalBase)customTerminalZoneSelectionData).DimensionIndex = def.DimensionIndex; ((GlobalBase)customTerminalZoneSelectionData).Layer = def.Layer; ((GlobalBase)customTerminalZoneSelectionData).LocalIndex = nested.LocalIndex; LG_Zone val = default(LG_Zone); ((GlobalBase)customTerminalZoneSelectionData).Zone = (GlobalIndexUtil.TryGetZone(def.DimensionIndex, def.Layer, nested.LocalIndex, ref val) ? val : null); customTerminalZoneSelectionData.SeedType = nested.SeedType; customTerminalZoneSelectionData.TerminalIndex = nested.TerminalIndex; customTerminalZoneSelectionData.StaticSeed = nested.StaticSeed; return customTerminalZoneSelectionData; }).ToList()).ToList() ?? new List>(); TerminalPasswordData data = obj; EOSTerminalUtil.BuildPassword(__instance.m_lockedTerminal, data); __result = true; return false; } } } namespace EOS.Patches.SecurityDoor { [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")] internal static class Patch_SecDoorLocks_OnDoorState { [HarmonyPostfix] [HarmonyPriority(400)] [HarmonyWrapSafe] private static void Patch_OnDoorState(LG_SecurityDoor_Locks __instance, pDoorState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if ((int)state.status == 5 || (int)state.status == 4) { BaseManager.Current.ReplaceText(__instance); } } } [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })] internal static class Patch_SecDoorLocks_Setup { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_Customize_SecDoor_Interaction_Text(LG_SecurityDoor_Locks __instance) { if (!BaseManager.Current.TryGetDefinition(__instance, out SecDoorIntTextDefinition def) || def.GlitchMode == GlitchMode.None) { return; } InteractGlitchComp comp = ((Component)__instance).gameObject.AddComponent(); comp.Init(def); __instance.m_intCustomMessage.OnInteractionSelected += Action.op_Implicit((Action)delegate(PlayerAgent agent, bool selected) { if (((Agent)agent).IsLocallyOwned) { comp.CanInteract = false; ((Behaviour)comp).enabled = selected; } }); __instance.m_intOpenDoor.OnInteractionSelected += Action.op_Implicit((Action)delegate(PlayerAgent agent, bool selected) { if (((Agent)agent).IsLocallyOwned) { comp.CanInteract = true; ((Behaviour)comp).enabled = selected; } }); } } } namespace EOS.Patches.Reactor { [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReactorVerify")] internal static class CommandInterpreter_ReactorVerify { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_ReactorVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null) { EOSLogger.Error("ReactorVerify: connected reactor is null - bug detected"); return true; } if (connectedReactor.m_isWardenObjective) { return true; } if (connectedReactor.ReadyForVerification && string.Equals(param1, connectedReactor.CurrentStateOverrideCode, StringComparison.InvariantCultureIgnoreCase)) { __instance.m_terminal.ChangeState((TERM_State)7); } else { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, Text.Get(2195342028u), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } } [HarmonyPatch] internal static class CommandInterpreter_ReceiveCommand { [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] [HarmonyPrefix] [HarmonyPriority(300)] [HarmonyWrapSafe] private static bool Pre_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null) { return true; } if ((int)cmd == 23 && !connectedReactor.m_isWardenObjective) { return Handle_ReactorShutdown(__instance, connectedReactor); } if ((int)cmd == 42) { return Handle_ReactorStartup_SpecialCommand(__instance, cmd, connectedReactor); } return true; } private static bool Handle_ReactorShutdown(LG_ComputerTerminalCommandInterpreter __instance, LG_WardenObjective_Reactor reactor) { if (!BaseManager.Current.TryGetDefinition(reactor, out ReactorShutdownDefinition definition)) { EOSLogger.Error("ReactorVerify: found built custom reactor shutdown but its definition is missing, what happened?"); return true; } __instance.AddOutput((TerminalLineType)3, Text.Get(3436726297u), 4f, (TerminalSoundType)0, (TerminalSoundType)0); if ((Object)(object)definition.ChainedPuzzleToActiveInstance != (Object)null) { __instance.AddOutput(Text.Get(2277987284u), true); if (SNet.IsMaster) { definition.ChainedPuzzleToActiveInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { reactor.AttemptInteract((eReactorInteraction)6, 0f); } return false; } private static bool Handle_ReactorStartup_SpecialCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, LG_WardenObjective_Reactor reactor) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_terminal.CommandIsHidden(cmd)) { return true; } OverrideReactorComp overrideReactorComp = default(OverrideReactorComp); if (!GameObjectPlusExtensions.TryAndGetComponent(((Component)reactor).gameObject, ref overrideReactorComp)) { return true; } if (!reactor.ReadyForVerification) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, LocaleText.op_Implicit(ReactorStartupOverrideManager.NotReadyForVerificationOutputText), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); return false; } if (overrideReactorComp.IsCorrectTerminal(__instance.m_terminal)) { EOSLogger.Log("Reactor Verify Correct!"); if (SNet.IsMaster) { reactor.AttemptInteract((eReactorInteraction)((reactor.m_currentWaveCount == reactor.m_waveCountMax) ? 5 : 3), 0f); } else { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(reactor.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray)null); } __instance.AddOutput(LocaleText.op_Implicit(ReactorStartupOverrideManager.CorrectTerminalOutputText), true); } else { EOSLogger.Log("Reactor Verify Incorrect!"); __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, LocaleText.op_Implicit(ReactorStartupOverrideManager.IncorrectTerminalOutputText), 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } } [HarmonyPatch(typeof(LG_GenericTerminalItem), "GetDetailedInfo")] internal static class GenericTerminalItem_GetDetailedInfo { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_GetDetailedInfo(LG_GenericTerminalItem __instance, List? defaultDetails, ref List? __result) { if (__result != null && __result.Count > 0) { return; } string terminalItemKey = __instance.TerminalItemKey; if (terminalItemKey == null || !terminalItemKey.StartsWith("REACTOR_")) { return; } List val = new List(); val.Add("----------------------------------------------------------------"); val.Add("MAIN POWER REACTOR"); if (defaultDetails != null) { Enumerator enumerator = defaultDetails.GetEnumerator(); while (enumerator.MoveNext()) { string current = enumerator.Current; val.Add(current); } } val.Add("----------------------------------------------------------------"); __result = val; } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "OnReactorShutdownVerifyChaosDone")] internal static class Reactor_OnReactorShutdownVerifyChaosDone { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_ComputerTerminalCommandInterpreter_OnReactorShutdownVerifyChaosDone(LG_ComputerTerminalCommandInterpreter __instance) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if ((Object)(object)connectedReactor == (Object)null || connectedReactor.m_isWardenObjective) { return true; } if (!BaseManager.Current.TryGetDefinition(connectedReactor, out ReactorShutdownDefinition definition)) { EOSLogger.Error("OnReactorShutdownVerifyChaosDone: found built custom reactor shutdown but its definition is missing, what happened?"); return false; } connectedReactor.AttemptInteract((eReactorInteraction)(((Object)(object)definition.ChainedPuzzleOnVerificationInstance != (Object)null) ? 8 : 9), 0f); return false; } } [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnTerminalStartupSequenceVerify")] internal static class OnTerminalStartupSequenceVerify { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_ExecuteEventsOnEndOnClientSide(LG_WardenObjective_Reactor __instance) { if (!SNet.IsMaster) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray)null); } } } [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] internal static class Reactor_OnBuildDone { [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(__instance.SpawnNode.LayerType, __instance.WardenObjectiveChainIndex, ref val) || ((val != null) ? val.ReactorWaves : null) == null || __instance.m_overrideCodes == null) { return; } int count = ((Il2CppArrayBase)(object)__instance.m_overrideCodes).Count; string[] array = new string[Math.Max(count, val.ReactorWaves.Count)]; for (int i = 0; i < array.Length; i++) { if (i < count) { array[i] = ((Il2CppArrayBase)(object)__instance.m_overrideCodes)[i]; } else { array[i] = SerialGenerator.GetCodeWord(); } } __instance.m_overrideCodes = Il2CppStringArray.op_Implicit(array); } [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 BaseManager.Current.Register(__instance); ReactorShutdownDefinition definition2; if (__instance.m_isWardenObjective) { if (!BaseManager.Current.TryGetDefinition(__instance, out ReactorStartupOverride definition)) { return; } WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(__instance.SpawnNode.LayerType, __instance.WardenObjectiveChainIndex, ref val) || val == null) { EOSLogger.Error("Failed to get WardenObjectiveData for this reactor"); return; } if ((int)val.Type != 1) { EOSLogger.Error($"Reactor Instance {definition} is not setup as vanilla ReactorStartup, cannot override"); return; } definition.ObjectiveDB = val; ReactorStartupOverrideManager.Build(__instance, definition); } else if (BaseManager.Current.TryGetDefinition(__instance, out definition2)) { ReactorShutdownObjectiveManager.Build(__instance, definition2); } else { EOSLogger.Error("EOS Reactor: something went wrong!"); } if ((Object)(object)__instance.m_terminal != (Object)null) { BaseManager.Current.Register(__instance.m_terminal); } } } [HarmonyPatch] internal class Reactor_OnStateChange { [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_WardenObjective_Reactor_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState, bool isDropinState) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10) { return true; } if (__instance.m_isWardenObjective) { if (BaseManager.Current.IsStartupReactor(__instance)) { Startup_OnStateChange(__instance, oldState, newState, isDropinState); } return true; } if (oldState.stateCount != newState.stateCount) { __instance.OnStateCountUpdate(newState.stateCount); } if (oldState.stateProgress != newState.stateProgress) { __instance.OnStateProgressUpdate(newState.stateProgress); } if (oldState.status == newState.status) { return false; } __instance.ReadyForVerification = false; if (BaseManager.Current.IsShutdownReactor(__instance)) { if (!BaseManager.Current.TryGetDefinition(__instance, out ReactorShutdownDefinition definition)) { EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but its definition is missing, what happened?"); return false; } Shutdown_OnStateChange(__instance, oldState, newState, isDropinState, definition); __instance.m_currentState = newState; return false; } EOSLogger.Error("Reactor_OnStateChange: found built custom reactor but it's not a shutdown reactor, what happened?"); return false; } private static void Startup_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!isDropinState && BaseManager.Current.TryGetDefinition(reactor, out ReactorStartupOverride definition) && (int)oldState.status == 0 && (Object)(object)reactor.m_chainedPuzzleToStartSequence != (Object)null) { EOSWardenEventManager.ExecuteWardenEvents(definition.EventsOnActive, (eWardenObjectiveEventTrigger)0); } } private static void Shutdown_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState, ReactorShutdownDefinition def) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown eReactorStatus status = newState.status; eReactorStatus val = status; switch (val - 6) { case 0: GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1080u), false, 200f, 8f, (Action)null); reactor.m_progressUpdateEnabled = true; reactor.m_currentDuration = 15f; reactor.m_lightCollection.SetMode(false); reactor.m_sound.Stop(); EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnActive, (eWardenObjectiveEventTrigger)0); break; case 1: GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1081u), false, 200f, 8f, (Action)null); reactor.m_progressUpdateEnabled = false; reactor.ReadyForVerification = true; break; case 2: reactor.m_progressUpdateEnabled = false; if ((Object)(object)def.ChainedPuzzleOnVerificationInstance != (Object)null) { GuiManager.PlayerLayer.m_wardenIntel.ShowSubObjectiveMessage("", Text.Get(1082u), false, 200f, 8f, (Action)null); def.ChainedPuzzleOnVerificationInstance.AttemptInteract((eChainedPuzzleInteraction)0); } EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnShutdownPuzzleStarts, (eWardenObjectiveEventTrigger)0); break; case 3: reactor.m_progressUpdateEnabled = false; reactor.m_objectiveCompleteTimer = Clock.Time + 5f; EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnComplete, (eWardenObjectiveEventTrigger)0); break; } } } [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateCountUpdate")] internal static class Reactor_OnStateCountUpdate { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_LG_WardenObjective_Reactor_OnStateCountUpdate(LG_WardenObjective_Reactor __instance, int count) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown if (__instance.m_isWardenObjective || BaseManager.Current.IsStartupReactor(__instance)) { return true; } if (!BaseManager.Current.IsShutdownReactor(__instance)) { EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but it's neither a startup nor shutdown reactor, what happen?"); return true; } if (!BaseManager.Current.TryGetDefinition(__instance, out ReactorShutdownDefinition definition)) { EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but its definition is missing, what happened?"); return true; } __instance.m_currentWaveCount = count; LG_ComputerTerminal val = null; if (definition.PutVerificationCodeOnTerminal) { val = BaseManager.Current.GetInstance(((GlobalBase)definition.VerificationCodeTerminal).IntTuple, definition.VerificationCodeTerminal.InstanceIndex); } __instance.m_currentWaveData = new ReactorWaveData { HasVerificationTerminal = ((Object)(object)val != (Object)null), VerificationTerminalSerial = (((val != null) ? val.ItemKey : null) ?? string.Empty), Warmup = 1f, WarmupFail = 1f, Wave = 1f, Verify = 1f, VerifyFail = 1f }; if (__instance.m_overrideCodes != null && !string.IsNullOrEmpty(((Il2CppArrayBase)(object)__instance.m_overrideCodes)[0])) { __instance.CurrentStateOverrideCode = ((Il2CppArrayBase)(object)__instance.m_overrideCodes)[0]; } else { EOSLogger.Error("Reactor_OnStateCountUpdate: code is not built?"); } return false; } } [HarmonyPatch] internal static class Reactor_Update { private static LocaleText _shutdownVerification_GUIText = LocaleText.Empty; private static bool _checked = false; [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")] [HarmonyPrefix] private static bool Pre_LG_WardenObjective_Reactor_Update(LG_WardenObjective_Reactor __instance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_isWardenObjective || (int)__instance.m_currentState.status != 7) { return true; } if (!_checked) { _shutdownVerification_GUIText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.ExtraObjectiveSetup_ReactorShutdown.SecurityVerificationRequired"), RawText = "SECURITY VERIFICATION REQUIRED. USE COMMAND REACTOR_VERIFY AND FIND CODE ON {0}." }; _checked = true; } string text = ((!__instance.m_currentWaveData.HasVerificationTerminal) ? string.Format(Text.Get(1107u), "" + __instance.CurrentStateOverrideCode + "") : string.Format(LocaleText.op_Implicit(_shutdownVerification_GUIText), __instance.m_currentWaveData.VerificationTerminalSerial)); __instance.SetGUIMessage(true, text, (ePUIMessageStyle)3, false, "", ""); return false; } } } namespace EOS.Patches.PowerGenerator { [HarmonyPatch(typeof(LG_PowerGeneratorCluster), "Setup")] internal static class Patch_LG_PowerGeneratorCluster { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_PowerGeneratorCluster_Setup(LG_PowerGeneratorCluster __instance) { BaseManager.Current.Register(__instance); if (!BaseManager.Current.TryGetDefinition(__instance, out GeneratorClusterDefinition definition)) { return; } EOSLogger.Debug("Found LG_PowerGeneratorCluster and its definition! Building this Generator cluster..."); __instance.m_serialNumber = SerialGeneratorManager.GetUniqueSerialNo(); __instance.m_itemKey = "GENERATOR_CLUSTER_" + __instance.m_serialNumber; __instance.m_terminalItem = GOUtil.GetInterfaceFromComp(__instance.m_terminalItemComp); __instance.m_terminalItem.Setup(__instance.m_itemKey, (AIG_CourseNode)null); __instance.m_terminalItem.FloorItemStatus = (eFloorInventoryObjectStatus)4; if (__instance.SpawnNode != null) { __instance.m_terminalItem.FloorItemLocation = __instance.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7); } List list = new List((IEnumerable)__instance.m_generatorAligns); uint numberOfGenerators = definition.NumberOfGenerators; __instance.m_generators = Il2CppReferenceArray.op_Implicit((LG_PowerGenerator_Core[])(object)new LG_PowerGenerator_Core[numberOfGenerators]); if (list.Count >= numberOfGenerators) { for (int i = 0; i < numberOfGenerators; i++) { int index = Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG"); LG_PowerGenerator_Core val = GOUtil.SpawnChildAndGetComp(__instance.m_generatorPrefab, list[index]); ((Il2CppArrayBase)(object)__instance.m_generators)[i] = val; val.SpawnNode = __instance.SpawnNode; BaseManager.Current.MarkAsGCGenerator(__instance, val); val.Setup(); val.SetCanTakePowerCell(true); Debug.Log(Object.op_Implicit("Spawning generator at alignIndex: " + index)); list.RemoveAt(index); } } else { Debug.LogError(Object.op_Implicit("LG_PowerGeneratorCluster does NOT have enough generator aligns to support the warden objective! Has " + list.Count + " needs " + numberOfGenerators)); } __instance.ObjectiveItemSolved = true; if (definition.EndSequenceChainedPuzzle != 0) { BaseManager.Current.RegisterForChainedPuzzleBuild(__instance, definition); } } } [HarmonyPatch] internal static class Patch_LG_PowerGenerator_Core_Setup { [HarmonyPatch(typeof(LG_PowerGenerator_Core), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_PowerGenerator_Setup(LG_PowerGenerator_Core __instance) { iCarryItemInteractionTarget powerCellInteraction = __instance.m_powerCellInteraction; powerCellInteraction.AttemptCarryItemInsert += Action.op_Implicit((Action)delegate(SNet_Player p, Item item) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Item val = default(Item); if (PlayerBackpackManager.TryGetItemInLevelFromItemData(item.Get_pItemData(), ref val)) { ItemInLevel val2 = ((Il2CppObjectBase)val).Cast(); val2.CanWarp = false; } else { EOSLogger.Error($"Inserting something other than PowerCell ({item.PublicName}) into {__instance.m_itemKey}, how?"); } }); if (!BaseManager.Current.IsGCGenerator(__instance)) { BaseManager.Current.Register(__instance); BaseManager.Current.Setup(__instance); } } } [HarmonyPatch(typeof(LG_PowerGenerator_Core), "SyncStatusChanged")] internal static class Patch_LG_PowerGenerator_Core_SyncStatusChanged { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_SyncStatusChanged(LG_PowerGenerator_Core __instance, pPowerGeneratorState state, bool isDropinState) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Invalid comparison between Unknown and I4 //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName != 10) { return; } ePowerGeneratorStatus status = state.status; LG_PowerGeneratorCluster parentGeneratorCluster = BaseManager.Current.GetParentGeneratorCluster(__instance); if ((Object)(object)parentGeneratorCluster != (Object)null && BaseManager.Current.TryGetDefinition(parentGeneratorCluster, out GeneratorClusterDefinition definition)) { EOSLogger.Log($"LG_PowerGeneratorCluster.powerGenerator.OnSyncStatusChanged! status: {status}, isDropinState: {isDropinState}"); if ((int)status == 0) { uint num = 0u; for (int i = 0; i < ((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators).Length; i++) { if ((int)((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators)[i].m_stateReplicator.State.status == 0) { num++; } } EOSLogger.Log($"Generator Cluster PowerCell inserted ({num} / {((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators).Count})"); List> eventsOnInsertCell = definition.EventsOnInsertCell; int num2 = (int)(num - 1); if (!isDropinState) { if (num2 >= 0 && num2 < eventsOnInsertCell.Count) { EOSLogger.Debug($"Executing events ({num} / {((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators).Count}). Event count: {eventsOnInsertCell[num2].Count}"); EOSWardenEventManager.ExecuteWardenEvents(eventsOnInsertCell[num2], (eWardenObjectiveEventTrigger)0); } if (num == ((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators).Count && !parentGeneratorCluster.m_endSequenceTriggered) { EOSLogger.Log("All generators powered, executing end sequence"); ((MonoBehaviour)__instance).StartCoroutine(parentGeneratorCluster.ObjectiveEndSequence()); parentGeneratorCluster.m_endSequenceTriggered = true; } } else if (num != ((Il2CppArrayBase)(object)parentGeneratorCluster.m_generators).Count) { parentGeneratorCluster.m_endSequenceTriggered = false; } } else if (isDropinState) { parentGeneratorCluster.m_endSequenceTriggered = false; } } if (BaseManager.Current.TryGetDefinition(__instance, out IndividualGeneratorDefinition definition2) && definition2.EventsOnInsertCell != null && (int)status == 0 && !isDropinState) { EOSWardenEventManager.ExecuteWardenEvents(definition2.EventsOnInsertCell, (eWardenObjectiveEventTrigger)0); } ExpeditionIGGroup expeditionIGGroup = BaseManager.Current.FindGroupDefOf(__instance); if (expeditionIGGroup == null) { return; } int num3 = 0; foreach (LG_PowerGenerator_Core generatorInstance in expeditionIGGroup.GeneratorInstances) { if ((int)generatorInstance.m_stateReplicator.State.status == 0) { num3++; } } if (isDropinState) { return; } if (num3 == expeditionIGGroup.GeneratorInstances.Count && expeditionIGGroup.PlayEndSequenceOnGroupComplete) { Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ExpeditionIGGroupManager.PlayGroupEndSequence(expeditionIGGroup)), (Action)null); WorldEventManager.m_worldEventEventCoroutines.Add(val); return; } int num4 = num3 - 1; if (num4 >= 0 && num4 < expeditionIGGroup.EventsOnInsertCell.Count) { EOSWardenEventManager.ExecuteWardenEvents(expeditionIGGroup.EventsOnInsertCell[num4], (eWardenObjectiveEventTrigger)0); } } } } namespace EOS.Patches.HSUActivator { [HarmonyPatch(typeof(LG_HSUActivator_Core), "SetupFromCustomGeomorph")] internal static class SetupFromCustomGeomorph { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_LG_HSUActivator_Core_SetupFromCustomGeomorph(LG_HSUActivator_Core __instance) { BaseManager.Current.Register(__instance); if (!BaseManager.Current.TryGetDefinition(__instance, out HSUActivatorDefinition definition)) { return; } if (__instance.m_isWardenObjective) { EOSLogger.Error("BuildCustomHSUActivator: the HSUActivator has been set up by vanilla! Aborting custom setup..."); EOSLogger.Error($"HSUActivator in {GlobalIndexUtil.ToIntTuple(__instance.SpawnNode.m_zone)}"); return; } __instance.m_linkedItemGoingIn = __instance.SpawnPickupItemOnAlign(definition.ItemFromStart, __instance.m_itemGoingInAlign, false, -1); __instance.m_linkedItemComingOut = __instance.SpawnPickupItemOnAlign(definition.ItemAfterActivation, __instance.m_itemComingOutAlign, false, -1); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemGoingIn).GetComponentInChildren()); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemComingOut).GetComponentInChildren()); __instance.m_linkedItemGoingIn.SetPickupInteractionEnabled(false); __instance.m_linkedItemComingOut.SetPickupInteractionEnabled(false); __instance.m_insertHSUInteraction.OnInteractionSelected = Action.op_Implicit((Action)delegate { }); __instance.m_sequencerInsertItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) pHSUActivatorState state = __instance.m_stateReplicator.State; if (!state.isSequenceIncomplete) { EOSLogger.Log(">>>>>> HSUInsertSequenceDone! Sequence was already complete"); } state.isSequenceIncomplete = false; __instance.m_stateReplicator.SetStateUnsynced(state); EOSLogger.Log(">>>>>> HSUInsertSequenceDone!"); if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } }); __instance.m_sequencerExtractItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //IL_0017: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) SNet_StateReplicator stateReplicator = __instance.m_stateReplicator; pHSUActivatorState state = __instance.m_stateReplicator.State; state.isSequenceIncomplete = true; stateReplicator.SetStateUnsynced(state); if (SNet.IsMaster) { __instance.AttemptInteract(new pHSUActivatorInteraction { type = (eHSUActivatorInteractionType)2 }); } }); EOSLogger.Debug($"HSUActivator: {definition}, custom setup complete"); } } [HarmonyPatch(typeof(LG_HSUActivator_Core), "SyncStatusChanged")] internal static class SyncStatusChanged { [HarmonyPrefix] [HarmonyWrapSafe] private unsafe static bool Pre_LG_HSUActivator_Core_SyncStatusChanged(LG_HSUActivator_Core __instance, pHSUActivatorState newState, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected I4, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || __instance.m_isWardenObjective) { return true; } if (!BaseManager.Current.TryGetDefinition(__instance, out HSUActivatorDefinition definition)) { return true; } if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } bool goingInVisibleForPostCulling = __instance.m_goingInVisibleForPostCulling; bool comingOutVisibleForPostCulling = __instance.m_comingOutVisibleForPostCulling; EOSLogger.Debug("LG_HSUActivator_Core.OnSyncStatusChanged " + ((object)(*(eHSUActivatorStatus*)(&newState.status))/*cast due to .constrained prefix*/).ToString()); eHSUActivatorStatus status = newState.status; eHSUActivatorStatus val = status; switch ((int)val) { case 0: __instance.m_insertHSUInteraction.SetActive(true); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, false, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StartSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 1: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, true, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); if (!isRecall) { __instance.m_sequencerInsertItem.StartSequence(); EOSWardenEventManager.ExecuteWardenEvents(definition.EventsOnHSUActivation, (eWardenObjectiveEventTrigger)0); if (SNet.IsMaster && (Object)(object)definition.ChainedPuzzleOnActivationInstance != (Object)null) { definition.ChainedPuzzleOnActivationInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 2: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StartSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 3: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, !__instance.m_showItemComingOut, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, __instance.m_showItemComingOut, definition.TakeOutItemAfterActivation, false, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StopSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StartSequence(); if (newState.isSequenceIncomplete) { __instance.HSUInsertSequenceDone(); } break; } return false; } } } namespace EOS.Patches.Expedition { [HarmonyPatch(typeof(FirstPersonItemHolder), "SetWieldedItem")] internal static class FirstPersonItemHolder_SetWieldedItem { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_SetWieldedItem(ItemEquippable item) { BaseManager.Current.OnPlayerItemWielded(item); BaseManager.Current.SetCurrentThermalSightSettings(1f); } } [HarmonyPatch(typeof(FPIS_Aim), "Update")] internal static class FPIS_Aim_Update { [HarmonyPostfix] private static void Post_Aim_Update(FPIS_Aim __instance) { if (!((Object)(object)((FPItemState)__instance).Holder.WieldedItem == (Object)null) && BaseManager.Current.IsGearWithThermal(BaseManager.Current.CurrentGearPID)) { float num = 1f - FirstPersonItemHolder.m_transitionDelta; BaseManager.Current.SetCurrentThermalSightSettings(num); BaseManager.Current.SetPuzzleVisualsIntensity(num); } } } [HarmonyPatch(typeof(GearManager), "LoadOfflineGearDatas")] internal static class GearManager_LoadOfflineGearDatas { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_GearManager_LoadOfflineGearDatas(GearManager __instance) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown BaseManager.Current.VanillaGearManager = __instance; foreach (KeyValuePair> gearSlot in BaseManager.Current.GearSlots) { gearSlot.Deconstruct(out var key, out var value); InventorySlot val = key; Dictionary dictionary = value; Enumerator enumerator2 = ((Il2CppArrayBase>)(object)__instance.m_gearPerSlot)[(int)val].GetEnumerator(); while (enumerator2.MoveNext()) { GearIDRange current = enumerator2.Current; uint offlineGearPID = ExpeditionGearManager.GetOfflineGearPID(current); dictionary.Add(offlineGearPID, current); } } BaseManager.Current.InitThermalOfflineGears(); } } [HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")] internal static class RundownManager_SetActiveExpedition { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RundownManager_SetActiveExpedition(RundownManager __instance, pActiveExpedition expPackage, ExpeditionInTierData expTierData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)expPackage.tier != 99) { BaseManager.Current.SetupAllowedGearsForActiveExpedition(); } } } [HarmonyPatch] internal static class TerminalExpeditionPatches { [HarmonyPatch(typeof(LG_ComputerTerminal), "OnProximityEnter")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_ComputerTerminal(LG_ComputerTerminal __instance) { if (SNet.IsMaster) { BaseManager.Current.GetTerminalWrapper(__instance)?.ChangeState(); } } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) BaseManager.Current.GetTerminalWrapper(__instance.m_terminal)?.ReceiveCommand(cmd, param1.ToUpperInvariant()); } } } namespace EOS.Patches.EMP { [HarmonyPatch] internal static class EMPEvents { [HarmonyPatch(typeof(PlayerInventoryBase), "OnItemEquippableFlashlightWielded")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_FlashlightWielded(GearPartFlashlight flashlight) { EMPManager.FlashlightWielded?.Invoke(flashlight); } [HarmonyPatch(typeof(PlayerInventoryLocal), "DoWieldItem")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_DoWieldItem(PlayerInventoryLocal __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) EMPManager.InventoryWielded?.Invoke(((PlayerInventoryBase)__instance).WieldedSlot); } } [HarmonyPatch] internal static class Patch_CM_PageMap { [HarmonyPatch(typeof(CM_PageMap), "UpdatePlayerData")] [HarmonyPostfix] [HarmonyAfter(new string[] { "dev.aurirex.gtfo.dimensionmaps" })] [HarmonyWrapSafe] private static void Post_UpdatePlayerData() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 CM_PageMap pageMap = MainMenuGuiLayer.Current.PageMap; if (!((Object)(object)pageMap == (Object)null) && RundownManager.ActiveExpedition != null && (int)GameStateManager.CurrentStateName == 10) { bool flag = BaseManager.Current.IsEMPOnPlayerMap(); pageMap.SetMapVisualsIsActive(!flag); pageMap.SetMapDisconnetedTextIsActive(flag); } } } [HarmonyPatch(typeof(EnemyScanner))] internal static class Patch_EnemyScanner { [HarmonyPatch("UpdateDetectedEnemies")] [HarmonyPrefix] private static bool Pre_UpdateDetectedEnemies() { EMPBioTrackerHandler instance = EMPBioTrackerHandler.Instance; return instance == null || !instance.IsEMPed(); } [HarmonyPatch("UpdateTagProgress")] [HarmonyPrefix] private static bool Pre_UpdateTagProgress(EnemyScanner __instance) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) EMPBioTrackerHandler instance = EMPBioTrackerHandler.Instance; if (instance == null || !instance.IsEMPed()) { __instance.m_screen.SetStatusText("Ready to tag"); __instance.m_screen.SetGuixColor(Color.red); return true; } ((ItemEquippable)__instance).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); __instance.m_screen.SetStatusText("ERROR"); ((ProgressBarBase)__instance.m_progressBar).SetProgress(1f); __instance.m_screen.SetGuixColor(Color.yellow); return false; } } [HarmonyPatch] internal static class Patch_PlayerAgent_Setup { [HarmonyPatch(typeof(PlayerAgent), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { GameObjectPlusExtensions.AddOrGetComponent(((Component)__instance).gameObject); } } } [HarmonyPatch] internal static class Patch_PlayerHUD { [HarmonyPatch(typeof(PlayerGuiLayer), "UpdateGUIElementsVisibility")] [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_UpdateGUIElementsVisibility() { EMPPlayerHudHandler instance = EMPPlayerHudHandler.Instance; return instance == null || !instance.IsEMPed(); } [HarmonyPatch(typeof(CellSettingsApply), "ApplyPlayerGhostOpacity")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_ApplyPlayerGhostOpacity(ref float value) { EMPPlayerHudHandler instance = EMPPlayerHudHandler.Instance; if (instance != null && instance.IsEMPed()) { value = 0f; } } [HarmonyPatch(typeof(CellSettingsApply), "ApplyHUDAlwaysShowTeammateInfo")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_ApplyHUDAlwaysShowTeammateInfo(ref bool value) { EMPPlayerHudHandler instance = EMPPlayerHudHandler.Instance; if (instance != null && instance.IsEMPed()) { value = false; } } } [HarmonyPatch] internal static class Patch_PlayerSync { [HarmonyPatch(typeof(PlayerSync), "WantsToSetFlashlightEnabled")] [HarmonyPrefix] [HarmonyAfter(new string[] { "EEC.Harmony" })] [HarmonyWrapSafe] private static void Pre_WantsToSetFlashlightEnabled(ref bool enable) { EMPPlayerFlashlightHandler instance = EMPPlayerFlashlightHandler.Instance; if (instance != null && instance.IsEMPed()) { enable = false; } } } [HarmonyPatch] internal static class Patch_SentryGunInstance { [HarmonyPatch(typeof(SentryGunInstance), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_Setup(SentryGunInstance __instance) { GameObjectPlusExtensions.AddOrGetComponent(((Component)__instance).gameObject).AssignHandler(new EMPSentryHandler()); } } } namespace EOS.Patches.ChainedPuzzle { [HarmonyPatch(typeof(ChainedPuzzleInstance), "OnStateChange")] internal static class ChainedPuzzleInstance_OnStateChange { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_ChainedPuzzleOnActivationInstance_OnStateChange(ChainedPuzzleInstance __instance, pChainedPuzzleState oldState, pChainedPuzzleState newState, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0025: 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) if ((int)GameStateManager.CurrentStateName == 10) { BaseManager.Current.Get_OnStateChange(__instance)?.Invoke(oldState, newState, isRecall); } } } [HarmonyPatch] internal static class ChainedPuzzleManager_CreatePuzzleInstance { [HarmonyPatch(typeof(ChainedPuzzleManager), "CreatePuzzleInstance", new Type[] { typeof(ChainedPuzzleDataBlock), typeof(LG_Area), typeof(LG_Area), typeof(Vector3), typeof(Transform), typeof(bool) })] [HarmonyPostfix] [HarmonyPriority(300)] [HarmonyWrapSafe] private static void Post_ChainedPuzzleInstance_Setup(ChainedPuzzleInstance __result) { BaseManager.Current.Register(__result); } } [HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")] internal static class CP_Bioscan_Core_Setup { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_CaptureBioscanVisual(CP_Bioscan_Core __instance) { BaseManager.Current.RegisterPuzzleVisual(__instance); } } [HarmonyPatch(typeof(CP_Cluster_Core), "OnSyncStateChange")] internal static class CP_Cluster_Core_FixRepeatablePuzzleBugs { [HarmonyPrefix] [HarmonyWrapSafe] private static bool Pre_CheckEventsOnPuzzleSolved(CP_Cluster_Core __instance, eClusterStatus newStatus, bool isDropinState) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 pClusterState currentState = __instance.m_sync.GetCurrentState(); if (isDropinState && (int)newStatus == 3) { __instance.m_spline.SetVisible(false); for (int i = 0; i < ((Il2CppArrayBase)(object)__instance.m_childCores).Length; i++) { ((Il2CppArrayBase)(object)__instance.m_childCores)[i].Deactivate(); } return false; } if (!isDropinState && (int)currentState.status == 3 && (int)newStatus == 1) { __instance.m_spline.Reveal(0f); return false; } return true; } } } namespace EOS.Modules.World { public enum ActiveState { DISABLED, ENABLED } } namespace EOS.Modules.World.SecuritySensor { public class MovableSensor { private readonly GameObject _graphicsGO = new GameObject(); private readonly CP_BasicMovable? _movingComp; public GameObject MovableGO { get; private set; } = new GameObject(); public MovableSensor(SensorSettings setting) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) MovableGO = Object.Instantiate(SecuritySensorManager.MovableSensor); CP_BasicMovable movingComp = default(CP_BasicMovable); if (GameObjectPlusExtensions.TryAndGetComponent(MovableGO, ref movingComp)) { _movingComp = movingComp; _movingComp.Setup(); Vector3 element = setting.Position; Vector3 val = setting.MovingPosition.First(); Vector3 val2 = setting.MovingPosition.Last(); IEnumerable source = setting.MovingPosition.Select((Vec3 e) => e.ToVector3()); if (!((Vector3)(ref element)).Equals(val)) { source = source.Prepend(element); } if (!((Vector3)(ref element)).Equals(val2)) { source = source.Append(element); } _movingComp.ScanPositions = ListExtensions.ToIl2Cpp(source.ToList()); _movingComp.m_amountOfPositions = source.Count() - 1; if (setting.MovingSpeedMulti > 0f) { CP_BasicMovable? movingComp2 = _movingComp; movingComp2.m_movementSpeed *= setting.MovingSpeedMulti; } _graphicsGO = ((Component)MovableGO.transform.GetChild(0)).gameObject; } } public void StartMoving() { _graphicsGO.SetActive(true); CP_BasicMovable? movingComp = _movingComp; if (movingComp != null) { movingComp.SyncUpdate(); } CP_BasicMovable? movingComp2 = _movingComp; if (movingComp2 != null) { movingComp2.StartMoving(); } } public void ResumeMoving() { _graphicsGO.SetActive(true); CP_BasicMovable? movingComp = _movingComp; if (movingComp != null) { movingComp.ResumeMovement(); } } public void StopMoving() { _graphicsGO.SetActive(false); CP_BasicMovable? movingComp = _movingComp; if (movingComp != null) { movingComp.StopMoving(); } } public void PauseMoving() { _graphicsGO.SetActive(false); CP_BasicMovable? movingComp = _movingComp; if (movingComp != null) { movingComp.PauseMovement(); } } } public sealed class SecuritySensorManager : GenericExpeditionDefinitionManager { public enum SensorEventType { ToggleSensorGroupState = 400, ToggleAllSensorGroups } internal static readonly SensorSync SyncTrigger; private readonly List _sensorGroups = new List(); private static readonly bool _flag; protected override string DEFINITION_NAME => "SecuritySensor"; public static GameObject CircleSensor { get; private set; } public static GameObject MovableSensor { get; private set; } public static GameObject WorkingText { get; private set; } static SecuritySensorManager() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown SyncTrigger = new SensorSync(); EOSWardenEventManager.AddEventDefinition(SensorEventType.ToggleSensorGroupState.ToString(), 400u, ToggleSensorGroup); EOSWardenEventManager.AddEventDefinition(SensorEventType.ToggleAllSensorGroups.ToString(), 401u, ToggleAllSensorGroups); ((SyncedEvent)SyncTrigger).Setup(); try { CircleSensor = AssetAPI.GetLoadedAsset("Assets/SecuritySensor/CircleSensor.prefab"); MovableSensor = AssetAPI.GetLoadedAsset("Assets/SecuritySensor/MovableSensor.prefab"); if ((Object)(object)CircleSensor == (Object)null || (Object)(object)MovableSensor == (Object)null) { throw new Exception("Failed to load security sensor prefabs!"); } GameObject loadedAsset = AssetAPI.GetLoadedAsset("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"); WorkingText = ((Component)loadedAsset.transform.GetChild(0).GetChild(1).GetChild(0)).gameObject; } catch (Exception value) { _flag = true; CircleSensor = new GameObject(); MovableSensor = new GameObject(); WorkingText = new GameObject(); EOSLogger.Error($"{value}"); } } protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); OnBuildStart(); OnEnterLevel(); } protected override void OnBuildStart() { OnLevelCleanup(); if (base.GenericExpDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out GenericExpeditionDefinition value)) { value.Definitions.ForEach(BuildSensorGroup); } } protected override void OnEnterLevel() { _sensorGroups.ForEach(delegate(SensorGroup sg) { sg.StartMovingMovables(); }); } protected override void OnLevelCleanup() { _sensorGroups.ForEach(delegate(SensorGroup sg) { sg.Destroy(); }); _sensorGroups.Clear(); } private void BuildSensorGroup(SensorGroupSettings sensorGroupSettings) { if (_flag) { FlagMsg(); } int num = ((sensorGroupSettings.Index == uint.MaxValue) ? _sensorGroups.Count : ((int)sensorGroupSettings.Index)); SensorGroup item = new SensorGroup(sensorGroupSettings, num); _sensorGroups.Add(item); EOSLogger.Debug($"SensorGroup_{num} built"); } internal void TriggerSensor(int packet) { int num = _sensorGroups.FindIndex((SensorGroup sg) => sg.SensorGroupIndex == packet); num = ((num == -1) ? packet : num); if (num < 0 || num >= _sensorGroups.Count) { EOSLogger.Error($"TriggerSensor: invalid SensorGroup index {num}"); } else { EOSLogger.Warning($"TriggerSensor: SensorGroup_{num} triggered"); EOSWardenEventManager.ExecuteWardenEvents(_sensorGroups[num].Settings.EventsOnTrigger, (eWardenObjectiveEventTrigger)0); } } public static bool InstantiateAndTryGetTMP(Transform parent, [MaybeNullWhen(false)] out TextMeshPro text) { GameObject val = Object.Instantiate(WorkingText, parent); if (!GameObjectPlusExtensions.TryAndGetComponent(val, ref text)) { EOSLogger.Error("SensorGroup: NO TEXT!"); return false; } return true; } private static void ToggleSensorGroup(WardenObjectiveEventData e) { if (_flag) { FlagMsg(); } if (SNet.IsMaster) { int num = BaseManager.Current._sensorGroups.FindIndex((SensorGroup sg) => sg.SensorGroupIndex == e.Count); num = ((num == -1) ? e.Count : num); if (num < 0 || num >= BaseManager.Current._sensorGroups.Count) { EOSLogger.Error($"ToggleSensorGroup: invalid SensorGroup index {num}"); } else { BaseManager.Current._sensorGroups[num].ChangeState(e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED); } } } private static void ToggleAllSensorGroups(WardenObjectiveEventData e) { if (_flag) { FlagMsg(); } if (!SNet.IsMaster) { return; } foreach (SensorGroup sensorGroup in BaseManager.Current._sensorGroups) { sensorGroup.ChangeState(e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED); } } private static void FlagMsg() { EOSLogger.Error("Failed to load security sensor prefabs during setup!"); } } public class SensorColliderComp : MonoBehaviour { public const float CHECK_INTERVAL = 0.1f; private float _sqrRadius; private float _nextCheckTime = float.NaN; private int _lastPlayersInSensor = 0; [HideFromIl2Cpp] public SensorGroup Parent { get; internal set; } = null; private Vector3 Position => ((Component)this).gameObject.transform.position; [HideFromIl2Cpp] public void Setup(SensorGroup parent, float radius) { Parent = parent; _sqrRadius = radius * radius; } public void Update() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(_nextCheckTime) && Clock.Time < _nextCheckTime)) { return; } _nextCheckTime = Clock.Time + 0.1f; if (Parent.Status != ActiveState.ENABLED) { return; } int num = 0; bool flag = false; Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!current.Owner.IsBot && ((Agent)current).Alive && GameObjectPlusExtensions.IsWithinSqrDistance(Position, ((Agent)current).Position, _sqrRadius)) { num++; flag |= ((Agent)current).IsLocallyOwned; } } if (num > _lastPlayersInSensor && flag) { ((SyncedEvent)SecuritySensorManager.SyncTrigger).Send(Parent.SensorGroupIndex, (SNet_Player)null, (SNet_ChannelType)2); } _lastPlayersInSensor = num; } } public class SensorGroup { private readonly List _basicSensors = new List(); private readonly List _movableSensors = new List(); public int SensorGroupIndex { get; private set; } public SensorGroupSettings Settings { get; private set; } public StateReplicator? Replicator { get; private set; } public ActiveState Status { get; private set; } = ActiveState.ENABLED; public IEnumerable BasicSensors => _basicSensors; public IEnumerable MovableSensors => _movableSensors; public SensorGroup(SensorGroupSettings sensorGroupSettings, int sensorGroupIndex) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) SensorGroupIndex = sensorGroupIndex; Settings = sensorGroupSettings; foreach (SensorSettings item in sensorGroupSettings.SensorGroup) { Vector3 val = item.Position; if (val == Vector3.zeroVector) { continue; } GameObject val2 = new GameObject(); switch (item.SensorType) { case SensorType.BASIC: val2 = Object.Instantiate(SecuritySensorManager.CircleSensor); _basicSensors.Add(val2); break; case SensorType.MOVABLE: { MovableSensor movableSensor = new MovableSensor(item); if (item.MovingPosition.Count < 1) { EOSLogger.Error("SensorGroup: at least 1 moving position is required to setup T-Sensor!"); continue; } val2 = movableSensor.MovableGO; _movableSensors.Add(movableSensor); break; } default: EOSLogger.Error($"Unsupported SensorType {item.SensorType}, skipped"); continue; } val2.transform.SetPositionAndRotation(val, Quaternion.identityQuaternion); Transform transform = val2.transform; transform.localPosition += Vector3.up * 0.6f / 3.7f; val2.transform.localScale = new Vector3(item.Radius, item.Radius, item.Radius); val2.AddComponent().Setup(this, item.Radius); ((Component)val2.transform.GetChild(0).GetChild(1)).GetComponentInChildren().material.SetColor("_ColorA", item.Color); Transform child = val2.transform.GetChild(0).GetChild(2); Transform child2 = child.GetChild(0); child2.SetParent((Transform)null); Object.Destroy((Object)(object)((Component)child2).gameObject); if (SecuritySensorManager.InstantiateAndTryGetTMP(child, out TextMeshPro text)) { ((TMP_Text)text).SetText(LocaleText.op_Implicit(item.Text), true); TextMeshPro obj = text; Color32 val3 = (((TMP_Text)text).m_fontColor32 = Color32.op_Implicit(item.TextColor)); ((TMP_Text)obj).m_fontColor = Color32.op_Implicit(val3); } val2.SetActive(true); } uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("SensorGroup: replicator IDs depleted, cannot setup StateReplicator"); return; } Replicator = StateReplicator.Create(num, new SensorGroupState { status = ActiveState.ENABLED }, (LifeTimeType)1, (IStateReplicatorHolder)null); Replicator.OnStateChanged += OnStateChanged; } public void Destroy() { _basicSensors.ForEach((Action)Object.Destroy); _movableSensors.ForEach(delegate(MovableSensor m) { Object.Destroy((Object)(object)m.MovableGO); }); Replicator?.Unload(); } public void ChangeState(ActiveState status) { EOSLogger.Debug($"ChangeState: SecuritySensorGroup_{SensorGroupIndex} changed to state {status}"); Replicator?.SetState(new SensorGroupState { status = status }); } private void OnStateChanged(SensorGroupState _, SensorGroupState state, bool isRecall) { if (Status != state.status) { Status = state.status; _basicSensors.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActive(Status == ActiveState.ENABLED); }); if (Status == ActiveState.ENABLED) { ResumeMovingMovables(); } else { PauseMovingMovables(); } } } public void StartMovingMovables() { _movableSensors.ForEach(delegate(MovableSensor movable) { movable.StartMoving(); }); } public void PauseMovingMovables() { _movableSensors.ForEach(delegate(MovableSensor movable) { movable.PauseMoving(); }); } public void ResumeMovingMovables() { _movableSensors.ForEach(delegate(MovableSensor movable) { movable.ResumeMoving(); }); } } public enum SensorType { BASIC, MOVABLE } public class SensorGroupSettings { public uint Index { get; set; } = uint.MaxValue; public List SensorGroup { get; set; } = new List { new SensorSettings() }; public List EventsOnTrigger { get; set; } = new List(); } public class SensorSettings { public Vec3 Position { get; set; } = new Vec3(); public float Radius { get; set; } = 2.3f; public Color Color { get; set; } = new Color { r = 99f / 106f, g = 0.1055641f, b = 0f, a = 0.2627451f }; public LocaleText Text { get; set; } = new LocaleText("S:_EC/uR_ITY S:/Ca_N"); public Color TextColor { get; set; } = new Color { r = 0.8862745f, g = 46f / 51f, b = 0.8980392f, a = 0.70980394f }; public SensorType SensorType { get; set; } = SensorType.BASIC; public float MovingSpeedMulti { get; set; } = 1f; public List MovingPosition { get; set; } = new List { new Vec3() }; } public struct SensorGroupState { public ActiveState status { get; set; } public SensorGroupState(SensorGroupState o) { status = ActiveState.DISABLED; status = o.status; } public SensorGroupState(ActiveState status) { this.status = ActiveState.DISABLED; this.status = status; } } public struct MovableSensorLerp { public float lerp { get; set; } public MovableSensorLerp(MovableSensorLerp o) { lerp = 0f; lerp = o.lerp; } public MovableSensorLerp(float lerp) { this.lerp = 0f; this.lerp = lerp; } } internal sealed class SensorSync : SyncedEvent { public override string GUID => "EOS-SensorTrigger"; protected override void Receive(int packet) { BaseManager.Current.TriggerSensor(packet); } protected override void ReceiveLocal(int packet) { ((SyncedEvent)this).Receive(packet); } } } namespace EOS.Modules.World.NavigationSpline { public class NavigationalSplineDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public float RevealSpeedMulti { get; set; } = 1f; public List Splines { get; set; } = new List { new Spline() }; } public class Spline { public Vec3 From { get; set; } = new Vec3(); public Vec3 To { get; set; } = new Vec3(); } public class NavigationalSplineManager : GenericExpeditionDefinitionManager { public enum SplineEventType { ToggleSplineState = 610 } private readonly Dictionary _splineGroups = new Dictionary(); private static readonly bool _flag; protected override string DEFINITION_NAME => "NavigationalSpline"; public static GameObject SplineGeneratorGO { get; private set; } static NavigationalSplineManager() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown EOSWardenEventManager.AddEventDefinition(SplineEventType.ToggleSplineState.ToString(), 610u, ToggleSplineState); try { SplineGeneratorGO = AssetAPI.GetLoadedAsset("Assets/EOSAssets/LG_ChainedPuzzleSplineGenerator.prefab"); if ((Object)(object)SplineGeneratorGO == (Object)null) { throw new Exception("Failed to load navigation spline prefab!"); } } catch (Exception value) { _flag = true; SplineGeneratorGO = new GameObject(); EOSLogger.Error($"{value}"); } } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { CollectionExtensions.ForEachValue((IDictionary)_splineGroups, (Action)delegate(GameObject group) { Object.Destroy((Object)(object)group); }); _splineGroups.Clear(); } protected override void OnBuildDone() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if (_flag) { FlagMsg(); } if (!base.GenericExpDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out GenericExpeditionDefinition value)) { return; } foreach (NavigationalSplineDefinition definition in value.Definitions) { if (_splineGroups.ContainsKey(definition.WorldEventObjectFilter)) { EOSLogger.Error(DEFINITION_NAME + ": duplicate 'WorldEventObjectFilter': " + definition.WorldEventObjectFilter + ", won't build"); continue; } GameObject val = new GameObject("NavigationalSpline_" + definition.WorldEventObjectFilter); for (int i = 0; i < definition.Splines.Count; i++) { Spline spline = definition.Splines[i]; GameObject val2 = new GameObject($"NavigationalSpline_{definition.WorldEventObjectFilter}_{i}"); val2.transform.SetParent(val.transform); CP_Holopath_Spline val3 = val2.AddComponent(); val3.m_splineGeneratorPrefab = SplineGeneratorGO; val3.Setup(false); val3.GeneratePath((Vector3)spline.From, (Vector3)spline.To); if (definition.RevealSpeedMulti > 0f) { val3.m_revealSpeed *= definition.RevealSpeedMulti; } } _splineGroups[definition.WorldEventObjectFilter] = val; } } private static void ToggleSplineState(WardenObjectiveEventData e) { if (_flag) { FlagMsg(); } if (!BaseManager.Current._splineGroups.TryGetValue(e.WorldEventObjectFilter, out GameObject value)) { EOSLogger.Error("NavigationalSplineManager: cannot find Spline Group with name '" + e.WorldEventObjectFilter); return; } CP_Holopath_Spline val = default(CP_Holopath_Spline); for (int i = 0; i < value.transform.childCount; i++) { if (GameObjectPlusExtensions.TryAndGetComponent(((Component)value.transform.GetChild(i)).gameObject, ref val)) { switch (e.Count) { case 0: val.SetSplineProgress(0f); val.Reveal(0f); break; case 1: val.SetSplineProgress(0.95f); val.Reveal(0f); break; case 2: val.SetVisible(false); break; } } } } private static void FlagMsg() { EOSLogger.Error("Failed to load navigation spline prefab during setup!"); } } } namespace EOS.Modules.World.EMP { public class EMPController : MonoBehaviour { private const float CHECK_INTERVAL = 0.15f; private const float CLEANUP_INTERVAL = 1f; private float _nextCleanupTime; private float _nextCheckTime; [HideFromIl2Cpp] public EMPHandler? Handler { get; private set; } [HideFromIl2Cpp] public void AssignHandler(EMPHandler handler) { if (Handler != null) { EOSLogger.Warning("EMPController: AssignHandler called when a handler was already assigned"); return; } Handler = handler; Handler.Setup(((Component)this).gameObject); } public void Update() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName != 10 || Handler == null) { return; } float time = Clock.Time; if (Handler.IsTransitioning || time >= _nextCheckTime) { Handler.Tick(); if (!Handler.IsTransitioning) { _nextCheckTime = time + 0.15f; } } if (time >= _nextCleanupTime) { Handler.RemoveInactiveSources(); _nextCleanupTime = time + 1f; } } public void ForceState(bool on) { Handler?.ForceState(on); } public void OnDestroy() { Handler?.OnDespawn(); } } public abstract class EMPHandler { private static readonly Dictionary s_handlers = new Dictionary(); private static long s_nextId = 0L; private readonly HashSet _affectedBy = new HashSet(); private long _id; protected bool _destroyed; private bool _targetOn = true; private bool _transitioning; private float _flickerStart; private float _flickerEnd; private bool? _appliedOn; public static IEnumerable All => s_handlers.Values; protected virtual float FlickerDuration => 0.25f; protected virtual float OnToOffMinDelay => 0f; protected virtual float OnToOffMaxDelay => 0.75f; protected virtual float OffToOnMinDelay => 0.5f; protected virtual float OffToOnMaxDelay => 1.25f; protected virtual bool ContinuouslyEnforce => false; public GameObject GameObject { get; private set; } = null; public Vector3 Position { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = GameObject; return (gameObject != null) ? gameObject.transform.position : Vector3.zero; } } public bool IsTransitioning => _transitioning; public virtual void Setup(GameObject gameObject) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) GameObject = gameObject; foreach (EMPShock activeShock in BaseManager.Current.ActiveShocks) { if (activeShock.InRange(Position)) { AddAffectedBy(activeShock); } } _id = s_nextId++; s_handlers[_id] = this; } public virtual void OnDespawn() { _destroyed = true; _affectedBy.Clear(); s_handlers.Remove(_id); GameObject = null; } public virtual bool IsEMPed() { foreach (IEMPSource item in _affectedBy) { if (item.IsActive) { return true; } } return false; } public void AddAffectedBy(IEMPSource source) { _affectedBy.Add(source); } public void RemoveAffectedBy(IEMPSource source) { _affectedBy.Remove(source); } internal void RemoveInactiveSources() { _affectedBy.RemoveWhere((IEMPSource src) => !src.IsActive); } public void Tick() { if (_destroyed) { return; } bool flag = !IsEMPed(); float time = Clock.Time; if (flag != _targetOn) { _targetOn = flag; float num = (flag ? EMPManager.RandRange(OffToOnMinDelay, OffToOnMaxDelay) : EMPManager.RandRange(OnToOffMinDelay, OnToOffMaxDelay)); _flickerStart = time + num; _flickerEnd = _flickerStart + FlickerDuration; _transitioning = true; } if (_transitioning) { if (!(time < _flickerStart)) { if (time < _flickerEnd) { FlickerDevice(); return; } _transitioning = false; ApplyState(_targetOn); } } else if (ContinuouslyEnforce) { ApplyState(_targetOn, force: true); } } public void ForceState(bool on) { _targetOn = on; _transitioning = false; ApplyState(on, force: true); } private void ApplyState(bool on, bool force = false) { if (force || _appliedOn != on) { _appliedOn = on; if (on) { DeviceOn(); } else { DeviceOff(); } } } protected abstract void DeviceOn(); protected abstract void DeviceOff(); protected abstract void FlickerDevice(); } public sealed class EMPManager : GenericExpeditionDefinitionManager { public enum EMPEventType { Instant_Shock = 300, Toggle_PEMP_State } internal readonly List ActiveShocks = new List(); internal readonly Dictionary PersistentEMPs = new Dictionary(); internal static Random Rand; internal static Action? FlashlightWielded; internal static Action? InventoryWielded; protected override string DEFINITION_NAME => "PersistentEMP"; static EMPManager() { Rand = new Random(); EOSWardenEventManager.AddEventDefinition(EMPEventType.Instant_Shock.ToString(), 300u, InstantShock); EOSWardenEventManager.AddEventDefinition(EMPEventType.Toggle_PEMP_State.ToString(), 301u, TogglePersistentEMPState); } protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); OnBuildStart(); } protected override void OnBuildStart() { OnLevelCleanup(); if (base.GenericExpDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out GenericExpeditionDefinition value)) { value.Definitions.ForEach(InitPersistentEMP); } } protected override void OnBuildDone() { foreach (LightWorker item in LightAPI.GetLightWorkersInDimension(Enum.GetValues())) { ((Component)item.Light).gameObject.AddComponent().AssignHandler(new EMPLightHandler(item)); } } protected override void OnLevelCleanup() { ActiveShocks.Clear(); CollectionExtensions.ForEachValue((IDictionary)PersistentEMPs, (Action)delegate(PersistentEMP pEMP) { pEMP.Destroy(); }); PersistentEMPs.Clear(); } private void InitPersistentEMP(PersistentEMPDefinition def) { PersistentEMPs[def.pEMPIndex] = new PersistentEMP(def); EOSLogger.Debug($"EMP: PersistentEMP #{def.pEMPIndex} initialized"); } internal void RemoveInactiveShocks() { ActiveShocks.RemoveAll((EMPShock s) => !s.IsActive); } public bool IsEMPOnPlayerMap() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10) { return false; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { return false; } Vector3 position = ((Agent)localPlayerAgent).Position; foreach (EMPShock activeShock in ActiveShocks) { if (activeShock.IsActive && activeShock.InRange(position)) { return true; } } foreach (PersistentEMP value in PersistentEMPs.Values) { if (value.IsActive && value.ItemToDisable.Map && value.InRange(position)) { return true; } } return false; } private static void InstantShock(WardenObjectiveEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0014: 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) if ((int)GameStateManager.CurrentStateName != 10) { return; } EMPShock eMPShock = new EMPShock(e.Position, e.FogTransitionDuration, Clock.Time + e.Duration); foreach (EMPHandler item in EMPHandler.All) { if (eMPShock.InRange(item.Position)) { item.AddAffectedBy(eMPShock); } } BaseManager.Current.ActiveShocks.Add(eMPShock); } private static void TogglePersistentEMPState(WardenObjectiveEventData e) { uint count = (uint)e.Count; if (!BaseManager.Current.PersistentEMPs.TryGetValue(count, out PersistentEMP value)) { EOSLogger.Error($"TogglepEMPState: no pEMP with index #{count} is defined for this level!"); } else if (SNet.IsMaster) { value.ChangeState(e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED); } } internal static float RandRange(float min, float max) { return min + Rand.NextSingle() * (max - min); } internal static bool RandCoin(int oneInX = 2) { return Rand.Next(0, oneInX) == 0; } } public sealed class EMPShock : IEMPSource { public Vector3 Position { get; } public float Range { get; } public float SqrRange { get; } public float EndTime { get; } public ItemToDisable ItemToDisable { get; } = new ItemToDisable(BioTracker: true, PlayerHUD: true, PlayerFlash: true, EnvLight: true, GunSight: true, Sentry: true, Map: true); public bool IsActive => Clock.Time < EndTime; public bool InRange(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GameObjectPlusExtensions.IsWithinSqrDistance(point, Position, SqrRange); } public EMPShock(Vector3 position, float range, float endTime) { //IL_001b: 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) Position = position; Range = range; SqrRange = range * range; EndTime = endTime; } } public interface IEMPSource { Vector3 Position { get; } float Range { get; } ItemToDisable ItemToDisable { get; } bool IsActive { get; } bool InRange(Vector3 point); } public sealed class PersistentEMP : IEMPSource { public StateReplicator? Replicator { get; private set; } public ActiveState Status { get; private set; } = ActiveState.DISABLED; public Vector3 Position { get; } public float Range { get; } public float SqrRange { get; } public ItemToDisable ItemToDisable { get; } public bool IsActive => Status == ActiveState.ENABLED; public uint Index { get; } public bool InRange(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GameObjectPlusExtensions.IsWithinSqrDistance(point, Position, SqrRange); } public PersistentEMP(PersistentEMPDefinition def) { //IL_0022: 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) Index = def.pEMPIndex; Position = def.Position; Range = def.Range; SqrRange = Range * Range; ItemToDisable = def.ItemToDisable; uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("pEMP: replicator IDs depleted, cannot setup StateReplicator"); return; } Replicator = StateReplicator.Create(num, new PersistentEMPState { status = ActiveState.DISABLED }, (LifeTimeType)1, (IStateReplicatorHolder)null); Replicator.OnStateChanged += OnStateChanged; } public void Destroy() { Replicator?.Unload(); foreach (EMPLightHandler allLight in EMPLightHandler.AllLights) { allLight.RemoveAffectedBy(this); } } public void ChangeState(ActiveState status) { EOSLogger.Debug($"ChangeState: pEMP #{Index} changed to state {status}"); Replicator?.SetState(new PersistentEMPState { status = status }); } private void OnStateChanged(PersistentEMPState _, PersistentEMPState state, bool isRecall) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) Status = state.status; if (!ItemToDisable.EnvLight) { return; } foreach (EMPLightHandler allLight in EMPLightHandler.AllLights) { if (IsActive && InRange(allLight.Position)) { allLight.AddAffectedBy(this); } else { allLight.RemoveAffectedBy(this); } } } } public readonly record struct ItemToDisable(bool BioTracker, bool PlayerHUD, bool PlayerFlash, bool EnvLight, bool GunSight, bool Sentry, bool Map); public class PersistentEMPDefinition { public uint pEMPIndex { get; set; } = 0u; public Vec3 Position { get; set; } = new Vec3(); public float Range { get; set; } = 0f; public ItemToDisable ItemToDisable { get; set; } = new ItemToDisable(BioTracker: true, PlayerHUD: true, PlayerFlash: true, EnvLight: true, GunSight: true, Sentry: true, Map: true); } public struct PersistentEMPState { public ActiveState status { get; set; } public PersistentEMPState(PersistentEMPState p) { status = ActiveState.DISABLED; status = p.status; } public PersistentEMPState(ActiveState status) { this.status = ActiveState.DISABLED; this.status = status; } } public class PlayerEMPComp : MonoBehaviour { private PlayerAgent _player = null; private const float UPDATE_INTERVAL = 0.15f; private float _nextUpdateTime; private readonly HashSet _gearHelded = new HashSet(); public void Awake() { _player = ((Component)this).GetComponent(); SetupHUDHandler(); SetupFlashlightHandler(); EMPManager.InventoryWielded = (Action)Delegate.Combine(EMPManager.InventoryWielded, new Action(OnInventoryWielded)); EMPManager.FlashlightWielded = (Action)Delegate.Combine(EMPManager.FlashlightWielded, new Action(OnFlashlightWielded)); } public void OnDestroy() { EMPManager.InventoryWielded = (Action)Delegate.Remove(EMPManager.InventoryWielded, new Action(OnInventoryWielded)); EMPManager.FlashlightWielded = (Action)Delegate.Remove(EMPManager.FlashlightWielded, new Action(OnFlashlightWielded)); _gearHelded.Clear(); } private void SetupHUDHandler() { ((Component)_player).gameObject.AddComponent().AssignHandler(new EMPPlayerHudHandler()); EOSLogger.Debug("EMP: PlayerHUD handler ready"); } private void SetupFlashlightHandler() { ((Component)_player).gameObject.AddComponent().AssignHandler(new EMPPlayerFlashlightHandler()); EOSLogger.Debug("EMP: Flashlight handler ready"); } private void OnInventoryWielded(InventorySlot slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (slot - 1 > 1) { if ((int)slot == 3) { SetupToolHandler(); } } else { SetupWeaponHandler(slot); } } private void SetupWeaponHandler(InventorySlot slot) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(slot, ref val) && !_gearHelded.Contains(((Object)val.Instance).GetInstanceID())) { _gearHelded.Add(((Object)val.Instance).GetInstanceID()); GameObjectPlusExtensions.AddOrGetComponent(((Component)val.Instance).gameObject).AssignHandler(new EMPGunSightHandler()); EOSLogger.Debug($"EMP: GunSight handler ready for slot {slot}"); } } private void SetupToolHandler() { BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem((InventorySlot)3, ref val) && !_gearHelded.Contains(((Object)val.Instance).GetInstanceID())) { _gearHelded.Add(((Object)val.Instance).GetInstanceID()); if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent() == (Object)null)) { GameObjectPlusExtensions.AddOrGetComponent(((Component)val.Instance).gameObject).AssignHandler(new EMPBioTrackerHandler()); EOSLogger.Debug("EMP: BioTracker handler ready"); } } } private void OnFlashlightWielded(GearPartFlashlight flashlight) { EMPPlayerFlashlightHandler.Instance?.OnFlashlightWielded(flashlight); } public void Update() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName == 10) { float time = Clock.Time; if (!(time < _nextUpdateTime)) { _nextUpdateTime = time + 0.15f; BaseManager.Current.RemoveInactiveShocks(); PersistentEMPProximityUpdate(); } } } private void PersistentEMPProximityUpdate() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Agent)_player).Position; foreach (PersistentEMP value in BaseManager.Current.PersistentEMPs.Values) { ItemToDisable itemToDisable = value.ItemToDisable; if (value.IsActive && value.InRange(position)) { if (itemToDisable.BioTracker) { EMPBioTrackerHandler.Instance?.AddAffectedBy(value); } if (itemToDisable.PlayerFlash) { EMPPlayerFlashlightHandler.Instance?.AddAffectedBy(value); } if (itemToDisable.PlayerHUD) { EMPPlayerHudHandler.Instance?.AddAffectedBy(value); } if (itemToDisable.Sentry) { foreach (EMPSentryHandler allSentry in EMPSentryHandler.AllSentries) { allSentry.AddAffectedBy(value); } } if (!itemToDisable.GunSight) { continue; } foreach (EMPGunSightHandler allGunSight in EMPGunSightHandler.AllGunSights) { allGunSight.AddAffectedBy(value); } continue; } if (itemToDisable.BioTracker) { EMPBioTrackerHandler.Instance?.RemoveAffectedBy(value); } if (itemToDisable.PlayerFlash) { EMPPlayerFlashlightHandler.Instance?.RemoveAffectedBy(value); } if (itemToDisable.PlayerHUD) { EMPPlayerHudHandler.Instance?.RemoveAffectedBy(value); } if (itemToDisable.Sentry) { foreach (EMPSentryHandler allSentry2 in EMPSentryHandler.AllSentries) { allSentry2.RemoveAffectedBy(value); } } if (!itemToDisable.GunSight) { continue; } foreach (EMPGunSightHandler allGunSight2 in EMPGunSightHandler.AllGunSights) { allGunSight2.RemoveAffectedBy(value); } } } } } namespace EOS.Modules.World.EMP.Handlers { public sealed class EMPBioTrackerHandler : EMPHandler { private EnemyScanner _scanner = null; public static EMPBioTrackerHandler Instance { get; private set; } public override void Setup(GameObject gameObject) { Instance?.OnDespawn(); base.Setup(gameObject); Instance = this; _scanner = gameObject.GetComponent(); } public override void OnDespawn() { base.OnDespawn(); if (Instance == this) { Instance = null; } } protected override void DeviceOn() { _scanner.m_graphics.m_display.enabled = true; } protected override void DeviceOff() { ((ItemEquippable)_scanner).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); _scanner.m_graphics.m_display.enabled = false; } protected override void FlickerDevice() { ((Behaviour)_scanner).enabled = EMPManager.RandCoin(); } } public sealed class EMPGunSightHandler : EMPHandler { private static readonly List s_instances; private GameObject[] _sightPictures = null; public static IEnumerable AllGunSights => s_instances; static EMPGunSightHandler() { s_instances = new List(); LevelAPI.OnBuildStart += s_instances.Clear; LevelAPI.OnLevelCleanup += s_instances.Clear; } public override void Setup(GameObject gameObject) { base.Setup(gameObject); _sightPictures = (from r in ((IEnumerable)base.GameObject.GetComponentsInChildren(true)).Where(delegate(Renderer r) { Material sharedMaterial = r.sharedMaterial; int result; if (sharedMaterial == null) { result = 0; } else { Shader shader = sharedMaterial.shader; result = ((((shader != null) ? new bool?(((Object)shader).name.Contains("HolographicSight")) : ((bool?)null)) == true) ? 1 : 0); } return (byte)result != 0; }) select ((Component)r).gameObject).ToArray(); s_instances.Add(this); } public override void OnDespawn() { base.OnDespawn(); s_instances.Remove(this); } protected override void DeviceOn() { SetSightsActive(active: true); } protected override void DeviceOff() { SetSightsActive(active: false); } protected override void FlickerDevice() { SetSightsActive(EMPManager.RandCoin()); } private void SetSightsActive(bool active) { GameObject[] sightPictures = _sightPictures; foreach (GameObject val in sightPictures) { if (val != null) { val.SetActive(active); } } } } public class EMPLightHandler : EMPHandler { private static readonly Dictionary s_instances; private readonly LightWorker _worker; private readonly LG_Light _light; private ILightModifier? _mod; public static IEnumerable AllLights => s_instances.Values; protected override float FlickerDuration => 0.4f; static EMPLightHandler() { s_instances = new Dictionary(); LevelAPI.OnBuildStart += s_instances.Clear; LevelAPI.OnLevelCleanup += s_instances.Clear; } public EMPLightHandler(LightWorker worker) { _worker = worker; _light = worker.Light; } public override void Setup(GameObject gameObject) { base.Setup(gameObject); s_instances[((Il2CppObjectBase)_light).Pointer] = this; } protected override void DeviceOn() { if (_worker != null) { ILightModifier? mod = _mod; if (mod != null) { mod.Remove(); } _mod = null; } } protected override void DeviceOff() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (_worker != null) { if (_mod == null) { _mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000); } _mod.Color = Color.black; _mod.Intensity = 0f; } } protected override void FlickerDevice() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (_worker != null) { if (_mod == null) { _mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000); } _mod.Intensity = EMPManager.Rand.NextSingle() * _worker.OrigIntensity; } } } public sealed class EMPPlayerFlashlightHandler : EMPHandler { private PlayerInventoryBase _inventory = null; private float _baseIntensity; private bool _flashlightWasOn; public static EMPPlayerFlashlightHandler Instance { get; private set; } public override void Setup(GameObject gameObject) { Instance?.OnDespawn(); base.Setup(gameObject); _inventory = gameObject.GetComponent().Inventory; PlayerInventoryBase inventory = _inventory; if ((Object)(object)((inventory != null) ? inventory.m_flashlight : null) != (Object)null) { _baseIntensity = _inventory.m_flashlight.intensity; } Instance = this; } public override void OnDespawn() { base.OnDespawn(); if (Instance == this) { Instance = null; } } public void OnFlashlightWielded(GearPartFlashlight flashlight) { _baseIntensity = GameDataBlockBase.GetBlock(flashlight.m_settingsID).intensity; } protected override void DeviceOn() { if (_flashlightWasOn != _inventory.FlashlightEnabled) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(_flashlightWasOn, false); } _inventory.m_flashlight.intensity = _baseIntensity; } protected override void DeviceOff() { _flashlightWasOn = _inventory.FlashlightEnabled; if (_flashlightWasOn) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(false, false); } } protected override void FlickerDevice() { if (_inventory.FlashlightEnabled) { _inventory.m_flashlight.intensity = EMPManager.Rand.NextSingle() * _baseIntensity; } } } public class EMPPlayerHudHandler : EMPHandler { private readonly List _hudElements = new List(); public static EMPPlayerHudHandler Instance { get; private set; } protected override bool ContinuouslyEnforce => true; public override void Setup(GameObject gameObject) { Instance?.OnDespawn(); base.Setup(gameObject); _hudElements.Clear(); _hudElements.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_compass); _hudElements.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_wardenObjective); _hudElements.Add((RectTransformComp)(object)GuiManager.PlayerLayer.Inventory); _hudElements.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_playerStatus); Instance = this; } public override void OnDespawn() { base.OnDespawn(); _hudElements.Clear(); if (Instance == this) { Instance = null; } } protected override void DeviceOn() { SetHudActive(on: true); SetNavMarkers(on: true); SetGhostOpacity(on: true); } protected override void DeviceOff() { SetHudActive(on: false); SetNavMarkers(on: false); SetGhostOpacity(on: false); } protected override void FlickerDevice() { bool flag = EMPManager.RandCoin(); SetHudActive(flag); SetNavMarkers(flag); SetGhostOpacity(flag); } private void SetHudActive(bool on) { foreach (RectTransformComp hudElement in _hudElements) { ((Component)hudElement).gameObject.SetActive(on); } } private void SetNavMarkers(bool on) { Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Agent)current).IsLocallyOwned) { current.NavMarker.SetMarkerVisible(on); } } } private void SetGhostOpacity(bool on) { CellSettingsApply.ApplyPlayerGhostOpacity(on ? CellSettingsManager.SettingsData.HUD.Player_GhostOpacity.Value : 0f); } } public sealed class EMPSentryHandler : EMPHandler { private static readonly List s_instances; private SentryGunInstance _sentry = null; private SentryGunInstance_ScannerVisuals_Plane _visuals = null; public static IEnumerable AllSentries => s_instances; static EMPSentryHandler() { s_instances = new List(); LevelAPI.OnBuildStart += s_instances.Clear; LevelAPI.OnLevelCleanup += s_instances.Clear; } public override void Setup(GameObject gameObject) { base.Setup(gameObject); _sentry = gameObject.GetComponent(); _visuals = gameObject.GetComponent(); if ((Object)(object)_sentry == (Object)null || (Object)(object)_visuals == (Object)null) { EOSLogger.Error($"EMPSentryHandler: missing components, will not setup! [Sentry: {(Object)(object)_sentry != (Object)null}, Visuals: {(Object)(object)_visuals != (Object)null}]"); OnDespawn(); } else { s_instances.Add(this); } } public override void OnDespawn() { base.OnDespawn(); s_instances.Remove(this); } protected override void DeviceOn() { _sentry.m_isSetup = true; _sentry.m_visuals.SetVisualStatus((eSentryGunStatus)0, true); _sentry.m_isScanning = false; _sentry.m_startScanTimer = Clock.Time + _sentry.m_initialScanDelay; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true); } protected override void DeviceOff() { //IL_000c: 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) _visuals.m_scannerPlane.SetColor(Color.clear); _visuals.UpdateLightProps(Color.clear, false); _sentry.m_isSetup = false; _sentry.m_isScanning = false; _sentry.m_isFiring = false; ((ItemEquippable)_sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true); } protected override void FlickerDevice() { _sentry.StopFiring(); switch (EMPManager.Rand.Next(0, 3)) { case 0: _visuals.SetVisualStatus((eSentryGunStatus)4, true); break; case 1: _visuals.SetVisualStatus((eSentryGunStatus)1, true); break; case 2: _visuals.SetVisualStatus((eSentryGunStatus)2, true); break; } } } } namespace EOS.Modules.Tweaks.TerminalTweak { public sealed class SerialGeneratorManager : BaseManager { public enum CodeWordLength { Three = 3, Four, Five, Six, Seven } private sealed class ShuffledStepArray { private readonly string[] _values; private readonly int[] _order; private int _step = -1; public ShuffledStepArray(IEnumerable values) { _values = values.Distinct().ToArray(); _order = Enumerable.Range(0, _values.Length).ToArray(); for (int num = _order.Length - 1; num > 0; num--) { int num2 = _random.Next(0, num + 1); ref int reference = ref _order[num]; ref int reference2 = ref _order[num2]; int num3 = _order[num2]; int num4 = _order[num]; reference = num3; reference2 = num4; } } public string Next() { _step++; if (_step >= _order.Length) { _step = 0; } return _values[_order[_step]]; } } public static readonly string[] CodeWordPrefixes; public static readonly string[] HardCodeWordPrefixes; public static readonly string[] ThreeLetterWords; public static readonly string[] FourLetterWords; public static readonly string[] FiveLetterWords; public static readonly string[] SixLetterWords; public static readonly string[] SevenLetterWords; public const string AUTOGEN_GUID = "000-the_tavern-AutogenRundown"; public const string LONGERCODES_GUID = "com.Brandont.LongerCodes"; private static Random _random; private static readonly bool _hasPluginConflict; private static readonly Dictionary _codeWords; private static ShuffledStepArray _hardPrefixes; protected override string DEFINITION_NAME => string.Empty; static SerialGeneratorManager() { CodeWordPrefixes = new string[27] { "X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "Y01", "Y02", "Y03", "Y04", "Y05", "Y06", "Y07", "Y08", "Y09", "Z01", "Z02", "Z03", "Z04", "Z05", "Z06", "Z07", "Z08", "Z09" }; HardCodeWordPrefixes = new string[84] { "A01", "A02", "A03", "A04", "A05", "A06", "A07", "A08", "A09", "A10", "A11", "A12", "B01", "B02", "B03", "B04", "B05", "B06", "B07", "B08", "B09", "B10", "B11", "B12", "C01", "C02", "C03", "C04", "C05", "C06", "C07", "C08", "C09", "C10", "C11", "C12", "W01", "W02", "W03", "W04", "W05", "W06", "W07", "W08", "W09", "W10", "W11", "W12", "X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "X10", "X11", "X12", "Y01", "Y02", "Y03", "Y04", "Y05", "Y06", "Y07", "Y08", "Y09", "Y10", "Y11", "Y12", "Z01", "Z02", "Z03", "Z04", "Z05", "Z06", "Z07", "Z08", "Z09", "Z10", "Z11", "Z12" }; ThreeLetterWords = new string[300] { "ace", "act", "add", "age", "ago", "aid", "aim", "air", "ale", "all", "and", "ant", "any", "ape", "apt", "arc", "are", "arm", "art", "ash", "ask", "ate", "bad", "bag", "ban", "bar", "bat", "bay", "bed", "bee", "beg", "bet", "bid", "big", "bin", "bit", "bob", "bog", "boo", "bow", "box", "boy", "bud", "bug", "bun", "bus", "but", "buy", "cab", "can", "cap", "car", "cat", "cob", "cod", "cog", "cop", "cow", "cry", "cub", "cup", "cut", "dad", "dap", "day", "den", "dew", "did", "die", "dig", "dim", "dip", "dog", "dot", "dry", "due", "duo", "ear", "eat", "egg", "ego", "end", "era", "eve", "eye", "fan", "far", "fat", "fed", "fee", "few", "fig", "fin", "fir", "fit", "fix", "fly", "fog", "for", "fox", "fry", "fun", "fur", "gap", "gas", "get", "gig", "god", "got", "gum", "gun", "guy", "gym", "had", "ham", "has", "hat", "hay", "hem", "hen", "her", "hey", "hid", "him", "hip", "his", "hit", "hot", "how", "hub", "hue", "hug", "hum", "hut", "ice", "ill", "ink", "inn", "ion", "its", "jam", "jar", "jaw", "jet", "job", "jog", "joy", "jug", "key", "kid", "kin", "kit", "lab", "lad", "lag", "lap", "law", "lay", "led", "leg", "let", "lid", "lie", "lip", "lit", "log", "lot", "low", "mad", "man", "map", "mat", "may", "men", "met", "mix", "mob", "mom", "mop", "mud", "mug", "nap", "net", "new", "nod", "not", "now", "nut", "oak", "oar", "odd", "off", "oil", "old", "one", "ore", "our", "out", "owe", "owl", "own", "pad", "pal", "pan", "par", "pat", "pay", "pea", "pen", "per", "pet", "pie", "pig", "pin", "pit", "pop", "pot", "pub", "put", "rag", "ram", "ran", "rap", "rat", "raw", "ray", "red", "rib", "rid", "rig", "rim", "rip", "rob", "rod", "rot", "row", "run", "sad", "sag", "sap", "sat", "saw", "say", "sea", "see", "set", "sew", "she", "shy", "sin", "sip", "sir", "sit", "six", "ski", "sky", "son", "spy", "sue", "sun", "tab", "tag", "tan", "tap", "tar", "tax", "tea", "ten", "the", "tie", "tin", "tip", "toe", "ton", "too", "top", "toy", "try", "two", "use", "van", "vet", "via", "war", "was", "way", "web", "wed", "wet", "who", "why", "win", "wit", "won", "wow", "yes", "yet", "you", "zip", "zoo" }; FourLetterWords = new string[733] { "jazz", "fuzz", "quiz", "jack", "jump", "junk", "cozy", "joke", "jive", "jeep", "lazy", "flux", "maze", "jury", "jobs", "mojo", "foxy", "jaws", "zoom", "kick", "gaze", "buck", "lynx", "puck", "flex", "pump", "back", "exam", "bump", "zone", "pack", "quit", "expo", "cuff", "jolt", "jail", "join", "just", "pick", "comb", "size", "biff", "much", "bomb", "hoax", "luck", "camp", "hack", "tzar", "duck", "hawk", "funk", "punk", "chip", "chew", "chef", "next", "club", "neck", "iffy", "knob", "hymn", "know", "folk", "flak", "dump", "deck", "whip", "milk", "hulk", "lack", "walk", "lump", "lock", "monk", "copy", "baby", "pulp", "numb", "hemp", "bank", "plum", "pawn", "hype", "beak", "sock", "gulf", "view", "kiwi", "verb", "dunk", "husk", "lamb", "bark", "peak", "vice", "vibe", "lamp", "mark", "mask", "week", "make", "damp", "weak", "wake", "work", "park", "levy", "skip", "bike", "wave", "sick", "envy", "flew", "flaw", "flip", "flop", "flow", "taxi", "flap", "film", "five", "plug", "pork", "poke", "fork", "perk", "keep", "king", "bake", "tick", "puma", "yank", "exit", "axis", "fake", "limb", "text", "cube", "move", "bowl", "book", "wolf", "blow", "navy", "cook", "cake", "clip", "rock", "cave", "claw", "clap", "wing", "wife", "brow", "fang", "farm", "riff", "pull", "ugly", "epic", "clay", "kind", "kill", "ramp", "face", "fact", "help", "fame", "pope", "form", "pony", "busy", "prop", "spam", "half", "busy", "fund", "full", "fury", "poem", "swim", "firm", "flag", "pipe", "yawn", "foam", "bull", "play", "nuke", "wasp", "warm", "such", "warp", "crab", "give", "hook", "link", "worm", "glow", "crop", "crow", "crew", "when", "hive", "push", "golf", "coma", "very", "beam", "beef", "inch", "body", "talk", "huge", "holy", "home", "hope", "tank", "rank", "rich", "mild", "menu", "mesh", "moth", "mule", "plan", "page", "oval", "oven", "path", "knee", "lawn", "lake", "itch", "kilo", "math", "like", "skin", "live", "sink", "love", "shop", "show", "silk", "look", "drum", "down", "volt", "void", "vine", "wage", "dawn", "dark", "dive", "diva", "wall", "wash", "echo", "type", "fill", "fall", "find", "fish", "turk", "foul", "twig", "evil", "etch", "bell", "bend", "bath", "bald", "ball", "band", "blur", "bold", "blue", "bill", "army", "clan", "clue", "city", "cold", "both", "brag", "burn", "wild", "cash", "cell", "will", "wind", "cage", "call", "desk", "grow", "game", "germ", "gasp", "grip", "fuel", "them", "frog", "gang", "grab", "must", "hill", "name", "gold", "mute", "card", "risk", "wine", "nice", "swan", "they", "news", "mint", "mile", "cone", "corn", "scan", "cool", "cure", "cute", "muse", "coin", "hold", "save", "coal", "moon", "mono", "code", "mood", "yell", "guru", "take", "task", "able", "acid", "pool", "pole", "plot", "yoga", "ally", "hall", "over", "hell", "wool", "wood", "bird", "once", "only", "omen", "bolt", "bone", "open", "born", "bead", "pelt", "peel", "barn", "pure", "word", "paid", "bent", "belt", "mini", "town", "duty", "dull", "lama", "lame", "visa", "lady", "vest", "idly", "spur", "slip", "slim", "slow", "slug", "took", "slam", "skit", "slap", "left", "snow", "hunt", "drop", "drip", "drug", "snug", "hurl", "soak", "leap", "draw", "vote", "leaf", "snip", "kite", "tuba", "fine", "soup", "span", "feed", "feel", "twin", "food", "foil", "fool", "flat", "tube", "vase", "kiss", "vast", "fade", "fail", "ever", "spin", "life", "snap", "made", "loaf", "deep", "long", "main", "weed", "mail", "want", "loop", "lush", "mean", "meal", "doom", "lift", "lily", "lime", "deny", "dime", "lips", "taco", "yard", "urge", "trip", "stew", "undo", "spit", "trim", "semi", "were", "west", "scar", "tame", "time", "your", "yarn", "wire", "snag", "wise", "raft", "rush", "step", "rely", "slay", "ring", "ripe", "roof", "rope", "robe", "rift", "rice", "thin", "then", "wait", "trap", "room", "sift", "tidy", "wart", "spot", "same", "stab", "soft", "stem", "term", "sing", "sofa", "soap", "race", "sign", "song", "safe", "some", "cost", "core", "lend", "coat", "cast", "case", "logo", "horn", "hood", "hour", "hurt", "hint", "hole", "dish", "land", "dash", "lash", "item", "mate", "boat", "boot", "mass", "miss", "mist", "bite", "mess", "boss", "care", "gain", "free", "frat", "fear", "fate", "feet", "fast", "foot", "fort", "fits", "fist", "fire", "halo", "hard", "drag", "doll", "hide", "herd", "head", "goal", "edge", "girl", "gone", "dual", "grin", "duel", "good", "grid", "dune", "oboe", "aged", "omit", "oily", "atom", "noun", "nosy", "pest", "post", "pose", "port", "past", "pass", "beer", "most", "beta", "best", "bait", "bias", "more", "unit", "goat", "runt", "this", "easy", "dust", "odds", "shoe", "rash", "duet", "airy", "that", "tell", "tend", "told", "used", "send", "nail", "tuna", "sand", "tune", "sell", "turn", "tall", "rage", "eery", "toll", "gear", "gate", "noon", "yeti", "deed", "lane", "lard", "none", "deal", "dead", "sold", "dine", "idol", "idle", "shot", "dent", "soul", "dial", "nine", "loan", "load", "rosy", "lint", "line", "lean", "lead", "lens", "year", "slur", "hero", "hire", "hiss", "here", "neon", "done", "ruin", "rule", "need", "hear", "heat", "lord", "host", "rude", "stun", "stay", "auto", "dirt", "diet", "door", "dose", "anti", "dire", "earn", "else", "does", "edit", "dare", "dart", "user", "data", "date", "tale", "lose", "lore", "loss", "lost", "side", "loot", "salt", "sane", "seen", "seed", "seal", "list", "last", "soda", "liar", "slot", "less", "rant", "rent", "redo", "raid", "rail", "rain", "ride", "nest", "ruse", "rust", "near", "neat", "nose", "note", "road", "tent", "tide", "lair", "tile", "teen", "torn", "true", "tool", "toad", "tone", "tilt", "soon", "idea", "sure", "sour", "iron", "suit", "rear", "iris", "rest", "tsar", "trio", "sort", "rate", "rare", "tree", "site", "tear", "stir", "east", "ease", "area", "rise", "roar", "tier", "ties", "test", "star", "tire", "rose", "riot" }; FiveLetterWords = new string[1064] { "about", "actor", "adapt", "adieu", "adobe", "aeons", "after", "again", "agape", "agate", "aging", "aglow", "agree", "ahead", "aimed", "aired", "alarm", "alive", "alley", "allow", "aloft", "along", "aloud", "alpha", "altar", "alter", "altos", "amiss", "amity", "among", "amour", "ample", "amply", "angle", "angry", "aping", "appal", "apply", "aptly", "arena", "array", "arson", "ashen", "aside", "asked", "asset", "atlas", "atone", "attic", "audio", "audit", "augur", "avail", "awake", "award", "awoke", "axles", "babel", "baits", "baize", "baker", "balmy", "banjo", "basal", "based", "baste", "batch", "bathe", "baths", "beads", "beams", "bears", "beast", "beaux", "begun", "being", "belie", "bench", "berry", "bible", "bides", "bight", "biped", "birch", "black", "blade", "blast", "blend", "bless", "blink", "bliss", "blots", "blown", "blues", "blush", "board", "boars", "boast", "bodes", "boggy", "boils", "boles", "books", "boons", "boots", "booze", "borne", "bough", "braid", "brake", "brats", "bread", "break", "brief", "brier", "brine", "bring", "brink", "briny", "brood", "brown", "budge", "bugle", "build", "built", "bulks", "bulls", "bunks", "burnt", "burrs", "burst", "buyer", "cabin", "cable", "caked", "cakes", "calms", "camps", "caper", "casks", "casts", "cater", "cause", "cedar", "chafe", "chaff", "chain", "chaos", "charm", "chart", "chary", "chasm", "chats", "cheat", "check", "cheek", "cheer", "chess", "chide", "child", "chill", "choir", "chops", "chord", "chump", "chums", "chunk", "churl", "chute", "cinch", "cites", "clash", "clasp", "class", "claws", "clear", "climb", "clips", "clods", "clogs", "close", "clout", "clown", "coast", "cobra", "comes", "comic", "cooed", "cools", "cores", "corns", "could", "count", "court", "cover", "covey", "crabs", "craft", "crash", "crass", "crate", "craze", "creak", "creek", "creep", "crews", "cribs", "crick", "cries", "crime", "croak", "croup", "crows", "crude", "cruel", "crumb", "cubes", "curls", "curly", "curve", "cycle", "cynic", "dairy", "dames", "damps", "dance", "dared", "dares", "dates", "daubs", "dears", "death", "debit", "debts", "decoy", "decry", "deeds", "deeps", "delay", "dells", "delta", "demon", "depot", "deuce", "dimes", "dimly", "diner", "ditch", "ditto", "ditty", "dizzy", "docks", "dogma", "doing", "doled", "dolls", "dosed", "doses", "doves", "downs", "drink", "drone", "ducks", "dukes", "dummy", "dumps", "dunce", "dupes", "dusty", "dwell", "dwelt", "eager", "earls", "early", "earth", "eaten", "eater", "edged", "egged", "eight", "elate", "elder", "elude", "email", "empty", "ended", "enemy", "ennui", "epics", "equal", "equip", "error", "every", "evils", "evoke", "exalt", "excel", "expel", "extra", "faces", "false", "fares", "farms", "fasts", "fault", "fears", "feign", "fells", "ferry", "feted", "fever", "fiche", "fiefs", "field", "fifth", "fifty", "fight", "files", "filet", "final", "fines", "fires", "first", "fishy", "fives", "fjord", "flaky", "flame", "flank", "flaps", "flats", "flaws", "fleck", "flees", "flesh", "flier", "fling", "flirt", "float", "flood", "floor", "floss", "flows", "flues", "fluke", "flume", "folio", "folks", "foods", "foray", "force", "fords", "forks", "forte", "forts", "forum", "found", "fours", "foxes", "frame", "fraud", "freer", "frees", "front", "fruit", "fugue", "fully", "fumed", "fumes", "furze", "fuses", "gains", "games", "gangs", "gapes", "gases", "gazes", "geese", "gents", "germs", "ghost", "giant", "gilds", "gills", "girth", "given", "gives", "glade", "glass", "glean", "glint", "glove", "glows", "gnaws", "goads", "godly", "going", "golly", "gongs", "goody", "gored", "gourd", "gowns", "grain", "grant", "graph", "grate", "grave", "graze", "great", "greed", "greys", "grime", "gross", "group", "grown", "grows", "guard", "guild", "guile", "guilt", "gully", "hails", "hairs", "hands", "hangs", "happy", "harms", "harsh", "haste", "haven", "heady", "heard", "heart", "hedge", "heirs", "helix", "helps", "hence", "hides", "hills", "hilts", "hinds", "hinge", "hives", "hoist", "holds", "holly", "homes", "horde", "hours", "house", "howls", "hulks", "human", "hunch", "hunts", "hurts", "icily", "ideas", "idiom", "idled", "idler", "idols", "image", "impel", "imply", "incur", "inept", "infer", "inter", "irony", "issue", "jacks", "jaunt", "jeans", "jeers", "jelly", "jests", "jetty", "jiffy", "jokes", "junks", "karma", "khaki", "kicks", "knack", "knelt", "knits", "knobs", "knots", "known", "label", "ladle", "lager", "lambs", "lamed", "lance", "lanes", "lapel", "larch", "large", "largo", "larva", "latch", "later", "lawns", "leafy", "leaky", "leans", "leapt", "lease", "least", "leave", "ledge", "level", "liege", "liens", "light", "liked", "liken", "limbo", "limbs", "limit", "lines", "lions", "lithe", "lived", "livid", "llama", "loads", "loans", "loath", "lobby", "lobes", "local", "looks", "looms", "loops", "loser", "lousy", "loved", "lower", "lowly", "lucid", "lucky", "lulls", "lunar", "lurid", "lusty", "lymph", "lyric", "mains", "maize", "major", "maker", "makes", "males", "mamma", "mange", "mango", "mania", "manor", "manse", "march", "mated", "mates", "maybe", "mayor", "mazes", "means", "meats", "medal", "media", "meets", "melon", "memes", "merit", "metal", "might", "milch", "miles", "milky", "mimes", "mince", "mined", "mines", "mints", "minus", "mirth", "mites", "mixed", "moats", "modem", "modes", "moles", "money", "month", "moody", "moral", "mores", "mouse", "mover", "mowed", "mower", "munch", "music", "musky", "musty", "myths", "naked", "names", "nasal", "nasty", "natty", "naval", "needs", "nerve", "nests", "never", "niche", "night", "nooks", "north", "nosed", "oases", "oaten", "odium", "offer", "often", "oiled", "olden", "older", "omits", "onion", "opals", "opens", "opera", "order", "other", "ounce", "ovals", "owner", "oxide", "paddy", "paler", "pales", "palsy", "panel", "panic", "pansy", "pared", "party", "paste", "patio", "paved", "payed", "payer", "peach", "peaks", "pears", "pecks", "pelts", "pence", "penne", "peril", "pesky", "pesos", "pests", "petal", "phase", "phone", "piled", "pinch", "pines", "pinto", "pints", "pitch", "pivot", "place", "plaid", "plant", "plaza", "plush", "poems", "poets", "point", "pokes", "pools", "popes", "poppy", "ports", "pound", "pours", "power", "press", "price", "prick", "pries", "prime", "privy", "prize", "props", "prosy", "prove", "prows", "proxy", "psalm", "pudgy", "puffy", "pumps", "puree", "purge", "putty", "quart", "quays", "queen", "queue", "quips", "quite", "raged", "raise", "rated", "raven", "react", "ready", "reaps", "rebus", "reeds", "reeve", "refer", "relic", "remit", "renew", "reply", "rests", "rhyme", "rides", "right", "riled", "rills", "rimes", "rinse", "ripen", "risen", "risks", "risky", "roads", "roams", "roast", "roles", "rolls", "roomy", "roost", "roots", "rosin", "rouge", "rough", "rouse", "rover", "rowdy", "rowed", "ruder", "ruins", "ruler", "runes", "ruses", "sagas", "sails", "salsa", "salvo", "scalp", "scarf", "scent", "scion", "scold", "scoop", "scope", "scour", "scowl", "seals", "sects", "seeds", "seems", "seers", "seize", "sense", "serfs", "serum", "sever", "sewed", "shack", "shaft", "shaky", "shale", "shall", "shams", "shape", "share", "shawl", "shear", "sheds", "shift", "ships", "shirk", "shoal", "shone", "short", "shout", "showy", "shred", "shrub", "siege", "sieve", "signs", "silky", "silly", "since", "siren", "sites", "skate", "skies", "skiff", "skips", "skirt", "skull", "slack", "slang", "slave", "sleds", "sleek", "sleet", "slept", "slime", "slink", "slips", "sloop", "slope", "slunk", "slush", "small", "smash", "smelt", "smite", "smoke", "snags", "snake", "snaky", "snaps", "snarl", "snipe", "snuff", "soars", "sober", "socks", "soggy", "songs", "sonny", "sores", "sough", "souls", "south", "sowed", "space", "spans", "spark", "spelt", "spicy", "spike", "spins", "spire", "split", "spoor", "sprig", "spurn", "squad", "stage", "stags", "stale", "stamp", "stank", "stare", "start", "state", "steal", "steep", "stews", "stiff", "still", "stoic", "store", "storm", "story", "stove", "strew", "study", "stump", "sucks", "suite", "suits", "sully", "surer", "surly", "sweat", "swell", "swept", "swims", "swing", "sworn", "synod", "taboo", "tacks", "taint", "taken", "tamed", "tapes", "tardy", "tarry", "tarts", "tasks", "taunt", "taxed", "teems", "teeth", "tempo", "temps", "tenet", "tents", "tepid", "texts", "thank", "their", "these", "thick", "thing", "think", "third", "those", "three", "thumb", "tibia", "tiers", "tight", "tiles", "times", "tires", "toads", "today", "toils", "tolls", "tonic", "tooth", "topaz", "topic", "torso", "torts", "tough", "tours", "towed", "toxic", "toyed", "trade", "trail", "trash", "treed", "trice", "trick", "tries", "trill", "tripe", "trite", "truly", "trump", "trunk", "trust", "tubes", "tunes", "tunic", "tusks", "tweed", "twice", "types", "udder", "uncle", "uncut", "under", "unfit", "unsay", "until", "urban", "users", "using", "utter", "vales", "vases", "venom", "verbs", "vials", "video", "views", "villa", "viola", "visit", "vista", "vogue", "voice", "volts", "voter", "vouch", "vowel", "vying", "wakes", "walks", "wants", "warns", "watch", "water", "waxed", "wears", "weave", "weeks", "weigh", "whale", "wheel", "whelp", "where", "which", "while", "whine", "whirl", "whist", "white", "whole", "whoop", "whose", "wield", "wilds", "wiles", "wills", "winds", "wines", "winks", "wiped", "wipes", "wired", "wires", "woman", "women", "words", "works", "world", "worst", "worth", "would", "wound", "wrath", "wreak", "wrong", "years", "yield", "yoked", "yolks", "young", "yours" }; SixLetterWords = new string[1394] { "abated", "abbess", "abbots", "abided", "aboard", "abroad", "abrupt", "abused", "abuser", "acacia", "accede", "acidic", "acorns", "across", "action", "addict", "adding", "adduce", "adduct", "adjoin", "admire", "admits", "adored", "adorns", "adroit", "adults", "agates", "agency", "agenda", "aghast", "agrees", "aisles", "albeit", "albums", "alcove", "allium", "allows", "allure", "almost", "alpaca", "alpine", "alumna", "always", "ambers", "amidst", "amoeba", "ampere", "amused", "anemia", "anemic", "angles", "animas", "anneal", "anodes", "anomie", "answer", "anthem", "anyone", "apices", "apiece", "append", "arcana", "arcane", "ardent", "around", "artful", "aspect", "aspire", "assort", "assure", "asylum", "atrial", "attack", "attend", "audits", "avatar", "avenge", "avocet", "avowed", "awakes", "axioms", "babies", "backer", "backup", "badges", "bagger", "bailer", "baited", "baking", "bamboo", "banged", "banger", "banned", "banyan", "baobab", "barbed", "baring", "barked", "barman", "barrel", "basket", "basque", "basses", "basted", "batted", "batten", "battle", "baying", "bayous", "beamer", "beaver", "become", "bedlam", "befall", "before", "begone", "behind", "behold", "beings", "belted", "belter", "bended", "better", "bevels", "biased", "biceps", "bidden", "bidder", "biller", "binder", "biomes", "bionic", "birder", "bisect", "blades", "blamed", "blames", "blasts", "blazer", "blazon", "blenny", "blight", "blocky", "blonde", "blooms", "bluest", "boasts", "boater", "bobbed", "bobcat", "bogeys", "bolded", "bombed", "boosts", "bosons", "botany", "bougie", "bouton", "bovine", "bowled", "bowman", "boxers", "bracer", "breeze", "bright", "brinks", "broads", "broker", "broods", "broths", "bruise", "brushy", "bryony", "bucked", "budget", "buffed", "buffer", "buffet", "bugged", "burden", "burley", "busker", "busses", "butter", "buyout", "bypass", "cabins", "cached", "called", "caller", "calmer", "cancan", "candor", "caning", "canner", "canons", "capita", "carafe", "career", "carman", "carols", "cartel", "caucus", "causer", "causes", "caveat", "celebs", "cental", "center", "chaise", "chance", "change", "charms", "chased", "chasms", "cheats", "chided", "chiles", "chintz", "chisel", "chocks", "choirs", "choker", "chokes", "cholla", "choose", "chords", "chucks", "clefts", "clerks", "climes", "cloned", "closed", "cloths", "cloudy", "clowns", "coddle", "coffee", "coffer", "cohort", "coined", "coking", "coldly", "comber", "coming", "common", "confit", "conics", "coning", "conned", "cookie", "cooper", "coping", "copped", "copter", "corals", "corded", "corked", "corker", "corner", "corral", "corset", "cortex", "cougar", "county", "couple", "coupon", "course", "covert", "cozens", "cramps", "crated", "craves", "crayon", "creaky", "critic", "crowns", "cruise", "crusts", "crypto", "cuboid", "cuddly", "cupids", "curing", "curlew", "curved", "custom", "cutest", "cyclic", "cypher", "dabble", "daemon", "daikon", "dampen", "danced", "dances", "danger", "darker", "darned", "darted", "dearer", "debate", "debits", "debugs", "decoys", "decree", "deepen", "defeat", "deists", "deltas", "dement", "demons", "demote", "demure", "depict", "depose", "depths", "derive", "desire", "detach", "detail", "detect", "detest", "devise", "devoid", "diadem", "dialup", "dictum", "digest", "dilate", "dimers", "dimmed", "dimmer", "dimple", "dinner", "discos", "discus", "dodges", "dogmas", "dollar", "donate", "donkey", "donned", "dosage", "dosing", "doting", "double", "dozers", "draper", "drapes", "dreamy", "dredge", "driers", "driver", "dually", "ducats", "duffel", "dumber", "dumped", "dunked", "dunker", "during", "duster", "dyadic", "earing", "earths", "earwax", "earwig", "easter", "echoes", "eddies", "editor", "eerily", "effete", "effort", "eights", "eighty", "either", "elects", "elicit", "eluted", "embark", "embeds", "emcees", "empire", "encore", "energy", "engulf", "enjoys", "enlace", "enough", "enrage", "entail", "enters", "entree", "envoys", "equine", "errata", "erupts", "eschew", "escrow", "esprit", "essays", "esteem", "esters", "evades", "evenly", "excels", "exhale", "exiles", "exodus", "exotic", "expire", "expiry", "extant", "extend", "eyelid", "family", "faster", "father", "fathom", "faults", "faulty", "favors", "feeble", "feeler", "feline", "felted", "femmes", "fenced", "fences", "fender", "fescue", "fiddle", "fiends", "filing", "filmed", "firmer", "fixate", "fixing", "fixity", "fizzle", "flaked", "flamed", "flaxen", "flayed", "fleece", "fleets", "flexor", "flicks", "flight", "flimsy", "flinch", "flings", "flocks", "floret", "fluffy", "fogged", "foiled", "fondly", "fondue", "forced", "forego", "formal", "format", "former", "francs", "freely", "freeze", "friend", "fronts", "frosts", "frosty", "frowns", "fruits", "funder", "fungal", "furrow", "futile", "future", "gables", "gadfly", "gagged", "gaging", "galore", "gambol", "gamete", "gaming", "gammon", "gander", "garage", "garden", "garnet", "gassed", "gather", "gauges", "ghetto", "gibbet", "ginkgo", "givers", "giving", "glared", "global", "globes", "gnomes", "goaded", "gobble", "gobies", "goober", "gouges", "gourds", "grainy", "grants", "graphs", "grates", "graven", "grebes", "greets", "greyed", "grieve", "groats", "groovy", "grovel", "groves", "guilds", "gummed", "gunman", "gunmen", "haggis", "halite", "halted", "hamper", "hanger", "hangup", "happen", "harass", "harbor", "having", "headed", "health", "hearts", "heated", "heaves", "heddle", "heeded", "height", "helped", "herder", "hereof", "heresy", "hermit", "herons", "hiatus", "highly", "hinted", "hipped", "hippie", "hitter", "holler", "hombre", "homers", "hominy", "honest", "honeys", "hoodie", "hoopoe", "hooves", "hopper", "horned", "horror", "hosing", "hotels", "howled", "hubbub", "hubris", "huddle", "humbly", "humbug", "hummus", "hunker", "hurdle", "hushed", "husker", "hymnal", "hyphen", "iceman", "imager", "imbued", "impair", "impugn", "inched", "indigo", "indole", "induct", "infant", "infest", "inform", "inking", "inning", "inputs", "insane", "inside", "insole", "invite", "inward", "islets", "isobar", "issues", "italic", "jabbed", "jacked", "jaunts", "jaunty", "jigger", "jigsaw", "jingle", "jokers", "jovian", "juggle", "juntas", "jurors", "kaftan", "karats", "keeper", "ketone", "kicked", "killed", "kimchi", "kindle", "kindly", "kiosks", "kismet", "kitbag", "kitted", "kitten", "kittle", "knifed", "knocks", "knowns", "koalas", "kvetch", "labile", "lackey", "ladder", "lament", "landau", "landed", "lapdog", "lapels", "laptop", "lasing", "lasses", "lasted", "lawyer", "layman", "laymen", "lazily", "league", "leaner", "leaves", "legume", "lender", "lesion", "lessee", "liable", "licked", "lifter", "likely", "liming", "limped", "limpid", "linage", "linens", "liners", "lingua", "linker", "little", "livery", "living", "loaded", "loader", "loaned", "loathe", "locate", "lodges", "looney", "looped", "looser", "looses", "louver", "loving", "lowest", "lowing", "lulled", "lumped", "luring", "lurked", "lusted", "luxury", "lyceum", "machos", "macros", "maimed", "making", "mallee", "mallow", "malted", "mangle", "maniac", "mantel", "manure", "mapper", "marked", "market", "maroon", "masons", "massif", "matter", "maxims", "mayors", "medals", "medley", "meeker", "melody", "member", "memory", "menace", "mended", "merely", "merest", "merino", "metals", "method", "methyl", "micron", "midair", "midden", "midrib", "mimics", "minced", "minors", "minted", "mirage", "misery", "mishap", "missal", "moaned", "mobbed", "mocked", "modern", "modest", "modulo", "moiety", "moment", "moneys", "months", "morrow", "mortar", "motels", "mother", "mounds", "mounts", "mouthy", "mouton", "museum", "musher", "mussel", "mutant", "mutton", "myopic", "myself", "mystic", "mythos", "nagged", "nailed", "nannie", "napped", "napper", "native", "navels", "nearby", "neared", "netted", "niacin", "nickel", "nipper", "nipple", "nobler", "noises", "nomads", "norths", "notify", "novena", "nudges", "number", "nutmeg", "nutria", "oblate", "obsess", "obtain", "obtuse", "occult", "oddest", "oddity", "odious", "offend", "office", "oldest", "online", "opened", "openly", "optics", "orbits", "ordain", "orders", "orgies", "origin", "ornate", "osprey", "others", "otters", "outdid", "outers", "output", "outrun", "owners", "oxides", "oxygen", "pagans", "paging", "pained", "paints", "palate", "paltry", "pandan", "pander", "parens", "parent", "parish", "parkas", "parlay", "parley", "parlor", "parody", "parole", "parrot", "parsed", "parses", "partly", "pastas", "pastel", "pastor", "payees", "payors", "peaker", "peapod", "pearly", "pecked", "peeler", "peeves", "pelvis", "people", "period", "person", "petals", "petite", "petrel", "petted", "phased", "phones", "phonic", "photos", "picker", "piddle", "pillar", "pillow", "pinger", "pipped", "pistil", "pistol", "plague", "plaids", "plaint", "plated", "plates", "playas", "played", "player", "pleads", "please", "plexus", "plural", "points", "police", "policy", "polkas", "polled", "poplar", "poppet", "portal", "posses", "possum", "postal", "poured", "precis", "prefer", "preset", "pretty", "preyed", "prised", "prissy", "proofs", "propel", "propyl", "proven", "prover", "pseudo", "public", "puffin", "pulley", "pulser", "pumper", "pundit", "pupils", "puppet", "purged", "purple", "puzzle", "pylons", "quarry", "queues", "quiver", "rabbit", "rabble", "rabies", "racing", "racked", "racoon", "radian", "radios", "raffia", "raffle", "raider", "rained", "ramjet", "rammed", "ranged", "ranked", "ranker", "rapper", "rashly", "rather", "ravers", "ravine", "really", "reaper", "reason", "rebels", "rebind", "recast", "recede", "reckon", "record", "recoup", "rectal", "rector", "redden", "redial", "redraw", "reefer", "refers", "refuel", "refute", "regime", "region", "reheat", "reined", "relate", "relent", "relied", "remain", "remand", "remits", "remove", "renege", "renown", "rented", "repeat", "report", "rescan", "reseal", "resent", "resign", "result", "retake", "retest", "return", "reverb", "revere", "review", "revise", "revive", "revolt", "revues", "revved", "rewire", "rhesus", "rhumba", "rhymer", "rhymes", "ribbon", "riches", "riding", "riffle", "rigged", "rigger", "righty", "rioted", "ripper", "riprap", "rising", "roader", "roared", "robbed", "rookie", "rooter", "rosary", "rotors", "rotten", "roughs", "roused", "rouser", "routes", "royals", "rubber", "rudder", "rueful", "rufous", "ruling", "rushed", "sachem", "saddle", "safari", "sagged", "sailer", "sanely", "sanity", "sarong", "satiny", "satyrs", "savant", "saying", "scalps", "scarfs", "schist", "school", "scopes", "scorch", "scored", "scorer", "scores", "scorns", "scours", "scouse", "scouts", "scrape", "scraps", "scrawl", "scrips", "scroll", "scrubs", "sculls", "season", "seaway", "secede", "second", "secret", "sector", "sedges", "seeker", "sender", "septic", "series", "setups", "sevens", "sewage", "shader", "shades", "shafts", "shaggy", "shales", "shamed", "shanty", "shaper", "shapes", "sharps", "sherry", "shiner", "shines", "shoppe", "shorty", "should", "shrews", "shrink", "shroud", "shrubs", "shunts", "sicker", "sidled", "sieves", "silage", "simmer", "simply", "sinewy", "single", "singly", "siphon", "sipper", "sitcom", "sitter", "skater", "sketch", "skills", "skyway", "slalom", "slings", "sloppy", "slough", "smacks", "smarmy", "smidge", "smiley", "smocks", "smudge", "smugly", "snacks", "snippy", "snuffy", "soaked", "social", "socked", "soiled", "soothe", "sorrow", "sought", "souped", "sowing", "spaced", "sparse", "specie", "specks", "speeds", "spells", "spices", "spiffy", "spinal", "spined", "spoons", "spores", "sprang", "sprays", "spring", "sprite", "sprung", "spurns", "spying", "square", "squawk", "staple", "stared", "stares", "starts", "stater", "states", "statue", "steamy", "steels", "steers", "stifle", "stinky", "stints", "stitch", "stoked", "stomps", "stools", "storks", "stowed", "straws", "street", "strewn", "strode", "strong", "strove", "struck", "stunts", "stupid", "subpar", "subsea", "subset", "subtly", "sucker", "suckle", "sudden", "sugars", "suited", "sunder", "sundew", "sundog", "sundry", "suplex", "surety", "surfer", "surged", "swales", "swamps", "swathe", "swears", "sweaty", "swifty", "swirls", "swivel", "swords", "syndic", "syrupy", "system", "tablet", "tacker", "taking", "talked", "tamper", "tangle", "tanked", "tanner", "tapped", "tapper", "target", "tattle", "tawdry", "teases", "teensy", "temper", "tempts", "tended", "tenner", "tennis", "tented", "termed", "thanks", "things", "though", "throat", "throbs", "throne", "thrush", "tickle", "tildes", "tilted", "tilter", "timers", "tiptoe", "tiptop", "tissue", "titers", "toasty", "toffee", "toiled", "tokens", "tomato", "tomcat", "toners", "tonics", "towels", "tracks", "trader", "trains", "treads", "trials", "tricks", "tricky", "troupe", "trying", "tsetse", "tufted", "tumult", "tundra", "turbid", "turbos", "turnip", "tuxedo", "twelve", "twined", "typify", "ulcers", "umlaut", "uncool", "undone", "undyed", "unhook", "united", "unites", "unless", "unlink", "unlock", "unread", "unroll", "unseat", "unspun", "unsung", "untrue", "unused", "unveil", "update", "upkeep", "urbane", "urgent", "urging", "ursine", "usable", "utopia", "valets", "valued", "valves", "vandal", "varies", "veered", "veiled", "venial", "verily", "vernal", "versed", "versus", "vertex", "vestry", "villas", "vining", "violet", "violin", "vireos", "virile", "vistas", "vizier", "voodoo", "vortex", "voters", "vowing", "wading", "wagers", "waited", "wanted", "warder", "warmly", "weapon", "wetted", "whaler", "whammy", "whence", "whinge", "whiten", "whoops", "wicked", "wiener", "wigeon", "wiggle", "wiggly", "wigwam", "window", "winnow", "wintry", "wipers", "within", "wolves", "wombat", "woolen", "woolly", "worded", "wormed", "wretch", "wrongs", "yahoos", "yawned", "yeoman", "yippee", "yogurt", "zealot", "zenith", "zephyr", "zeroes", "zigzag", "zinger", "zinnia", "zodiac", "zombie", "zoomed", "zygote" }; SevenLetterWords = new string[1601] { "abating", "abiding", "ability", "abolish", "abyssal", "acacias", "academy", "accents", "account", "acquire", "acreage", "actions", "acutely", "address", "adjunct", "adjusts", "adviser", "affixed", "affront", "against", "aground", "aircrew", "airflow", "airmail", "allelic", "allowed", "allured", "almanac", "almonds", "alpacas", "already", "amateur", "amazing", "ambling", "amended", "ammonia", "amorous", "amyloid", "anarchy", "anguish", "annexes", "annulus", "another", "answers", "antacid", "antenna", "anthems", "antonym", "anymore", "apostle", "apparel", "applies", "aqueous", "archery", "archive", "armband", "armorer", "arouses", "arrival", "arsenic", "article", "artless", "arugula", "asylums", "attract", "aunties", "auroras", "austere", "authors", "avenger", "avenues", "average", "awakens", "awaking", "awesome", "babbled", "babysit", "backing", "backlog", "badgers", "baggage", "ballads", "ballots", "baneful", "banging", "bangles", "banking", "banquet", "baptize", "barking", "baronet", "baroque", "barring", "bashful", "basques", "bathtub", "battles", "baubles", "beading", "bearish", "beavers", "because", "bedrock", "beepers", "beeping", "befalls", "belcher", "beliefs", "believe", "belongs", "belting", "bending", "benefit", "berated", "betrays", "betting", "bettors", "between", "bicycle", "bifocal", "biggest", "biology", "biotics", "birding", "bishops", "bitumen", "blacked", "blacken", "blaming", "blankly", "bleeder", "blessed", "blinded", "blister", "blitzed", "blocker", "bloomed", "blooper", "blouses", "blowers", "blunted", "blurred", "blurted", "blusher", "boarded", "boatmen", "boffins", "boggles", "bolding", "bollard", "bombard", "bonuses", "bookend", "bookies", "booklet", "boolean", "boomers", "booster", "boredom", "borings", "borough", "bossier", "bothers", "bottles", "bouncer", "bounces", "bowhead", "boycott", "bracing", "brasher", "braving", "breaded", "breathy", "breezes", "bribery", "bridals", "briefed", "brights", "brining", "briskly", "bristle", "bristly", "broadly", "bromide", "bronzes", "brother", "brought", "brownie", "browsed", "bruises", "brutish", "buddies", "budgets", "buffers", "buffets", "bugbear", "bulbous", "bulging", "bulking", "bulldog", "bullies", "bullish", "bullpen", "bumpers", "bunched", "bungled", "bunting", "buoyant", "bureaus", "burgers", "burrito", "butters", "buttery", "buyouts", "cabanas", "cabinet", "caching", "cadmium", "calcium", "calling", "cantons", "capping", "caprice", "captain", "captors", "carafes", "caramel", "caravan", "carcass", "cargoes", "carpets", "carrion", "carrots", "cartoon", "castors", "catarrh", "catcher", "catches", "catered", "causing", "caveman", "ceasing", "cements", "censors", "censure", "centers", "central", "century", "certain", "ceviche", "chafing", "chalice", "challah", "changed", "changes", "channel", "chanted", "chaotic", "chapped", "charger", "charted", "chasers", "chasing", "checker", "cherubs", "chevron", "chicory", "chiming", "choline", "chopped", "chorale", "chorizo", "chucked", "clapped", "clashed", "classic", "cleanse", "clearly", "clicked", "climbed", "clinger", "clipped", "clipper", "clogged", "closely", "closeup", "clotted", "clovers", "clubbed", "coaches", "coasted", "coerced", "cognate", "collars", "college", "combust", "comedic", "comment", "commies", "commune", "company", "compare", "compels", "compere", "comport", "compose", "conceal", "concert", "concise", "condemn", "condors", "conjure", "console", "consume", "contact", "contend", "content", "contest", "control", "convert", "cookout", "coolest", "coopers", "cooties", "coppers", "copycat", "cornets", "coronet", "corsage", "cougars", "coulomb", "council", "country", "courage", "courant", "coursed", "courses", "covered", "cowbird", "coyotes", "cracked", "crackle", "crashed", "creaked", "created", "credits", "crimper", "crimson", "cronies", "cropper", "crowing", "crucify", "crudely", "cruelly", "crusher", "crushes", "cubbies", "cubicle", "culture", "culvert", "cumulus", "cunning", "currant", "current", "curried", "cushion", "cuticle", "cutlery", "cyclops", "cypress", "dabbled", "damping", "damsels", "dancing", "dawning", "daytime", "debater", "debtors", "decease", "decided", "decimal", "deckers", "decoder", "decodes", "decreed", "deduced", "deeming", "defiant", "defraud", "defunct", "defused", "deicing", "deliver", "deltoid", "demands", "demonic", "demoted", "deniers", "densest", "depicts", "deposed", "depress", "dequeue", "derails", "derived", "derives", "designs", "desired", "desktop", "despite", "details", "detects", "detente", "devises", "devours", "diabolo", "dialing", "dictate", "diesels", "digests", "diggers", "digging", "digital", "dilated", "dilator", "dinette", "diorama", "dirtier", "disable", "disease", "dislike", "display", "dispute", "diurnal", "divider", "divides", "divisor", "doctors", "dollars", "dominos", "donning", "dossier", "drafted", "dragoon", "dreaded", "drifter", "drinker", "drizzly", "droning", "dubious", "durable", "dusting", "dyeable", "eagerly", "earlier", "earlobe", "earners", "earshot", "echelon", "echoing", "edibles", "edifice", "edition", "ejected", "elected", "elector", "elution", "embassy", "embolic", "eminent", "emirate", "empower", "emptied", "emulate", "encased", "encores", "endgame", "endings", "endowed", "endures", "enjoins", "enjoyed", "enlaces", "enraged", "enteric", "envious", "enzymes", "episode", "erosive", "erratum", "estates", "evacuee", "evaders", "evasion", "evoking", "evolved", "exactly", "examine", "example", "excises", "exciter", "excites", "exempts", "existed", "explain", "exploit", "exports", "expunge", "faculty", "faintly", "fairies", "falcons", "fangled", "farmers", "farming", "farther", "fascias", "fastest", "fatally", "fateful", "fathers", "favored", "fawning", "federal", "feeders", "feelers", "feeling", "females", "fetched", "fielder", "fifteen", "figures", "filling", "finally", "finance", "fishery", "fission", "flaming", "flatbed", "flecked", "flicked", "floated", "floored", "flopped", "flowery", "fluidic", "flutter", "foaming", "folders", "fondled", "fooling", "footway", "forages", "forceps", "foresaw", "forests", "forgave", "forging", "forgive", "forsake", "forward", "framers", "fraying", "freeing", "freezer", "frescos", "freshly", "friends", "frigate", "fringes", "fuchsia", "fuelled", "fulcrum", "fumbles", "funnies", "further", "futures", "gallery", "galling", "gallops", "gambler", "gangway", "gapping", "garners", "garters", "gasping", "gazelle", "gazette", "gelatin", "general", "genetic", "genital", "gestalt", "getting", "gigabit", "giraffe", "glacial", "glamour", "glanced", "glassed", "glazing", "gleeful", "glimmer", "glossed", "glutton", "goalies", "gobbler", "godhead", "goofing", "goulash", "gracing", "grained", "granary", "grander", "granola", "granted", "grantee", "granule", "grassed", "gravest", "graying", "greases", "greater", "greener", "gremlin", "grenade", "griddle", "gripper", "grizzle", "grooved", "grosses", "grouchy", "grouped", "growing", "growths", "grudges", "grumble", "guessed", "gumtree", "gymnast", "habitat", "hacksaw", "halcyon", "hallows", "hallway", "halting", "hammers", "hamster", "handing", "handoff", "hapless", "haploid", "happens", "harmony", "harping", "harpoon", "hastens", "hatches", "haulage", "hawkish", "hayseed", "hazards", "healers", "heaping", "heaters", "heavier", "heights", "helmets", "hickory", "himself", "hipster", "history", "hitched", "hobnail", "hoedown", "hoisted", "hollers", "hollows", "hooting", "hopeful", "hoppers", "hopping", "hormone", "horrors", "hospice", "hostels", "hostile", "hosting", "hotdogs", "hotline", "however", "hulking", "humanly", "humbled", "humerus", "humidor", "humming", "hunters", "husband", "huskers", "huskies", "idyllic", "ignited", "imagine", "impaler", "imperil", "impiety", "impious", "implies", "imposed", "impound", "imprint", "improve", "imputed", "include", "indents", "indexed", "indexer", "indexes", "indicts", "indulge", "infects", "inflict", "infuser", "ingress", "injects", "injured", "innings", "inquest", "inroads", "insider", "insides", "insight", "insists", "inspect", "instate", "instead", "insured", "insures", "invents", "inverse", "ionized", "ionizer", "islands", "isomers", "isotope", "issuers", "jackals", "janitor", "january", "jarring", "jazzman", "jeepers", "jellies", "jerking", "jigsaws", "jobbers", "jobsite", "joiners", "joining", "jolting", "journal", "judging", "jungles", "justice", "karaoke", "kernels", "ketchup", "ketones", "ketosis", "keylock", "keypads", "kicking", "kimonos", "kindred", "kinetic", "kissing", "kitting", "kneeled", "knowhow", "labored", "lacking", "lagging", "lagoons", "lancets", "largely", "latches", "lateral", "launder", "lawless", "layaway", "leaders", "leading", "leaflet", "leaking", "leaving", "lecture", "leeward", "legumes", "leisure", "lemming", "leopard", "lessees", "liberty", "library", "licking", "lifting", "likable", "lilting", "limited", "limiter", "lintels", "listens", "listing", "lithium", "liturgy", "livable", "lobbies", "located", "locater", "locates", "lockets", "locknut", "lodging", "logbook", "looking", "lookout", "lookups", "looming", "lotions", "louvers", "loyalty", "lurkers", "machine", "magical", "magnify", "mahjong", "mailbox", "maiming", "majored", "malting", "manager", "manatee", "mangers", "mangoes", "mankind", "mansion", "mariner", "markets", "married", "marries", "marshal", "martial", "martyrs", "massing", "mastiff", "mastoid", "matinee", "maudlin", "mauling", "maxilla", "meaning", "medical", "mediums", "meeting", "melanin", "members", "mermaid", "message", "meteors", "microbe", "middles", "midline", "midterm", "million", "mimosas", "mincing", "minding", "mingled", "mingles", "minimum", "minnows", "minuses", "minutes", "miserly", "mislead", "missile", "missing", "mistake", "modeled", "modular", "moments", "monarch", "montage", "monthly", "moorhen", "moorish", "morning", "mosaics", "mothers", "mountie", "mulling", "mullion", "mumbles", "mummies", "musings", "muskets", "muskrat", "mutable", "mutants", "mutates", "mutters", "mystics", "nagging", "napkins", "natural", "nebulae", "nesting", "netball", "netting", "network", "nibbles", "nightly", "nipping", "noisily", "noncash", "nonstop", "notable", "notably", "notched", "notches", "nothing", "noticed", "novelty", "nozzles", "numbers", "numeric", "nurture", "nutcase", "oakmoss", "obviate", "ocarina", "octaves", "october", "offends", "offeror", "officer", "offside", "ominous", "omnibus", "onboard", "oneself", "onshore", "openers", "opening", "opinion", "opossum", "optical", "options", "oracles", "oranges", "orbital", "ordeals", "outcome", "outfits", "outlets", "outlier", "outrage", "outside", "overdue", "overrun", "oversaw", "oxfords", "oysters", "pageant", "paisley", "pampers", "panacea", "pancake", "paneled", "panning", "pansies", "papayas", "parable", "paraded", "parapet", "parents", "parfait", "parlors", "paroled", "parsley", "parsons", "parties", "passage", "passing", "passive", "pastors", "patella", "patrons", "pattern", "pausing", "payable", "payment", "payroll", "pecking", "penalty", "pending", "peonies", "percent", "percept", "perches", "perfect", "perfume", "perhaps", "pickets", "picture", "piercer", "pigtail", "pincher", "pinkish", "pinless", "pirated", "pitched", "pitfall", "pivoted", "plainer", "plainly", "planets", "planted", "planter", "plateau", "platoon", "players", "playing", "pleases", "pliable", "plotter", "plunges", "plywood", "poetess", "pointed", "pointer", "pontiff", "pontoon", "pooling", "poppies", "popular", "porcine", "possums", "postbag", "postfix", "posting", "postman", "postwar", "potions", "powdery", "powered", "preachy", "preamps", "precise", "pregame", "preheat", "premise", "prepare", "present", "preteen", "preying", "primacy", "priming", "prisons", "privacy", "private", "problem", "process", "proctor", "prodded", "produce", "product", "profess", "profile", "profits", "program", "project", "prolong", "protect", "provide", "proving", "proxied", "proxies", "prudent", "psyched", "publish", "puffing", "pulsars", "punched", "punches", "pungent", "puritan", "pursuer", "pushing", "pushrod", "putters", "puzzled", "pygmies", "pyramid", "quality", "quantal", "quarrel", "quickly", "quintet", "quizzes", "radiate", "raiders", "raiding", "railway", "raining", "rallied", "rambled", "rancher", "ranchos", "rangers", "rapidly", "rappers", "rascals", "rattled", "ravioli", "rawhide", "reached", "reacher", "reading", "readout", "reasons", "rebuked", "recalls", "recipes", "reckons", "recline", "records", "rectors", "rectory", "recurse", "recusal", "recused", "redbird", "reddish", "redfish", "reeling", "reentry", "referee", "reflect", "refocus", "reforms", "refuted", "regaled", "regency", "regimen", "regress", "regrets", "regroup", "regular", "reissue", "rejoice", "relapse", "related", "relaxed", "release", "reliant", "remakes", "remarks", "remarry", "remixed", "remnant", "remodel", "removes", "renames", "rentals", "renters", "reorder", "repeals", "repents", "replays", "replete", "reports", "reproof", "repulse", "request", "rescale", "resists", "resound", "respect", "restate", "results", "retails", "reticle", "retract", "retread", "returns", "reunion", "reveals", "reveled", "revered", "reverse", "reviews", "reviser", "revisor", "revived", "rewinds", "rewrote", "ribbons", "ricotta", "ridding", "riddled", "rioting", "ripcord", "ripoffs", "riposte", "rippers", "riveted", "riveter", "roaring", "roasted", "roebuck", "rollout", "romaine", "rompers", "roofing", "rooster", "rotator", "rounded", "rounder", "rousing", "royalty", "ruffles", "rumbled", "rumored", "rundown", "running", "runtime", "rustled", "saguaro", "saintly", "salmons", "salting", "salvage", "sampled", "sandman", "saucers", "savages", "savings", "savored", "sayings", "scalper", "scamper", "scanner", "scarcer", "scarier", "scarred", "scatter", "schools", "science", "scissor", "scooped", "scooter", "scourge", "scouted", "scraped", "scrapes", "scratch", "scribes", "scrubby", "seasons", "seaters", "seconds", "secrete", "section", "seeders", "seethed", "seismic", "selfish", "sellout", "serious", "servant", "service", "settles", "several", "shadowy", "shakeup", "shapely", "sharing", "sheared", "sheaths", "sheeted", "shellac", "shifted", "shifter", "shingle", "shipper", "shocker", "shoeing", "shovels", "showers", "shrieks", "shrinks", "shudder", "shuffle", "sickens", "sidecar", "sigmoid", "signers", "silents", "similar", "similes", "sirloin", "sizzler", "skewing", "skidded", "skillet", "skimmed", "skipper", "skylark", "slander", "slapped", "sleeper", "slicker", "slivers", "sloping", "smacked", "smarter", "smiling", "smitten", "smudges", "smuggle", "sneaked", "sneezed", "snicker", "snorkel", "snuffed", "soaking", "soberly", "society", "softest", "softies", "someone", "sonnets", "soothed", "sorcery", "sorrows", "sorters", "sorting", "sources", "spatial", "spawner", "spaying", "special", "species", "specify", "specter", "spiders", "spiller", "spindle", "spinner", "splints", "spotter", "squalls", "squeals", "squishy", "stabler", "stainer", "stamped", "stapled", "starker", "started", "station", "statute", "stereos", "sterner", "stipend", "stopgap", "stopped", "stopper", "stories", "storing", "streets", "strolls", "stubble", "student", "studies", "stuffed", "stunned", "subdued", "subject", "sublime", "subsume", "subtype", "success", "suggest", "summery", "summons", "sunrise", "sunsets", "sunspot", "suppers", "support", "surface", "surfers", "surgeon", "surgery", "surreal", "swapper", "swarmed", "swarthy", "sweeper", "swifter", "swisher", "systems", "tablets", "tacitly", "tacking", "tactics", "tailors", "talking", "tamping", "tangent", "tangles", "tanners", "tannery", "tannins", "tantrum", "tapioca", "tassels", "tatting", "tattoos", "teaches", "teacups", "teasers", "tedious", "tempted", "tempter", "tenable", "tenders", "tending", "tenures", "termini", "testbed", "testers", "tetanus", "textual", "theater", "thereon", "thicken", "thimble", "thirdly", "thirsty", "thither", "thought", "threads", "through", "thumbed", "thumper", "tickets", "tickled", "tidings", "tidying", "tilings", "tinting", "tippers", "tissues", "tithing", "toaster", "toggled", "toggles", "toiling", "tonight", "tooting", "topiary", "topside", "torrent", "tossing", "touched", "touches", "touting", "towards", "toyland", "traffic", "tragedy", "trapped", "treason", "treated", "trefoil", "tresses", "tricked", "trigram", "trimmed", "triplet", "tripods", "tritone", "trolled", "troller", "trotted", "trustee", "tubular", "tumbles", "tutored", "twaddle", "tweedle", "tweeter", "twiddle", "twining", "twinkle", "twisted", "ugliest", "unarmed", "unasked", "unblock", "uncivil", "unfired", "unicorn", "unifies", "unknown", "unlearn", "unspent", "untruth", "untying", "untyped", "unwired", "updated", "upholds", "uploads", "upwards", "usually", "utilize", "utopian", "vacancy", "vaccine", "vagrant", "valiant", "various", "vassals", "vectors", "velvety", "vendors", "verbose", "verdant", "version", "vertigo", "vestige", "vetting", "vibrant", "violent", "virtues", "viruses", "viscous", "visions", "visuals", "voicing", "wafting", "waiting", "wallaby", "walling", "wardens", "warming", "warning", "warring", "warrior", "warthog", "website", "weekend", "welcome", "wettest", "whaling", "wheelie", "whereby", "wherein", "whether", "whitish", "whizzes", "widower", "winches", "windows", "windrow", "winging", "winking", "winless", "winning", "winsome", "wiretap", "wisdoms", "wishful", "wishing", "without", "wizards", "wobbler", "workers", "working", "workmen", "wrapper", "wreaths", "wriggle", "writing", "written", "xylitol" }; _random = null; _codeWords = new Dictionary(); _hardPrefixes = null; _hasPluginConflict = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("000-the_tavern-AutogenRundown") || ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.Brandont.LongerCodes"); if (_hasPluginConflict) { EOSLogger.Warning("Conflicting plugin: \"000-the_tavern-AutogenRundown\" and/or \"com.Brandont.LongerCodes\". Using default SerialGenerator settings"); } } protected override void OnBuildStart() { _random = RandomUtil.CreateSessionRandom("EOS_SerialGenerator"); _codeWords.Clear(); _codeWords[CodeWordLength.Three] = new ShuffledStepArray(ThreeLetterWords); _codeWords[CodeWordLength.Five] = new ShuffledStepArray(FiveLetterWords); _codeWords[CodeWordLength.Six] = new ShuffledStepArray(SixLetterWords); _codeWords[CodeWordLength.Seven] = new ShuffledStepArray(SevenLetterWords); _hardPrefixes = new ShuffledStepArray(HardCodeWordPrefixes); } public static int GetUniqueSerialNo() { return SerialGenerator.GetUniqueSerialNo(); } public static string GetIPAddress(bool useIPv6) { if (_hasPluginConflict || !useIPv6) { return SerialGenerator.GetIpAddress(); } string[] array = new string[4] { RandomHex(256, 4608), RandomHex(4096, 65535), RandomHex(0, 511), RandomHex(0, 16383) }; int num = array.Length; while (num > 1) { int num2 = _random.Next(0, num--); ref string reference = ref array[num2]; ref string reference2 = ref array[num]; string text = array[num]; string text2 = array[num2]; reference = text; reference2 = text2; } return RandomHex(8192, 16383) + "::" + string.Join(':', array); } private static string RandomHex(int min, int max) { return _random.Next(min, max).ToString("x"); } public static string GetCodeWord(CodeWordLength wordLength) { if (_hasPluginConflict || !_codeWords.TryGetValue(wordLength, out ShuffledStepArray value)) { return SerialGenerator.GetCodeWord(); } return value.Next(); } public static string GetCodeWordPrefix(bool useHardPrefixes, bool hyphenate = false) { string text = ((!_hasPluginConflict && useHardPrefixes) ? _hardPrefixes.Next() : SerialGenerator.GetCodeWordPrefix()); return hyphenate ? text.Insert(1, "-") : text; } public static void SetupUplinkPuzzle(LG_ComputerTerminal terminal, UplinkDefinition def) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown TerminalUplinkPuzzle uplinkPuzzle = terminal.UplinkPuzzle; uplinkPuzzle.m_rounds = ListExtensions.ToIl2Cpp(new List()); uplinkPuzzle.TerminalUplinkIP = GetIPAddress(def.UseIPv6Addresses); uplinkPuzzle.m_roundIndex = 0; uplinkPuzzle.m_lastRoundIndexToUpdateGui = -1; uplinkPuzzle.m_position = ((Component)terminal).transform.position; uplinkPuzzle.IsCorrupted = def.SetupAsCorruptedUplink && (Object)(object)terminal.CorruptedUplinkReceiver != (Object)null; uplinkPuzzle.m_terminal = terminal; uint num = Math.Max(def.NumberOfVerificationRounds, 1u); int num2 = Math.Clamp(def.CandidateWordsCount, 6, 15); for (int i = 0; i < num; i++) { TerminalUplinkPuzzleRound val = new TerminalUplinkPuzzleRound(); val.CorrectIndex = _random.Next(0, num2); val.Prefixes = Il2CppStringArray.op_Implicit(new string[num2]); val.Codes = Il2CppStringArray.op_Implicit(new string[num2]); TerminalUplinkPuzzleRound val2 = val; for (int j = 0; j < num2; j++) { ((Il2CppArrayBase)(object)val2.Codes)[j] = GetCodeWord(def.CodeWordLength); ((Il2CppArrayBase)(object)val2.Prefixes)[j] = GetCodeWordPrefix(def.UseHardCodeWordPrefixes, def.HyphanateCodeWordPrefixes); } uplinkPuzzle.m_rounds.Add(val2); } } public static void RerollCorrectIndex(TerminalUplinkPuzzle uplinkPuzzle, int retryCount) { for (int i = 0; i < retryCount; i++) { Enumerator enumerator = uplinkPuzzle.m_rounds.GetEnumerator(); while (enumerator.MoveNext()) { TerminalUplinkPuzzleRound current = enumerator.Current; current.CorrectIndex = _random.Next(0, ((Il2CppArrayBase)(object)current.Codes).Length); } } } } public struct TerminalState { public bool enabled; public bool approached; private int _data; private byte _length; public bool[] Value { readonly get { bool[] array = new bool[_length]; for (int i = 0; i < _length; i++) { array[i] = (_data & (1 << i)) != 0; } return array; } set { if (value.Length > 32) { return; } _data = 0; _length = (byte)value.Length; for (int i = 0; i < value.Length; i++) { if (value[i]) { _data |= 1 << i; } } } } public TerminalState() { enabled = true; approached = false; _data = 0; _length = 0; _data = 0; _length = 0; } public TerminalState(bool[] arr) { enabled = true; approached = false; _data = 0; _length = 0; Value = arr; } } public class TerminalWrapper { private readonly Dictionary> _logEventMap = new Dictionary>(); private readonly List _filenameList = new List(); private readonly ExpeditionTerminalsDefinition? _expTermDef = null; public LG_ComputerTerminal Terminal { get; private set; } = null; public StateReplicator? Replicator { get; private set; } public TerminalWrapper(LG_ComputerTerminal term, uint replicatorID) { if ((Object)(object)term == (Object)null || replicatorID == 0) { return; } Terminal = term; Replicator = StateReplicator.Create(replicatorID, new TerminalState(), (LifeTimeType)1, (IStateReplicatorHolder)null); Replicator.OnStateChanged += OnStateChanged; if (!BaseManager.Current.TryGetTerminalDefinitionFromInstance(term, out ExpeditionTerminalsDefinition termDef) || termDef == null) { return; } _expTermDef = termDef; foreach (TerminalLogFileEvents logFile in _expTermDef.LogFiles) { if (!Utility.IsNullOrWhiteSpace(logFile.FileName)) { _logEventMap[logFile.FileName.ToUpperInvariant()] = logFile.EventsOnFileRead; _filenameList.Add(logFile.FileName.ToUpperInvariant()); } } } public void ReceiveCommand(TERM_Command cmd, string param) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if (_expTermDef == null) { return; } if (SNet.IsMaster && (int)cmd == 29) { ChangeState(param); } if ((int)cmd == 31) { float delay; List eData; if (!Terminal.EvaluatePassword(param)) { List eventsOnPasswordInputFailure = _expTermDef.EventsOnPasswordInputFailure; float num = 2.6f; delay = num; eData = eventsOnPasswordInputFailure; } else { List eventsOnPasswordInputSuccess = _expTermDef.EventsOnPasswordInputSuccess; float num = 2.8f; delay = num; eData = eventsOnPasswordInputSuccess; } MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)Terminal, DoEvents(eData, delay)); } } public void ChangeState() { StateReplicator? replicator = Replicator; if (replicator != null && !replicator.State.approached) { StateReplicator? replicator2 = Replicator; if (replicator2 != null) { TerminalState state = Replicator.State; state.approached = true; replicator2.SetState(state); } } } public void ChangeState(bool enabled) { StateReplicator? replicator = Replicator; if (replicator != null) { TerminalState state = Replicator.State; state.enabled = enabled; replicator.SetState(state); } } public void ChangeState(string filename) { int num = _filenameList.IndexOf(filename); if (_expTermDef == null || Replicator == null || num == -1) { return; } bool[] value = Replicator.State.Value; bool[] array = new bool[_filenameList.Count]; for (int i = 0; i < value.Length && i < array.Length; i++) { array[i] = value[i]; } if (!array[num]) { array[num] = true; StateReplicator? replicator = Replicator; if (replicator != null) { TerminalState state = Replicator.State; state.Value = array; replicator.SetState(state); } } } private void OnStateChanged(TerminalState oldState, TerminalState state, bool isRecall) { if (oldState.enabled != state.enabled) { bool enabled = state.enabled; Terminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)Terminal).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = enabled; ((Interact_Base)componentInChildren).SetActive(enabled); } Terminal.m_interfaceScreen.SetActive(enabled); Terminal.m_loginScreen.SetActive(enabled); if ((Object)(object)Terminal.m_text != (Object)null) { ((Behaviour)Terminal.m_text).enabled = enabled; } if (!enabled) { PlayerAgent localInteractionSource = Terminal.m_localInteractionSource; if (localInteractionSource != null) { FirstPersonItemHolder fPItemHolder = localInteractionSource.FPItemHolder; if (((fPItemHolder != null) ? new bool?(fPItemHolder.InTerminalTrigger) : ((bool?)null)) == true) { Terminal.ExitFPSView(); } } } } if (_expTermDef == null || isRecall) { return; } if (!oldState.approached && state.approached) { EOSWardenEventManager.ExecuteWardenEvents(_expTermDef.EventsOnApproach, (eWardenObjectiveEventTrigger)0); } bool[] value = oldState.Value; bool[] value2 = state.Value; for (int i = 0; i < _filenameList.Count; i++) { bool flag = i < value.Length && value[i]; bool flag2 = i < value2.Length && value2[i]; if (!flag && flag2 && _logEventMap.TryGetValue(_filenameList[i], out List value3)) { MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)Terminal, DoEvents(value3, 3f)); } } } private static IEnumerator DoEvents(List eData, float delay) { yield return (object)new WaitForSeconds(delay); EOSWardenEventManager.ExecuteWardenEvents(eData, (eWardenObjectiveEventTrigger)0); } } } namespace EOS.Modules.Tweaks.TerminalPosition { public class TerminalPosition : BaseInstanceDefinition { public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); public bool RepositionCover { get; set; } = false; public bool HideCover { get; set; } = false; } public sealed class TerminalPositionOverrideManager : InstanceDefinitionManager { protected override string DEFINITION_NAME => "TerminalPosition"; public void Setup(LG_ComputerTerminal term) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)term.ConnectedReactor != (Object)null) { return; } var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(term); if (!TryGetDefinition(globalIndex, instanceIndex, out TerminalPosition definition)) { return; } Vector3 val = definition.Position; Quaternion val2 = definition.Rotation; if (val == Vector3.zero) { return; } term.m_sound.UpdatePosition(val); LG_MarkerProducer componentInParent = ((Component)term).GetComponentInParent(); if ((!definition.RepositionCover && !definition.HideCover) || (Object)(object)componentInParent == (Object)null) { ((Component)term).transform.SetPositionAndRotation(val, val2); } else { Transform val3 = ((Component)componentInParent).transform; while (val3.childCount == 1 && (Object)(object)((Component)val3.GetChild(0)).GetComponent() == (Object)null) { val3 = val3.GetChild(0); } for (int i = 0; i < val3.childCount; i++) { Transform child = val3.GetChild(i); LG_ComputerTerminal componentInChildren = ((Component)child).GetComponentInChildren(true); if (definition.HideCover && (Object)(object)componentInChildren == (Object)null) { ((Component)child).gameObject.SetActive(false); } else { child.SetPositionAndRotation(val, val2); } } } EOSLogger.Debug($"{DEFINITION_NAME}: modified for {definition}"); } } } namespace EOS.Modules.Tweaks.SecDoorIntText { public class InteractGlitchComp : MonoBehaviour { public const string HEX_CHARPOOL = "0123456789ABCDEF"; public const string ERR_CHARPOOL = "$#/-01"; public const string RICH_TEXT = "<\\/?(b|i|u|s|align|allcaps|alpha|br|color|cspace|font|font-weight|gradient|indent|line-height|line-indent|link|lowercase|margin|mark|mspace|nobr|noparse|page|pos|rotate|size|smallcaps|space|sprite|style|sub|sup|uppercase|voffset|width)(=[^>]*)?>"; public const string ESCAPE_CHAR = "[\\n\\r\\t\\v\\b\\\\\\'\"]"; private readonly StringBuilder _strBuilder = new StringBuilder(); private readonly List<(string, bool)> _style2Text = new List<(string, bool)>(); private Random _random = null; private eDoorStatus[] _statusWhitelist = null; private uint _holdTextID; private float _timer; public LG_SecurityDoor_Locks Locks { get; private set; } = null; public GlitchMode Mode { get; internal set; } = GlitchMode.None; public bool CanInteract { get; internal set; } = false; [HideFromIl2Cpp] public void Init(SecDoorIntTextDefinition def) { //IL_0061: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) Locks = ((Component)this).GetComponent(); Mode = def.GlitchMode; _random = new Random(((Object)Locks).GetInstanceID()); _statusWhitelist = def.ActiveGlitchStatusWhitelist; _holdTextID = GameDataBlockBase.GetBlockID("InGame.InteractionPrompt.Hold_X"); if (Mode == GlitchMode.Style2) { int num = 0; string text = LocaleText.op_Implicit(def.Style2Text); _style2Text.Add((def.Style2Prefix.ParseTextFragments(), true)); foreach (Match item in Regex.Matches(LocaleText.op_Implicit(def.Style2Text), "<\\/?(b|i|u|s|align|allcaps|alpha|br|color|cspace|font|font-weight|gradient|indent|line-height|line-indent|link|lowercase|margin|mark|mspace|nobr|noparse|page|pos|rotate|size|smallcaps|space|sprite|style|sub|sup|uppercase|voffset|width)(=[^>]*)?>|[\\n\\r\\t\\v\\b\\\\\\'\"]", RegexOptions.IgnoreCase)) { if (item.Index > num) { _style2Text.Add((text.Substring(num, item.Index - num), false)); } _style2Text.Add((item.Value, true)); num = item.Index + item.Length; } if (num < text.Length) { _style2Text.Add((text.Substring(num), false)); } _style2Text.Add((def.Style2Postfix.ParseTextFragments(), true)); } ((Behaviour)this).enabled = false; } public void Update() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (((Behaviour)this).enabled && !(_timer > Clock.Time) && GuiManager.InteractionLayer != null && Mode != GlitchMode.None && (!_statusWhitelist.Any() || _statusWhitelist.Contains(Locks.m_lastStatus))) { GuiManager.InteractionLayer.SetInteractPrompt((Mode == GlitchMode.Style1) ? GetFormat1() : GetFormat2(), CanInteract ? Text.Format(_holdTextID, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName((InputAction)6)) }) : string.Empty, (ePUIMessageStyle)0); GuiManager.InteractionLayer.InteractPromptVisible = true; _timer = Clock.Time + ((Mode == GlitchMode.Style1) ? 0.05f : 0.075f); } } private string GetFormat1() { return "://Decryption E_RR at: [" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "]"; } private string GetRandomHex() { return string.Format("{0}{1}", "0123456789ABCDEF"[_random.Next(0, "0123456789ABCDEF".Length)], "0123456789ABCDEF"[_random.Next(0, "0123456789ABCDEF".Length)]); } private string GetFormat2() { _strBuilder.Clear(); foreach (var item in _style2Text) { var (text, _) = item; if (item.Item2) { _strBuilder.Append(text); continue; } string text2 = text; foreach (char c in text2) { if (_random.NextDouble() > 0.009999999776482582 || c == ':') { _strBuilder.Append(c); } else { _strBuilder.Append("$#/-01"[_random.Next(0, "$#/-01".Length)]); } } } return _strBuilder.ToString(); } } public enum GlitchMode { None, Style1, Style2 } public class SecDoorIntTextDefinition : GlobalBased { public LocaleText Prefix { get; set; } = LocaleText.Empty; public LocaleText Postfix { get; set; } = LocaleText.Empty; public LocaleText TextToReplace { get; set; } = LocaleText.Empty; public eDoorStatus[] ActiveTextOverrideWhitelist { get; set; } = Array.Empty(); public GlitchMode GlitchMode { get; set; } = GlitchMode.None; public LocaleText Style2Prefix { get; set; } = LocaleText.Empty; public LocaleText Style2Postfix { get; set; } = LocaleText.Empty; public LocaleText Style2Text { get; set; } = new LocaleText(841u); public eDoorStatus[] ActiveGlitchStatusWhitelist { get; set; } = Array.Empty(); } public sealed class SecDoorIntTextOverrideManager : ZoneDefinitionManager { protected override string DEFINITION_NAME => "SecDoorIntText"; public bool TryGetDefinition(LG_SecurityDoor_Locks locks, [MaybeNullWhen(false)] out SecDoorIntTextDefinition def) { LG_SecurityDoor door = locks.m_door; (int, int, int)? obj; if (door == null) { obj = null; } else { LG_Gate gate = door.Gate; if (gate == null) { obj = null; } else { LG_Area linksTo = ((LG_ZoneExpander)gate).m_linksTo; if (linksTo == null) { obj = null; } else { LG_Zone zone = linksTo.m_zone; obj = ((zone != null) ? new(int, int, int)?(GlobalIndexUtil.ToIntTuple(zone)) : (((int, int, int)?)null)); } } } (int, int, int) globalIndex = obj ?? (-1, -1, -1); return ((ZoneDefinitionManager)this).TryGetDefinition(globalIndex, out def); } protected override void OnBuildDone() { foreach (SecDoorIntTextDefinition item in GetDefinitionsForLevel(BaseManager.CurrentMainLevelLayout)) { LG_Zone zone = ((GlobalBase)item).Zone; object obj; if (zone == null) { obj = null; } else { LG_Gate sourceGate = zone.m_sourceGate; if (sourceGate == null) { obj = null; } else { iLG_Door_Core spawnedDoor = sourceGate.SpawnedDoor; if (spawnedDoor == null) { obj = null; } else { LG_SecurityDoor obj2 = ((Il2CppObjectBase)spawnedDoor).TryCast(); if (obj2 == null) { obj = null; } else { iLG_Door_Locks locks = obj2.m_locks; obj = ((locks != null) ? ((Il2CppObjectBase)locks).TryCast() : null); } } } } LG_SecurityDoor_Locks val = (LG_SecurityDoor_Locks)obj; if ((Object)(object)val != (Object)null) { ReplaceText(val, item); } } } public void ReplaceText(LG_SecurityDoor_Locks locks, SecDoorIntTextDefinition? def = null) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((def != null || TryGetDefinition(locks, out def)) && (!def.ActiveTextOverrideWhitelist.Any() || def.ActiveTextOverrideWhitelist.Contains(locks.m_lastStatus))) { locks.m_intCustomMessage.m_message = ReplaceText(locks.m_intCustomMessage.m_message); locks.m_intOpenDoor.InteractionMessage = ReplaceText(locks.m_intOpenDoor.InteractionMessage); locks.m_intUseKeyItem.m_msgNeedItemHeader = ReplaceText(locks.m_intUseKeyItem.m_msgNeedItemHeader); } string ReplaceText(string input) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); if (!string.IsNullOrEmpty(LocaleText.op_Implicit(def.Prefix))) { stringBuilder.Append(LocaleText.op_Implicit(def.Prefix)).AppendLine(); } string value = (string.IsNullOrEmpty(LocaleText.op_Implicit(def.TextToReplace)) ? input : LocaleText.op_Implicit(def.TextToReplace)); stringBuilder.Append(value); if (!string.IsNullOrEmpty(LocaleText.op_Implicit(def.Postfix))) { stringBuilder.AppendLine().Append(LocaleText.op_Implicit(def.Postfix)); } return stringBuilder.ToString(); } } } } namespace EOS.Modules.Tweaks.ScoutEvents { public class EventsOnZoneScoutScream : GlobalBased { public bool SuppressVanillaScoutWave { get; set; } = false; public List EventsOnScoutScream { get; set; } = new List(); } public sealed class ScoutScreamEventManager : ZoneDefinitionManager { protected override string DEFINITION_NAME => "EventsOnScoutScream"; } } namespace EOS.Modules.Tweaks.DimensionWarp { public class DimensionWarpDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public eDimensionIndex DimensionIndex { get; set; } = (eDimensionIndex)0; public OnWarp OnWarp { get; set; } = new OnWarp(); public List Locations { get; set; } = new List(); } public class OnWarp { public bool WarpTeam_WarpAllWarpableBigPickupItems { get; set; } = true; public bool WarpRange_WarpDeployedSentryOutsideRange { get; set; } = true; public bool WarpItemsInZone_OnlyWarpWarpable { get; set; } = true; } public class PositionAndLookDir { public Vec3 Position { get; set; } = new Vec3(); public int LookDir { get; set; } = 0; } public sealed class DimensionWarpManager : GenericExpeditionDefinitionManager { public enum WarpEventType { WarpTeam = 160, WarpRange, WarpItemsInZone } private readonly ImmutableList _lookDirs = ImmutableList.Create((Vector3[])(object)new Vector3[4] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right }); protected override string DEFINITION_NAME => "DimensionWarp"; static DimensionWarpManager() { EOSWardenEventManager.AddEventDefinition(WarpEventType.WarpTeam.ToString(), 160u, WarpTeam); EOSWardenEventManager.AddEventDefinition(WarpEventType.WarpRange.ToString(), 161u, WarpRange); EOSWardenEventManager.AddEventDefinition(WarpEventType.WarpItemsInZone.ToString(), 162u, WarpItemsInZone); } public bool TryGetWarpDefinition(string worldEventObjectFilter, [MaybeNullWhen(false)] out DimensionWarpDefinition warpDef) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 warpDef = null; if ((int)GameStateManager.CurrentStateName != 10 || !base.GenericExpDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out GenericExpeditionDefinition value)) { return false; } warpDef = value.Definitions.Find((DimensionWarpDefinition w) => w.WorldEventObjectFilter == worldEventObjectFilter); return warpDef != null; } private static void WarpTeam(WardenObjectiveEventData e) { if (!BaseManager.Current.TryGetWarpDefinition(e.WorldEventObjectFilter, out DimensionWarpDefinition warpDef)) { EOSLogger.Error("WarpTeam: def WorldEventObjectFilter '" + e.WorldEventObjectFilter + "' is not defined"); } else { BaseManager.Current.WarpTeam(warpDef); } } public void WarpTeam(DimensionWarpDefinition def) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) List locations = def.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpTeam: no warp locations found"); return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int num = localPlayerAgent.PlayerSlotIndex % locations.Count; Vector3 val = locations[num].Position; int index = locations[num].LookDir % _lookDirs.Count; Vector3 val2 = _lookDirs[index]; int num2 = 0; List list = new List(); Enumerator enumerator = Dimension.WarpableObjects.GetEnumerator(); while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast(); if (val3 != null && ((ItemEquippable)val3).LocallyPlaced) { list.Add(val3); } else if (SNet.IsMaster && def.OnWarp.WarpTeam_WarpAllWarpableBigPickupItems) { ItemInLevel val4 = ((Il2CppObjectBase)current).TryCast(); if (val4 != null && val4.CanWarp && val4.internalSync.GetCurrentState().placement.droppedOnFloor) { Vec3 position = locations[num2].Position; WarpItem(val4, def.DimensionIndex, position); num2 = (num2 + 1) % locations.Count; } } } list.ForEach(delegate(SentryGunInstance sentryGun) { sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0); }); if (!localPlayerAgent.TryWarpTo(def.DimensionIndex, val, val2, true)) { EOSLogger.Error($"WarpTeam: TryWarpTo failed. Position: {val}, playerSlotIndex: {localPlayerAgent.PlayerSlotIndex}, warpLocationIndex: {num}"); } } private static void WarpRange(WardenObjectiveEventData e) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!BaseManager.Current.TryGetWarpDefinition(e.WorldEventObjectFilter, out DimensionWarpDefinition warpDef)) { EOSLogger.Error("WarpTeam: def WorldEventObjectFilter '" + e.WorldEventObjectFilter + "' is not defined"); } else { BaseManager.Current.WarpRange(warpDef, e.Position, e.FogTransitionDuration); } } public void WarpRange(DimensionWarpDefinition def, Vector3 rangeOrigin, float range) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) List locations = def.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpAlivePlayersInRange: no warp locations found"); return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int index = localPlayerAgent.PlayerSlotIndex % locations.Count; Vector3 val = locations[index].Position; int index2 = locations[index].LookDir % _lookDirs.Count; Vector3 val2 = _lookDirs[index2]; float num = range * range; int num2 = 0; List list = new List(); Enumerator enumerator = Dimension.WarpableObjects.GetEnumerator(); while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast(); if ((Object)(object)val3 != (Object)null) { bool flag = ((ItemEquippable)val3).LocallyPlaced && ((Agent)((Item)val3).Owner).Alive && GameObjectPlusExtensions.IsWithinSqrDistance(rangeOrigin, ((Agent)((Item)val3).Owner).Position, num); bool flag2 = def.OnWarp.WarpRange_WarpDeployedSentryOutsideRange || GameObjectPlusExtensions.IsWithinSqrDistance(rangeOrigin, ((Component)val3).transform.position, num); if (flag && flag2) { list.Add(val3); continue; } } if (SNet.IsMaster) { ItemInLevel val4 = ((Il2CppObjectBase)current).TryCast(); if ((Object)(object)val4 != (Object)null && GameObjectPlusExtensions.IsWithinSqrDistance(((Component)val4).transform.position, rangeOrigin, num)) { Vec3 position = locations[num2].Position; WarpItem(val4, def.DimensionIndex, position); num2 = (num2 + 1) % locations.Count; } } } list.ForEach(delegate(SentryGunInstance sentryGun) { sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0); }); bool flag3 = ((Agent)localPlayerAgent).Alive && GameObjectPlusExtensions.IsWithinSqrDistance(rangeOrigin, ((Agent)localPlayerAgent).Position, num); if (!localPlayerAgent.TryWarpTo(def.DimensionIndex, val, val2, true)) { EOSLogger.Error($"WarpAlivePlayersInRange: TryWarpTo failed, Position: {val}"); } } private static void WarpItemsInZone(WardenObjectiveEventData e) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster) { if (!BaseManager.Current.TryGetWarpDefinition(e.WorldEventObjectFilter, out DimensionWarpDefinition warpDef)) { EOSLogger.Error("WarpTeam: def WorldEventObjectFilter '" + e.WorldEventObjectFilter + "' is not defined"); } else { WarpItemsInZone(warpDef, e.DimensionIndex, e.Layer, e.LocalIndex); } } } public static void WarpItemsInZone(DimensionWarpDefinition def, eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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) List locations = def.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpItemsInZone: no warp locations found"); return; } int num = 0; Enumerator enumerator = Dimension.WarpableObjects.GetEnumerator(); while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; ItemInLevel val = ((Il2CppObjectBase)current).TryCast(); if (!((Object)(object)val == (Object)null)) { bool droppedOnFloor = val.internalSync.GetCurrentState().placement.droppedOnFloor; (int, int, int) tuple = GlobalIndexUtil.ToIntTuple(val.CourseNode.m_zone); (int, int, int) tuple2 = GlobalIndexUtil.ToIntTuple(dimensionIndex, layer, localIndex); bool flag = !def.OnWarp.WarpItemsInZone_OnlyWarpWarpable || val.CanWarp; int num2; if (droppedOnFloor) { (int, int, int) tuple3 = tuple; (int, int, int) tuple4 = tuple2; num2 = ((tuple3.Item1 == tuple4.Item1 && tuple3.Item2 == tuple4.Item2 && tuple3.Item3 == tuple4.Item3) ? 1 : 0); } else { num2 = 0; } if (((uint)num2 & (flag ? 1u : 0u)) != 0) { Vec3 position = locations[num].Position; WarpItem(val, dimensionIndex, position); } num = (num + 1) % locations.Count; } } } public static void WarpItem(ItemInLevel item, eDimensionIndex warpToDim, Vector3 warpToPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode courseNode = CourseNodeUtil.GetCourseNode(warpToPosition, warpToDim); if (courseNode == null) { EOSLogger.Error("WarpItem: cannot find course node for item to warp"); } else if (item != null) { iPickupItemSync syncComponent = item.GetSyncComponent(); if (syncComponent != null) { syncComponent.AttemptPickupInteraction((ePickupItemInteractionType)1, (SNet_Player)null, ((Item)item).pItemData.custom, warpToPosition, Quaternion.identity, courseNode, true, true); } } } } } namespace EOS.Modules.Tweaks.BossEvents { public sealed class BossDeathEventManager : ZoneDefinitionManager { public enum Mode { HIBERNATE, WAVE } public const int UNLIMITED_COUNT = int.MaxValue; private readonly ConcurrentDictionary<(int, int, int), EventsOnZoneBossDeath> _levelBDEs = new ConcurrentDictionary<(int, int, int), EventsOnZoneBossDeath>(); protected override string DEFINITION_NAME => "EventsOnBossDeath"; protected override void OnBuildStart() { OnLevelCleanup(); SetupForCurrentExpedition(); } protected override void OnLevelCleanup() { CollectionExtensions.ForEachValue<(int, int, int), EventsOnZoneBossDeath>((IDictionary<(int, int, int), EventsOnZoneBossDeath>)_levelBDEs, (Action)delegate(EventsOnZoneBossDeath bde) { bde.Destroy(); }); _levelBDEs.Clear(); } private void SetupForCurrentExpedition() { foreach (EventsOnZoneBossDeath item in GetDefinitionsForLevel(BaseManager.CurrentMainLevelLayout)) { if (_levelBDEs.ContainsKey(((GlobalBase)item).IntTuple)) { EOSLogger.Warning($"BossDeathEvent: found duplicate setup for zone {item}, will overwrite!"); } if (item.ApplyToHibernateCount != int.MaxValue || item.ApplyToWaveCount != int.MaxValue) { uint num = EOSNetworking.AllotReplicatorID(); if (num != 0) { item.SetupReplicator(num); } else { EOSLogger.Error("BossDeathEvent: replicator IDs depleted, cannot setup StateReplicator"); } } _levelBDEs[((GlobalBase)item).IntTuple] = item; } } public bool TryConsumeBDEventsExecutionTimes(EventsOnZoneBossDeath def, Mode mode) { if (!_levelBDEs.TryGetValue(((GlobalBase)def).IntTuple, out EventsOnZoneBossDeath value)) { EOSLogger.Error($"BossDeathEventManager: got an unregistered entry: {def} {mode}"); return false; } int num = ((mode == Mode.HIBERNATE) ? value.HibernateCount : value.WaveCount); if (num == int.MaxValue) { return true; } if (num > 0) { value.Replicator?.SetStateUnsynced(new FiniteBDEState { applyToHibernateCount = ((mode == Mode.HIBERNATE) ? (num - 1) : value.HibernateCount), applyToWaveCount = ((mode == Mode.WAVE) ? (num - 1) : value.WaveCount) }); return true; } return false; } } public class EventsOnZoneBossDeath : GlobalBased { public bool ApplyToHibernate { get; set; } = true; public int ApplyToHibernateCount { get; set; } = int.MaxValue; public bool ApplyToWave { get; set; } = false; public int ApplyToWaveCount { get; set; } = int.MaxValue; public List BossIDs { get; set; } = new List { 29u, 36u, 37u }; public List EventsOnBossDeath { get; set; } = new List(); [JsonIgnore] public StateReplicator? Replicator { get; private set; } [JsonIgnore] public int HibernateCount => Replicator?.State.applyToHibernateCount ?? int.MaxValue; [JsonIgnore] public int WaveCount => Replicator?.State.applyToWaveCount ?? int.MaxValue; public void SetupReplicator(uint replicatorID) { if (ApplyToHibernateCount != int.MaxValue || ApplyToWaveCount != int.MaxValue) { Replicator = StateReplicator.Create(replicatorID, new FiniteBDEState { applyToHibernateCount = ApplyToHibernateCount, applyToWaveCount = ApplyToWaveCount }, (LifeTimeType)1, (IStateReplicatorHolder)null); } } internal void Destroy() { Replicator?.Unload(); Replicator = null; } } public struct FiniteBDEState { public int applyToHibernateCount; public int applyToWaveCount; public FiniteBDEState() { applyToHibernateCount = int.MaxValue; applyToWaveCount = int.MaxValue; } public FiniteBDEState(FiniteBDEState other) { applyToHibernateCount = int.MaxValue; applyToWaveCount = int.MaxValue; applyToHibernateCount = other.applyToHibernateCount; applyToHibernateCount = other.applyToWaveCount; } public FiniteBDEState(int hibernateCount, int waveCount) { applyToHibernateCount = int.MaxValue; applyToWaveCount = int.MaxValue; applyToHibernateCount = hibernateCount; applyToWaveCount = waveCount; } } } namespace EOS.Modules.Objectives.TerminalUplink { public enum UplinkTerminal { SENDER, RECEIVER } public class UplinkDefinition : BaseInstanceDefinition { private bool _firstRoundOutputted = false; [JsonPropertyOrder(0)] public int WardenObjectiveIndex { get; set; } = -1; [JsonPropertyOrder(1)] public bool DisplayUplinkWarning { get; set; } = true; [JsonPropertyOrder(2)] public bool SetupAsCorruptedUplink { get; set; } = false; [JsonPropertyOrder(3)] public BaseTerminalDefinition CorruptedUplinkReceiver { get; set; } = new BaseTerminalDefinition(); [JsonPropertyOrder(4)] public bool UseUplinkAddress { get; set; } = true; [JsonPropertyOrder(5)] public BaseTerminalDefinition UplinkAddressLogPosition { get; set; } = new BaseTerminalDefinition(); [JsonPropertyOrder(6)] public bool UseIPv6Addresses { get; set; } = false; [JsonPropertyOrder(7)] public bool HyphanateCodeWordPrefixes { get; set; } = false; [JsonPropertyOrder(8)] public bool UseHardCodeWordPrefixes { get; set; } = false; [JsonPropertyOrder(9)] public SerialGeneratorManager.CodeWordLength CodeWordLength { get; set; } = SerialGeneratorManager.CodeWordLength.Four; [JsonPropertyOrder(10)] public int CandidateWordsCount { get; set; } = 6; [JsonPropertyOrder(11)] public uint ChainedPuzzleToStartUplink { get; set; } = 0u; [JsonPropertyOrder(12)] public uint NumberOfVerificationRounds { get; set; } = 1u; [JsonPropertyOrder(13)] public TimeSettings DefaultTimeSettings { get; set; } = new TimeSettings(); [JsonPropertyOrder(14)] public List RoundOverrides { get; set; } = new List { new UplinkRound() }; [JsonPropertyOrder(15)] public List EventsOnCommence { get; set; } = new List(); [JsonPropertyOrder(16)] public List EventsOnComplete { get; set; } = new List(); internal void Cleanup() { ResetFirstRoundOutput(); RoundOverrides.ForEach(delegate(UplinkRound r) { r.ChainedPuzzleToEndRoundInstance = null; }); } internal bool FirstRoundOutputted(int roundIndex) { if (roundIndex == 0 && !_firstRoundOutputted) { return _firstRoundOutputted = true; } return false; } internal void ResetFirstRoundOutput() { _firstRoundOutputted = false; } } public class UplinkRound { public int RoundIndex { get; set; } = -1; public uint ChainedPuzzleToEndRound { get; set; } = 0u; public UplinkTerminal BuildChainedPuzzleOn { get; set; } = UplinkTerminal.SENDER; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleToEndRoundInstance { get; set; } = null; public TimeSettings OverrideTimeSettings { get; set; } = new TimeSettings { TimeToStartVerify = -1f, TimeToCompleteVerify = -1f, TimeToRestoreFromFail = -1f }; public List EventsOnRound { get; set; } = new List(); } public class TimeSettings { public float TimeToStartVerify { get; set; } = 5f; public float TimeToCompleteVerify { get; set; } = 6f; public float TimeToRestoreFromFail { get; set; } = 6f; } public sealed class UplinkObjectiveManager : InstanceDefinitionManager { private List _currentDefs = new List(); private readonly Dictionary _wardenUplinkDefs = new Dictionary(); private readonly Dictionary?> _stateReplicators = new Dictionary>(); protected override string DEFINITION_NAME { get; } = "TerminalUplink"; public override uint ChainedPuzzleLoadOrder => 3u; public static LocaleText UplinkAddrLogContent { get; private set; } = LocaleText.Empty; protected override void AddDefinitions(InstanceDefinitionsForLevel definitions) { Sort(definitions); definitions.Definitions.ForEach(delegate(UplinkDefinition u) { u.RoundOverrides.Sort((UplinkRound r1, UplinkRound r2) => r1.RoundIndex.CompareTo(r2.RoundIndex)); }); base.AddDefinitions(definitions); } public bool TryGetDefinition(LG_ComputerTerminal term, [MaybeNullWhen(false)] out UplinkDefinition definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(term); return TryGetDefinition(globalIndex, instanceIndex, out definition); } protected override void OnBuildDone() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!base.InstanceDefinitions.ContainsKey(BaseManager.CurrentMainLevelLayout)) { return; } UplinkAddrLogContent = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.UplinkTerminal.UplinkAddrLog"), RawText = "Available uplink address for TERMINAL_{0}: {1}" }; _currentDefs = new List(GetDefinitionsForLevel(BaseManager.CurrentMainLevelLayout)); foreach (UplinkDefinition currentDef in _currentDefs) { Build(currentDef); } } protected override void OnEnterLevel() { foreach (LG_ComputerTerminal item in _stateReplicators.Select>, LG_ComputerTerminal>((KeyValuePair> kvp) => new LG_ComputerTerminal(kvp.Key))) { SerialGeneratorManager.RerollCorrectIndex(item.UplinkPuzzle, CheckpointManager.CheckpointUsage); } } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { _currentDefs.ForEach(delegate(UplinkDefinition b) { b.Cleanup(); }); _currentDefs.Clear(); _wardenUplinkDefs.Clear(); CollectionExtensions.ForEachValue>((IDictionary>)_stateReplicators, (Action>)delegate(StateReplicator u) { u?.Unload(); }); _stateReplicators.Clear(); } public UplinkDefinition? GetWardenDefinition(LG_ComputerTerminal terminal) { return _wardenUplinkDefs.GetValueOrDefault(((Il2CppObjectBase)terminal).Pointer); } private void Build(UplinkDefinition def) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Expected O, but got Unknown //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Expected O, but got Unknown //IL_04dc: Expected O, but got Unknown //IL_05cb: Unknown result type (might be due to invalid IL or missing references) //IL_07db: Unknown result type (might be due to invalid IL or missing references) if (def.WardenObjectiveIndex >= 0) { LG_ComputerTerminal wardenUplink = BaseManager.Current.GetWardenUplink(((GlobalBase)def).Layer, def.WardenObjectiveIndex); if ((Object)(object)wardenUplink == (Object)null || !wardenUplink.m_isWardenObjective || ((int)wardenUplink.WardenObjectiveType != 1 && (int)wardenUplink.WardenObjectiveType != 2)) { EOSLogger.Error($"BuildUplink: warden objective uplink not built, aborting! (Null: {(Object)(object)wardenUplink == (Object)null}, IsWarden: {((wardenUplink != null) ? new bool?(wardenUplink.m_isWardenObjective) : ((bool?)null))}, ObjectiveType: {((wardenUplink != null) ? new TERM_WO_Type?(wardenUplink.WardenObjectiveType) : ((TERM_WO_Type?)null))})"); } else { _wardenUplinkDefs.TryAdd(((Il2CppObjectBase)wardenUplink).Pointer, def); } return; } if (!BaseManager.Current.TryGetInstance(((GlobalBase)def).IntTuple, def.InstanceIndex, out LG_ComputerTerminal uplinkTerminal)) { EOSLogger.Error($"BuildUplink: terminal {def} does not exist!"); return; } if (uplinkTerminal.m_isWardenObjective && uplinkTerminal.UplinkPuzzle != null) { EOSLogger.Error($"BuildUplink: terminal uplink {def} already built (by vanilla or custom build), aborting!"); return; } if (def.SetupAsCorruptedUplink) { if (!BaseManager.Current.TryGetInstanceFromUplinkDef(def.CorruptedUplinkReceiver, out LG_ComputerTerminal instance)) { EOSLogger.Error($"BuildUplink: SetupAsCorruptedUplink specified but didn't find the receiver terminal! Aborting... sender was: {def}"); return; } if (((Il2CppObjectBase)instance).Pointer == ((Il2CppObjectBase)uplinkTerminal).Pointer) { EOSLogger.Error($"BuildUplink: don't specify uplink sender and receiver on the same terminal {def}"); return; } uplinkTerminal.CorruptedUplinkReceiver = instance; instance.CorruptedUplinkReceiver = uplinkTerminal; } uplinkTerminal.UplinkPuzzle = new TerminalUplinkPuzzle(); SerialGeneratorManager.SetupUplinkPuzzle(uplinkTerminal, def); TerminalUplinkPuzzle uplinkPuzzle = uplinkTerminal.UplinkPuzzle; uplinkPuzzle.OnPuzzleSolved += Action.op_Implicit((Action)delegate { EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnComplete, (eWardenObjectiveEventTrigger)0); }); uplinkTerminal.m_command.AddCommand((TERM_Command)((!def.SetupAsCorruptedUplink || (Object)(object)uplinkTerminal.CorruptedUplinkReceiver == (Object)null) ? 25 : 33), def.UseUplinkAddress ? "UPLINK_CONNECT" : "UPLINK_ESTABLISH", new LocalizedText { UntranslatedText = Text.Get(3914968919u), Id = 3914968919u }, (TERM_CommandRule)0); uplinkTerminal.m_command.AddCommand((TERM_Command)26, "UPLINK_VERIFY", new LocalizedText { UntranslatedText = Text.Get(1728022075u), Id = 1728022075u }, (TERM_CommandRule)0); if (def.UseUplinkAddress) { if (!BaseManager.Current.TryGetInstanceFromUplinkDef(def.UplinkAddressLogPosition, out LG_ComputerTerminal instance2)) { EOSLogger.Error("BuildUplinkOverride: didn't find the uplink address log terminal, will put on uplink terminal"); instance2 = uplinkTerminal; } instance2.AddLocalLog(new TerminalLogFileData { FileName = $"UPLINK_ADDR_{uplinkTerminal.m_serialNumber}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format(LocaleText.op_Implicit(UplinkAddrLogContent), uplinkTerminal.m_serialNumber, uplinkTerminal.UplinkPuzzle.TerminalUplinkIP), Id = 0u } }, true); instance2.m_command.ClearOutputQueueAndScreenBuffer(); instance2.m_command.AddInitialTerminalOutput(); } if (def.ChainedPuzzleToStartUplink != 0) { ChainedPuzzleDataBlock val = default(ChainedPuzzleDataBlock); if (!DataBlockUtil.TryGetBlock(def.ChainedPuzzleToStartUplink, ref val)) { EOSLogger.Error($"BuildTerminalUplink: ChainedPuzzleToStartUplink with id {def.ChainedPuzzleToStartUplink} is specified, but no enabled ChainedPuzzleDataBlock definition was found..."); uplinkTerminal.m_chainPuzzleForWardenObjective = null; } else { uplinkTerminal.m_chainPuzzleForWardenObjective = ChainedPuzzleManager.CreatePuzzleInstance(val, uplinkTerminal.SpawnNode.m_area, uplinkTerminal.m_wardenObjectiveSecurityScanAlign.position, uplinkTerminal.m_wardenObjectiveSecurityScanAlign); bool corrupted = def.SetupAsCorruptedUplink && (Object)(object)uplinkTerminal.CorruptedUplinkReceiver != (Object)null; uplinkTerminal.m_chainPuzzleForWardenObjective.Add_OnStateChange(delegate(pChainedPuzzleState oldState, pChainedPuzzleState newState, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (!(oldState.status == newState.status || (int)newState.status != 2 || isRecall)) { if (corrupted) { LG_ComputerTerminal corruptedUplinkReceiver = uplinkTerminal.CorruptedUplinkReceiver; if (corruptedUplinkReceiver != null) { corruptedUplinkReceiver.m_command.StartTerminalUplinkSequence(string.Empty, true); } } else { uplinkTerminal.m_command.StartTerminalUplinkSequence(uplinkTerminal.UplinkPuzzle.TerminalUplinkIP, false); } } }); } } ChainedPuzzleDataBlock val2 = default(ChainedPuzzleDataBlock); foreach (UplinkRound roundOverride in def.RoundOverrides) { if (roundOverride.ChainedPuzzleToEndRound == 0) { continue; } if (!DataBlockUtil.TryGetBlock(roundOverride.ChainedPuzzleToEndRound, ref val2)) { EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} was specified, but didn't find its enabled ChainedPuzzleDatablock definition..."); continue; } LG_ComputerTerminal val3 = null; switch (roundOverride.BuildChainedPuzzleOn) { case UplinkTerminal.SENDER: val3 = uplinkTerminal; break; case UplinkTerminal.RECEIVER: if (def.SetupAsCorruptedUplink && (Object)(object)uplinkTerminal.CorruptedUplinkReceiver != (Object)null) { val3 = uplinkTerminal.CorruptedUplinkReceiver; break; } EOSLogger.Error($"ChainedPuzzleToEndRound: {roundOverride.ChainedPuzzleToEndRound} specified to build on receiver but this is not a properly setup corr-uplink! Will build ChainedPuzzle on sender side"); val3 = uplinkTerminal; break; default: EOSLogger.Error($"Unimplemented enum UplinkTerminal type {roundOverride.BuildChainedPuzzleOn}"); continue; } roundOverride.ChainedPuzzleToEndRoundInstance = ChainedPuzzleManager.CreatePuzzleInstance(val2, val3.SpawnNode.m_area, val3.m_wardenObjectiveSecurityScanAlign.position, val3.m_wardenObjectiveSecurityScanAlign); } SetupUplinkReplicator(uplinkTerminal, def); EOSLogger.Debug($"BuildUplink: built on {def}"); } private void SetupUplinkReplicator(LG_ComputerTerminal uplinkTerminal, UplinkDefinition def) { uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("BuildUplink: replicator IDs depleted, cannot setup StateReplicator"); return; } StateReplicator val = StateReplicator.Create(num, new UplinkState { status = UplinkStatus.Unfinished }, (LifeTimeType)1, (IStateReplicatorHolder)null); val.OnStateChanged += delegate(UplinkState oldState, UplinkState state, bool isRecall) { if (oldState.status != state.status) { EOSLogger.Debug($"Uplink Terminal_{uplinkTerminal.m_serialNumber} - OnStateChanged: {oldState.status} -> {state.status}"); switch (state.status) { case UplinkStatus.Unfinished: uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = false; uplinkTerminal.UplinkPuzzle.Connected = false; uplinkTerminal.UplinkPuzzle.Solved = false; uplinkTerminal.UplinkPuzzle.m_roundIndex = 0; if (isRecall) { SerialGeneratorManager.RerollCorrectIndex(uplinkTerminal.UplinkPuzzle, CheckpointManager.CheckpointUsage - oldState.retryCount); def.ResetFirstRoundOutput(); } break; case UplinkStatus.InProgress: uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = true; uplinkTerminal.UplinkPuzzle.Connected = true; uplinkTerminal.UplinkPuzzle.Solved = false; uplinkTerminal.UplinkPuzzle.m_roundIndex = state.currentRoundIndex; break; case UplinkStatus.Finished: uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = false; uplinkTerminal.UplinkPuzzle.Connected = true; uplinkTerminal.UplinkPuzzle.Solved = true; uplinkTerminal.UplinkPuzzle.m_roundIndex = uplinkTerminal.UplinkPuzzle.m_rounds.Count - 1; break; } } }; _stateReplicators[((Il2CppObjectBase)uplinkTerminal).Pointer] = val; } internal void ChangeState(LG_ComputerTerminal terminal, UplinkState newState) { if (!_stateReplicators.TryGetValue(((Il2CppObjectBase)terminal).Pointer, out StateReplicator value)) { EOSLogger.Error(terminal.ItemKey + " doesn't have a registered StateReplicator!"); } else if (SNet.IsMaster && value != null) { StateReplicator obj = value; UplinkState state = newState; state.retryCount = CheckpointManager.CheckpointUsage; obj.SetState(state); } } } public enum UplinkStatus { Unfinished, InProgress, Finished } public struct UplinkState { public UplinkStatus status { get; set; } public int currentRoundIndex { get; set; } public int retryCount { get; set; } public UplinkState() { status = UplinkStatus.Unfinished; currentRoundIndex = 0; retryCount = 0; } public UplinkState(UplinkState o) { status = UplinkStatus.Unfinished; currentRoundIndex = 0; retryCount = 0; status = o.status; currentRoundIndex = o.currentRoundIndex; retryCount = o.retryCount; } } } namespace EOS.Modules.Objectives.Reactor { public class BaseReactorDefinition : BaseInstanceDefinition { [JsonPropertyOrder(-8)] public TerminalDefinition ReactorTerminal { get; set; } = new TerminalDefinition(); [JsonPropertyOrder(-7)] public List EventsOnActive { get; set; } = new List(); [JsonPropertyOrder(-1)] public SerialGeneratorManager.CodeWordLength CodeWordLength { get; set; } = SerialGeneratorManager.CodeWordLength.Four; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleToActiveInstance { get; set; } = null; } public class OverrideReactorComp : MonoBehaviour { private readonly List _waveData = new List(); public LG_WardenObjective_Reactor ChainedReactor { get; internal set; } = null; [HideFromIl2Cpp] public ReactorStartupOverride OverrideData { get; internal set; } = null; public WardenObjectiveDataBlock ObjectiveData => OverrideData?.ObjectiveDB; private (int, int, int) OrigVerifyZone(eLocalZoneIndex zoneForVerification) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) return GlobalIndexUtil.ToIntTuple(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, zoneForVerification); } [HideFromIl2Cpp] public void Init(LG_WardenObjective_Reactor reactor, ReactorStartupOverride def) { ChainedReactor = reactor; OverrideData = def; for (int i = 0; i < OverrideData.Overrides.Count; i++) { WaveOverride waveOverride = OverrideData.Overrides[i]; WaveOverride waveOverride2 = ((i - 1 >= 0) ? OverrideData.Overrides[i - 1] : null); if (waveOverride2 != null && waveOverride.WaveIndex == waveOverride2.WaveIndex) { EOSLogger.Error($"Found duplicate wave index {waveOverride.WaveIndex}, this could lead to reactor override exception!"); continue; } for (int j = ((waveOverride2 != null) ? (waveOverride2.WaveIndex + 1) : 0); j < waveOverride.WaveIndex; j++) { _waveData.Add(new WaveOverride { WaveIndex = j }); } _waveData.Add(waveOverride); } _waveData.ForEach(delegate(WaveOverride w) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) w.CustomVerifyText = w.VerifySequenceText.ParseTextFragments(); }); LevelAPI.OnEnterLevel += OnEnterLevel; } private void OnEnterLevel() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if ((int)ObjectiveData.Type != 1) { EOSLogger.Error("Only reactor startup is supported"); ((Behaviour)this).enabled = false; return; } if (OverrideData.StartupOnDrop && SNet.IsMaster) { ChainedReactor.AttemptInteract((eReactorInteraction)0, 0f); ChainedReactor.m_terminal.TrySyncSetCommandHidden((TERM_Command)21); } SetupVerifyZoneOverrides(); SetupWaves(); SetupCodeWords(); } private void SetupVerifyZoneOverrides() { //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Expected O, but got Unknown //IL_035b: Expected O, but got Unknown foreach (WaveOverride waveDatum in _waveData) { if (!waveDatum.ChangeVerifyZone) { continue; } if (waveDatum.VerificationType == EOSReactorVerificationType.BY_WARDEN_EVENT) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Verification Type is {2}, which doesn't work with VerifyZoneOverride"); continue; } BaseInstanceDefinition verifyZone = waveDatum.VerifyZone; LG_Zone zone = ((GlobalBase)verifyZone).Zone; if ((Object)(object)zone == (Object)null) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find target zone {verifyZone}."); continue; } if (zone.TerminalsSpawnedInZone == null || zone.TerminalsSpawnedInZone.Count == 0) { EOSLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {verifyZone}."); continue; } LG_ComputerTerminal val; if (verifyZone.InstanceIndex >= 0) { val = BaseManager.Current.GetInstance(((GlobalBase)verifyZone).IntTuple, verifyZone.InstanceIndex); if ((Object)(object)val == (Object)null) { EOSLogger.Error($"VerifyZoneOverride: cannot find target terminal with Terminal Instance Index: {waveDatum}"); continue; } } else { if (!BaseManager.Current.TryGetInstancesInZone(((GlobalBase)verifyZone).IntTuple, out IReadOnlyList instances)) { continue; } int index = Builder.SessionSeedRandom.Range(0, instances.Count, "NO_TAG"); val = instances[index]; } waveDatum.VerifyTerminal = val; if (waveDatum.WaveIndex >= ObjectiveData.ReactorWaves.Count) { continue; } ReactorWaveData val2 = ObjectiveData.ReactorWaves[waveDatum.WaveIndex]; TerminalLogFileData val3; if (val2.VerifyInOtherZone) { if (!TryGetVerifyTerminal(val2, waveDatum, out LG_ComputerTerminal verifyTerminal)) { continue; } string text = val2.VerificationTerminalFileName.ToUpperInvariant(); val3 = verifyTerminal.GetLocalLog(text); if (val3 == null) { EOSLogger.Error("VerifyZoneOverrides: Cannot find vanilla-generated reactor verify log on terminal..."); continue; } verifyTerminal.RemoveLocalLog(text); verifyTerminal.ResetInitialOutput(); } else { val2.VerificationTerminalFileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log"; val3 = new TerminalLogFileData { FileName = val2.VerificationTerminalFileName.ToUpperInvariant(), FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpper()), Id = 0u } }; EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Log generated."); } val2.HasVerificationTerminal = true; val2.VerificationTerminalSerial = val.ItemKey; val.AddLocalLog(val3, true); val.ResetInitialOutput(); EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} verification overriden"); } } private void SetupWaves() { int num = 0; for (int i = 0; i < _waveData.Count; i++) { ReactorWaveData val = ObjectiveData.ReactorWaves[i]; WaveOverride waveOverride = _waveData[i]; switch (waveOverride.VerificationType) { case EOSReactorVerificationType.BY_SPECIAL_COMMAND: if (!val.HasVerificationTerminal) { waveOverride.VerifyTerminal = ChainedReactor.m_terminal; AddVerifyCommand(ChainedReactor.m_terminal); } else { if (!TryGetVerifyTerminal(val, waveOverride, out LG_ComputerTerminal verifyTerminal)) { break; } verifyTerminal.ConnectedReactor = ChainedReactor; verifyTerminal.RemoveLocalLog(val.VerificationTerminalFileName.ToUpperInvariant()); AddVerifyCommand(verifyTerminal); verifyTerminal.ResetInitialOutput(); waveOverride.VerifyTerminal = verifyTerminal; } num++; EOSLogger.Debug($"WaveOverride: Setup as Wave Verification {1} for Wave_{i}"); break; case EOSReactorVerificationType.BY_WARDEN_EVENT: EOSLogger.Debug($"WaveOverride: Setup as Wave Verification {2} for Wave_{i}"); break; default: EOSLogger.Error($"Unimplemented Verification Type {waveOverride.VerificationType}"); break; case EOSReactorVerificationType.NORMAL: break; } } if (num == ObjectiveData.ReactorWaves.Count) { ChainedReactor.m_terminal.TrySyncSetCommandHidden((TERM_Command)22); } } private void SetupCodeWords() { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_014d: Expected O, but got Unknown bool flag = OverrideData.CodeWordLength != SerialGeneratorManager.CodeWordLength.Four; bool useHardLogFilenameSuffix = OverrideData.UseHardLogFilenameSuffix; string[] array = new string[ObjectiveData.ReactorWaves.Count]; for (int i = 0; i < array.Length; i++) { ReactorWaveData val = ObjectiveData.ReactorWaves[i]; WaveOverride waveOverride = _waveData.ElementAtOrDefault(i); if (flag) { array[i] = SerialGeneratorManager.GetCodeWord(OverrideData.CodeWordLength); } else { array[i] = ((Il2CppArrayBase)(object)ChainedReactor.m_overrideCodes)[i]; } if ((flag || useHardLogFilenameSuffix) && val.HasVerificationTerminal && TryGetVerifyTerminal(val, waveOverride, out LG_ComputerTerminal verifyTerminal)) { string text = val.VerificationTerminalFileName.ToUpperInvariant(); verifyTerminal.RemoveLocalLog(text); verifyTerminal.ResetInitialOutput(); val.VerificationTerminalFileName = "reactor_ver" + SerialGeneratorManager.GetCodeWordPrefix(OverrideData.UseHardLogFilenameSuffix) + ".log"; TerminalLogFileData val2 = new TerminalLogFileData { FileName = val.VerificationTerminalFileName.ToUpperInvariant(), FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), array[i].ToUpper()), Id = 0u } }; verifyTerminal.AddLocalLog(val2, true); verifyTerminal.ResetInitialOutput(); } } ChainedReactor.m_overrideCodes = Il2CppStringArray.op_Implicit(array); } [HideFromIl2Cpp] private bool TryGetVerifyTerminal(ReactorWaveData waveData, WaveOverride? waveOverride, [NotNullWhen(true)] out LG_ComputerTerminal? verifyTerminal) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) int value = ObjectiveData.ReactorWaves.IndexOf(waveData); verifyTerminal = waveOverride?.VerifyTerminal; if ((Object)(object)verifyTerminal == (Object)null) { List list = EOSTerminalUtil.FindTerminals(OrigVerifyZone(waveData.ZoneForVerification), (LG_ComputerTerminal terminal) => terminal.ItemKey.Equals(waveData.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)); if (list == null || list.Count == 0) { EOSLogger.Error($"TryGetVerifyTerminal: cannot find verify terminal for Wave_{value}, skipped"); return false; } LG_ComputerTerminal val = list[0]; if ((Object)(object)val == (Object)null) { EOSLogger.Error($"TryGetVerifyTerminal: Wave_{value} - Cannot find log terminal"); return false; } verifyTerminal = val; } return true; } private static void AddVerifyCommand(LG_ComputerTerminal terminal) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) LG_ComputerTerminalCommandInterpreter command = terminal.m_command; if (command.HasRegisteredCommand((TERM_Command)42)) { EOSLogger.Warning("TERM_Command.UniqueCommand5 already registered..."); EOSLogger.Debug("...If this terminal is specified as objective terminal for 2 waves and the number of commands in 'UniqueCommands' on this terminal isn't more than 4, simply ignore this message."); } else { command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", LocaleText.op_Implicit(ReactorStartupOverrideManager.CooldownCommandDesc), (TERM_CommandRule)0); terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0); } } public bool IsCorrectTerminal(LG_ComputerTerminal terminal) { int num = ChainedReactor.m_currentWaveCount - 1; if (num >= 0) { EOSLogger.Debug($"Index: {num}"); EOSLogger.Debug("Comp Terminal Key1: " + terminal.ItemKey); EOSLogger.Debug("Comp Terminal Key2: " + (((Object)(object)_waveData[num].VerifyTerminal != (Object)null) ? _waveData[num].VerifyTerminal.ItemKey : "empty")); if (_waveData[num].VerifyTerminal.ItemKey != null && _waveData[num].VerifyTerminal.ItemKey.Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase)) { return true; } } return false; } public void SetIdle() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ChainedReactor == (Object)null)) { pReactorState state = new pReactorState { status = (eReactorStatus)0, stateCount = 0, stateProgress = 0f, verifyFailed = false }; ChainedReactor.m_stateReplicator.State = state; } } public void OnDestroy() { LevelAPI.OnEnterLevel -= OnEnterLevel; ChainedReactor = null; OverrideData = null; } public void LateUpdate() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0025: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName == 10) { eReactorStatus status = ChainedReactor.m_currentState.status; UpdateGUIText(status); } } private void UpdateGUIText(eReactorStatus status) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) int num = ChainedReactor.m_currentWaveCount - 1; if (num < 0 || num >= _waveData.Count) { return; } WaveOverride waveOverride = _waveData[num]; string format = string.Empty; if (waveOverride.UseCustomVerifyText) { format = waveOverride.CustomVerifyText; } if ((int)status != 4) { return; } switch (waveOverride.VerificationType) { case EOSReactorVerificationType.NORMAL: if (ChainedReactor.m_currentWaveData.HasVerificationTerminal) { if (!waveOverride.UseCustomVerifyText) { format = Text.Get(1103u); } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + ""), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "" + Text.Get(1104u), ""); } else { if (!waveOverride.UseCustomVerifyText) { format = Text.Get(1105u); } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "" + ChainedReactor.CurrentStateOverrideCode + ""), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "" + Text.Get(1104u), ""); } break; case EOSReactorVerificationType.BY_SPECIAL_COMMAND: { string text = (ChainedReactor.m_currentWaveData.HasVerificationTerminal ? ChainedReactor.m_currentWaveData.VerificationTerminalSerial : LocaleText.op_Implicit(ReactorStartupOverrideManager.MainTerminalText)); if (!waveOverride.UseCustomVerifyText) { format = LocaleText.op_Implicit(ReactorStartupOverrideManager.SpecialCmdVerifyText); } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "" + text + ""), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "" + Text.Get(1104u), ""); break; } case EOSReactorVerificationType.BY_WARDEN_EVENT: if (!waveOverride.UseCustomVerifyText) { format = LocaleText.op_Implicit(ReactorStartupOverrideManager.InfiniteWaveVerifyText); } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "" + Text.Get(1104u), ""); break; } } } public class ReactorShutdownDefinition : BaseReactorDefinition { [JsonPropertyOrder(-7)] public uint ChainedPuzzleToActive { get; set; } = 0u; [JsonPropertyOrder(-6)] public bool PutVerificationCodeOnTerminal { get; set; } = false; [JsonPropertyOrder(-5)] public BaseInstanceDefinition VerificationCodeTerminal { get; set; } = new BaseInstanceDefinition(); [JsonPropertyOrder(0)] public uint ChainedPuzzleOnVerification { get; set; } = 0u; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleOnVerificationInstance { get; set; } = null; [JsonPropertyOrder(1)] public List EventsOnShutdownPuzzleStarts { get; set; } = new List(); [JsonPropertyOrder(2)] public List EventsOnComplete { get; set; } = new List(); } public sealed class ReactorShutdownObjectiveManager : InstanceDefinitionManager { protected override string DEFINITION_NAME => "ReactorShutdown"; public override uint ChainedPuzzleLoadOrder => 4u; public bool TryGetDefinition(LG_WardenObjective_Reactor reactor, [MaybeNullWhen(false)] out ReactorShutdownDefinition definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(reactor); return TryGetDefinition(globalIndex, instanceIndex, out definition); } internal static void Build(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01a5: Expected O, but got Unknown if (reactor.m_isWardenObjective) { EOSLogger.Error($"ReactorShutdown: Reactor definition for reactor {def} is already setup by vanilla, won't build."); return; } GenericObjectiveSetup(reactor, def); reactor.m_lightCollection = LG_LightCollection.Create(reactor.m_reactorArea.m_courseNode, reactor.m_terminalAlign.position, (LG_LightCollectionSorting)1, float.MaxValue); reactor.m_lightCollection.SetMode(true); if (def.PutVerificationCodeOnTerminal) { LG_ComputerTerminal instance = BaseManager.Current.GetInstance(((GlobalBase)def.VerificationCodeTerminal).IntTuple, def.VerificationCodeTerminal.InstanceIndex); if ((Object)(object)instance == (Object)null) { EOSLogger.Error($"ReactorShutdown: PutVerificationCodeOnTerminal is specified but could NOT find terminal {def.VerificationCodeTerminal}, will show verification code upon shutdown initiation"); } else { string fileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log"; TerminalLogFileData val = new TerminalLogFileData { FileName = fileName, FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase)(object)reactor.m_overrideCodes)[0].ToUpperInvariant()), Id = 0u } }; instance.AddLocalLog(val, true); instance.m_command.ClearOutputQueueAndScreenBuffer(); instance.m_command.AddInitialTerminalOutput(); } } if (reactor.SpawnNode != null && reactor.m_terminalItem != null) { reactor.m_terminalItem.SpawnNode = reactor.SpawnNode; reactor.m_terminalItem.FloorItemLocation = reactor.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7); } if (BuildChainedPuzzle(def.ChainedPuzzleToActive, (eReactorInteraction)6, out var cp)) { def.ChainedPuzzleToActiveInstance = cp; } else { EOSLogger.Debug("ReactorShutdown: Reactor has no ChainedPuzzleToActive, will start shutdown sequence on shutdown command initiation."); } if (BuildChainedPuzzle(def.ChainedPuzzleOnVerification, (eReactorInteraction)9, out var cp2)) { def.ChainedPuzzleOnVerificationInstance = cp2; } else { EOSLogger.Debug("ReactorShutdown: ChainedPuzzleOnVerification unspecified, will complete shutdown on verification."); } LG_ComputerTerminal terminal = reactor.m_terminal; iLG_SpawnedInNodeHandler val2 = default(iLG_SpawnedInNodeHandler); if (terminal != null && GameObjectPlusExtensions.TryAndGetComponent(((Component)terminal).gameObject, ref val2)) { val2.SpawnNode = reactor.SpawnNode; } reactor.SetLightsEnabled(reactor.m_lightsWhenOff, false); reactor.SetLightsEnabled(reactor.m_lightsWhenOn, true); BaseManager.Current.MarkAsShutdownReactor(reactor); EOSLogger.Debug($"ReactorShutdown: {def}, custom setup completed"); bool BuildChainedPuzzle(uint id, eReactorInteraction state, [NotNullWhen(true)] out ChainedPuzzleInstance? reference) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) ChainedPuzzleDataBlock val3 = default(ChainedPuzzleDataBlock); if (!DataBlockUtil.TryGetBlock(id, ref val3)) { EOSLogger.Error($"ReactorShutdown: {id} is specified but could not find its ChainedPuzzleDatablock definition!"); reference = null; return false; } ChainedPuzzleDataBlock obj = val3; AIG_CourseNode spawnNode = reactor.SpawnNode; reference = ChainedPuzzleManager.CreatePuzzleInstance(obj, (spawnNode != null) ? spawnNode.m_area : null, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform); ChainedPuzzleInstance? obj2 = reference; obj2.OnPuzzleSolved += Action.op_Implicit((Action)delegate { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster) { reactor.AttemptInteract(state, 0f); } }); return (Object)(object)reference != (Object)null; } } private static void GenericObjectiveSetup(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) reactor.m_stateReplicator = SNet_StateReplicator.Create(new iSNet_StateReplicatorProvider(((Il2CppObjectBase)reactor).Pointer), (eSNetReplicatorLifeTime)1, default(pReactorState), (SNet_ChannelType)2); reactor.m_serialNumber = SerialGeneratorManager.GetUniqueSerialNo(); reactor.m_itemKey = "REACTOR_" + reactor.m_serialNumber; reactor.m_terminalItem = GOUtil.GetInterfaceFromComp(reactor.m_terminalItemComp); reactor.m_terminalItem.Setup(reactor.m_itemKey, (AIG_CourseNode)null); reactor.m_terminalItem.FloorItemStatus = EnumUtil.GetRandomValue(); reactor.m_overrideCodes = Il2CppStringArray.op_Implicit(new string[1] { SerialGeneratorManager.GetCodeWord(def.CodeWordLength) }); reactor.m_terminal = GOUtil.SpawnChildAndGetComp(reactor.m_terminalPrefab, reactor.m_terminalAlign); reactor.m_terminal.Setup((TerminalStartStateData)null, (TerminalPlacementData)null); reactor.m_terminal.ConnectedReactor = reactor; ReactorInstanceManager.SetupReactorTerminal(reactor, def.ReactorTerminal); reactor.m_sound = new CellSoundPlayer(reactor.m_terminalAlign.position); reactor.m_sound.Post(EVENTS.REACTOR_POWER_LEVEL_1_LOOP, true); reactor.m_sound.SetRTPCValue(GAME_PARAMETERS.REACTOR_POWER, 100f); reactor.m_terminal.m_command.SetupReactorCommands(false, true); } } public enum EOSReactorVerificationType { NORMAL, BY_SPECIAL_COMMAND, BY_WARDEN_EVENT } public class ReactorStartupOverride : BaseReactorDefinition { [JsonPropertyOrder(-6)] public bool StartupOnDrop { get; set; } = false; [JsonPropertyOrder(-5)] public bool UseHardLogFilenameSuffix { get; set; } = false; [JsonIgnore] public WardenObjectiveDataBlock ObjectiveDB { get; set; } = null; [JsonPropertyOrder(0)] public List Overrides { get; set; } = new List { new WaveOverride() }; } public class WaveOverride { public int WaveIndex { get; set; } = -1; public EOSReactorVerificationType VerificationType { get; set; } = EOSReactorVerificationType.NORMAL; public bool HideVerificationTimer { get; set; } = false; public bool ChangeVerifyZone { get; set; } = false; public BaseInstanceDefinition VerifyZone { get; set; } = new BaseInstanceDefinition(); public bool UseCustomVerifyText { get; set; } = false; public LocaleText VerifySequenceText { get; set; } = LocaleText.Empty; [JsonIgnore] public string CustomVerifyText { get; set; } = string.Empty; [JsonIgnore] public LG_ComputerTerminal VerifyTerminal { get; set; } = null; } public sealed class ReactorStartupOverrideManager : InstanceDefinitionManager { public enum ReactorEventType { ReactorStartup = 150, CompleteCurrentVerify } protected override string DEFINITION_NAME => "ReactorStartup"; public override uint ChainedPuzzleLoadOrder => 5u; public static LocaleText MainTerminalText { get; private set; } public static LocaleText SpecialCmdVerifyText { get; private set; } public static LocaleText CooldownCommandDesc { get; private set; } public static LocaleText InfiniteWaveVerifyText { get; private set; } public static LocaleText NotReadyForVerificationOutputText { get; private set; } public static LocaleText IncorrectTerminalOutputText { get; private set; } public static LocaleText CorrectTerminalOutputText { get; private set; } static ReactorStartupOverrideManager() { //IL_0000: 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) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0028: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) MainTerminalText = LocaleText.Empty; SpecialCmdVerifyText = LocaleText.Empty; CooldownCommandDesc = LocaleText.Empty; InfiniteWaveVerifyText = LocaleText.Empty; NotReadyForVerificationOutputText = LocaleText.Empty; IncorrectTerminalOutputText = LocaleText.Empty; CorrectTerminalOutputText = LocaleText.Empty; EOSWardenEventManager.AddEventDefinition(ReactorEventType.ReactorStartup.ToString(), 150u, ReactorStartup); EOSWardenEventManager.AddEventDefinition(ReactorEventType.CompleteCurrentVerify.ToString(), 151u, CompleteCurrentVerify); } protected override void AddDefinitions(InstanceDefinitionsForLevel definitions) { definitions.Definitions.ForEach(delegate(ReactorStartupOverride def) { def.Overrides.Sort((WaveOverride o1, WaveOverride o2) => o1.WaveIndex.CompareTo(o2.WaveIndex)); }); base.AddDefinitions(definitions); } public bool TryGetDefinition(LG_WardenObjective_Reactor reactor, [MaybeNullWhen(false)] out ReactorStartupOverride definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(reactor); return TryGetDefinition(globalIndex, instanceIndex, out definition); } protected override void OnEnterLevel() { //IL_0003: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) MainTerminalText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName"), RawText = "Main Terminal" }; SpecialCmdVerifyText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification"), RawText = "\"REACTOR COOLING REQUIRED ({0}/{1})\\nMANUAL OVERRIDE REQUIRED. USE COMMAND REACTOR_COOLDOWN AT {2}" }; CooldownCommandDesc = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc"), RawText = "Confirm Reactor Startup Cooling Protocol" }; InfiniteWaveVerifyText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave"), RawText = "VERIFICATION ({0}/{1})." }; NotReadyForVerificationOutputText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output"), RawText = "Reactor intensive test in progress, cannot initate cooldown" }; IncorrectTerminalOutputText = new LocaleText { ID = GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output"), RawText = "Reactor stage cooldown completed" }; CorrectTerminalOutputText = new LocaleText(GameDataBlockBase.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output")); } internal static void Build(LG_WardenObjective_Reactor reactor, ReactorStartupOverride def) { ((Component)reactor).gameObject.AddComponent().Init(reactor, def); BaseManager.Current.MarkAsStartupReactor(reactor); ReactorInstanceManager.SetupReactorTerminal(reactor, def.ReactorTerminal); def.ChainedPuzzleToActiveInstance = reactor.m_chainedPuzzleToStartSequence; EOSLogger.Debug($"ReactorStartup: {def}, override completed"); } private static void ReactorStartup(WardenObjectiveEventData e) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_009a: 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) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Invalid comparison between Unknown and I4 //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val) || val == null) { EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock"); return; } if ((int)val.Type != 1) { EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid."); return; } LG_WardenObjective_Reactor val2 = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count); if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"ReactorStartup: Cannot find reactor in {e.Layer}."); } else if ((int)val2.m_currentState.status == 0) { val2.AttemptInteract((eReactorInteraction)0, 0f); val2.m_terminal.TrySyncSetCommandHidden((TERM_Command)21); EOSLogger.Debug($"ReactorStartup: Current reactor wave for {e.Layer} completed"); } } private static void CompleteCurrentVerify(WardenObjectiveEventData e) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val) || val == null) { EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock"); return; } if ((int)val.Type != 1) { EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid."); return; } LG_WardenObjective_Reactor val2 = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count); if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"CompleteCurrentReactorWave: Cannot find reactor in {e.Layer}."); return; } if (SNet.IsMaster) { if (val2.m_currentWaveCount == val2.m_waveCountMax) { val2.AttemptInteract((eReactorInteraction)5, 0f); } else { val2.AttemptInteract((eReactorInteraction)3, 0f); } } else { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(val2.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray)null); } EOSLogger.Debug($"CompleteCurrentReactorWave: Current reactor verify for {e.Layer} completed"); } } } namespace EOS.Modules.Objectives.ObjectiveCounter { public struct CounterStatus { public int count; } public class Counter { private readonly HashSet _executedOnce = new HashSet(); public ObjectiveCounterDefinition Def { get; private set; } public int CurrentCount { get; private set; } = 0; public StateReplicator? Replicator { get; private set; } public Counter(ObjectiveCounterDefinition def) { Def = def; CurrentCount = def.StartingCount; uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("Counter: replicator IDs depleted, cannot setup StateReplicator"); return; } Replicator = StateReplicator.Create(num, new CounterStatus { count = Def.StartingCount }, (LifeTimeType)1, (IStateReplicatorHolder)null); Replicator.OnStateChanged += OnStateChanged; } private void OnStateChanged(CounterStatus _, CounterStatus state, bool isRecall) { if (state.count != CurrentCount) { CurrentCount = state.count; } } private void ReachTo(int count) { EOSLogger.Debug($"Counter '{Def.WorldEventObjectFilter}' reached {count}"); IEnumerable enumerable = Def.OnReached.Where((OnCounter c) => c.Count == count); foreach (OnCounter item in enumerable) { if (!item.ExecuteOnce || !_executedOnce.Contains(item)) { EOSWardenEventManager.ExecuteWardenEvents(item.EventsOnReached, (eWardenObjectiveEventTrigger)0); if (item.ExecuteOnce) { _executedOnce.Add(item); } } } } public void Increment(int by) { int currentCount = CurrentCount; CurrentCount = Math.Min(CurrentCount + by, Def.MaxCount); for (int i = currentCount + 1; i <= CurrentCount; i++) { ReachTo(i); } Replicator?.SetStateUnsynced(new CounterStatus { count = CurrentCount }); } public void Decrement(int by) { int currentCount = CurrentCount; CurrentCount = Math.Max(CurrentCount - by, Def.MinCount); for (int num = currentCount - 1; num >= CurrentCount; num--) { ReachTo(num); } Replicator?.SetStateUnsynced(new CounterStatus { count = CurrentCount }); } public void Set(int num) { CurrentCount = Math.Clamp(num, Def.MinCount, Def.MaxCount); ReachTo(CurrentCount); Replicator?.SetStateUnsynced(new CounterStatus { count = CurrentCount }); } public void Jump(int num) { CurrentCount = Math.Clamp(CurrentCount + num, Def.MinCount, Def.MaxCount); ReachTo(CurrentCount); Replicator?.SetStateUnsynced(new CounterStatus { count = CurrentCount }); } } public class OnCounter { public int Count { get; set; } = -1; public bool ExecuteOnce { get; set; } = false; public List EventsOnReached { get; set; } = new List(); } public class ObjectiveCounterDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public int StartingCount { get; set; } = 0; public int MinCount { get; set; } = int.MinValue; public int MaxCount { get; set; } = int.MaxValue; public List OnReached { get; set; } = new List { new OnCounter() }; } public sealed class ObjectiveCounterManager : GenericExpeditionDefinitionManager { public enum CounterWardenEvent { ChangeCounter = 500, SetCounter, JumpCounter } private readonly Dictionary _counters = new Dictionary(); protected override string DEFINITION_NAME => "ObjectiveCounter"; public IReadOnlyDictionary Counters => _counters; static ObjectiveCounterManager() { EOSWardenEventManager.AddEventDefinition(CounterWardenEvent.ChangeCounter.ToString(), 500u, ChangeCounter); EOSWardenEventManager.AddEventDefinition(CounterWardenEvent.SetCounter.ToString(), 501u, SetCounter); EOSWardenEventManager.AddEventDefinition(CounterWardenEvent.JumpCounter.ToString(), 502u, JumpCounter); } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnBuildDone() { if (base.GenericExpDefinitions.ContainsKey(BaseManager.CurrentMainLevelLayout)) { base.GenericExpDefinitions[BaseManager.CurrentMainLevelLayout].Definitions.ForEach(Build); } } protected override void OnLevelCleanup() { CollectionExtensions.ForEachValue((IDictionary)_counters, (Action)delegate(Counter c) { c.Replicator?.Unload(); }); _counters.Clear(); } private void Build(ObjectiveCounterDefinition def) { if (_counters.ContainsKey(def.WorldEventObjectFilter)) { EOSLogger.Error("Build Counter: counter '" + def.WorldEventObjectFilter + "' already exists..."); return; } Counter value = new Counter(def); _counters[def.WorldEventObjectFilter] = value; EOSLogger.Debug("Build Counter: counter '" + def.WorldEventObjectFilter + "' setup completed"); } private static void ChangeCounter(WardenObjectiveEventData e) { if (!BaseManager.Current._counters.TryGetValue(e.WorldEventObjectFilter, out Counter value)) { EOSLogger.Error("ChangeCounter: " + e.WorldEventObjectFilter + " is not defined"); return; } int count = e.Count; if (count > 0) { value.Increment(count); } else if (count < 0) { value.Decrement(Math.Abs(count)); } } private static void SetCounter(WardenObjectiveEventData e) { if (!BaseManager.Current._counters.TryGetValue(e.WorldEventObjectFilter, out Counter value)) { EOSLogger.Error("ChangeCounter: " + e.WorldEventObjectFilter + " is not defined"); } else { value.Set(e.Count); } } private static void JumpCounter(WardenObjectiveEventData e) { if (!BaseManager.Current._counters.TryGetValue(e.WorldEventObjectFilter, out Counter value)) { EOSLogger.Error("ChangeCounter: " + e.WorldEventObjectFilter + " is not defined"); } else { value.Jump(e.Count); } } } } namespace EOS.Modules.Objectives.IndividualGenerator { public sealed class IndividualGeneratorObjectiveManager : InstanceDefinitionManager { protected override string DEFINITION_NAME { get; } = "IndividualGenerator"; public override uint ChainedPuzzleLoadOrder => 0u; public bool TryGetDefinition(LG_PowerGenerator_Core instance, [MaybeNullWhen(false)] out IndividualGeneratorDefinition definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(instance); return TryGetDefinition(globalIndex, instanceIndex, out definition); } public void Setup(LG_PowerGenerator_Core gen) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_002e: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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) if (!TryGetDefinition(gen, out IndividualGeneratorDefinition definition)) { return; } Vector3 val = definition.Position; Quaternion val2 = definition.Rotation; if (val != Vector3.zero) { gen.m_sound.UpdatePosition(val); LG_MarkerProducer componentInParent = ((Component)gen).GetComponentInParent(); if ((!definition.RepositionCover && !definition.HideCover) || (Object)(object)componentInParent == (Object)null) { ((Component)gen).transform.SetPositionAndRotation(val, val2); } else { Transform val3 = ((Component)componentInParent).transform; while (val3.childCount == 1 && (Object)(object)((Component)val3.GetChild(0)).GetComponent() == (Object)null) { val3 = val3.GetChild(0); } for (int i = 0; i < val3.childCount; i++) { Transform child = val3.GetChild(i); LG_PowerGenerator_Core componentInChildren = ((Component)child).GetComponentInChildren(true); if (definition.HideCover && (Object)(object)componentInChildren == (Object)null) { ((Component)child).gameObject.SetActive(false); } else { child.SetPositionAndRotation(val, val2); } } } } gen.SetCanTakePowerCell(definition.ForceAllowPowerCellInsertion); EOSLogger.Debug($"{DEFINITION_NAME}: overriden, instance {definition}"); } } public class IndividualGeneratorDefinition : BaseInstanceDefinition { public bool ForceAllowPowerCellInsertion { get; set; } = false; public List EventsOnInsertCell { get; set; } = new List(); public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); public bool RepositionCover { get; set; } = false; public bool HideCover { get; set; } = false; } } namespace EOS.Modules.Objectives.GeneratorCluster { public class GeneratorClusterDefinition : BaseInstanceDefinition { public uint NumberOfGenerators { get; set; } = 0u; public List> EventsOnInsertCell { get; set; } = new List> { new List() }; public uint EndSequenceChainedPuzzle { get; set; } = 0u; public List EventsOnEndSequenceChainedPuzzleComplete { get; set; } = new List(); } public sealed class GeneratorClusterObjectiveManager : InstanceDefinitionManager { private readonly List<(LG_PowerGeneratorCluster, GeneratorClusterDefinition)> _chainedPuzzleToBuild = new List<(LG_PowerGeneratorCluster, GeneratorClusterDefinition)>(); protected override string DEFINITION_NAME { get; } = "GeneratorCluster"; public override uint ChainedPuzzleLoadOrder => 1u; protected override void AddDefinitions(InstanceDefinitionsForLevel definitions) { Sort(definitions); base.AddDefinitions(definitions); } public bool TryGetDefinition(LG_PowerGeneratorCluster instance, [MaybeNullWhen(false)] out GeneratorClusterDefinition definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(instance); return TryGetDefinition(globalIndex, instanceIndex, out definition); } internal void RegisterForChainedPuzzleBuild(LG_PowerGeneratorCluster instance, GeneratorClusterDefinition GeneratorClusterConfig) { _chainedPuzzleToBuild.Add((instance, GeneratorClusterConfig)); } protected override void OnBuildDone() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) ChainedPuzzleDataBlock val2 = default(ChainedPuzzleDataBlock); foreach (var item in _chainedPuzzleToBuild) { var (val, config) = item; if (!DataBlockUtil.TryGetBlock(config.EndSequenceChainedPuzzle, ref val2)) { continue; } EOSLogger.Debug($"GeneratorCluster: Building EndSequenceChainedPuzzle for LG_PowerGeneratorCluster in {GlobalIndexUtil.ToStruct(val.SpawnNode.m_zone)}"); val.m_chainedPuzzleMidObjective = ChainedPuzzleManager.CreatePuzzleInstance(val2, val.SpawnNode.m_area, val.m_chainedPuzzleAlignMidObjective.position, val.m_chainedPuzzleAlignMidObjective); val.m_chainedPuzzleMidObjective.Add_OnStateChange(delegate(pChainedPuzzleState _, pChainedPuzzleState newState, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)newState.status == 2 && !isRecall) { EOSWardenEventManager.ExecuteWardenEvents(config.EventsOnEndSequenceChainedPuzzleComplete, (eWardenObjectiveEventTrigger)0); } }); } } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { _chainedPuzzleToBuild.Clear(); } } } namespace EOS.Modules.Objectives.ActivateSmallHSU { public class HSUActivatorDefinition : BaseInstanceDefinition { public List EventsOnHSUActivation { get; set; } = new List(); public uint ItemFromStart { get; set; } = 0u; public uint ItemAfterActivation { get; set; } = 0u; public bool RequireItemAfterActivationInExitScan { get; set; } = false; public bool TakeOutItemAfterActivation { get; set; } = true; public uint ChainedPuzzleOnActivation { get; set; } = 0u; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleOnActivationInstance { get; set; } = null; public Vec3 ChainedPuzzleStartPosition { get; set; } = new Vec3(); public List EventsOnActivationScanSolved { get; set; } = new List(); } public sealed class HSUActivatorObjectiveManager : InstanceDefinitionManager { private readonly Dictionary _hsuActivatorPuzzles = new Dictionary(); protected override string DEFINITION_NAME { get; } = "ActivateSmallHSU"; public override uint ChainedPuzzleLoadOrder => 2u; public HSUActivatorObjectiveManager() { SNetEvents.OnRecallDone += OnEnterLevel; } protected override void AddDefinitions(InstanceDefinitionsForLevel definitions) { Sort(definitions); base.AddDefinitions(definitions); } internal HSUActivatorDefinition? GetHSUActivatorDefinition(ChainedPuzzleInstance chainedPuzzle) { HSUActivatorDefinition value; return _hsuActivatorPuzzles.TryGetValue(((Il2CppObjectBase)chainedPuzzle).Pointer, out value) ? value : null; } public bool TryGetDefinition(LG_HSUActivator_Core instance, [MaybeNullWhen(false)] out HSUActivatorDefinition definition) { var (globalIndex, instanceIndex) = BaseManager.Current.GetGlobalInstance(instance); return TryGetDefinition(globalIndex, instanceIndex, out definition); } protected override void OnBuildDone() { foreach (HSUActivatorDefinition item in GetDefinitionsForLevel(BaseManager.CurrentMainLevelLayout)) { BuildHSUActivatorChainedPuzzle(item); } } protected override void OnEnterLevel() { foreach (HSUActivatorDefinition item in GetDefinitionsForLevel(BaseManager.CurrentMainLevelLayout)) { if (!BaseManager.Current.TryGetInstance(((GlobalBase)item).IntTuple, item.InstanceIndex, out LG_HSUActivator_Core instance)) { break; } MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)instance, DelayedCullingSetup(instance)); } } private static IEnumerator DelayedCullingSetup(LG_HSUActivator_Core instance) { yield return (object)new WaitForSeconds(1.5f); instance.PostCullingSetup(); } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { CollectionExtensions.ForEachValue((IDictionary)_hsuActivatorPuzzles, (Action)delegate(HSUActivatorDefinition h) { h.ChainedPuzzleOnActivationInstance = null; }); _hsuActivatorPuzzles.Clear(); } private void BuildHSUActivatorChainedPuzzle(HSUActivatorDefinition def) { //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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 (!BaseManager.Current.TryGetInstance(((GlobalBase)def).IntTuple, def.InstanceIndex, out LG_HSUActivator_Core instance)) { EOSLogger.Error($"Found unused HSUActivator config: {def}"); return; } bool insertAnimDone = false; LG_AnimationSequencer sequencerWaitingForItem = instance.m_sequencerWaitingForItem; sequencerWaitingForItem.OnSequenceDone += Action.op_Implicit((Action)delegate { insertAnimDone = false; }); LG_AnimationSequencer sequencerInsertItem = instance.m_sequencerInsertItem; sequencerInsertItem.OnSequenceDone += Action.op_Implicit((Action)delegate { insertAnimDone = true; }); LG_AnimationSequencer sequencerExtractionDone = instance.m_sequencerExtractionDone; sequencerExtractionDone.OnSequenceDone += Action.op_Implicit((Action)delegate { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (def.RequireItemAfterActivationInExitScan) { WardenObjectiveManager.AddObjectiveItemAsRequiredForExitScan(true, (iWardenObjectiveItem[])(object)new iWardenObjectiveItem[1] { new iWardenObjectiveItem(((Il2CppObjectBase)instance.m_linkedItemComingOut).Pointer) }); EOSLogger.Debug($"HSUActivator: {def} - added required item for extraction scan"); } if (def.TakeOutItemAfterActivation) { instance.LinkedItemComingOut.m_navMarkerPlacer.SetMarkerVisible(true); } }); if (def.ChainedPuzzleOnActivation == 0) { if (def.TakeOutItemAfterActivation) { instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)instance).StartCoroutine(instance.TriggerRemoveSequence()); } return; } ChainedPuzzleDataBlock val = default(ChainedPuzzleDataBlock); if (!DataBlockUtil.TryGetBlock(def.ChainedPuzzleOnActivation, ref val)) { EOSLogger.Error("HSUActivator: ChainedPuzzleOnActivation is specified but ChainedPuzzleDatablock definition is not found, won't build"); return; } Vector3 val2 = (((Vector3)def.ChainedPuzzleStartPosition == Vector3.zeroVector) ? instance.m_itemGoingInAlign.position : ((Vector3)def.ChainedPuzzleStartPosition)); ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(val, instance.SpawnNode.m_area, val2, ((Component)instance.SpawnNode.m_area).transform); def.ChainedPuzzleOnActivationInstance = val3; _hsuActivatorPuzzles[((Il2CppObjectBase)val3).Pointer] = def; val3.Add_OnStateChange(delegate(pChainedPuzzleState _, pChainedPuzzleState newState, bool isRecall) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if (!((int)newState.status != 2 || isRecall)) { EOSWardenEventManager.ExecuteWardenEvents(def.EventsOnActivationScanSolved, (eWardenObjectiveEventTrigger)0); if (def.TakeOutItemAfterActivation) { if (!insertAnimDone) { LG_AnimationSequencer sequencerInsertItem2 = instance.m_sequencerInsertItem; sequencerInsertItem2.OnSequenceDone += Action.op_Implicit((Action)delegate { instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)instance).StartCoroutine(instance.TriggerRemoveSequence()); }); } else { instance.m_triggerExtractSequenceRoutine = ((MonoBehaviour)instance).StartCoroutine(instance.TriggerRemoveSequence()); } } } }); EOSLogger.Debug($"HSUActivator: ChainedPuzzleOnActivation ID: {def.ChainedPuzzleOnActivation} specified and created"); } } } namespace EOS.Modules.Instances { public sealed class ChainedPuzzleInstanceManager : InstanceManager { private readonly Dictionary?> _puzzlesOnStateChange = new Dictionary>(); protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { _puzzlesOnStateChange.Clear(); base.OnLevelCleanup(); } public override (int, int, int) GetGlobalIndex(ChainedPuzzleInstance instance) { return GlobalIndexUtil.ToIntTuple(instance.m_sourceArea.m_courseNode.m_zone); } public override uint Register((int, int, int) globalZoneIndex, ChainedPuzzleInstance instance) { uint num = base.Register(globalZoneIndex, instance); if (num != uint.MaxValue) { _puzzlesOnStateChange[((Il2CppObjectBase)instance).Pointer] = null; } return num; } public void Add_OnStateChange(ChainedPuzzleInstance instance, Action action) { Add_OnStateChange(((Il2CppObjectBase)instance).Pointer, action); } public void Add_OnStateChange(IntPtr pointer, Action action) { if (_puzzlesOnStateChange.ContainsKey(pointer)) { Dictionary> puzzlesOnStateChange = _puzzlesOnStateChange; puzzlesOnStateChange[pointer] = (Action)Delegate.Combine(puzzlesOnStateChange[pointer], action); } else { EOSLogger.Error("ChainedPuzzleInstanceManager: passed in pointer is an unregistered ChainedPuzzleInstance, or is not a ChainedPuzzle"); } } public void Remove_OnStateChange(ChainedPuzzleInstance instance, Action action) { Remove_OnStateChange(((Il2CppObjectBase)instance).Pointer, action); } public void Remove_OnStateChange(IntPtr pointer, Action action) { if (_puzzlesOnStateChange.ContainsKey(pointer)) { Dictionary> puzzlesOnStateChange = _puzzlesOnStateChange; puzzlesOnStateChange[pointer] = (Action)Delegate.Remove(puzzlesOnStateChange[pointer], action); } else { EOSLogger.Error("ChainedPuzzleInstanceManager: passed in pointer is an unregistered ChainedPuzzleInstance, or is not a ChainedPuzzle"); } } public Action? Get_OnStateChange(ChainedPuzzleInstance instance) { return Get_OnStateChange(((Il2CppObjectBase)instance).Pointer); } public Action? Get_OnStateChange(IntPtr pointer) { Action value; return _puzzlesOnStateChange.TryGetValue(pointer, out value) ? value : null; } } public sealed class GeneratorClusterInstanceManager : InstanceManager { public override (int, int, int) GetGlobalIndex(LG_PowerGeneratorCluster instance) { return GlobalIndexUtil.ToIntTuple(instance.SpawnNode.m_zone); } } public sealed class HSUActivatorInstanceManager : InstanceManager { public override (int, int, int) GetGlobalIndex(LG_HSUActivator_Core instance) { return GlobalIndexUtil.ToIntTuple(instance.SpawnNode.m_zone); } } public sealed class PowerGeneratorInstanceManager : InstanceManager { private readonly Dictionary _gcGenerators = new Dictionary(); protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { _gcGenerators.Clear(); base.OnLevelCleanup(); } public override (int, int, int) GetGlobalIndex(LG_PowerGenerator_Core instance) { return GlobalIndexUtil.ToIntTuple(instance.SpawnNode.m_zone); } public override uint Register((int, int, int) globalZoneIndex, LG_PowerGenerator_Core instance) { if (_gcGenerators.ContainsKey(((Il2CppObjectBase)instance).Pointer)) { EOSLogger.Error("PowerGeneratorInstanceManager: Trying to register a GC Generator, which is an invalid operation"); return uint.MaxValue; } return base.Register(globalZoneIndex, instance); } public void MarkAsGCGenerator(LG_PowerGeneratorCluster parent, LG_PowerGenerator_Core child) { if (IsRegistered(child)) { EOSLogger.Error("PowerGeneratorInstanceManager: Trying to mark a registered Generator as GC Generator, which is an invalid operation"); } else { _gcGenerators[((Il2CppObjectBase)child).Pointer] = parent; } } public bool IsGCGenerator(LG_PowerGenerator_Core instance) { return _gcGenerators.ContainsKey(((Il2CppObjectBase)instance).Pointer); } public LG_PowerGeneratorCluster? GetParentGeneratorCluster(LG_PowerGenerator_Core instance) { LG_PowerGeneratorCluster value; return _gcGenerators.TryGetValue(((Il2CppObjectBase)instance).Pointer, out value) ? value : null; } } public sealed class ReactorInstanceManager : InstanceManager { private readonly HashSet _startupReactor = new HashSet(); private readonly HashSet _shutdownReactor = new HashSet(); protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown foreach (IntPtr item in _startupReactor) { LG_WardenObjective_Reactor val = new LG_WardenObjective_Reactor(item); if (val != null) { CellSoundPlayer sound = val.m_sound; if (sound != null) { sound.Recycle(); } } } foreach (IntPtr item2 in _shutdownReactor) { LG_WardenObjective_Reactor val2 = new LG_WardenObjective_Reactor(item2); if (val2 != null) { CellSoundPlayer sound2 = val2.m_sound; if (sound2 != null) { sound2.Recycle(); } } } _startupReactor.Clear(); _shutdownReactor.Clear(); base.OnLevelCleanup(); } public override (int, int, int) GetGlobalIndex(LG_WardenObjective_Reactor instance) { return GlobalIndexUtil.ToIntTuple(instance.SpawnNode.m_zone); } public void MarkAsStartupReactor(LG_WardenObjective_Reactor reactor) { if (_shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { EOSLogger.Error("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } else { _startupReactor.Add(((Il2CppObjectBase)reactor).Pointer); } } public void MarkAsShutdownReactor(LG_WardenObjective_Reactor reactor) { if (_startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { EOSLogger.Error("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } else { _shutdownReactor.Add(((Il2CppObjectBase)reactor).Pointer); } } public bool IsStartupReactor(LG_WardenObjective_Reactor reactor) { return _startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer); } public bool IsShutdownReactor(LG_WardenObjective_Reactor reactor) { return _shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer); } public static void SetupReactorTerminal(LG_WardenObjective_Reactor reactor, TerminalDefinition reactorTerminalData) { if (reactorTerminalData != null) { reactorTerminalData.LocalLogFiles?.ForEach(delegate(TerminalLogFileData log) { reactor.m_terminal.AddLocalLog(log, true); }); reactorTerminalData.UniqueCommands?.ForEach(delegate(CustomCommand cmd) { EOSTerminalUtil.AddUniqueCommand(reactor.m_terminal, cmd); }); EOSTerminalUtil.BuildPassword(reactor.m_terminal, reactorTerminalData.PasswordData); } } public static LG_WardenObjective_Reactor? FindVanillaReactor(LG_LayerType layer, int count) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (count < 0) { EOSLogger.Error($"FindVanillaReactor: count should be non-negative, but got {count}!"); return null; } LG_WardenObjective_Reactor val = null; int num = count; Enumerator enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; if (current.Key.Layer != layer) { continue; } iWardenObjectiveItem value = current.Value; val = ((value != null) ? ((Il2CppObjectBase)value).TryCast() : null); if (!((Object)(object)val == (Object)null)) { if (num <= 0) { break; } val = null; num--; } } if ((Object)(object)val == (Object)null) { EOSLogger.Error($"FindVanillaReactor: reactor not found with index(Count) {num} in {layer}!"); } return val; } } public sealed class TerminalInstanceManager : InstanceManager { public enum TerminalWardenEvents { EOSSetTerminalCommand = 600, EOSToggleTerminalState } private readonly Dictionary _uniqueCommandChainPuzzles = new Dictionary(); private readonly Dictionary> _wardenUplinks = new Dictionary>(); private readonly Dictionary _terminalWrappers = new Dictionary(); public static ImmutableList UNIQUE_CMDS { get; } static TerminalInstanceManager() { TERM_Command[] array = new TERM_Command[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); UNIQUE_CMDS = ImmutableList.Create((TERM_Command[])(object)array); EOSWardenEventManager.AddEventDefinition(TerminalWardenEvents.EOSSetTerminalCommand.ToString(), 600u, SetTerminalCommand); EOSWardenEventManager.AddEventDefinition(TerminalWardenEvents.EOSToggleTerminalState.ToString(), 601u, ToggleTerminalState); } protected override void OnEnterLevel() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 ChainedPuzzleInstance val = default(ChainedPuzzleInstance); foreach (LG_ComputerTerminal item in base.Index2Instance.SelectMany>, LG_ComputerTerminal>((KeyValuePair<(int, int, int), List> kvp) => kvp.Value)) { foreach (TERM_Command uNIQUE_CMD in UNIQUE_CMDS) { if (!item.m_command.m_commandsPerEnum.ContainsKey(uNIQUE_CMD)) { continue; } string command = item.m_command.m_commandsPerEnum[uNIQUE_CMD]; List uniqueCommandEvents = item.GetUniqueCommandEvents(command); for (int num = 0; num < uniqueCommandEvents.Count; num++) { if (uniqueCommandEvents[num].ChainPuzzle != 0 && item.TryGetChainPuzzleForCommand(uNIQUE_CMD, num, ref val) && !((Object)(object)val == (Object)null)) { _uniqueCommandChainPuzzles[((Il2CppObjectBase)val).Pointer] = item; if ((int)item.GetCommandRule(uNIQUE_CMD) == 0) { ChainedPuzzleInstance obj = val; obj.OnPuzzleSolved += Action.op_Implicit((Action)val.ResetProgress); } } } } } } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { _uniqueCommandChainPuzzles.Clear(); _wardenUplinks.Clear(); CollectionExtensions.ForEachValue((IDictionary)_terminalWrappers, (Action)delegate(TerminalWrapper w) { w.Replicator?.Unload(); }); _terminalWrappers.Clear(); base.OnLevelCleanup(); } public override (int, int, int) GetGlobalIndex(LG_ComputerTerminal instance) { if (instance.SpawnNode == null) { if ((Object)(object)instance.ConnectedReactor != (Object)null) { return GlobalIndexUtil.ToIntTuple(instance.ConnectedReactor.SpawnNode.m_zone); } EOSLogger.Error("LG_ComputerTerminal: both SpawnNode and ConnectedReactor are null!"); return (-1, -1, -1); } return GlobalIndexUtil.ToIntTuple(instance.SpawnNode.m_zone); } public override uint Register(LG_ComputerTerminal instance) { if (instance.SpawnNode == null) { return uint.MaxValue; } uint result = Register(GetGlobalIndex(instance), instance); SetupTerminalWrapper(instance); return result; } public void SetupTerminalWrapper(LG_ComputerTerminal terminal) { if (_terminalWrappers.ContainsKey(((Il2CppObjectBase)terminal).Pointer)) { EOSLogger.Error("TerminalInstanceManager: " + terminal.ItemKey + " is already setup with wrapper..."); return; } uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("TerminalInstanceManager: replicator IDs depleted, cannot setup StateReplicator"); } else { _terminalWrappers[((Il2CppObjectBase)terminal).Pointer] = new TerminalWrapper(terminal, num); } } public TerminalWrapper? GetTerminalWrapper(LG_ComputerTerminal terminal) { TerminalWrapper value; return _terminalWrappers.TryGetValue(((Il2CppObjectBase)terminal).Pointer, out value) ? value : null; } public bool TryGetParentTerminal(ChainedPuzzleInstance cpInstance, [MaybeNullWhen(false)] out LG_ComputerTerminal terminal) { return _uniqueCommandChainPuzzles.TryGetValue(((Il2CppObjectBase)cpInstance).Pointer, out terminal); } public bool TryGetParentTerminal(IntPtr pointer, [MaybeNullWhen(false)] out LG_ComputerTerminal terminal) { return _uniqueCommandChainPuzzles.TryGetValue(pointer, out terminal); } public bool TryGetInstanceFromUplinkDef(BaseTerminalDefinition term, [MaybeNullWhen(false)] out LG_ComputerTerminal instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) (int, int, int) globalIndex = GlobalIndexUtil.ToIntTuple(term.DimensionIndex, term.Layer, term.LocalIndex); return TryGetInstance(globalIndex, term.InstanceIndex, out instance); } public int RegisterWardenUplink(LG_ComputerTerminal terminal) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) List orAddNew = CollectionExtensions.GetOrAddNew>((IDictionary>)_wardenUplinks, terminal.SpawnNode.LayerType); orAddNew.Add(terminal); return orAddNew.Count - 1; } public LG_ComputerTerminal GetWardenUplink(LG_LayerType layer, int objectiveIndex) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (_wardenUplinks.TryGetValue(layer, out List value) && objectiveIndex >= 0 && objectiveIndex < value.Count) { return value[objectiveIndex]; } return null; } private static void SetTerminalCommand(WardenObjectiveEventData e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) (int, int, int) globalIndex = GlobalIndexUtil.ToIntTuple(e.DimensionIndex, e.Layer, e.LocalIndex); if (!BaseManager.Current.TryGetInstance(globalIndex, (uint)e.Count, out LG_ComputerTerminal instance)) { EOSLogger.Error($"SetTerminalCommand_Custom: Cannot find terminal for {(e.DimensionIndex, e.Layer, e.LocalIndex, e.Count)}"); return; } if (e.Enabled) { instance.TrySyncSetCommandShow(e.TerminalCommand); } else { instance.TrySyncSetCommandHidden(e.TerminalCommand); } EOSLogger.Debug($"SetTerminalCommand: Terminal_{instance.m_serialNumber}, command '{e.TerminalCommand}' enabled ? {e.Enabled}"); } private static void ToggleTerminalState(WardenObjectiveEventData e) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster) { (int, int, int) globalIndex = GlobalIndexUtil.ToIntTuple(e.DimensionIndex, e.Layer, e.LocalIndex); TerminalWrapper value; if (!BaseManager.Current.TryGetInstance(globalIndex, (uint)e.Count, out LG_ComputerTerminal instance)) { EOSLogger.Error($"ToggleTerminalState: terminal with index {(e.DimensionIndex, e.Layer, e.LocalIndex, e.Count)} not found"); } else if (!BaseManager.Current._terminalWrappers.TryGetValue(((Il2CppObjectBase)instance).Pointer, out value)) { EOSLogger.Error($"ToggleTerminalState: internal error: terminal wrapper not found - {(e.DimensionIndex, e.Layer, e.LocalIndex, e.Count)}"); } else { value.ChangeState(e.Enabled); } } } } } namespace EOS.Modules.Expedition { public class ExpeditionDefinition { public uint MainLevelLayout { get; set; } = 0u; public ExpeditionGearsDefinition ExpeditionGears { get; set; } = new ExpeditionGearsDefinition(); public List GeneratorGroups { get; set; } = new List { new ExpeditionIGGroup() }; public List Terminals { get; set; } = new List { new ExpeditionTerminalsDefinition() }; } public class ExpeditionTerminalsDefinition : BaseTerminalDefinition { public List EventsOnApproach { get; set; } = new List(); public SerialGeneratorManager.CodeWordLength PasswordWordLength { get; set; } = SerialGeneratorManager.CodeWordLength.Four; public List EventsOnPasswordInputSuccess { get; set; } = new List(); public List EventsOnPasswordInputFailure { get; set; } = new List(); public List LogFiles { get; set; } = new List(); } public class TerminalLogFileEvents { public string FileName { get; set; } = string.Empty; public List EventsOnFileRead { get; set; } = new List(); } public sealed class ExpeditionDefinitionManager : BaseManager { private readonly Dictionary _definitions = new Dictionary(); protected override string DEFINITION_NAME => "ExtraExpeditionSettings"; protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new ExpeditionDefinition())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); ExpeditionDefinition definitions = EOSJson.Deserialize(json); AddDefinitions(definitions); } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ExpeditionDefinition definitions = EOSJson.Deserialize(content); AddDefinitions(definitions); }); } private void AddDefinitions(ExpeditionDefinition definitions) { if (definitions != null) { if (_definitions.ContainsKey(definitions.MainLevelLayout)) { EOSLogger.Log("Replaced MainLevelLayout {0}", definitions.MainLevelLayout); } _definitions[definitions.MainLevelLayout] = definitions; } } public bool TryGetDefinition(uint mainLevelLayout, [MaybeNullWhen(false)] out ExpeditionDefinition definition) { return _definitions.TryGetValue(mainLevelLayout, out definition); } public bool TryGetTerminalDefinitionFromInstance(LG_ComputerTerminal terminal, [MaybeNullWhen(false)] out ExpeditionTerminalsDefinition termDef) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode spawnNode = terminal.SpawnNode ?? CourseNodeUtil.GetCourseNode(terminal.m_position); if (!_definitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out ExpeditionDefinition value) || spawnNode == null) { termDef = null; return false; } termDef = value.Terminals.FirstOrDefault(delegate(ExpeditionTerminalsDefinition gIndex) { (int, int, int) intTuple = gIndex.GetIntTuple(); (int, int, int) tuple = GlobalIndexUtil.ToIntTuple(spawnNode.m_zone); return intTuple.Item1 == tuple.Item1 && intTuple.Item2 == tuple.Item2 && intTuple.Item3 == tuple.Item3; }); return termDef != null; } } } namespace EOS.Modules.Expedition.ThermalSights { public class PuzzleVisualWrapper { public GameObject? GO { get; set; } = null; public Material? Material { get; set; } = null; public float Intensity { get; set; } public float BehindWallIntensity { get; set; } public void SetIntensity(float t) { GameObject? gO = GO; if (gO != null && gO.active && !((Object)(object)Material == (Object)null)) { if (Intensity > 0f) { Material.SetFloat("_Intensity", Intensity * t); } if (BehindWallIntensity > 0f) { Material.SetFloat("_BehindWallIntensity", BehindWallIntensity * t); } } } } public class TSADefinition { public float OffAimPixelZoom { get; set; } = 1f; public TSShader Shader { get; set; } = new TSShader(); } public class TSShader { [JsonPropertyName("DistanceFalloff")] [Range(0.0, 1.0)] public float HeatFalloff { get; set; } = 0.01f; [Range(0.0, 1.0)] public float FogFalloff { get; set; } = 0.1f; [JsonPropertyName("PixelZoom")] [Range(0.0, 1.0)] public float Zoom { get; set; } = 0.8f; [JsonPropertyName("AspectRatioAdjust")] [Range(0.0, 2.0)] public float RatioAdjust { get; set; } = 1f; [Range(0.0, 1.0)] public float DistortionCenter { get; set; } = 0.5f; public float DistortionScale { get; set; } = 1f; public float DistortionSpeed { get; set; } = 1f; public float DistortionSignalSpeed { get; set; } = 0.025f; [Range(0.0, 1.0)] public float DistortionMin { get; set; } = 0.01f; [Range(0.0, 1.0)] public float DistortionMax { get; set; } = 0.4f; [JsonPropertyName("AmbientTemperature")] [Range(0.0, 1.0)] public float AmbientTemp { get; set; } = 0.15f; [JsonPropertyName("BackgroundTemperature")] [Range(0.0, 1.0)] public float BackgroundTemp { get; set; } = 0.05f; [Range(0.0, 10.0)] public float AlbedoColorFactor { get; set; } = 0.5f; [Range(0.0, 10.0)] public float AmbientColorFactor { get; set; } = 5f; public float OcclusionHeat { get; set; } = 0.5f; public float BodyOcclusionHeat { get; set; } = 2.5f; [Range(0.0, 1.0)] public float ScreenIntensity { get; set; } = 0.2f; [Range(0.0, 1.0)] public float OffAngleFade { get; set; } = 0.95f; [Range(0.0, 1.0)] public float Noise { get; set; } = 0.1f; [JsonPropertyName("MinShadowEnemyDistortion")] [Range(0.0, 1.0)] public float DistortionMinShadowEnemies { get; set; } = 0.2f; [JsonPropertyName("MaxShadowEnemyDistortion")] [Range(0.0, 1.0)] public float DistortionMaxShadowEnemies { get; set; } = 1f; [Range(0.0, 1.0)] public float DistortionSignalSpeedShadowEnemies { get; set; } = 1f; public float ShadowEnemyFresnel { get; set; } = 10f; [Range(0.0, 1.0)] public float ShadowEnemyHeat { get; set; } = 0.1f; public Color ReticuleColorA { get; set; } = new Color { r = 1f, g = 1f, b = 1f, a = 1f }; public Color ReticuleColorB { get; set; } = new Color { r = 1f, g = 1f, b = 1f, a = 1f }; public Color ReticuleColorC { get; set; } = new Color { r = 1f, g = 1f, b = 1f, a = 1f }; [Range(0.0, 20.0)] public float SightDirt { get; set; } = 0f; public bool LitGlass { get; set; } = false; public bool ClipBorders { get; set; } = true; public Vec4 AxisX { get; set; } = new Vec4(); public Vec4 AxisY { get; set; } = new Vec4(); public Vec4 AxisZ { get; set; } = new Vec4(); public bool Flip { get; set; } = true; [JsonPropertyName("Distance1")] [Range(0.0, 100.0)] public float ProjDist1 { get; set; } = 100f; [JsonPropertyName("Distance2")] [Range(0.0, 100.0)] public float ProjDist2 { get; set; } = 66f; [JsonPropertyName("Distance3")] [Range(0.0, 100.0)] public float ProjDist3 { get; set; } = 33f; [JsonPropertyName("Size1")] [Range(0.0, 3.0)] public float ProjSize1 { get; set; } = 1f; [JsonPropertyName("Size2")] [Range(0.0, 3.0)] public float ProjSize2 { get; set; } = 1f; [JsonPropertyName("Size3")] [Range(0.0, 3.0)] public float ProjSize3 { get; set; } = 1f; [JsonPropertyName("Zeroing")] [Range(-1.0, 1.0)] public float ZeroOffset { get; set; } = 0f; } public sealed class TSAManager : GenericDefinitionManager { public const string THERMAL = "Thermal"; public const string ZOOM = "_Zoom"; private readonly Dictionary _inLevelGearThermals = new Dictionary(); private readonly HashSet _modifiedInLevelGearThermals = new HashSet(); private readonly HashSet _thermalOfflineGears = new HashSet(); public const string ZONE = "Zone"; public const string INTENSITY = "_Intensity"; public const string BEHIND_WALL_INTENSITY = "_BehindWallIntensity"; private readonly List _puzzleVisuals = new List(); protected override string DEFINITION_NAME => "ThermalSight"; public uint CurrentGearPID { get; private set; } = 0u; protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); InitThermalOfflineGears(); CleanupInLevelGearThermals(keepCurrentGear: true); SetThermalSightRenderer(CurrentGearPID); } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { CurrentGearPID = 0u; CleanupInLevelGearThermals(); CleanupPuzzleVisuals(); } public bool IsGearWithThermal(uint gearPID) { return _thermalOfflineGears.Contains(gearPID); } internal void InitThermalOfflineGears() { _thermalOfflineGears.Clear(); foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { if (((GameDataBlockBase)(object)allBlock).internalEnabled && ((GameDataBlockBase)(object)allBlock).name.ToLowerInvariant().EndsWith("_t")) { _thermalOfflineGears.Add(((GameDataBlockBase)(object)allBlock).persistentID); } } EOSLogger.Debug($"Found OfflineGears with registered thermal sight, count: {_thermalOfflineGears.Count}"); } private void CleanupInLevelGearThermals(bool keepCurrentGear = false) { if (keepCurrentGear && _inLevelGearThermals.TryGetValue(CurrentGearPID, out Renderer[] value)) { _inLevelGearThermals.Clear(); _inLevelGearThermals[CurrentGearPID] = value; } else { _inLevelGearThermals.Clear(); } _modifiedInLevelGearThermals.Clear(); } internal void OnPlayerItemWielded(ItemEquippable item) { if (((item != null) ? item.GearIDRange : null) == null) { CurrentGearPID = 0u; return; } CurrentGearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange); GetInLevelGearThermalRenderersFromItem(item, CurrentGearPID); SetThermalSightRenderer(CurrentGearPID); } internal void SetCurrentThermalSightSettings(float t) { if (base.GenericDefinitions.TryGetValue(CurrentGearPID, out GenericDefinition value) && _inLevelGearThermals.TryGetValue(CurrentGearPID, out Renderer[] value2)) { SetPuzzleVisualsIntensity(t); Renderer[] array = value2; foreach (Renderer val in array) { float zoom = value.Definition.Shader.Zoom; float offAimPixelZoom = value.Definition.OffAimPixelZoom; float num = Mathf.Lerp(zoom, offAimPixelZoom, t); val.material.SetFloat("_Zoom", num); } } } private void GetInLevelGearThermalRenderersFromItem(ItemEquippable item, uint gearPID) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (((item != null) ? item.GearIDRange : null) == null) { return; } if (gearPID == 0) { gearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange); } if (gearPID == 0 || !IsGearWithThermal(gearPID)) { return; } bool flag = false; if (!_inLevelGearThermals.TryGetValue(gearPID, out Renderer[] value)) { flag = true; } else { try { _ = ((Component)value[0]).gameObject.transform.position; flag = false; } catch { _modifiedInLevelGearThermals.Remove(gearPID); flag = true; } } if (!flag) { return; } value = ((IEnumerable)((Component)item).GetComponentsInChildren(true)).Where(delegate(Renderer r) { Material sharedMaterial = r.sharedMaterial; int result; if (sharedMaterial == null) { result = 0; } else { Shader shader = sharedMaterial.shader; result = ((((shader == null) ? ((bool?)null) : ((Object)shader).name?.Contains("Thermal", StringComparison.OrdinalIgnoreCase)) == true) ? 1 : 0); } return (byte)result != 0; }).ToArray(); if (value.Length == 0) { EOSLogger.Debug("ThermalSights: " + ((Item)item).PublicName + ": thermal renderer not found"); return; } if (value.Length > 1) { EOSLogger.Warning("ThermalSights: " + ((Item)item).PublicName + " contains more than 1 thermal renderer!"); } _inLevelGearThermals[gearPID] = value; } private void SetThermalSightRenderer(uint gearPID = 0u) { //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) if (gearPID == 0) { gearPID = CurrentGearPID; } if (!IsGearWithThermal(gearPID) || _modifiedInLevelGearThermals.Contains(gearPID) || !base.GenericDefinitions.TryGetValue(gearPID, out GenericDefinition value) || !_inLevelGearThermals.TryGetValue(gearPID, out Renderer[] value2)) { return; } TSADefinition definition = value.Definition; TSShader shader = definition.Shader; Renderer[] array = value2; foreach (Renderer val in array) { PropertyInfo[] properties = shader.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; string text = "_" + propertyInfo.Name; if (type == typeof(float)) { val.material.SetFloat(text, (float)propertyInfo.GetValue(shader)); } else if (type == typeof(Color)) { Color val2 = (Color)propertyInfo.GetValue(shader); val.material.SetVector(text, Color.op_Implicit(val2)); } else if (type == typeof(bool)) { bool flag = (bool)propertyInfo.GetValue(shader); val.material.SetFloat(text, flag ? 1f : 0f); } else if (type == typeof(Vec4)) { Vec4 vec = (Vec4)propertyInfo.GetValue(shader); val.material.SetVector(text, (Vector4)vec); } } } _modifiedInLevelGearThermals.Add(gearPID); } internal void RegisterPuzzleVisual(CP_Bioscan_Core core) { Il2CppArrayBase componentsInChildren = ((Component)core).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } foreach (Renderer item2 in ((IEnumerable)componentsInChildren).Where((Renderer comp) => ((Object)((Component)comp).gameObject).name.Equals("Zone"))) { PuzzleVisualWrapper item = new PuzzleVisualWrapper { GO = ((Component)item2).gameObject, Material = item2.material, Intensity = item2.material.GetFloat("_Intensity"), BehindWallIntensity = item2.material.GetFloat("_BehindWallIntensity") }; _puzzleVisuals.Add(item); } } internal void SetPuzzleVisualsIntensity(float t) { _puzzleVisuals.ForEach(delegate(PuzzleVisualWrapper v) { v.SetIntensity(t); }); } private void CleanupPuzzleVisuals() { _puzzleVisuals.Clear(); } } } namespace EOS.Modules.Expedition.IndividualGeneratorGroup { public class ExpeditionIGGroup { public List Generators { get; set; } = new List(); [JsonIgnore] public List GeneratorInstances { get; set; } = new List(); public bool PlayEndSequenceOnGroupComplete { get; set; } = false; public List> EventsOnInsertCell { get; set; } = new List> { new List() }; } public sealed class ExpeditionIGGroupManager : BaseManager { private readonly Dictionary _generatorGroups = new Dictionary(); protected override string DEFINITION_NAME => string.Empty; protected override void OnBuildDone() { if (!BaseManager.Current.TryGetDefinition(BaseManager.CurrentMainLevelLayout, out ExpeditionDefinition definition) || definition.GeneratorGroups == null || definition.GeneratorGroups.Count < 1) { return; } foreach (ExpeditionIGGroup generatorGroup in definition.GeneratorGroups) { foreach (LG_PowerGenerator_Core item in GatherIGs(generatorGroup)) { _generatorGroups[((Il2CppObjectBase)item).Pointer] = generatorGroup; } } } protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { CollectionExtensions.ForEachValue((IDictionary)_generatorGroups, (Action)delegate(ExpeditionIGGroup groupDef) { groupDef.GeneratorInstances.Clear(); }); _generatorGroups.Clear(); } private static List GatherIGs(ExpeditionIGGroup IGGroup) { List list = new List(); foreach (BaseInstanceDefinition generator in IGGroup.Generators) { if (!BaseManager.Current.TryGetInstance(((GlobalBase)generator).IntTuple, generator.InstanceIndex, out LG_PowerGenerator_Core instance)) { EOSLogger.Error($"Generator instance not found! Instance index: {generator}"); } else { list.Add(instance); } } IGGroup.GeneratorInstances = list; return list; } public ExpeditionIGGroup? FindGroupDefOf(LG_PowerGenerator_Core core) { ExpeditionIGGroup value; return _generatorGroups.TryGetValue(((Il2CppObjectBase)core).Pointer, out value) ? value : null; } internal static IEnumerator PlayGroupEndSequence(ExpeditionIGGroup igGroup) { yield return (object)new WaitForSeconds(4f); CellSound.Post(EVENTS.DISTANT_EXPLOSION_SEQUENCE); yield return (object)new WaitForSeconds(2f); EnvironmentStateManager.AttemptSetExpeditionLightMode(false); CellSound.Post(EVENTS.LIGHTS_OFF_GLOBAL); yield return (object)new WaitForSeconds(3f); int g = 0; while (g < igGroup.GeneratorInstances.Count) { igGroup.GeneratorInstances[g].TriggerPowerFailureSequence(); yield return (object)new WaitForSeconds(Random.Range(0.3f, 1f)); int num = g + 1; g = num; } yield return (object)new WaitForSeconds(4f); EnvironmentStateManager.AttemptSetExpeditionLightMode(true); int eventIndex = igGroup.GeneratorInstances.Count - 1; if (eventIndex >= 0 && eventIndex < igGroup.EventsOnInsertCell.Count) { EOSWardenEventManager.ExecuteWardenEvents(igGroup.EventsOnInsertCell[eventIndex], (eWardenObjectiveEventTrigger)0); } } } } namespace EOS.Modules.Expedition.Gears { public sealed class ExpeditionGearManager : BaseManager { private readonly HashSet _gearIds = new HashSet(); private Mode _mode = Mode.DISALLOW; protected override string DEFINITION_NAME => string.Empty; public GearManager VanillaGearManager { get; internal set; } = null; public ImmutableDictionary> GearSlots { get; } = ImmutableDictionary.CreateRange(new KeyValuePair>[4] { new KeyValuePair>((InventorySlot)1, new Dictionary()), new KeyValuePair>((InventorySlot)2, new Dictionary()), new KeyValuePair>((InventorySlot)10, new Dictionary()), new KeyValuePair>((InventorySlot)3, new Dictionary()) }); private void ClearLoadedGears() { foreach (int item in GearSlots.Select>, int>((KeyValuePair> kvp) => (int)kvp.Key)) { ((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[item].Clear(); } } private bool IsGearAllowed(uint playerOfflineGearDBPID) { switch (_mode) { case Mode.ALLOW: return _gearIds.Contains(playerOfflineGearDBPID); case Mode.DISALLOW: return !_gearIds.Contains(playerOfflineGearDBPID); default: EOSLogger.Error($"Unimplemented Mode: {_mode}, will allow gears anyway..."); return true; } } private void AddGearForCurrentExpedition() { //IL_0027: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair> gearSlot in GearSlots) { gearSlot.Deconstruct(out var key, out var value); InventorySlot val = key; Dictionary dictionary = value; List val2 = ((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[(int)val]; Dictionary dictionary2 = dictionary; if (dictionary2.Count == 0) { EOSLogger.Debug($"No gear has been loaded for {val}"); continue; } foreach (uint key2 in dictionary2.Keys) { if (IsGearAllowed(key2)) { val2.Add(dictionary2[key2]); } } if (val2.Count == 0) { EOSLogger.Error($"No gear is allowed for {val}, there must be at least 1 allowed gear!"); val2.Add(dictionary2.First().Value); } } } private void ResetPlayerSelectedGears() { //IL_00fa: Expected O, but got Unknown VanillaGearManager.RescanFavorites(); foreach (int item in GearSlots.Select>, int>((KeyValuePair> kvp) => (int)kvp.Key)) { try { if (((Il2CppArrayBase)(object)VanillaGearManager.m_lastEquippedGearPerSlot)[item] != null) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase)(object)VanillaGearManager.m_lastEquippedGearPerSlot)[item]); } else if (((Il2CppArrayBase>)(object)VanillaGearManager.m_favoriteGearPerSlot)[item].Count > 0) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase>)(object)VanillaGearManager.m_favoriteGearPerSlot)[item][0]); } else if (((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[item].Count > 0) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[item][0]); } } catch (Il2CppException ex) { Il2CppException ex2 = ex; EOSLogger.Error($"Error attempting to equip gear for slot {item}:\n{((Exception)(object)ex2).StackTrace}"); } } } private void ConfigExpeditionGears() { _mode = Mode.DISALLOW; _gearIds.Clear(); if (BaseManager.Current.TryGetDefinition(BaseManager.CurrentMainLevelLayout, out ExpeditionDefinition definition) && definition.ExpeditionGears != null) { _mode = definition.ExpeditionGears.Mode; definition.ExpeditionGears.GearIds.ForEach(delegate(uint id) { _gearIds.Add(id); }); } } internal void SetupAllowedGearsForActiveExpedition() { ConfigExpeditionGears(); ClearLoadedGears(); AddGearForCurrentExpedition(); ResetPlayerSelectedGears(); } public static uint GetOfflineGearPID(GearIDRange gearIDRange) { string playfabItemInstanceId = gearIDRange.PlayfabItemInstanceId; if (!playfabItemInstanceId.Contains("OfflineGear_ID_")) { EOSLogger.Error("Find PlayfabItemInstanceId without substring 'OfflineGear_ID_'! " + playfabItemInstanceId); return 0u; } try { return uint.Parse(playfabItemInstanceId.Substring("OfflineGear_ID_".Length)); } catch { EOSLogger.Error("Caught exception while trying to parse persistentID of PlayerOfflineGearDB from GearIDRange, which means itemInstanceId could be ill-formated"); return 0u; } } } public enum Mode { ALLOW, DISALLOW } public class ExpeditionGearsDefinition { public Mode Mode { get; set; } = Mode.DISALLOW; public List GearIds { get; set; } = new List { 0u }; } } namespace EOS.JSON { public static class EOSJson { private static readonly JsonSerializerOptions _setting; static EOSJson() { _setting = JsonSerializerUtil.CreateDefaultSettings(true, PData_Wrapper.IsLoaded, InjectLib_Wrapper.IsLoaded); _setting.Converters.Add(new MyVector3Converter()); } public static T Deserialize(string json) { return JsonSerializer.Deserialize(json, _setting); } public static object Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize(T value) { return JsonSerializer.Serialize(value, _setting); } } public sealed class MyVector3Converter : JsonConverter { public override bool HandleNull => false; public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) Vector3 vector = Vector3.zero; switch (reader.TokenType) { case JsonTokenType.StartObject: { int currentDepth = reader.CurrentDepth; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == currentDepth) { EOSLogger.Warning($"Parsed Vector3 : {vector}"); return vector; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string text2 = reader.GetString(); reader.Read(); switch (text2.ToLowerInvariant()) { case "x": vector.x = reader.GetSingle(); break; case "y": vector.y = reader.GetSingle(); break; case "z": vector.z = reader.GetSingle(); break; } } throw new JsonException("Expected EndObject token"); } case JsonTokenType.String: { string text = reader.GetString().Trim(); if (TryParseVector3(text, out vector)) { return vector; } throw new JsonException("Vector3 format is not right: " + text); } default: throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!"); } } private static bool TryParseVector3(string input, out Vector3 vector) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) float[] array = default(float[]); if (!RegexUtils.TryParseVectorString(input, ref array)) { vector = Vector3.zero; return false; } if (array.Length < 3) { vector = Vector3.zero; return false; } vector = new Vector3(array[0], array[1], array[2]); return true; } public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) writer.WriteStringValue($"({value.x} {value.y} {value.z})"); } } } namespace EOS.JSON.Extensions { public static class JsonExtensions { public static IEnumerable Descendants(this JsonNode? root) { return root.DescendantsAndSelf(includeSelf: false); } public static IEnumerable DescendantsAndSelf(this JsonNode? root, bool includeSelf = true) { return from i in root.DescendantItemsAndSelf(includeSelf) select i.node; } public static IEnumerable<(JsonNode? node, int? index, string? name, JsonNode? parent)> DescendantItemsAndSelf(this JsonNode? root, bool includeSelf = true) { return RecursiveEnumerableExtensions.Traverse<(JsonNode, int?, string, JsonNode)>((root, null, null, null), delegate((JsonNode node, int? index, string name, JsonNode parent) i) { JsonNode item = i.node; if (item is JsonObject o) { return from p in o.AsDictionary() select ((JsonNode Value, int?, string, JsonNode))(Value: p.Value, null, p.Key.AsNullableReference(), i.node.AsNullableReference()); } return (IEnumerable<(JsonNode node, int? index, string name, JsonNode parent)>)((item is JsonArray source) ? ((IEnumerable)source.Select((JsonNode item2, int index) => ((JsonNode item, int?, string, JsonNode))(item: item2, index.AsNullableValue(), null, i.node.AsNullableReference()))) : ((IEnumerable)i.ToEmptyEnumerable())); }, includeSelf); } private static IEnumerable ToEmptyEnumerable(this T item) { return Enumerable.Empty(); } private static T? AsNullableReference(this T item) where T : class { return item; } private static T? AsNullableValue(this T item) where T : struct { return item; } private static IDictionary AsDictionary(this JsonObject o) { return o; } } public static class RecursiveEnumerableExtensions { public static IEnumerable Traverse(T root, Func> children, bool includeSelf = true) { if (includeSelf) { yield return root; } Stack> stack = new Stack>(); try { stack.Push(children(root).GetEnumerator()); while (stack.Count != 0) { IEnumerator enumerator = stack.Peek(); if (!enumerator.MoveNext()) { stack.Pop(); enumerator.Dispose(); } else { yield return enumerator.Current; stack.Push(children(enumerator.Current).GetEnumerator()); } } } finally { foreach (IEnumerator enumerator3 in stack) { enumerator3.Dispose(); } } } } } namespace EOS.BaseClasses { public class GlobalBased : GlobalBase { [JsonPropertyOrder(-10)] public LG_LayerType LayerType { private get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ((GlobalBase)this).Layer; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((GlobalBase)this).Layer = value; } } public (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GlobalZoneIndexTuple() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) return (((GlobalBase)this).DimensionIndex, ((GlobalBase)this).Layer, ((GlobalBase)this).LocalIndex); } } public class BaseInstanceDefinition : GlobalBased { [JsonPropertyOrder(-9)] public uint InstanceIndex { get; set; } = uint.MaxValue; public override string ToString() { return ((GlobalBase)this).ToString() + $", Instance_{InstanceIndex}"; } } public abstract class BaseManager : BaseManager where TBase : BaseManager { public static TBase Current { get; private set; } public BaseManager() { Current = (TBase)this; } } public abstract class BaseManager { private static readonly List _baseManagers = new List(); private LiveEditListener? _liveEditListener; private bool _initialized; public static uint CurrentMainLevelLayout { get { ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition; return (activeExpedition != null) ? activeExpedition.LevelLayoutData : 0u; } } public static string MODULE_CUSTOM_FOLDER { get; private set; } = Path.Combine(MTFOPathAPI.CustomPath, "ExtraObjectiveSetup"); public string DEFINITION_PATH { get; private set; } = string.Empty; protected abstract string DEFINITION_NAME { get; } public virtual uint ChainedPuzzleLoadOrder { get; protected set; } = uint.MaxValue; internal static void SetupManagers(IEnumerable managers) { foreach (BaseManager manager in managers) { _baseManagers.Add(manager); manager.Init(); } } public void Init() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; if (DEFINITION_NAME != string.Empty) { if (!Directory.Exists(MODULE_CUSTOM_FOLDER)) { Directory.CreateDirectory(MODULE_CUSTOM_FOLDER); } DEFINITION_PATH = Path.Combine(MODULE_CUSTOM_FOLDER, DEFINITION_NAME); if (!Directory.Exists(DEFINITION_PATH)) { Directory.CreateDirectory(DEFINITION_PATH); } ReadFiles(); _liveEditListener = LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } LevelAPI.OnBuildStart += OnBuildStart; LevelAPI.OnBuildDone += OnBuildDone; LevelAPI.OnEnterLevel += OnEnterLevel; LevelAPI.OnLevelCleanup += OnLevelCleanup; } protected virtual void ReadFiles() { } protected virtual void FileChanged(LiveEditEventArgs e) { } protected virtual void OnBuildStart() { } protected virtual void OnBuildDone() { } protected virtual void OnEnterLevel() { } protected virtual void OnLevelCleanup() { } } public class GenericDefinition where T : new() { public uint ID { get; set; } = 0u; public T Definition { get; set; } = new T(); } public abstract class GenericDefinitionManager : BaseManager where TDef : new() where TBase : GenericDefinitionManager { protected Dictionary> GenericDefinitions { get; set; } = new Dictionary>(); protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new GenericDefinition())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); GenericDefinition definition = EOSJson.Deserialize>(json); AddDefinitions(definition); } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { GenericDefinition definition = EOSJson.Deserialize>(content); AddDefinitions(definition); }); } protected virtual void AddDefinitions(GenericDefinition definition) { if (definition != null) { if (GenericDefinitions.ContainsKey(definition.ID)) { EOSLogger.Log("Replaced ID {0}", definition.ID); } GenericDefinitions[definition.ID] = definition; } } public GenericDefinition GetDefinition(uint id) { GenericDefinition definition; return TryGetDefinition(id, out definition) ? definition : null; } public bool TryGetDefinition(uint id, [MaybeNullWhen(false)] out GenericDefinition definition) { if (GenericDefinitions.ContainsKey(id)) { definition = GenericDefinitions[id]; return true; } definition = null; return false; } } public class GenericExpeditionDefinition where T : new() { public uint MainLevelLayout { get; set; } = 0u; public List Definitions { get; set; } = new List { new T() }; } public abstract class GenericExpeditionDefinitionManager : BaseManager where TDef : new() where TBase : GenericExpeditionDefinitionManager { protected Dictionary> GenericExpDefinitions { get; set; } = new Dictionary>(); protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new GenericExpeditionDefinition())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); GenericExpeditionDefinition definitions = EOSJson.Deserialize>(json); AddDefinitions(definitions); } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { GenericExpeditionDefinition definitions = EOSJson.Deserialize>(content); AddDefinitions(definitions); }); } protected virtual void AddDefinitions(GenericExpeditionDefinition definitions) { if (definitions != null) { if (GenericExpDefinitions.ContainsKey(definitions.MainLevelLayout)) { EOSLogger.Log("Replaced MainLevelLayout {0}", definitions.MainLevelLayout); } GenericExpDefinitions[definitions.MainLevelLayout] = definitions; } } public GenericExpeditionDefinition GetDefinition(uint id) { GenericExpeditionDefinition definition; return TryGetDefinition(id, out definition) ? definition : null; } public bool TryGetDefinition(uint id, [MaybeNullWhen(false)] out GenericExpeditionDefinition definition) { if (GenericExpDefinitions.ContainsKey(id)) { definition = GenericExpDefinitions[id]; return true; } definition = null; return false; } } public abstract class InstanceDefinitionManager : BaseManager where TDef : BaseInstanceDefinition, new() where TBase : InstanceDefinitionManager { protected Dictionary> InstanceDefinitions { get; set; } = new Dictionary>(); protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new InstanceDefinitionsForLevel())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); InstanceDefinitionsForLevel definitions = EOSJson.Deserialize>(json); AddDefinitions(definitions); } } protected virtual void AddDefinitions(InstanceDefinitionsForLevel definitions) { if (definitions != null) { if (InstanceDefinitions.ContainsKey(definitions.MainLevelLayout)) { EOSLogger.Log("Replaced MainLevelLayout {0}", definitions.MainLevelLayout); } InstanceDefinitions[definitions.MainLevelLayout] = definitions; } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { InstanceDefinitionsForLevel definitions = EOSJson.Deserialize>(content); AddDefinitions(definitions); }); } public virtual IReadOnlyList GetDefinitionsForLevel(uint mainLevelLayout) { InstanceDefinitionsForLevel value; return InstanceDefinitions.TryGetValue(mainLevelLayout, out value) ? value.Definitions : new List(); } public virtual TDef GetDefinition((int, int, int) globalIndex, uint instanceIndex) { TDef definition; return TryGetDefinition(globalIndex, instanceIndex, out definition) ? definition : null; } public virtual bool TryGetDefinition((int, int, int) globalIndex, uint instanceIndex, [MaybeNullWhen(false)] out TDef definition) { definition = null; if (!InstanceDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out InstanceDefinitionsForLevel value)) { return false; } definition = value.Definitions.Find(delegate(TDef def) { (int, int, int) intTuple = ((GlobalBase)def).IntTuple; (int, int, int) tuple = globalIndex; return intTuple.Item1 == tuple.Item1 && intTuple.Item2 == tuple.Item2 && intTuple.Item3 == tuple.Item3 && def.InstanceIndex == instanceIndex; }); return definition != null; } protected void Sort(InstanceDefinitionsForLevel levelDefs) { levelDefs.Definitions.Sort(delegate(TDef u1, TDef u2) { int num = ((GlobalBase)u1).IntTuple.CompareTo(((GlobalBase)u2).IntTuple); return (num != 0) ? num : u1.InstanceIndex.CompareTo(u2.InstanceIndex); }); } } public class InstanceDefinitionsForLevel where T : BaseInstanceDefinition, new() { public uint MainLevelLayout { get; set; } = 0u; public List Definitions { get; set; } = new List { new T() }; } public abstract class InstanceManager : BaseManager where T : Object where TBase : InstanceManager { public const uint INVALID_INSTANCE_INDEX = uint.MaxValue; protected override string DEFINITION_NAME => string.Empty; protected Dictionary<(int, int, int), Dictionary> Instances2Index { get; } = new Dictionary<(int, int, int), Dictionary>(); protected Dictionary<(int, int, int), List> Index2Instance { get; } = new Dictionary<(int, int, int), List>(); protected override void OnBuildStart() { OnLevelCleanup(); } protected override void OnLevelCleanup() { Instances2Index.Clear(); Index2Instance.Clear(); } public virtual uint Register(T instance) { return Register(GetGlobalIndex(instance), instance); } public virtual uint Register((int, int, int) globalIndex, T instance) { if (instance == null) { return uint.MaxValue; } Dictionary orAddNew = CollectionExtensions.GetOrAddNew<(int, int, int), Dictionary>((IDictionary<(int, int, int), Dictionary>)Instances2Index, globalIndex); if (orAddNew.ContainsKey(((Il2CppObjectBase)(object)instance).Pointer)) { EOSLogger.Warning($"InstanceManager<{typeof(T)}>: trying to register duplicate instance! Skipped...."); return uint.MaxValue; } uint count = (uint)orAddNew.Count; orAddNew[((Il2CppObjectBase)(object)instance).Pointer] = count; CollectionExtensions.GetOrAddNew<(int, int, int), List>((IDictionary<(int, int, int), List>)Index2Instance, globalIndex).Add(instance); return count; } public abstract (int, int, int) GetGlobalIndex(T instance); public uint GetInstanceIndex(T instance, (int, int, int)? globalIndex = null) { (int, int, int) valueOrDefault = globalIndex.GetValueOrDefault(); if (!globalIndex.HasValue) { valueOrDefault = GetGlobalIndex(instance); globalIndex = valueOrDefault; } if (!Instances2Index.TryGetValue(globalIndex.Value, out Dictionary value)) { return uint.MaxValue; } uint value2; return value.TryGetValue(((Il2CppObjectBase)(object)instance).Pointer, out value2) ? value2 : uint.MaxValue; } public ((int, int, int), uint) GetGlobalInstance(T instance) { (int, int, int) globalIndex = GetGlobalIndex(instance); uint instanceIndex = GetInstanceIndex(instance, globalIndex); return (globalIndex, instanceIndex); } public T? GetInstance((int, int, int) globalIndex, uint instanceIndex) { T instance; return TryGetInstance(globalIndex, instanceIndex, out instance) ? instance : default(T); } public bool TryGetInstance((int, int, int) globalIndex, uint instanceIndex, [MaybeNullWhen(false)] out T instance) { instance = default(T); if (!Index2Instance.TryGetValue(globalIndex, out List value) || instanceIndex >= value.Count) { return false; } instance = value[(int)instanceIndex]; return true; } public IReadOnlyList GetInstancesInZone((int, int, int) globalIndex) { IReadOnlyList result; if (!TryGetInstancesInZone(globalIndex, out IReadOnlyList instances)) { IReadOnlyList readOnlyList = new List(); result = readOnlyList; } else { result = instances; } return result; } public bool TryGetInstancesInZone((int, int, int) globalIndex, out IReadOnlyList instances) { if (Index2Instance.TryGetValue(globalIndex, out List value)) { instances = value; return true; } instances = new List(); return false; } public bool IsRegistered(T instance) { Dictionary value; return Instances2Index.TryGetValue(GetGlobalIndex(instance), out value) && value.ContainsKey(((Il2CppObjectBase)(object)instance).Pointer); } public IEnumerable<(int, int, int)> RegisteredZones() { return Index2Instance.Keys; } } public class RundownWiseDefinition where T : new() { public int RundownID { get; set; } = -1; public List Definitions { get; set; } = new List { new T() }; } public abstract class RundownWiseDefinitionManager : BaseManager where TDef : new() where TBase : RundownWiseDefinitionManager { public const int INVALID_RUNDOWN_ID = -1; public const int APPLY_TO_ALL_RUNDOWN_ID = 0; protected Dictionary> RundownDefinitions { get; set; } = new Dictionary>(); protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new RundownWiseDefinition())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); RundownWiseDefinition definitions = EOSJson.Deserialize>(json); AddDefinitions(definitions); } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { RundownWiseDefinition definitions = EOSJson.Deserialize>(content); AddDefinitions(definitions); }); } protected virtual void AddDefinitions(RundownWiseDefinition definitions) { if (definitions != null && definitions.RundownID != -1) { if (RundownDefinitions.ContainsKey(definitions.RundownID)) { EOSLogger.Log($"Replaced RundownID: '{definitions.RundownID}' ({0} means 'apply to all rundowns')"); } RundownDefinitions[definitions.RundownID] = definitions; } } public RundownWiseDefinition? GetDefinition(int id) { RundownWiseDefinition definition; return TryGetDefinition(id, out definition) ? definition : null; } public bool TryGetDefinition(int ID, [MaybeNullWhen(false)] out RundownWiseDefinition definition) { if (RundownDefinitions.ContainsKey(ID)) { definition = RundownDefinitions[ID]; return true; } definition = null; return false; } } public abstract class ZoneDefinitionManager : BaseManager where TDef : GlobalBased, new() where TBase : ZoneDefinitionManager { protected Dictionary> ZoneDefinitions { get; set; } = new Dictionary>(); protected override void ReadFiles() { File.WriteAllText(Path.Combine(base.DEFINITION_PATH, "Template.json"), EOSJson.Serialize(new ZoneDefinitionsForLevel())); foreach (string item in Directory.EnumerateFiles(base.DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { string json = File.ReadAllText(item); ZoneDefinitionsForLevel definitions = EOSJson.Deserialize>(json); AddDefinitions(definitions); } } protected override void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ZoneDefinitionsForLevel definitions = EOSJson.Deserialize>(content); AddDefinitions(definitions); }); } protected virtual void AddDefinitions(ZoneDefinitionsForLevel definitions) { if (definitions != null) { if (ZoneDefinitions.ContainsKey(definitions.MainLevelLayout)) { EOSLogger.Log("Replaced MainLevelLayout {0}", definitions.MainLevelLayout); } ZoneDefinitions[definitions.MainLevelLayout] = definitions; } } public virtual IReadOnlyList GetDefinitionsForLevel(uint mainLevelLayout) { ZoneDefinitionsForLevel value; return ZoneDefinitions.TryGetValue(mainLevelLayout, out value) ? value.Definitions : new List(); } public virtual TDef GetDefinition((int, int, int) globalIndex) { TDef definition; return TryGetDefinition(globalIndex, out definition) ? definition : null; } public virtual bool TryGetDefinition((int, int, int) globalIndex, [MaybeNullWhen(false)] out TDef definition) { definition = null; if (!ZoneDefinitions.TryGetValue(BaseManager.CurrentMainLevelLayout, out ZoneDefinitionsForLevel value)) { return false; } definition = value.Definitions.Find(delegate(TDef def) { (int, int, int) intTuple = ((GlobalBase)def).IntTuple; (int, int, int) tuple = globalIndex; return intTuple.Item1 == tuple.Item1 && intTuple.Item2 == tuple.Item2 && intTuple.Item3 == tuple.Item3; }); return definition != null; } protected void Sort(ZoneDefinitionsForLevel levelDefs) { levelDefs.Definitions.Sort((TDef u1, TDef u2) => ((GlobalBase)u1).IntTuple.CompareTo(((GlobalBase)u2).IntTuple)); } } public class ZoneDefinitionsForLevel where T : GlobalBased, new() { public uint MainLevelLayout { get; set; } = 0u; public List Definitions { get; set; } = new List { new T() }; } } namespace EOS.BaseClasses.CustomTerminalDefinition { public class CustomCommand { public struct LocaleTerminalOutput { public TerminalLineType LineType { get; set; } public LocaleText Output { get; set; } public float Time { get; set; } public readonly TerminalOutput ToTerminalOutput() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown return new TerminalOutput { LineType = LineType, Output = new LocalizedText { UntranslatedText = Output.ParseTextFragments(), Id = 0u }, Time = Time }; } } public string Command { get; set; } = string.Empty; public LocaleText CommandDesc { get; set; } = LocaleText.Empty; public List PostCommandOutputs { get; set; } = new List(); public List CommandEvents { get; set; } = new List(); public TERM_CommandRule SpecialCommandRule { get; set; } = (TERM_CommandRule)0; public CustomTerminalCommand ToVanillaDataType() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_008f: Expected O, but got Unknown return new CustomTerminalCommand { Command = Command, CommandDesc = new LocalizedText { UntranslatedText = CommandDesc.ParseTextFragments(), Id = 0u }, CommandEvents = ListExtensions.ToIl2Cpp(CommandEvents), PostCommandOutputs = ListExtensions.ToIl2Cpp(PostCommandOutputs.ConvertAll((LocaleTerminalOutput x) => x.ToTerminalOutput())), SpecialCommandRule = SpecialCommandRule }; } } public class TerminalPasswordData { public bool PasswordProtected { get; set; } = false; public string Password { get; set; } = string.Empty; public string PasswordHintText { get; set; } = "Password Required."; public bool GeneratePassword { get; set; } = true; public int PasswordPartCount { get; set; } = 1; public bool ShowPasswordLength { get; set; } = false; public bool ShowPasswordPartPositions { get; set; } = false; public SerialGeneratorManager.CodeWordLength PasswordWordLength { get; set; } = SerialGeneratorManager.CodeWordLength.Four; public List> TerminalZoneSelectionDatas { get; set; } = new List> { new List { new CustomTerminalZoneSelectionData() } }; public TerminalPasswordData() { PasswordPartCount = Math.Max(1, PasswordPartCount); } } public class BaseTerminalDefinition { [JsonPropertyOrder(-10)] public eDimensionIndex DimensionIndex { get; set; } [JsonPropertyOrder(-10)] public LG_LayerType Layer { get; set; } [JsonPropertyOrder(-10)] public LG_LayerType LayerType { private get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Layer; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Layer = value; } } [JsonPropertyOrder(-10)] public eLocalZoneIndex LocalIndex { get; set; } [JsonPropertyOrder(-9)] public uint InstanceIndex { get; set; } = uint.MaxValue; public (int, int, int) GetIntTuple() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected I4, but got Unknown //IL_0017: Expected I4, but got Unknown //IL_0017: Expected I4, but got Unknown return ((int)DimensionIndex, (int)Layer, (int)LocalIndex); } } public class TerminalDefinition { public List LocalLogFiles { get; set; } = new List(); public List UniqueCommands { get; set; } = new List { new CustomCommand() }; public TerminalPasswordData PasswordData { get; set; } = new TerminalPasswordData(); } public class CustomTerminalZoneSelectionData : GlobalBased { public eSeedType SeedType { get; set; } = (eSeedType)1; public int TerminalIndex { get; set; } = 0; public int StaticSeed { get; set; } = 0; public CustomTerminalZoneSelectionData() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) TerminalIndex = Math.Max(0, TerminalIndex); } } }