Decompiled source of ExtraObjectiveSetup M v0.1.1
plugins/Inas07.ExtraObjectiveSetup.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Globalization; 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 AIGraph; using AK; using Agents; using AmorLib.Dependencies; using AmorLib.Networking.StateReplicators; using AmorLib.Utils; using AmorLib.Utils.JsonElementConverters; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using ChainedPuzzles; using Enemies; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.Expedition; using ExtraObjectiveSetup.Expedition.Gears; using ExtraObjectiveSetup.Expedition.IndividualGeneratorGroup; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.Instances.ChainedPuzzle; using ExtraObjectiveSetup.JSON; using ExtraObjectiveSetup.Objectives.ActivateSmallHSU; using ExtraObjectiveSetup.Objectives.GeneratorCluster; using ExtraObjectiveSetup.Objectives.IndividualGenerator; using ExtraObjectiveSetup.Objectives.ObjectiveCounter; using ExtraObjectiveSetup.Objectives.TerminalUplink; using ExtraObjectiveSetup.Tweaks.BossEvents; using ExtraObjectiveSetup.Tweaks.Scout; using ExtraObjectiveSetup.Tweaks.TerminalPosition; using ExtraObjectiveSetup.Tweaks.TerminalTweak; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime; 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 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("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4c41a207dfaa6ad7f7c49b30d46675feaa6c9188")] [assembly: AssemblyProduct("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyTitle("Inas07.ExtraObjectiveSetup")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExtraObjectiveSetup { 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 uint currentForeverID; private static uint currentID; private static HashSet<uint> foreverUsedIDs; private static HashSet<uint> usedIDs; public static uint AllotReplicatorID() { while (currentID >= 10000 && usedIDs.Contains(currentID)) { currentID++; } if (currentID < 10000) { EOSLogger.Error("Replicator ID depleted. How?"); return 0u; } uint num = currentID; usedIDs.Add(num); currentID++; return num; } 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 num = currentForeverID; foreverUsedIDs.Add(num); currentForeverID++; return num; } private static void Clear() { usedIDs.Clear(); currentID = 10000u; } public static void ClearForever() { foreverUsedIDs.Clear(); currentForeverID = 1000u; } static EOSNetworking() { currentForeverID = 1000u; currentID = 10000u; foreverUsedIDs = new HashSet<uint>(); usedIDs = new HashSet<uint>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } public sealed class BatchBuildManager { private Dictionary<BatchName, Action> OnBatchStart = new Dictionary<BatchName, Action>(); private Dictionary<BatchName, Action> OnBatchDone = new Dictionary<BatchName, Action>(); public static BatchBuildManager Current { get; private set; } public void Init() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (OnBatchStart.Count < 1) { foreach (object value in Enum.GetValues(typeof(BatchName))) { OnBatchStart[(BatchName)value] = null; } } if (OnBatchDone.Count >= 1) { return; } foreach (object value2 in Enum.GetValues(typeof(BatchName))) { OnBatchDone[(BatchName)value2] = null; } } public void Add_OnBatchDone(BatchName batchName, Action action) { //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_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) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Combine(onBatchDone[batchName], action); } public void Remove_OnBatchDone(BatchName batchName, Action action) { //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_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) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Remove(onBatchDone[batchName], action); } public Action Get_OnBatchDone(BatchName batchName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return OnBatchDone[batchName]; } public void Add_OnBatchStart(BatchName batchName, Action action) { //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_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) Dictionary<BatchName, Action> onBatchStart = OnBatchStart; onBatchStart[batchName] = (Action)Delegate.Combine(onBatchStart[batchName], action); } public void Remove_OnBatchStart(BatchName batchName, Action action) { //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_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) Dictionary<BatchName, Action> onBatchStart = OnBatchStart; onBatchStart[batchName] = (Action)Delegate.Remove(onBatchStart[batchName], action); } public Action Get_OnBatchStart(BatchName batchName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return OnBatchStart[batchName]; } private BatchBuildManager() { } static BatchBuildManager() { Current = new BatchBuildManager(); } } [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.*/)] [BepInPlugin("Inas.ExtraObjectiveSetup", "ExtraObjectiveSetup", "1.8.0")] [BepInIncompatibility("Amor.ExcellentObjectiveSetup")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "ExtraObjectiveSetup"; public const string VERSION = "1.8.0"; private Harmony m_Harmony; public override void Load() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown m_Harmony = new Harmony("ExtraObjectiveSetup"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { LocalPlayer.Init(); BatchBuildManager.Current.Init(); SerialGeneratorManager.Init(); IndividualGeneratorObjectiveManager.Current.Init(); GeneratorClusterObjectiveManager.Current.Init(); HSUActivatorObjectiveManager.Current.Init(); UplinkObjectiveManager.Current.Init(); TerminalPositionOverrideManager.Current.Init(); ScoutScreamEventManager.Current.Init(); BossDeathEventManager.Current.Init(); ExpeditionDefinitionManager.Current.Init(); ExpeditionGearManager.Current.Init(); ExpeditionIGGroupManager.Current.Init(); GeneratorClusterInstanceManager.Current.Init(); HSUActivatorInstanceManager.Current.Init(); PowerGeneratorInstanceManager.Current.Init(); TerminalInstanceManager.Current.Init(); ObjectiveCounterManager.Current.Init(); } } } namespace ExtraObjectiveSetup.Utils { public static class EOSTerminalUtils { public static List<LG_ComputerTerminal> FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, Predicate<LG_ComputerTerminal> 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_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_0090: 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<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>(); Enumerator<LG_ComputerTerminal> 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<string, TerminalLogFileData> 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<WardenObjectiveEventData> GetUniqueCommandEvents(this LG_ComputerTerminal terminal, string command) { List<WardenObjectiveEventData> result = new List<WardenObjectiveEventData>(); if ((Object)(object)terminal.ConnectedReactor != (Object)null) { return result; } List<LG_ComputerTerminal> terminalsSpawnedInZone = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone; int num = terminalsSpawnedInZone.IndexOf(terminal); AIG_CourseNode spawnNode = terminal.SpawnNode; ExpeditionZoneData val = ((spawnNode != null) ? spawnNode.m_zone.m_settings.m_zoneData : null) ?? null; if (val == null) { EOSLogger.Error("GetCommandEvents: Cannot find target zone data."); return result; } if (num < 0 || num >= val.TerminalPlacements.Count) { EOSLogger.Debug($"GetCommandEvents: TerminalDataIndex({num}), TargetZoneData.TerminalPlacements.Count == ({val.TerminalPlacements.Count}) - maybe a custom terminal, skipped"); return result; } List<CustomTerminalCommand> uniqueCommands = val.TerminalPlacements[num].UniqueCommands; Enumerator<CustomTerminalCommand> enumerator = uniqueCommands.GetEnumerator(); while (enumerator.MoveNext()) { CustomTerminalCommand current = enumerator.Current; if (current.Command.ToLower().Equals(command.ToLower())) { return current.CommandEvents.ToManaged<WardenObjectiveEventData>(); } } EOSLogger.Error("GetCommandEvents: command '" + command + "' not found on " + terminal.ItemKey); return result; } 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<LG_ComputerTerminal> list = FindTerminal(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_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Invalid comparison between Unknown and I4 //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Expected O, but got Unknown //IL_058c: Expected O, but got Unknown if (!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 = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on "; int num = data.PasswordPartCount; if (codeWord.Length % num != 0) { EOSLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({num}). Defaulting to 1."); num = 1; } string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(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<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>(); LG_Zone val = default(LG_Zone); for (int j = 0; j < num; j++) { int index = j % data.TerminalZoneSelectionDatas.Count; List<CustomTerminalZoneSelectionData> list = data.TerminalZoneSelectionDatas[index]; int index2 = Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG"); CustomTerminalZoneSelectionData customTerminalZoneSelectionData = list[index2]; LG_ComputerTerminal val2; if ((int)customTerminalZoneSelectionData.SeedType == 0) { if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } if (val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find terminal zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } val2 = val.TerminalsSpawnedInZone[customTerminalZoneSelectionData.TerminalIndex]; } else { val2 = SelectPasswordTerminal(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, customTerminalZoneSelectionData.SeedType); } if ((Object)(object)val2 == (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 val3 = new TerminalLogFileData { FileName = $"key{value}_{LG_TerminalPasswordLinkerJob.GetTerminalNumber(terminal)}{(val2.HasPasswordPart ? "_1" : "")}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get((num > 1) ? 1431221909u : 2260297836u), text4), Id = 0u } }; val2.AddLocalLog(val3, true); if (!hashSet.Contains(val2)) { if (j > 0) { text += ", "; } text = text + val2.PublicName + " in " + val2.SpawnNode.m_zone.AliasName; } hashSet.Add(val2); val2.HasPasswordPart = true; } string text5 = text + "."; if (data.ShowPasswordLength) { terminal.LockWithPassword(codeWord, new string[3] { passwordHintText, text5, "Char[" + codeWord.Length + "]" }); } else { terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text5 }); } } public static void AddUniqueCommand(LG_ComputerTerminal terminal, CustomCommand cmd) { //IL_0067: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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; } terminal.m_command.AddCommand(val, cmd.Command, cmd.CommandDesc.ParseToLocalizedText(), cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(cmd.PostCommandOutputs.ConvertAll((CustomCommand.LocaleTerminalOutput x) => x.ToTerminalOutput()))); for (int num = 0; num < cmd.CommandEvents.Count; num++) { WardenObjectiveEventData val2 = cmd.CommandEvents[num]; if (val2.ChainPuzzle == 0) { continue; } ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle); if (block == null) { continue; } LG_Area val3; Transform val4; if (terminal.SpawnNode != null) { val3 = terminal.SpawnNode.m_area; val4 = 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; } val3 = (LG_Area)obj; LG_WardenObjective_Reactor connectedReactor2 = terminal.ConnectedReactor; val4 = ((connectedReactor2 != null) ? connectedReactor2.m_chainedPuzzleAlign : null) ?? null; } if ((Object)(object)val3 == (Object)null) { EOSLogger.Error("Terminal Source Area is not found! Cannot create chained puzzle for command " + cmd.Command + "!"); continue; } ChainedPuzzleInstance val5 = ChainedPuzzleManager.CreatePuzzleInstance(block, val3, val4.position, val4, val2.UseStaticBioscanPoints); List<WardenObjectiveEventData> events = ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents.GetRange(num, cmd.CommandEvents.Count - num)); val5.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); }); terminal.SetChainPuzzleForCommand(val, num, val5); } } } public static class EOSUtils { public static List<T> ToManaged<T>(this List<T> il2cppList) { List<T> list = new List<T>(); Enumerator<T> enumerator = il2cppList.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; list.Add(current); } return list; } public static void ResetProgress(this ChainedPuzzleInstance chainedPuzzle) { //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_0028: Expected O, but got Unknown //IL_006e: 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_0077: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) //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) if (chainedPuzzle.Data.DisableSurvivalWaveOnComplete) { chainedPuzzle.m_sound = new CellSoundPlayer(chainedPuzzle.m_parent.position); } foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(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<CP_Bioscan_Core>(); if ((Object)(object)val2 != (Object)null) { CP_Holopath_Spline val3 = ((Il2CppObjectBase)val2.m_spline).Cast<CP_Holopath_Spline>(); CP_PlayerScanner val4 = ((Il2CppObjectBase)val2.PlayerScanner).Cast<CP_PlayerScanner>(); val4.ResetScanProgression(0f); val2.Deactivate(); } else { CP_Cluster_Core val5 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>(); if ((Object)(object)val5 == (Object)null) { EOSLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core..."); } else { CP_Holopath_Spline val6 = ((Il2CppObjectBase)val5.m_spline).Cast<CP_Holopath_Spline>(); foreach (iChainedPuzzleCore item2 in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val5.m_childCores) { ResetChild(item2); } val5.Deactivate(); } } } } } public static class TSL_Wrapper { public static LocalizedText ParseToLocalizedText(this LocaleText text) { //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_0007: 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_001c: Expected O, but got Unknown return new LocalizedText { UntranslatedText = text.ParseTextFragments(), Id = 0u }; } 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 EOSColor { public float r { get; set; } public float g { get; set; } public float b { get; set; } public float a { get; set; } = 1f; public Color ToUnityColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(r, g, b, a); } } public static class VanillaTMPPros { public const string VANILLA_CP_PREFAB_PATH = "Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"; public static GameObject Instantiate(GameObject parent = null) { GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"); if ((Object)(object)loadedAsset == (Object)null) { EOSLogger.Error("VanillaTMPPros.Instantiate: Cannot find TMPPro from vanilla CP!"); return null; } GameObject gameObject = ((Component)loadedAsset.transform.GetChild(0).GetChild(1).GetChild(0)).gameObject; return ((Object)(object)parent != (Object)null) ? Object.Instantiate<GameObject>(gameObject.gameObject, parent.transform) : Object.Instantiate<GameObject>(gameObject.gameObject); } } 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 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 class EOSLogger { private static ManualLogSource logger = Logger.CreateLogSource("ExtraObjectiveSetup"); private static string Timestamped(string str) { return "[" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture) + "] " + str; } 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)Timestamped(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)Timestamped(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)Timestamped(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)8, (object)Timestamped(str)); } } } public static class LocalPlayer { private static int? _InstanceID; private static bool _started; public static bool HasAgent { get; private set; } public static PlayerAgent Agent { get; private set; } public static LocalPlayerAgent LocalAgent { get; private set; } public static bool TryGetAgent(out PlayerAgent agent) { agent = Agent; return HasAgent; } public static bool TryGetLocalAgent(out LocalPlayerAgent agent) { agent = LocalAgent; return HasAgent; } public static Vector3 GetPosition() { //IL_0013: 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) return HasAgent ? ((Agent)Agent).Position : Vector3.zero; } public static Vector3 GetPosition(Vector3 fallback) { //IL_000f: 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) return HasAgent ? ((Agent)Agent).Position : fallback; } public static Vector3 GetEyePosition() { //IL_0013: 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) return HasAgent ? ((Agent)Agent).EyePosition : Vector3.zero; } public static Vector3 GetEyePosition(Vector3 fallback) { //IL_000f: 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) return HasAgent ? ((Agent)Agent).EyePosition : fallback; } internal static void Init() { AssetAPI.OnStartupAssetsLoaded += StartPolling; if (AssetAPI.Status != null && AssetAPI.Status.Ready) { StartPolling(); } } private static void StartPolling() { if (!_started) { _started = true; CoroutineDispatcher.StartCoroutine(UpdatePlayerInfo()); } } private static IEnumerator UpdatePlayerInfo() { while (true) { if (PlayerManager.HasLocalPlayerAgent()) { PlayerAgent agent = PlayerManager.GetLocalPlayerAgent(); int instanceID = ((Object)agent).GetInstanceID(); if (!_InstanceID.HasValue || _InstanceID.Value != instanceID) { Agent = agent; LocalAgent = ((Il2CppObjectBase)agent).Cast<LocalPlayerAgent>(); _InstanceID = instanceID; HasAgent = true; } } else { Agent = null; LocalAgent = null; _InstanceID = null; HasAgent = false; } yield return null; } } } } namespace ExtraObjectiveSetup.Tweaks.TerminalTweak { 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; } public TerminalState(bool Enabled) { _data = 0; _length = 0; this.Enabled = true; Approached = false; this.Enabled = Enabled; } public TerminalState(bool[] logFileRead) { _data = 0; _length = 0; Enabled = true; Approached = false; Value = logFileRead; } public TerminalState(TerminalState o) { Enabled = true; Approached = false; Enabled = o.Enabled; Approached = o.Approached; _data = o._data; _length = o._length; } } public class TerminalWrapper { private readonly Dictionary<string, List<WardenObjectiveEventData>> logFileEvents = new Dictionary<string, List<WardenObjectiveEventData>>(); private readonly List<string> logFileNames = new List<string>(); public LG_ComputerTerminal lgTerminal { get; private set; } public StateReplicator<TerminalState> stateReplicator { get; private set; } private ExpeditionTerminalsDefinition expeditionTerminalDefinition { get; set; } = null; private void ChangeStateUnsynced(bool enabled) { EOSLogger.Debug($"{lgTerminal.ItemKey} state, enabled: {enabled}"); lgTerminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)lgTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true); bool flag = enabled; if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = flag; ((Interact_Base)componentInChildren).SetActive(flag); } lgTerminal.m_interfaceScreen.SetActive(flag); lgTerminal.m_loginScreen.SetActive(flag); if ((Object)(object)lgTerminal.m_text != (Object)null) { ((Behaviour)lgTerminal.m_text).enabled = flag; } if (!flag) { PlayerAgent localInteractionSource = lgTerminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { lgTerminal.ExitFPSView(); } } } public void ChangeState(bool enabled) { ChangeStateUnsynced(enabled); if (SNet.IsMaster) { StateReplicator<TerminalState> obj = stateReplicator; TerminalState state = stateReplicator.State; state.Enabled = enabled; obj.SetState(state); } } public void ChangeState() { if (SNet.IsMaster && !stateReplicator.State.Approached) { StateReplicator<TerminalState> obj = stateReplicator; TerminalState state = stateReplicator.State; state.Approached = true; obj.SetState(state); } } 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 (expeditionTerminalDefinition == null) { return; } if (SNet.IsMaster && (int)cmd == 29) { ChangeState(param); } if ((int)cmd == 31) { float delay; List<WardenObjectiveEventData> events; if (!lgTerminal.EvaluatePassword(param)) { List<WardenObjectiveEventData> eventsOnPasswordInputFailure = expeditionTerminalDefinition.EventsOnPasswordInputFailure; float num = 2.6f; delay = num; events = eventsOnPasswordInputFailure; } else { List<WardenObjectiveEventData> eventsOnPasswordInputSuccess = expeditionTerminalDefinition.EventsOnPasswordInputSuccess; float num = 2.8f; delay = num; events = eventsOnPasswordInputSuccess; } ExecuteEvents(events, delay); } } public void ChangeState(string fileName) { int num = logFileNames.IndexOf(fileName); if (expeditionTerminalDefinition != null && stateReplicator != null && num != -1) { bool[] value = stateReplicator.State.Value; bool[] array = new bool[logFileNames.Count]; for (int i = 0; i < value.Length && i < array.Length; i++) { array[i] = value[i]; } if (!array[num]) { array[num] = true; StateReplicator<TerminalState> obj = stateReplicator; TerminalState state = stateReplicator.State; state.Value = array; obj.SetState(state); } } } private void OnStateChanged(TerminalState oldState, TerminalState newState, bool isRecall) { if (oldState.Enabled != newState.Enabled) { ChangeStateUnsynced(newState.Enabled); } if (expeditionTerminalDefinition == null || isRecall) { return; } if (!oldState.Approached && newState.Approached) { ExecuteEvents(expeditionTerminalDefinition.EventsOnApproach, 0f); } bool[] value = oldState.Value; bool[] value2 = newState.Value; for (int i = 0; i < logFileNames.Count; i++) { bool flag = i < value.Length && value[i]; bool flag2 = i < value2.Length && value2[i]; if (!flag && flag2 && logFileEvents.TryGetValue(logFileNames[i], out var value3)) { ExecuteEvents(value3, 3f); } } } private void ExecuteEvents(List<WardenObjectiveEventData> events, float delay) { if (events != null && events.Count != 0) { if (delay <= 0f) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } else { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DelayedEvents(events, delay)), (Action)null); } } } private static IEnumerator DelayedEvents(List<WardenObjectiveEventData> events, float delay) { yield return (object)new WaitForSeconds(delay); WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } private void SetupExpeditionDefinition() { if (!ExpeditionDefinitionManager.Current.TryGetTerminalDefinitionFromInstance(lgTerminal, out var termDef)) { return; } expeditionTerminalDefinition = termDef; foreach (TerminalLogFileEvents logFile in termDef.LogFiles) { if (!string.IsNullOrWhiteSpace(logFile.FileName)) { string text = logFile.FileName.ToUpperInvariant(); logFileEvents[text] = logFile.EventsOnFileRead; logFileNames.Add(text); } } } public static TerminalWrapper Instantiate(LG_ComputerTerminal lgTerminal, uint replicatorID) { if ((Object)(object)lgTerminal == (Object)null || replicatorID == 0) { return null; } TerminalWrapper terminalWrapper = new TerminalWrapper(); terminalWrapper.lgTerminal = lgTerminal; terminalWrapper.stateReplicator = StateReplicator<TerminalState>.Create(replicatorID, new TerminalState { Enabled = true }, (LifeTimeType)1, (IStateReplicatorHolder<TerminalState>)null); terminalWrapper.stateReplicator.OnStateChanged += terminalWrapper.OnStateChanged; terminalWrapper.SetupExpeditionDefinition(); return terminalWrapper; } private TerminalWrapper() { } } public static class SerialGeneratorManager { private class ShuffledStepArray { private readonly string[] _values; private readonly int[] _order; private int _step = -1; public ShuffledStepArray(IEnumerable<string> 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 enum CodeWordLength { Three = 3, Four, Five, Six, Seven } 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<CodeWordLength, ShuffledStepArray> _codeWords; private static ShuffledStepArray _hardPrefixes; 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; static SerialGeneratorManager() { _random = null; _codeWords = new Dictionary<CodeWordLength, ShuffledStepArray>(); _hardPrefixes = null; 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" }; _hasPluginConflict = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("000-the_tavern-AutogenRundown") || ((BaseChainloader<BasePlugin>)(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"); } } private static 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 void Init() { LevelAPI.OnBuildStart += OnBuildStart; } 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 var value)) { return SerialGenerator.GetCodeWord(); } return value.Next(); } public static string GetCodeWordPrefix(bool useHardPrefixes, bool hyphenate = false) { string text = ((!_hasPluginConflict && useHardPrefixes) ? _hardPrefixes.Next() : SerialGenerator.
plugins/AmorLib.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using AIGraph; using Agents; using AmorLib.API; using AmorLib.Dependencies; using AmorLib.Events; using AmorLib.Utils; using AmorLib.Utils.Extensions; using AmorLib.Utils.JsonElementConverters; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CullingSystem; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.JSON; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using InjectLib.JsonNETInjection.Supports; using LevelGeneration; using Localization; using MTFO.Ext.PartialData; using MTFO.Managers; using Microsoft.CodeAnalysis; using Player; using SNetwork; using SemanticVersioning; 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("AmorLib")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ca3f17a6fa8ba94a25bbaf8db1f8b73b29636030")] [assembly: AssemblyProduct("AmorLib")] [assembly: AssemblyTitle("AmorLib")] [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 AmorLib { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] internal sealed class CallConstructorOnLoadAttribute : Attribute { } [BepInPlugin("Amor.AmorLib", "AmorLib", "1.3.1")] [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 { public override void Load() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Logger.MLS = ((BasePlugin)this).Log; new Harmony("Amor.AmorLib").PatchAll(); CallAllAutoConstructors(); Logger.Message("AmorLib is done loading!"); } private void CallAllAutoConstructors() { IEnumerable<Type> enumerable = from t in AccessTools.GetTypesFromAssembly(((object)this).GetType().Assembly) where t.IsDefined(typeof(CallConstructorOnLoadAttribute), inherit: false) select t; foreach (Type item in enumerable) { RuntimeHelpers.RunClassConstructor(item.TypeHandle); } } } internal static class Logger { public static ManualLogSource MLS { get; internal set; } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { MLS.LogError(handler); } public static void Error(string str) { MLS.LogError((object)str); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { MLS.LogWarning(handler); } public static void Warn(string str) { MLS.LogWarning((object)str); } public static void Message(BepInExMessageLogInterpolatedStringHandler handler) { MLS.LogMessage(handler); } public static void Message(string str) { MLS.LogMessage((object)str); } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { MLS.LogInfo(handler); } public static void Info(string str) { MLS.LogInfo((object)str); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { MLS.LogDebug(handler); } public static void Debug(string str) { MLS.LogDebug((object)str); } } } namespace AmorLib.Utils { [CallConstructorOnLoad] public static class CourseNodeUtil { private class DimensionMap { private const float IndexSize = 4f; public List<AIG_CourseNode>?[,] BuildNodeMap; public AIG_CourseNode[,][] NodeMap; public (int x, int z) MinCellBound; public (int x, int z) MaxCellBound; public (int x, int z) MapSize; internal DimensionMap() { BuildNodeMap = null; NodeMap = null; MapSize = (x: 0, z: 0); MinCellBound = (x: int.MaxValue, z: int.MaxValue); MaxCellBound = (x: int.MinValue, z: int.MinValue); } internal void UpdateBounds(Vector3 position) { //IL_0001: 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) int val = (int)(position.x / 4f); int val2 = (int)(position.z / 4f); MinCellBound = (x: Math.Min(val, MinCellBound.x), z: Math.Min(val2, MinCellBound.z)); MaxCellBound = (x: Math.Max(val, MaxCellBound.x), z: Math.Max(val2, MaxCellBound.z)); } internal void CreateNodeMap() { MapSize = (x: MaxCellBound.x - MinCellBound.x + 1, z: MaxCellBound.z - MinCellBound.z + 1); BuildNodeMap = new List<AIG_CourseNode>[MapSize.x, MapSize.z]; NodeMap = new AIG_CourseNode[MapSize.x, MapSize.z][]; } internal (int x, int z) GetMapPos(Vector3 position) { //IL_0001: 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) return (x: Math.Clamp((int)(position.x / 4f) - MinCellBound.x, 0, MapSize.x - 1), z: Math.Clamp((int)(position.z / 4f) - MinCellBound.z, 0, MapSize.z - 1)); } internal List<AIG_CourseNode> GetBuildNodeList(Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) (int x, int z) mapPos = GetMapPos(position); int item = mapPos.x; int item2 = mapPos.z; List<AIG_CourseNode> list = BuildNodeMap[item, item2]; if (list == null) { list = (BuildNodeMap[item, item2] = new List<AIG_CourseNode>()); } return list; } internal void FinishBuild() { for (int i = 0; i < MapSize.x; i++) { for (int j = 0; j < MapSize.z; j++) { NodeMap[i, j] = BuildNodeMap[i, j]?.ToArray(); } } BuildNodeMap = null; } public AIG_CourseNode[] GetNodes(Vector3 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) var (num, num2) = GetMapPos(position); if (NodeMap[num, num2] != null) { return NodeMap[num, num2]; } float num3 = Math.Max(MapSize.x, MapSize.z); for (int i = 1; (float)i < num3; i++) { int num4 = Math.Max(num - i, 0); int num5 = Math.Min(num + i, MapSize.x - 1); int num6 = Math.Max(num2 - i, 0); int num7 = Math.Min(num2 + i, MapSize.z - 1); for (int j = num4; j <= num5; j++) { if (NodeMap[j, num6] != null) { return NodeMap[j, num6]; } if (NodeMap[j, num7] != null) { return NodeMap[j, num7]; } } for (int k = num6 + 1; k <= num7 - 1; k++) { if (NodeMap[num4, k] != null) { return NodeMap[num4, k]; } if (NodeMap[num5, k] != null) { return NodeMap[num5, k]; } } } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(66, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unable to get any node for ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(position); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")! How are you even playing the game?!"); } Logger.Error(val); return null; } } private static readonly Dictionary<eDimensionIndex, DimensionMap> _maps; static CourseNodeUtil() { _maps = new Dictionary<eDimensionIndex, DimensionMap>(); LevelAPI.OnAfterBuildBatch += OnAfterBuildBatch; } private static void OnAfterBuildBatch(BatchName batch) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0069: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) if ((int)batch != 38) { return; } _maps.Clear(); Enumerator<AIG_NodeCluster> enumerator = AIG_NodeCluster.AllNodeClusters.GetEnumerator(); while (enumerator.MoveNext()) { AIG_NodeCluster current = enumerator.Current; object obj; if (current == null) { obj = null; } else { AIG_CourseNode courseNode = current.m_courseNode; obj = ((courseNode != null) ? courseNode.m_dimension : null); } if (obj != null) { if (!_maps.TryGetValue(current.m_courseNode.m_dimension.DimensionIndex, out DimensionMap value)) { _maps.Add(current.m_courseNode.m_dimension.DimensionIndex, value = new DimensionMap()); } Enumerator<AIG_INode> enumerator2 = current.m_nodes.GetEnumerator(); while (enumerator2.MoveNext()) { AIG_INode current2 = enumerator2.Current; value.UpdateBounds(current2.Position); } } } foreach (DimensionMap value2 in _maps.Values) { value2.CreateNodeMap(); } Enumerator<AIG_NodeCluster> enumerator4 = AIG_NodeCluster.AllNodeClusters.GetEnumerator(); while (enumerator4.MoveNext()) { AIG_NodeCluster current4 = enumerator4.Current; object obj2; if (current4 == null) { obj2 = null; } else { AIG_CourseNode courseNode2 = current4.m_courseNode; obj2 = ((courseNode2 != null) ? courseNode2.m_dimension : null); } if (obj2 == null) { continue; } DimensionMap dimensionMap = _maps[current4.m_courseNode.m_dimension.DimensionIndex]; int id = current4.CourseNode.NodeID; Enumerator<AIG_INode> enumerator5 = current4.m_nodes.GetEnumerator(); while (enumerator5.MoveNext()) { AIG_INode current5 = enumerator5.Current; List<AIG_CourseNode> buildNodeList = dimensionMap.GetBuildNodeList(current5.Position); if (!buildNodeList.Any((AIG_CourseNode node) => id == node.NodeID)) { buildNodeList.Add(current4.CourseNode); } } } foreach (DimensionMap value3 in _maps.Values) { value3.FinishBuild(); } } private static bool TryGetClosestNodeInCluster(AIG_NodeCluster cluster, Vector3 position, out AIG_INode node) { //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_001b: 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_00d4: 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_00da: 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) AIG_VoxelNodeVolume voxelNodeVolume = cluster.m_nodeVolume.m_voxelNodeVolume; if (voxelNodeVolume.TryGetCloseVoxelNode_Safe(position, position.y - 0.5f, position.y + 0.5f, ref node, false)) { return true; } int num = default(int); int num2 = default(int); voxelNodeVolume.GetGridPosition(position, ref num, ref num2); num = Mathf.Clamp(num, 0, voxelNodeVolume.m_countX - 1); num2 = Mathf.Clamp(num2, 0, voxelNodeVolume.m_countZ - 1); float num3 = float.MaxValue; AIG_VoxelNode val = null; AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar); for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (!voxelNodeVolume.TryGetPillar(num + i, num2 + j, ref val2)) { continue; } Enumerator<AIG_VoxelNode> enumerator = val2.m_nodes.GetEnumerator(); while (enumerator.MoveNext()) { AIG_VoxelNode current = enumerator.Current; if (current.ClusterID != cluster.ID) { continue; } Vector3 val3 = current.Position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num3) { val = current; num3 = sqrMagnitude; if (num3 < 0.55f) { node = ((Il2CppObjectBase)val).Cast<AIG_INode>(); return true; } } } } } if (val != null) { node = ((Il2CppObjectBase)val).Cast<AIG_INode>(); return true; } return false; } public static AIG_CourseNode ResolveCourseNode(AIG_CourseNode[] list, Vector3 position) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (list == null) { return null; } if (list.Length == 1) { return list[0]; } (AIG_CourseNode, AIG_INode)[] array = new(AIG_CourseNode, AIG_INode)[list.Length]; int num = 0; foreach (AIG_CourseNode val in list) { if (!TryGetClosestNodeInCluster(val.m_nodeCluster, position, out AIG_INode node)) { node = val.m_nodeCluster.m_nodes[0]; } array[num++] = (val, node); } bool flag = false; float num2 = float.MaxValue; AIG_CourseNode result = null; (AIG_CourseNode, AIG_INode)[] array2 = array; for (int j = 0; j < array2.Length; j++) { var (val2, val3) = array2[j]; if (val3 != null) { bool flag2 = val3.Position.y - 0.25f <= position.y; Vector3 val4 = position - val3.Position; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if ((!flag && flag2) || (flag == flag2 && sqrMagnitude < num2)) { flag = flag2; num2 = sqrMagnitude; result = val2; } } } return result; } public static AIG_CourseNode GetCourseNode(Vector3 position) { //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_000f: Unknown result type (might be due to invalid IL or missing references) Dimension dimensionFromPos = Dimension.GetDimensionFromPos(position); return GetCourseNode(position, (eDimensionIndex)((dimensionFromPos != null) ? ((int)dimensionFromPos.DimensionIndex) : 0)); } public static AIG_CourseNode GetCourseNode(Vector3 position, eDimensionIndex dimensionIndex) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!_maps.TryGetValue(dimensionIndex, out DimensionMap value)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No Position-To-Node map for dimension "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimensionIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!"); } Logger.Error(val); return null; } return ResolveCourseNode(value.GetNodes(position), position); } public static AIG_CourseNode[] GetCourseNodes(Vector3 position, eDimensionIndex dimensionIndex) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0021: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!_maps.TryGetValue(dimensionIndex, out DimensionMap value)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No Position-To-Node map for dimension "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimensionIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!"); } Logger.Error(val); return null; } return value.GetNodes(position); } } public static class DataBlockUtil { public static bool TryGetBlock<T>(string name, [MaybeNullWhen(false)] out T block) where T : GameDataBlockBase<T> { if (PartialData_Wrapper.TryGetGUID(name, out var guid)) { return DataBlockUtil.TryGetBlock<T>(guid, out block); } block = GameDataBlockBase<T>.GetBlock(name); return block != null && ((GameDataBlockBase<T>)block).internalEnabled; } public static bool TryGetBlock<T>(uint id, [MaybeNullWhen(false)] out T block) where T : GameDataBlockBase<T> { block = GameDataBlockBase<T>.GetBlock(id); return block != null && ((GameDataBlockBase<T>)block).internalEnabled; } } public abstract class GlobalBase { private eDimensionIndex _dimIndex = (eDimensionIndex)0; private LG_LayerType _layerType = (LG_LayerType)0; private eLocalZoneIndex _localIndex = (eLocalZoneIndex)0; private GlobalZoneIndex _struct; private (int dim, int layer, int zone) _tuple; public Dimension? Dimension; public LG_Zone? Zone; private bool _isDirty = true; [JsonPropertyOrder(-10)] public eDimensionIndex DimensionIndex { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return _dimIndex; } set { //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) _dimIndex = value; MarkDirty(); } } [JsonPropertyOrder(-10)] public LG_LayerType Layer { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return _layerType; } set { //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) _layerType = value; MarkDirty(); } } [JsonPropertyOrder(-10)] public eLocalZoneIndex LocalIndex { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return _localIndex; } set { //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) _localIndex = value; MarkDirty(); } } [JsonIgnore] public GlobalZoneIndex GlobalZoneIndex { get { //IL_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) Refresh(); return _struct; } } [JsonIgnore] public (int dimension, int layer, int zone) IntTuple { get { Refresh(); return _tuple; } } protected GlobalBase() { //IL_0002: 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_0010: Unknown result type (might be due to invalid IL or missing references) Refresh(); GlobalIndexUtil.BaseInstances.Add(new WeakReference<GlobalBase>(this)); } private void MarkDirty() { _isDirty = true; } private void Refresh() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_002f: 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_003b: Unknown result type (might be due to invalid IL or missing references) if (_isDirty) { _struct = GlobalIndexUtil.ToStruct(DimensionIndex, Layer, LocalIndex); _tuple = GlobalIndexUtil.ToIntTuple(DimensionIndex, Layer, LocalIndex); _isDirty = false; } } public override string ToString() { //IL_0019: 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_004f: Unknown result type (might be due to invalid IL or missing references) return $"({DimensionIndex}, {Layer}, {LocalIndex})"; } } public static class GlobalIndexUtil { internal static readonly List<WeakReference<GlobalBase>> BaseInstances; static GlobalIndexUtil() { BaseInstances = new List<WeakReference<GlobalBase>>(); LevelAPI.OnAfterBuildBatch += OnAfterBuildBatch; LevelAPI.OnLevelCleanup += OnLevelCleanup; } private static void OnAfterBuildBatch(BatchName batch) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if ((int)batch != 8) { return; } foreach (WeakReference<GlobalBase> baseInstance in BaseInstances) { if (baseInstance.TryGetTarget(out var target)) { target.Dimension = (TryGetDimension(target.DimensionIndex, out Dimension dim) ? dim : null); target.Zone = (TryGetZone(target.DimensionIndex, target.Layer, target.LocalIndex, out LG_Zone zone) ? zone : null); } } } private static void OnLevelCleanup() { BaseInstances.RemoveAll(delegate(WeakReference<GlobalBase> weakRef) { if (weakRef.TryGetTarget(out GlobalBase target)) { target.Dimension = null; target.Zone = null; return false; } return true; }); } public static (int dimension, int layer, int zone) ToIntTuple(this LG_Zone zone) { //IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references) return ToIntTuple(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex); } public static (int dimension, int layer, int zone) ToIntTuple(this GlobalZoneIndex globalIndex) { //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_000d: 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) return ToIntTuple(globalIndex.Dimension, globalIndex.Layer, globalIndex.Zone); } public static (int dimension, int layer, int zone) ToIntTuple(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zone) { //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_0009: Expected I4, but got Unknown //IL_0009: Expected I4, but got Unknown //IL_0009: Expected I4, but got Unknown return (dimension: (int)dimension, layer: (int)layer, zone: (int)zone); } public static GlobalZoneIndex ToStruct(this LG_Zone zone) { //IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references) //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_0020: Unknown result type (might be due to invalid IL or missing references) return ToStruct(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex); } public static GlobalZoneIndex ToStruct(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zone) { //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_0009: 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) return new GlobalZoneIndex(dimension, layer, zone); } public static bool TryGetZone(this (int, int, int) index, [MaybeNullWhen(false)] out LG_Zone zone) { return TryGetZone((eDimensionIndex)index.Item1, (LG_LayerType)(byte)index.Item2, (eLocalZoneIndex)index.Item3, out zone); } public static bool TryGetZone(this GlobalZoneIndex index, [MaybeNullWhen(false)] out LG_Zone zone) { //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_000d: 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) return TryGetZone(index.Dimension, index.Layer, index.Zone, out zone); } public static bool TryGetZone(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex localIndex, [MaybeNullWhen(false)] out LG_Zone zone) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_008c: 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_0035: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) zone = null; if ((Object)(object)Builder.CurrentFloor == (Object)null || (int)GameStateManager.CurrentStateName < 6 || (int)GameStateManager.CurrentStateName > 10) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryGetZone("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimension); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LG_LayerType>(layer); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eLocalZoneIndex>(localIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Not in level!"); } Logger.Error(val); return false; } if (TryGetDimension(dimension, out Dimension dim)) { Enumerator<LG_Layer> enumerator = dim.Layers.GetEnumerator(); while (enumerator.MoveNext()) { LG_Layer current = enumerator.Current; if (current.m_type == layer && current.m_zonesByLocalIndex.ContainsKey(localIndex)) { zone = current.m_zonesByLocalIndex[localIndex]; return (Object)(object)zone != (Object)null; } } } return false; } public static bool TryGetDimension(eDimensionIndex dimension, [MaybeNullWhen(false)] out Dimension dim) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0070: 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_0035: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) dim = null; if ((Object)(object)Builder.CurrentFloor == (Object)null || (int)GameStateManager.CurrentStateName < 6 || (int)GameStateManager.CurrentStateName > 10) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TryGetDimension("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eDimensionIndex>(dimension); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Not in level!"); } Logger.Error(val); return false; } Dictionary<eDimensionIndex, Dimension> indexToDimensionMap = Builder.CurrentFloor.m_indexToDimensionMap; if (indexToDimensionMap.ContainsKey(dimension)) { dim = indexToDimensionMap[dimension]; return dim != null; } return false; } } public static class JsonSerializerUtil { public static JsonSerializerOptions CreateDefaultSettings(bool useLocalizedText = true, bool usePartialData = false, bool useInjectLib = false) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions(JsonSerializer.DefaultSerializerSettings); if (useLocalizedText) { if (usePartialData && PartialData_Wrapper.IsLoaded) { jsonSerializerOptions.Converters.Add(new LocalizedTextPDataConverter()); } else { jsonSerializerOptions.Converters.Add((JsonConverter)new LocalizedTextConverter()); } } if (usePartialData && PartialData_Wrapper.IsLoaded) { jsonSerializerOptions.Converters.Add(PartialData_Wrapper.PersistentIDConverter); } if (useInjectLib && InjectLib_Wrapper.IsLoaded) { jsonSerializerOptions.Converters.Add(InjectLib_Wrapper.InjectLibConverter); } return jsonSerializerOptions; } } public static class RandomUtil { public static Random CreateSessionRandom(string offsetKey) { int seed = RundownManager.ActiveExpedition.SessionSeed ^ HashOffsetKey(offsetKey); return new Random(seed); } private static int HashOffsetKey(string offsetKey) { uint num = 2166136261u; foreach (char c in offsetKey) { num ^= c; num *= 16777619; } return (int)num; } } public sealed class ZoneNode { public class ZoneEdge { public readonly LG_Gate Gate; public readonly ZoneNode Neighbor; public bool IsOpen { get; private set; } public ZoneEdge(LG_Gate gate, ZoneNode zone) { Gate = gate; Neighbor = zone; UpdateOpen(); } internal void UpdateOpen() { IsOpen = Gate.IsTraversable; } } public readonly LG_Zone Zone; private List<(LG_Gate gate, ZoneNode zone)> _neighborsToAdd = new List<(LG_Gate, ZoneNode)>(); private readonly Dictionary<ushort, int> _areaGroups = new Dictionary<ushort, int>(); public AreaNode[] Areas { get; private set; } = null; public ZoneEdge[] Edges { get; private set; } = null; public IReadOnlyCollection<ushort> AreaGroups => _areaGroups.Keys; public ushort Group { get; private set; } = 0; public ZoneNode(LG_Zone zone) { Zone = zone; LG_Gate sourceGate = zone.m_sourceGate; object obj; if (sourceGate == null) { obj = null; } else { LG_Area linksFrom = ((LG_ZoneExpander)sourceGate).m_linksFrom; obj = ((linksFrom != null) ? linksFrom.m_zone : null); } LG_Zone val = (LG_Zone)obj; if ((Object)(object)val != (Object)null) { ZoneNode zoneNode = ZoneGraphUtil.GetZoneNode(val); zoneNode._neighborsToAdd.Add((sourceGate, this)); _neighborsToAdd.Add((sourceGate, zoneNode)); } } internal void OnNodesCreated() { Edges = _neighborsToAdd.ConvertAll(((LG_Gate gate, ZoneNode zone) pair) => new ZoneEdge(pair.gate, pair.zone)).ToArray(); _neighborsToAdd = null; List<AreaNode> list = new List<AreaNode>(Zone.m_areas.Count); Enumerator<LG_Area> enumerator = Zone.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { LG_Area current = enumerator.Current; list.Add(ZoneGraphUtil.GetAreaNode(current)); } Areas = list.ToArray(); } public bool IsZoneReachable(ZoneGraphGroup group) { return Group == group.Zone && group.Zone != 0; } public bool IsZoneReachable(ushort group) { return Group == group && group != 0; } public bool IsZoneReachable() { return Group != 0; } public bool IsReachable(ZoneGraphGroup group) { return _areaGroups.ContainsKey(group.Area); } public bool IsReachable(ushort group) { return _areaGroups.ContainsKey(group); } public bool IsReachable() { return _areaGroups.Count > 0; } internal void Reset() { _areaGroups.Clear(); Group = 0; } internal void SetGroup(ushort group) { Group = group; } internal void UpdateEdges() { ZoneEdge[] edges = Edges; foreach (ZoneEdge zoneEdge in edges) { zoneEdge.UpdateOpen(); } } internal void OnAreaReachable(ushort newGroup, ushort oldGroup) { if (_areaGroups.TryGetValue(oldGroup, out var value) && --value == 0) { _areaGroups.Remove(oldGroup); } if (newGroup != 0) { value = _areaGroups.GetValueOrDefault(newGroup); _areaGroups[newGroup] = value + 1; } } } public sealed class AreaNode { public class AreaEdge { public readonly LG_Gate Gate; public readonly AreaNode Neighbor; public bool IsOpen { get; private set; } public AreaEdge(LG_Gate gate, AreaNode area) { Gate = gate; Neighbor = area; UpdateOpen(); } internal void UpdateOpen() { IsOpen = Gate.IsTraversable; } } public readonly LG_Area Area; public ushort Group { get; private set; } = 0; public ZoneNode Zone { get; private set; } = null; public AreaEdge[] Edges { get; private set; } = null; public AreaNode(LG_Area area) { Area = area; } public bool IsReachable(ZoneGraphGroup group) { return Group == group.Area && group.Area != 0; } public bool IsReachable(ushort group) { return Group == group && group != 0; } public bool IsReachable() { return Group != 0; } internal void OnNodesCreated() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Invalid comparison between Unknown and I4 Zone = ZoneGraphUtil.GetZoneNode(Area.m_zone); List<AreaEdge> list = new List<AreaEdge>(); Enumerator<LG_Gate> enumerator = Area.m_gates.GetEnumerator(); while (enumerator.MoveNext()) { LG_Gate current = enumerator.Current; LG_Area val = ((LG_ZoneExpander)current).m_linksFrom; if (!((Object)(object)val == (Object)null)) { if (val.UID == Area.UID) { val = ((LG_ZoneExpander)current).m_linksTo; } if (!((Object)(object)val == (Object)null) && (int)((LG_ZoneExpander)current).ExpanderStatus != 2) { list.Add(new AreaEdge(current, ZoneGraphUtil.GetAreaNode(val))); } } } Edges = list.ToArray(); } internal void Reset() { Group = 0; } internal void SetGroup(ushort group) { Zone.OnAreaReachable(group, Group); Group = group; } internal void UpdateEdges() { AreaEdge[] edges = Edges; foreach (AreaEdge areaEdge in edges) { areaEdge.UpdateOpen(); } } } public record struct ZoneGraphGroup { public ushort Zone; public ushort Area; public ZoneGraphGroup() { Zone = 0; Area = 0; Zone = 0; Area = 0; } public void Reset() { Zone = 0; Area = 0; } } [CallConstructorOnLoad] public sealed class ZoneGraphUtil { public const ushort NoGroup = 0; internal static readonly ZoneGraphUtil Current; private readonly Dictionary<int, ZoneNode> _zoneToNode = new Dictionary<int, ZoneNode>(); private readonly Dictionary<int, AreaNode> _areaToNode = new Dictionary<int, AreaNode>(); private readonly Dictionary<int, ZoneGraphGroup> _playerToGroup = new Dictionary<int, ZoneGraphGroup>(); private ZoneGraphGroup _lastGroup = new ZoneGraphGroup(); public static bool IsReady { get; private set; } public static event Action? OnReachableUpdate; public static ZoneNode GetZoneNode(Agent agent) { return GetZoneNode(agent.CourseNode.m_zone); } public static ZoneNode GetZoneNode(AIG_CourseNode courseNode) { return GetZoneNode(courseNode.m_zone); } public static ZoneNode GetZoneNode(LG_Zone zone) { return Current._zoneToNode[zone.ID]; } public static AreaNode GetAreaNode(Agent agent) { return GetAreaNode(agent.CourseNode.m_area); } public static AreaNode GetAreaNode(AIG_CourseNode courseNode) { return GetAreaNode(courseNode.m_area); } public static AreaNode GetAreaNode(LG_Area area) { return Current._areaToNode[area.UID]; } public static ZoneGraphGroup GetPlayerGroup(PlayerAgent player) { return Current._playerToGroup.GetValueOrDefault(player.PlayerSlotIndex); } public static bool IsReachable(PlayerAgent player, AIG_CourseNode courseNode) { return GetAreaNode(courseNode).IsReachable(GetPlayerGroup(player)); } public static bool IsReachable(PlayerAgent player, LG_Area area) { return GetAreaNode(area).IsReachable(GetPlayerGroup(player)); } public static bool IsReachable(PlayerAgent player, LG_Zone zone) { return GetZoneNode(zone).IsReachable(GetPlayerGroup(player)); } public static bool IsReachable(AIG_CourseNode courseNode) { return GetAreaNode(courseNode).IsReachable(); } public static bool IsReachable(LG_Area area) { return GetAreaNode(area).IsReachable(); } public static bool IsReachable(LG_Zone zone) { return GetZoneNode(zone).IsReachable(); } public static bool IsZoneReachable(PlayerAgent player, AIG_CourseNode courseNode) { return GetZoneNode(courseNode.m_zone).IsZoneReachable(GetPlayerGroup(player)); } public static bool IsZoneReachable(PlayerAgent player, LG_Area area) { return GetZoneNode(area.m_zone).IsZoneReachable(GetPlayerGroup(player)); } public static bool IsZoneReachable(PlayerAgent player, LG_Zone zone) { return GetZoneNode(zone).IsZoneReachable(GetPlayerGroup(player)); } public static bool IsZoneReachable(AIG_CourseNode courseNode) { return GetZoneNode(courseNode.m_zone).IsZoneReachable(); } public static bool IsZoneReachable(LG_Area area) { return GetZoneNode(area.m_zone).IsZoneReachable(); } public static bool IsZoneReachable(LG_Zone zone) { return GetZoneNode(zone).IsZoneReachable(); } static ZoneGraphUtil() { IsReady = false; Current = new ZoneGraphUtil(); LevelAPI.OnBuildStart += delegate { LG_Area.s_areaUIDCounter = 0; }; LevelAPI.OnBuildDone += Current.BuildZoneGraph; LevelAPI.OnLevelCleanup += Current.Cleanup; EventAPI.OnCheckpointReloaded += Current.RefreshOnCheckpoint; } private static void DebugLogging() { OnReachableUpdate += delegate { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown string text = string.Join(", ", Current._playerToGroup.ToList().ConvertAll((KeyValuePair<int, ZoneGraphGroup> kv) => $"(Slot: {kv.Key}, Zone: {kv.Value.Zone}, Area: {kv.Value.Area})")); string text2 = string.Join(", ", from a in Current._areaToNode.Values where a.IsReachable() select $"({((Object)a.Zone.Zone.NavInfo).ToString()}{((Object)a.Area.m_navInfo).ToString()}:{a.Group})"); string text3 = string.Join(", ", from z in Current._zoneToNode.Values where z.IsReachable() select $"({((Object)z.Zone.NavInfo).ToString()}:[{string.Join(", ", z.AreaGroups)}])"); string text4 = string.Join(", ", from z in Current._zoneToNode.Values where z.IsZoneReachable() select $"({((Object)z.Zone.NavInfo).ToString()}:{z.Group})"); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(101, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Graph update | Player groups: ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] | Reachable nodes: ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] | Reachable zones: ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("], ZoneReachable zones: ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]"); } Logger.Info(val); }; } private void BuildZoneGraph() { Enumerator<LG_Zone> enumerator = Builder.CurrentFloor.allZones.GetEnumerator(); while (enumerator.MoveNext()) { LG_Zone current = enumerator.Current; _zoneToNode.TryAdd(current.ID, new ZoneNode(current)); Enumerator<LG_Area> enumerator2 = current.m_areas.GetEnumerator(); while (enumerator2.MoveNext()) { LG_Area current2 = enumerator2.Current; _areaToNode.TryAdd(current2.UID, new AreaNode(current2)); } } foreach (ZoneNode value in _zoneToNode.Values) { value.OnNodesCreated(); } foreach (AreaNode value2 in _areaToNode.Values) { value2.OnNodesCreated(); } IsReady = true; } private void Cleanup() { _zoneToNode.Clear(); _areaToNode.Clear(); _playerToGroup.Clear(); _lastGroup.Reset(); IsReady = false; } private void RefreshOnCheckpoint() { foreach (ZoneNode value in _zoneToNode.Values) { value.UpdateEdges(); } foreach (AreaNode value2 in _areaToNode.Values) { value2.UpdateEdges(); } RefreshGraph(); } private void RefreshGraph() { foreach (ZoneNode value in _zoneToNode.Values) { value.Reset(); } foreach (AreaNode value2 in _areaToNode.Values) { value2.Reset(); } _playerToGroup.Clear(); _lastGroup.Reset(); Enumerator<PlayerAgent> enumerator3 = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator3.MoveNext()) { PlayerAgent current3 = enumerator3.Current; if (((Agent)current3).CourseNode != null) { UpdateOrCreateGroup(current3, out var _); } } ZoneGraphUtil.OnReachableUpdate?.Invoke(); } private bool UpdateOrCreateGroup(PlayerAgent player, out ZoneGraphGroup group) { group = new ZoneGraphGroup(); AreaNode areaNode = GetAreaNode((Agent)(object)player); ZoneNode zone = areaNode.Zone; if (areaNode.IsReachable()) { group.Area = areaNode.Group; } else { group.Area = ++_lastGroup.Area; PropagateGroup(areaNode, group.Area); } if (zone.IsZoneReachable()) { group.Zone = zone.Group; } else { group.Zone = ++_lastGroup.Zone; PropagateGroup(zone, group.Zone); } if (!_playerToGroup.TryGetValue(player.PlayerSlotIndex, out var value) || value != group) { _playerToGroup[player.PlayerSlotIndex] = group; return true; } return false; } private static void PropagateGroup(AreaNode areaNode, ushort group) { areaNode.SetGroup(group); AreaNode.AreaEdge[] edges = areaNode.Edges; foreach (AreaNode.AreaEdge areaEdge in edges) { if (areaEdge.IsOpen && areaEdge.Neighbor.Group != group) { PropagateGroup(areaEdge.Neighbor, group); } } } private static void PropagateGroup(ZoneNode zoneNode, ushort group) { zoneNode.SetGroup(group); ZoneNode.ZoneEdge[] edges = zoneNode.Edges; foreach (ZoneNode.ZoneEdge zoneEdge in edges) { if (zoneEdge.IsOpen && zoneEdge.Neighbor.Group != group) { PropagateGroup(zoneEdge.Neighbor, group); } } } internal void Internal_OnPlayerNodeChanged(PlayerAgent player, AIG_CourseNode oldNode) { if (!IsReady) { return; } ZoneGraphGroup group; bool flag = UpdateOrCreateGroup(player, out group); if (oldNode != null) { AreaNode oldAreaNode = GetAreaNode(oldNode.m_area); if (!oldAreaNode.IsReachable(group.Area) && _playerToGroup.Values.All((ZoneGraphGroup zoneGraphGroup) => !oldAreaNode.IsReachable(zoneGraphGroup.Area))) { PropagateGroup(oldAreaNode, 0); flag = true; } ZoneNode oldZoneNode = oldAreaNode.Zone; if (!oldZoneNode.IsZoneReachable(group.Zone) && _playerToGroup.Values.All((ZoneGraphGroup zoneGraphGroup) => !oldZoneNode.IsZoneReachable(zoneGraphGroup.Zone))) { PropagateGroup(oldZoneNode, 0); flag = true; } } if (flag) { ZoneGraphUtil.OnReachableUpdate?.Invoke(); } } internal void Internal_OnDoorStateChanged(LG_Gate gate, bool isOpen) { if (!IsReady) { return; } AreaNode areaNode = GetAreaNode(((LG_ZoneExpander)gate).m_linksFrom); AreaNode areaNode2 = GetAreaNode(((LG_ZoneExpander)gate).m_linksTo); bool flag = areaNode.Zone != areaNode2.Zone; areaNode.UpdateEdges(); areaNode2.UpdateEdges(); if (flag) { areaNode.Zone.UpdateEdges(); areaNode2.Zone.UpdateEdges(); } if (!isOpen) { if (areaNode.IsReachable() || (flag && areaNode.Zone.IsZoneReachable())) { RefreshGraph(); } return; } bool flag2 = TryPropagate(areaNode2, areaNode) || TryPropagate(areaNode, areaNode2); bool flag3 = flag && (TryPropagateZone(areaNode2.Zone, areaNode.Zone) || TryPropagateZone(areaNode.Zone, areaNode2.Zone)); if (flag2 || flag3) { ZoneGraphUtil.OnReachableUpdate?.Invoke(); } bool TryPropagate(AreaNode oldArea, AreaNode newArea) { if (!newArea.IsReachable()) { return false; } KeyValuePair<int, ZoneGraphGroup>[] array = _playerToGroup.ToArray(); foreach (KeyValuePair<int, ZoneGraphGroup> keyValuePair in array) { keyValuePair.Deconstruct(out var key, out var value); int key2 = key; ZoneGraphGroup zoneGraphGroup = value; if (zoneGraphGroup.Area == oldArea.Group) { Dictionary<int, ZoneGraphGroup> playerToGroup = _playerToGroup; value = zoneGraphGroup with { Area = newArea.Group }; playerToGroup[key2] = value; } } PropagateGroup(oldArea, newArea.Group); return true; } bool TryPropagateZone(ZoneNode oldZone, ZoneNode newZone) { if (!newZone.IsZoneReachable()) { return false; } KeyValuePair<int, ZoneGraphGroup>[] array = _playerToGroup.ToArray(); foreach (KeyValuePair<int, ZoneGraphGroup> keyValuePair in array) { keyValuePair.Deconstruct(out var key, out var value); int key2 = key; ZoneGraphGroup zoneGraphGroup = value; if (zoneGraphGroup.Zone == oldZone.Group) { Dictionary<int, ZoneGraphGroup> playerToGroup = _playerToGroup; value = zoneGraphGroup with { Zone = newZone.Group }; playerToGroup[key2] = value; } } PropagateGroup(oldZone, newZone.Group); return true; } } } } namespace AmorLib.Utils.JsonElementConverters { [JsonConverter(typeof(BoolBaseConverter))] public struct BoolBase { public BoolMode Mode; public static readonly BoolBase False = new BoolBase(BoolMode.False); public static readonly BoolBase True = new BoolBase(BoolMode.True); public static readonly BoolBase Unchanged = new BoolBase(BoolMode.Unchanged); public BoolBase(bool mode) { Mode = (mode ? BoolMode.True : BoolMode.False); } public BoolBase(BoolMode mode) { Mode = mode; } public readonly bool GetValue(bool originalValue) { return Mode switch { BoolMode.True => true, BoolMode.False => false, _ => originalValue, }; } } public enum BoolMode { False, True, Unchanged } public sealed class BoolBaseConverter : JsonConverter<BoolBase> { public override bool HandleNull => false; public override bool CanConvert(Type objectType) { return objectType == typeof(BoolBase); } public override BoolBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) { case JsonTokenType.String: { string text = reader.GetString()?.Trim(); if (string.IsNullOrEmpty(text)) { throw new JsonException("BoolBase string value is null or empty!"); } if (text.EqualsAny(true, "Unchanged", "Ignore", "Keep", "Original", "KeepOriginal")) { return BoolBase.Unchanged; } if (bool.TryParse(text, out var result)) { return new BoolBase(result); } throw new JsonException("Cannot parse BoolBase string: " + text + "! Are you sure it's in right format?"); } case JsonTokenType.True: return BoolBase.True; case JsonTokenType.False: return BoolBase.False; default: throw new JsonException($"BoolBaseJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, BoolBase value, JsonSerializerOptions options) { switch (value.Mode) { case BoolMode.True: writer.WriteBooleanValue(value: true); break; case BoolMode.False: writer.WriteBooleanValue(value: false); break; case BoolMode.Unchanged: writer.WriteStringValue("Unchanged"); break; } writer.WriteCommentValue("BoolBase"); } } [JsonConverter(typeof(LocaleTextConverter))] public struct LocaleText : IEquatable<LocaleText> { public uint ID; public string RawText; public static readonly LocaleText Empty = new LocaleText(string.Empty); private readonly string TextFallback => (ID == 0) ? RawText : Text.Get(ID); public LocaleText(LocalizedText baseText) { RawText = ((Object)baseText).ToString(); ID = baseText.Id; } public LocaleText(string text) { if (PartialData_Wrapper.TryGetGUID(text, out var guid)) { RawText = string.Empty; ID = guid; } else { RawText = text; ID = 0u; } } public LocaleText(uint id) { RawText = string.Empty; ID = id; } public readonly LocalizedText ToLocalizedText() { //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_0021: Expected O, but got Unknown return new LocalizedText { Id = ID, UntranslatedText = TextFallback }; } public static explicit operator LocaleText(LocalizedText localizedText) { return new LocaleText(localizedText); } public static explicit operator LocaleText(string text) { return new LocaleText(text); } public static implicit operator LocalizedText(LocaleText localeText) { return localeText.ToLocalizedText(); } public static implicit operator string(LocaleText localeText) { return localeText.ToString(); } public override readonly string ToString() { return TextFallback; } public readonly bool Equals(LocaleText other) { return ID == other.ID && string.Equals(RawText, other.RawText, StringComparison.Ordinal); } public override readonly bool Equals(object? obj) { return obj is LocaleText other && Equals(other); } public override readonly int GetHashCode() { return HashCode.Combine(ID, RawText); } public static bool operator ==(LocaleText left, LocaleText right) { return left.Equals(right); } public static bool operator !=(LocaleText left, LocaleText right) { return !(left == right); } } public class LocaleTextConverter : JsonConverter<LocaleText> { public override bool HandleNull => true; public override LocaleText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.TokenType switch { JsonTokenType.String => new LocaleText(reader.GetString()), JsonTokenType.Number => new LocaleText(reader.GetUInt32()), JsonTokenType.Null => LocaleText.Empty, _ => throw new JsonException($"LocaleTextJson type: {reader.TokenType} is not implemented!"), }; } public override void Write(Utf8JsonWriter writer, LocaleText value, JsonSerializerOptions options) { if (value.ID != 0) { writer.WriteNumberValue(value.ID); } else { writer.WriteStringValue(value.RawText); } } } public sealed class LocalizedTextPDataConverter : JsonConverter<LocalizedText> { public override bool HandleNull => false; public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown if (reader.TokenType == JsonTokenType.String) { string text = reader.GetString(); LocalizedText val = new LocalizedText(); if (PartialData_Wrapper.TryGetGUID(text, out var guid)) { val.Id = guid; val.UntranslatedText = null; } else { val.Id = 0u; val.UntranslatedText = text; } return val; } if (reader.TokenType == JsonTokenType.Number) { return new LocalizedText { Id = reader.GetUInt32(), UntranslatedText = null }; } throw new JsonException($"LocalizedTextJson type: {reader.TokenType} not implemented"); } public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options) { if (value.Id != 0) { JsonSerializer.Serialize(writer, value.Id, options); } else { JsonSerializer.Serialize(writer, value.UntranslatedText, options); } } } [JsonConverter(typeof(ValueBaseConverter))] public struct ValueBase { public float Value; public ValueMode Mode; public bool FromDefault; public static readonly ValueBase Unchanged = new ValueBase(1f, ValueMode.Rel, fromDefault: true); public static readonly ValueBase Zero = new ValueBase(0f, ValueMode.Abs, fromDefault: false); public ValueBase(float value = 1f, ValueMode mode = ValueMode.Rel, bool fromDefault = true) { Value = value; Mode = mode; FromDefault = fromDefault; } public readonly float GetAbsValue(float maxValue, float currentValue) { if (Mode == ValueMode.Rel) { return FromDefault ? (currentValue * Value) : (maxValue * Value); } return Value; } public readonly float GetAbsValue(float baseValue) { return (Mode == ValueMode.Abs) ? Value : (baseValue * Value); } public readonly int GetAbsValue(int maxValue, int currentValue) { return (int)Math.Round(GetAbsValue((float)maxValue, (float)currentValue)); } public readonly int GetAbsValue(int baseValue) { return (int)Math.Round(GetAbsValue((float)baseValue)); } public override readonly string ToString() { return $"[Mode: {Mode}, Value: {Value}]"; } } public enum ValueMode { Rel, Abs } public sealed class ValueBaseConverter : JsonConverter<ValueBase> { public override bool HandleNull => false; public override bool CanConvert(Type objectType) { return objectType == typeof(ValueBase); } public override ValueBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) { case JsonTokenType.Number: return new ValueBase(reader.GetSingle(), ValueMode.Abs); case JsonTokenType.StartObject: { ValueBase result3 = default(ValueBase); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return result3; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string text3 = reader.GetString(); reader.Read(); switch (text3.ToLowerInvariant()) { case "value": result3.Value = reader.GetSingle(); break; case "mode": { if (Enum.TryParse<ValueMode>(reader.GetString(), out var result4)) { result3.Mode = result4; } break; } case "fromdefault": result3.FromDefault = reader.GetBoolean(); break; } } throw new JsonException("Expected EndObject token"); } case JsonTokenType.String: { string text = reader.GetString()?.Trim(); if (string.IsNullOrEmpty(text)) { throw new JsonException("ValueBase string value is null or empty!"); } bool fromDefault = false; if (text.EndsWith("of default", StringComparison.OrdinalIgnoreCase)) { fromDefault = true; string text2 = text; text = text2.Substring(0, text2.Length - 10).TrimEnd(); } if (text.EndsWith("%", StringComparison.InvariantCulture)) { string text2 = text; if (float.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result)) { return new ValueBase(result / 100f, ValueMode.Rel, fromDefault); } } if (text.EqualsAny(true, "Unchanged", "Ignore", "Keep", "Original", "KeepOriginal")) { return new ValueBase(1f, ValueMode.Rel, fromDefault: false); } if (float.TryParse(text, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result2)) { return new ValueBase(result2, ValueMode.Abs); } throw new JsonException("Cannot parse ValueBase string: " + text + "! Are you sure it's in right format?"); } default: throw new JsonException($"ValueBaseJson type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, ValueBase value, JsonSerializerOptions options) { switch (value.Mode) { case ValueMode.Rel: { if (Mathf.Approximately(value.Value, 1f)) { writer.WriteStringValue("Unchanged"); break; } string format = (value.FromDefault ? "{0}% of default" : "{0}%"); writer.WriteStringValue(string.Format(format, value.Value * 100f)); break; } case ValueMode.Abs: writer.WriteStringValue(value.Value.ToString()); break; } writer.WriteCommentValue("ValueBase"); } } } namespace AmorLib.Utils.Extensions { public static class CollectionExtensions { public static TValue GetOrAddNew<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key) where TValue : new() { if (!dict.TryGetValue(key, out TValue value)) { value = (dict[key] = new TValue()); } return value; } public static void ForEachValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, Action<TValue> action) where TKey : notnull { foreach (TValue value in dict.Values) { action(value); } } public static bool AnyAllValues<TKey, TCollection, TValue>(this IDictionary<TKey, TCollection> dict, Func<TValue, bool> predicate) where TCollection : IEnumerable<TValue> { foreach (TCollection value in dict.Values) { if (value.Any(predicate)) { return true; } } return false; } public static TValue? FirstOrDefaultAllValues<TKey, TCollection, TValue>(this IDictionary<TKey, TCollection> dict, Func<TValue, bool> predicate) where TCollection : IEnumerable<TValue> { foreach (TCollection value in dict.Values) { foreach (TValue item in value) { if (predicate(item)) { return item; } } } return default(TValue); } } public static class GameObjectPlusExtensions { public static bool TryAndGetComponent<T>(this GameObject go, out T component) { component = go.GetComponent<T>(); return component != null; } public static T AddOrGetComponent<T>(this GameObject go) where T : Component { if (!go.TryAndGetComponent<T>(out var component)) { return go.AddComponent<T>(); } return component; } public static bool HasComponent<T>(this GameObject go) where T : Component { return (Object)(object)go.GetComponent<T>() != (Object)null; } public static string GetFullPath(this GameObject go) { StringBuilder stringBuilder = new StringBuilder(((Object)go).name); Transform parent = go.transform.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, ((Object)parent).name + "/"); parent = parent.parent; } return stringBuilder.ToString(); } public static GameObject ClonePrefabSpawners(this GameObject original, Vector3 position, Quaternion rotation, Transform parent) { //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_0032: 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_00b6: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(original, position, rotation, parent); foreach (LG_PrefabSpawner componentsInChild in val.GetComponentsInChildren<LG_PrefabSpawner>()) { try { GameObject val2 = Object.Instantiate<GameObject>(componentsInChild.m_prefab, ((Component)componentsInChild).transform.position, ((Component)componentsInChild).transform.rotation, ((Component)componentsInChild).transform.parent); if (componentsInChild.m_disableCollision) { foreach (Collider componentsInChild2 in val2.GetComponentsInChildren<Collider>()) { componentsInChild2.enabled = false; } } if (componentsInChild.m_applyScale) { val2.transform.localScale = ((Component)componentsInChild).transform.localScale; } val2.transform.SetParent(((Component)componentsInChild).transform); } catch { } } return val; } public static uint PostWithCleanup(this CellSoundPlayer soundPlayer, uint eventID, Vector3 pos, uint in_uFlags = 1u) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return soundPlayer.Post(eventID, pos, in_uFlags, EventCallback.op_Implicit((Action<Object, AkCallbackType, AkCallbackInfo>)SoundDoneCallback), (Object)(object)soundPlayer); } private static void SoundDoneCallback(Object in_pCookie, AkCallbackType in_type, AkCallbackInfo callbackInfo) { CellSoundPlayer val = ((Il2CppObjectBase)in_pCookie).Cast<CellSoundPlayer>(); if (val != null) { val.Recycle(); } } public static bool IsWithinSqrDistance(this Vector3 a, Vector3 b, float sqrThreshold, out float sqrDistance) { //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_0009: Unknown result type (might be due to invalid IL or missing references) Vector3 val = a - b; sqrDistance = ((Vector3)(ref val)).sqrMagnitude; return sqrDistance <= sqrThreshold; } public static bool IsWithinSqrDistance(this Vector3 a, Vector3 b, float sqrThreshold) { //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_0008: Unknown result type (might be due to invalid IL or missing references) Vector3 val = a - b; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; return sqrMagnitude <= sqrThreshold; } public static Quaternion ToQuaternion(this Vector3 rotation) { //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_000a: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(rotation); } public static void SetPositionRotationScale(this Transform transform, Vector3 position, Vector3 rotation, Vector3 scale) { //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_0010: Unknown result type (might be due to invalid IL or missing references) transform.SetPositionAndRotation(position, rotation.ToQuaternion()); transform.localScale = scale; } } public static class PluginInfoExtensions { public static bool VersionEquals(this PluginInfo pluginInfo, string verison) { int? num = CompareVersion(pluginInfo, verison); return num.HasValue && num.GetValueOrDefault() == 0; } public static bool VersionExceeds(this PluginInfo pluginInfo, string version) { int? num = CompareVersion(pluginInfo, version); return num.HasValue && num.GetValueOrDefault() > 0; } public static bool VersionAtLeast(this PluginInfo pluginInfo, string version) { int? num = CompareVersion(pluginInfo, version); return num.HasValue && num.GetValueOrDefault() >= 0; } private static int? CompareVersion(PluginInfo pluginInfo, string verison) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown object obj; if (pluginInfo == null) { obj = null; } else { BepInPlugin metadata = pluginInfo.Metadata; obj = ((metadata != null) ? metadata.Version : null); } if ((Version)obj == (Version)null) { Logger.Error("PluginInfo or Version.Metadata is null"); return null; } Match match = Regex.Match(verison, "^(\\d+)\\.(\\d+)\\.(\\d+)$"); if (!match.Success) { Logger.Error("Version string format is incorrect"); return null; } int num = int.Parse(match.Groups[1].Value); int num2 = int.Parse(match.Groups[2].Value); int num3 = int.Parse(match.Groups[3].Value); return pluginInfo.Metadata.Version.CompareTo(new Version(num, num2, num3, (string)null, (string)null)); } } public static class StringExtensions { public static bool EqualsAny(this string input, bool ignoreCase = false, params string[] args) { StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); foreach (string value in args) { if (input.Equals(value, comparisonType)) { return true; } } return false; } public static LocaleText ToLocaleText(this string input) { return new LocaleText(input); } } } namespace AmorLib.Patches.SNet { [HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")] internal static class Patch_OnRecallDone { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RecallDone() { SNetEvents.RecallDone(); } } [HarmonyPatch(typeof(SNet_Capture))] internal static class Patch_SNet_Capture { [HarmonyPatch("TriggerCapture")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_TriggerCapture(SNet_Capture __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SNetEvents.BufferCaptured(__instance.PrimedBufferType); } [HarmonyPatch("RecallBuffer")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!__instance.IsRecalling) { SNetEvents.BufferRecalled(bufferType); } } } } namespace AmorLib.Patches.LevelGen { [HarmonyPatch] internal static class BuilderPatches { [HarmonyPatch(typeof(Builder), "BuildDone")] [HarmonyPostfix] [HarmonyBefore(new string[] { "dev.gtfomodding.gtfo-api" })] [HarmonyWrapSafe] private static void BuildDone_Early() { LevelEvents.BuildDoneEarly(); } [HarmonyPatch(typeof(Builder), "BuildDone")] [HarmonyPostfix] [HarmonyAfter(new string[] { "dev.gtfomodding.gtfo-api" })] [HarmonyWrapSafe] private static void BuildDone_Late() { LevelEvents.BuildDoneLate(); } } [HarmonyPatch(typeof(LG_BuildZoneLightsJob), "Build")] internal static class LightsPatches { [HarmonyPrefix] [HarmonyPriority(600)] [HarmonyWrapSafe] private static void Pre_ZoneBuild(LG_BuildZoneLightsJob __instance, out List<LightWorker>? __state) { LG_Zone zone = __instance.m_zone; if ((Object)(object)zone == (Object)null) { __state = null; return; } __state = new List<LightWorker>(); Enumerator<AIG_CourseNode> enumerator = zone.m_courseNodes.GetEnumerator(); while (enumerator.MoveNext()) { AIG_CourseNode current = enumerator.Current; foreach (LG_Light componentsInChild in ((Component)current.m_area).GetComponentsInChildren<LG_Light>(false)) { __state.Add(new LightWorker(zone, current, componentsInChild, ((Object)componentsInChild).GetInstanceID(), componentsInChild.m_intensity)); } } } [HarmonyPostfix] [HarmonyPriority(600)] [HarmonyWrapSafe] private static void Post_ZoneBuild(LG_BuildZoneLightsJob __instance, bool __result, List<LightWorker>? __state) { if ((Object)(object)__instance.m_zone == (Object)null || !__result || __state == null) { return; } foreach (LightWorker item in __state) { item.Setup(); LightAPI.AllLightsMap.TryAdd(item.InstanceID, item); } } } [HarmonyPatch] internal static class TerminalPatches { private static readonly Dictionary<(int, int, int), LG_ComputerTerminal> ReactorTerminals; static TerminalPatches() { ReactorTerminals = new Dictionary<(int, int, int), LG_ComputerTerminal>(); LevelAPI.OnAfterBuildBatch += OnAfterBatchBuild; LevelAPI.OnLevelCleanup += OnLevelCleanup; } private static void OnAfterBatchBuild(BatchName batch) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 if ((int)batch != 47) { return; } foreach (KeyValuePair<(int, int, int), LG_ComputerTerminal> kvp in ReactorTerminals) { if (kvp.Key.TryGetZone(out LG_Zone zone) && !ListExtensions.ToManaged<LG_ComputerTerminal>(zone.TerminalsSpawnedInZone).Any((LG_ComputerTerminal term) => term.SyncID == kvp.Value.SyncID)) { zone.TerminalsSpawnedInZone.Add(kvp.Value); Logger.Debug("Appended reactor terminal to its TerminalsSpawnedInZone"); } } } private static void OnLevelCleanup() { ReactorTerminals.Clear(); } [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] [HarmonyPrefix] [HarmonyPriority(700)] [HarmonyWrapSafe] private static void HiddenCommandExecutionFix(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_002b: 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_0030: Invalid comparison between Unknown and I4 //IL_001e: 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_0037: Invalid comparison between Unknown and I4 //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) //IL_0027: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 if (((Il2CppArrayBase<TERM_Command>)(object)LG_ComputerTerminalCommandInterpreter.m_alwaysHiddenCommands).Contains(cmd)) { return; } TERM_Command val = cmd; TERM_Command val2 = val; if ((int)val2 <= 6) { if ((int)val2 == 0 || val2 - 5 <= 1) { return; } } else if (val2 - 10 <= 1 || (int)val2 == 16 || (int)val2 == 31) { return; } if (__instance.m_terminal.CommandIsHidden(cmd)) { cmd = (TERM_Command)10; } } [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Start")] [HarmonyPostfix] [HarmonyWrapSafe] private static void CustomReactorTerminalFix(LG_WardenObjective_Reactor __instance) { if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("FlowGeos") && !((Object)(object)__instance.m_terminalPrefab != (Object)null)) { Logger.Info("Resolving terminal prefab for reactor"); GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/FunctionMarkers/Terminal_Floor.prefab"); if ((Object)(object)loadedAsset == (Object)null) { Logger.Error("Failed to find terminal prefab loaded asset?"); } else { __instance.m_terminalPrefab = loadedAsset; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool ReactorTerminalSpawnNodeFix(LG_ComputerTerminal __instance, ref AIG_CourseNode __result) { if ((Object)(object)__instance.ConnectedReactor != (Object)null && __instance.m_terminalItem.SpawnNode == null) { __result = __instance.ConnectedReactor.SpawnNode; return false; } return true; } [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "GenericObjectiveSetup")] [HarmonyPostfix] [HarmonyWrapSafe] private static void ReactorTerminalInZoneFix(LG_WardenObjective_Reactor __instance) { if (__instance.SpawnNode.m_zone.TerminalsSpawnedInZone != null && (Object)(object)__instance.m_terminal != (Object)null) { ReactorTerminals.Add(__instance.SpawnNode.m_zone.ToIntTuple(), __instance.m_terminal); } } } [HarmonyPatch] internal static class ZoneGraphPatches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static void Pre_PlayerNodeSet(PlayerAgent __instance, ref AIG_CourseNode __state) { __state = ((Agent)__instance).CourseNode; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void Post_PlayerNodeSet(PlayerAgent __instance, AIG_CourseNode __state) { AIG_CourseNode courseNode = ((Agent)__instance).CourseNode; if (courseNode != null && __state != courseNode) { ZoneGraphUtil.Current.Internal_OnPlayerNodeChanged(__instance, __state); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static void Pre_GateIsTraversable(LG_Gate __instance, ref bool __state) { __state = __instance.IsTraversable; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void Post_GateIsTraversable(LG_Gate __instance, bool __state) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (__state != __instance.IsTraversable && (int)((LG_ZoneExpander)__instance).ExpanderStatus == 1) { ZoneGraphUtil.Current.Internal_OnDoorStateChanged(__instance, !__state); } } } } namespace AmorLib.Networking { public struct LowResColor { public byte r; public byte g; public byte b; public byte a; private static Color _color = Color.black; public static implicit operator Color(LowResColor lowResColor) { //IL_005d: 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_0065: Unknown result type (might be due to invalid IL or missing references) _color.r = (float)(int)lowResColor.r / 255f; _color.g = (float)(int)lowResColor.g / 255f; _color.b = (float)(int)lowResColor.b / 255f; _color.a = (float)(int)lowResColor.a / 255f; return _color; } public static implicit operator LowResColor(Color color) { //IL_000b: 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_0033: 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) return new LowResColor { r = (byte)(color.r * 255f), g = (byte)(color.g * 255f), b = (byte)(color.b * 255f), a = (byte)(color.a * 255f) }; } } public abstract class SyncedEvent<S> where S : struct { public delegate void ReceiveHandler(S packet); public virtual string Prefix => string.Empty; public abstract string GUID { get; } public bool IsSetup { get; private set; } = false; public string EventName { get; private set; } = string.Empty; public event ReceiveHandler? OnReceive; public event ReceiveHandler? OnReceiveLocal; public void Setup() { if (!IsSetup) { EventName = (Utility.IsNullOrWhiteSpace(Prefix) ? ("SE-" + GUID) : ("SE-" + Prefix + "-" + GUID)); NetworkAPI.RegisterEvent<S>(EventName, (Action<ulong, S>)ReceiveClient_Callback); IsSetup = true; } } public void Send(S packetData, SNet_Player? target = null, SNet_ChannelType priority = (SNet_ChannelType)4) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target != (Object)null) { NetworkAPI.InvokeEvent<S>(EventName, packetData, target, priority); } else { NetworkAPI.InvokeEvent<S>(EventName, packetData, priority); } ReceiveLocal_Callback(packetData); } private void ReceiveLocal_Callback(S packet) { ReceiveLocal(packet); this.OnReceiveLocal?.Invoke(packet); } private void ReceiveClient_Callback(ulong sender, S packet) { Receive(packet); this.OnReceive?.Invoke(packet); } protected virtual void ReceiveLocal(S packet) { } protected virtual void Receive(S packet) { } } public abstract class SyncedEventMasterOnly<S> : SyncedEvent<S> where S : struct { public void Send(S packet, SNet_ChannelType priority = (SNet_ChannelType)4) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { Send(packet, SNet.Master, priority); } else { Receive(packet); } } } } namespace AmorLib.Networking.StateReplicators { public interface IStateReplicatorHolder<S> where S : struct { StateReplicator<S>? Replicator { get; } void OnStateChange(S oldState, S state, bool isRecall); } public struct Packet { public uint replicatorID; public PacketAction action; } public enum PacketAction : byte { Created, Destroyed, SyncRequest } internal sealed class ReplicatorHandshake { public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer); private readonly Dictionary<uint, (bool SetupOnHost, bool SetupOnClient)> _lookup = new Dictionary<uint, (bool, bool)>(); public string EventName { get; private set; } public bool IsReadyToSync { get; private set; } public event ClientRequestedSyncDel? OnClientSyncRequested; public ReplicatorHandshake(string eventName) { EventName = eventName; NetworkAPI.RegisterEvent<Packet>(EventName, (Action<ulong, Packet>)OnSyncAction); SNetEvents.OnRecallDone += OnRecallDone; } private void OnRecallDone() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(EventName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Client sending sync request"); } Logger.Warn(val); ClientSyncRequest(); } private void ClientSyncRequest() { if (SNet.IsMaster) { return; } foreach (uint key in _lookup.Keys) { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = key, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); } } public void Reset() { _lookup.Clear(); } private void OnSyncAction(ulong sender, Packet packet) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown if (!SNet.IsMaster && sender == SNet.Master.Lookup) { if (packet.action != PacketAction.SyncRequest) { SetHostState(packet.replicatorID, packet.action == PacketAction.Created); } else { Logger.Warn("Handshake :: OnSyncAction host sync request has no implementation"); } } else { if (!SNet.IsMaster) { return; } bool flag = default(bool); switch (packet.action) { case PacketAction.Created: SetClientState(packet.replicatorID, isSetup: true); break; case PacketAction.Destroyed: SetClientState(packet.replicatorID, isSetup: false); break; case PacketAction.SyncRequest: { SNet_Player requestedPlayer = default(SNet_Player); if (!SNet.TryGetPlayer(sender, ref requestedPlayer)) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: Cannot find player from sender: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(sender); } Logger.Error(val); } else { this.OnClientSyncRequested?.Invoke(requestedPlayer); } break; } default: { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Handshake :: Unknown packet action "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<PacketAction>(packet.action); } Logger.Error(val); break; } } } } public void UpdateCreated(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, (SNet_ChannelType)2); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, SNet.Master, (SNet_ChannelType)2); } else { Logger.Error("Handshake :: MASTER is NULL in lobby; this should NOT happen!!"); } } else { Logger.Error("Handshake :: Session LifeTimeType StateReplicator cannot be created without lobby!"); } } public void UpdateDestroyed(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, (SNet_ChannelType)2); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, SNet.Master, (SNet_ChannelType)2); } else { Logger.Error("Handshake :: MASTER is NULL in lobby; this should NOT happen!!"); } } else { Logger.Error("Handshake :: Session LifeTimeType StateReplicator cannot be created without lobby!"); } } private void SetHostState(uint id, bool isSetup) { if (_lookup.TryGetValue(id, out (bool, bool) value)) { value.Item1 = isSetup; } else { _lookup[id] = new(bool, bool) { Item1 = isSetup }; } UpdateSyncState(id); } private void SetClientState(uint id, bool isSetup) { if (_lookup.TryGetValue(id, out (bool, bool) value)) { value.Item2 = isSetup; } else { _lookup[id] = new(bool, bool) { Item2 = isSetup }; } UpdateSyncState(id); } private void UpdateSyncState(uint id) { bool isReadyToSync = IsReadyToSync; IsReadyToSync = _lookup.TryGetValue(id, out (bool, bool) value) && value.Item1 && value.Item2; if (IsReadyToSync && IsReadyToSync != isReadyToSync && SNet.HasMaster && !SNet.IsMaster) { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); } } } public enum Size { State4Byte = 4, State8Byte = 8, State16Byte = 16, State32Byte = 32, State48Byte = 48, State64Byte = 64, State80Byte = 80, State96Byte = 96, State128Byte = 128, State196Byte = 196, State256Byte = 256 } internal delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct; internal interface IReplicatorEvent<S> { string EventName { get; } bool IsRegistered { get; } void Invoke(uint replicatorID, S data, SNet_Player? target = null, SNet_ChannelType priority = (SNet_ChannelType)2); } internal interface IStatePayload { uint ID { get; set; } S Get<S>(Size size) where S : struct; void Set<S>(S stateData, Size size) where S : struct; } internal class ReplicatorPayload<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload { private readonly Size _payloadSize; public string EventName { get; private set; } = string.Empty; public bool IsRegistered => NetworkAPI.IsEventRegistered(EventName); public ReplicatorPayload(Size size, string eventName, OnReceiveDel<S> onReceiveCallback) { ReplicatorPayload<S, P> replicatorPayload = this; NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload) { onReceiveCallback?.Invoke(sender, payload.ID, payload.Get<S>(replicatorPayload._payloadSize)); }); EventName = eventName; _payloadSize = size; } public void Invoke(uint replicatorID, S data, SNet_Player? target, SNet_ChannelType priority) { //IL_0054: 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) P val = new P { ID = replicatorID }; val.Set(data, _payloadSize); if ((Object)(object)target != (Object)null) { NetworkAPI.InvokeEvent<P>(EventName, val, target, priority); } else { NetworkAPI.InvokeEvent<P>(EventName, val, priority); } } } internal struct StatePayloadBytes : IStatePayload { public unsafe fixed byte PayloadBytes[256]; public uint ID { get; set; } public unsafe S Get<S>(Size size) where S : struct { byte[] array = new byte[(int)size]; fixed (byte* payloadBytes = PayloadBytes) { Marshal.Copy((IntPtr)payloadBytes, array, 0, (int)size); } return FromBytes<S>(array); } public unsafe void Set<S>(S stateData, Size size) where S : struct { byte[] array = ToBytes(stateData); if (array.Length > (int)size) { throw new ArgumentException($"Data size {array.Length} exceeds payload size {size}, unable to serialize {"S"}!"); } fixed (byte* payloadBytes = PayloadBytes) { Marshal.Copy(array, 0, (IntPtr)payloadBytes, array.Length); for (int i = array.Length; i < (int)size; i++) { payloadBytes[i] = 0; } } } private static byte[] ToBytes<S>(S data) where S : struct { int num = Marshal.SizeOf<S>(); byte[] array = new byte[num]; IntPtr intPtr = Marshal.AllocHGlobal(num); try { Marshal.StructureToPtr(data, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, num); return array; } finally { Marshal.FreeHGlobal(intPtr); } } private static S FromBytes<S>(byte[] arr) where S : struct { IntPtr intPtr = Marshal.AllocHGlobal(arr.Length); try { Marshal.Copy(arr, 0, intPtr, arr.Length); return Marshal.PtrToStructure<S>(intPtr); } finally { Marshal.FreeHGlobal(intPtr); } } } public enum LifeTimeType { Permanent, Session } public sealed class StateReplicator<S> where S : struct { internal readonly Dictionary<eBufferType, S> _recallStateSnapshots = new Dictionary<eBufferType, S>(); public static readonly string Name; public static readonly string HashName; public static readonly string ClientRequestEventName; public static readonly string HostSetStateEventName; public static readonly string HostSetRecallStateEventName; public static readonly string HandshakeEventName; public static readonly int StateSize; public static readonly Size StateSizeType; private static readonly IReplicatorEvent<S>? _clientRequestEvent; private static readonly IReplicatorEvent<S>? _hostSetStateEvent; private static readonly IReplicatorEvent<S>? _hostSetRecallStateEvent; private static readonly ReplicatorHandshake? _handshake; internal static readonly Dictionary<uint, StateReplicator<S>> _replicators; public bool IsValid => ID != 0; public bool IsInvalid => ID == 0; public uint ID { get; private set; } public LifeTimeType LifeTime { get; private set; } public IStateReplicatorHolder<S>? Holder { get; private set; } public S State { get; private set; } public S LastState { get; private set; } public bool ClientSendStateAllowed { get; set; } = true; public bool CanSendToClient => SNet.IsInLobby && SNet.IsMaster; public bool CanSendToHost => SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster && ClientSendStateAllowed; public event Action<S, S, bool>? OnStateChanged; public void SetState(S state) { if (!IsInvalid) { DoSync(state); } } public void SetStateUnsynced(S state) { if (!IsInvalid) { LastState = state; State = state; } } public void Unload() { if (IsValid) { _replicators.Remove(ID); _recallStateSnapshots.Clear(); _handshake?.UpdateDestroyed(ID); ID = 0u; } } private void DoSync(S newState) { if (IsValid) { if (CanSendToClient) { _hostSetStateEvent?.Invoke(ID, newState, null, (SNet_ChannelType)2); Internal_ChangeState(newState, isRecall: false); } else if (CanSendToHost) { _clientRequestEvent?.Invoke(ID, newState, SNet.Master, (SNet_ChannelType)2); } } } private void Internal_ChangeState(S state, bool isRecall) { if (!IsInvalid) { S state2 = State; State = state; LastState = state2; this.OnStateChanged?.Invoke(state2, state, isRecall); Holder?.OnStateChange(state2, state, isRecall); } } private void SendDropInState(SNet_Player target) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (IsInvalid || (Object)(object)target == (Object)null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("IsInvalid: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(IsInvalid); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SendDropInState"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" :: Target was null? "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)target == (Object)null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?"); } Logger.Error(val); } else { _hostSetRecallStateEvent?.Invoke(ID, State, target, (SNet_ChannelType)2); } } public void ClearAllRecallSnapshot() { if (!IsInvalid) { _recallStateSnapshots.Clear(); } } private void SaveSnapshot(eBufferType type) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!IsInvalid) { _recallStateSnapshots[type] = State; } } private void RestoreSnapshot(eBufferType type) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!IsValid || !CanSendToClient) { return; } if (_recallStateSnapshots.TryGetValue(type, out var value)) { _hostSetRecallStateEvent?.Invoke(ID, value, null, (SNet_ChannelType)2); Internal_ChangeState(value, isRecall: true); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RestoreSnapshot"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" :: There was no snapshot for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eBufferType>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?"); } Logger.Error(val); } static StateReplicator() { _replicators = new Dictionary<uint, StateReplicator<S>>(); Name = typeof(S).Name; StateSize = Marshal.SizeOf(typeof(S)); StateSizeType = GetSizeType(StateSize); using MD5 mD = MD5.Create(); byte[] inArray = mD.ComputeHash(Encoding.UTF8.GetBytes(typeof(S).FullName)); HashName = Convert.ToBase64String(inArray); ClientRequestEventName = "SRcr-" + Name + "-" + HashName; HostSetStateEventName = "SRhs-" + Name + "-" + HashName; HostSetRecallStateEventName = "SRre-" + Name + "-" + HashName; HandshakeEventName = "RH-" + Name + "-" + HashName; _clientRequestEvent = CreatePayloadEvent(ClientRequestEventName, ClientRequestEventCallback); _hostSetStateEvent = CreatePayloadEvent(HostSetStateEventName, HostSetStateEventCallback); _hostSetRecallStateEvent = CreatePayloadEvent(HostSetRecallStateEventName, HostSetRecallStateEventCallback); _handshake = CreateHandshakeEvent(); SNetEvents.OnBufferCapture += BufferStored; SNetEvents.OnBufferRecall += BufferRecalled; LevelAPI.OnLevelCleanup += OnLevelCleanup; } public static StateReplicator<S>? Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S>? holder = null) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown if (replicatorID == 0) { Logger.Error("Replicator ID 0 is reserved for empty!"); return null; } if (_replicators.ContainsKey(replicatorID)) { Logger.Error("Replicator ID has already assigned!"); return null; } StateReplicator<S> stateReplicator = new StateReplicator<S> { ID = replicatorID, LifeTime = lifeTime, Holder = holder, State = startState }; switch (lifeTime) { case LifeTimeType.Permanent: Logger.Debug("LifeTime is Permanent :: Handshaking is disabled"); break; case LifeTimeType.Session: _handshake?.UpdateCreated(replicatorID); break; default: { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is invalid!"); } Logger.Error(val); return null; } } _replicators[replicatorID] = stateReplicator; return stateReplicator; } public static Size GetSizeType(int stateSize) { Size size = Size.State8Byte; foreach (Size value in Enum.GetValues(typeof(Size))) { if (stateSize <= (int)value && size < value) { size = valu
plugins/Inas07.EOSExt.DimensionWarp.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using EOSExt.DimensionWarp.Definition; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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("Inas07.EOSExt.DimensionWarp")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8d057572a2fe6c6426a9495668599f755b5e51b0")] [assembly: AssemblyProduct("Inas07.EOSExt.DimensionWarp")] [assembly: AssemblyTitle("Inas07.EOSExt.DimensionWarp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.DimensionWarp { public class DimensionWarpManager : GenericExpeditionDefinitionManager<DimensionWarpDefinition> { public enum WardenEvents_Warp { WarpTeam = 160, WarpRange, WarpItemsInZone } private readonly ImmutableList<Vector3> lookDirs = new List<Vector3> { Vector3.forward, Vector3.back, Vector3.left, Vector3.right }.ToImmutableList(); public static DimensionWarpManager Current { get; private set; } protected override string DEFINITION_NAME => "DimensionWarp"; public AIG_NodeCluster GetNodeFromDimensionPosition(eDimensionIndex dimensionIndex, Vector3 position) { //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_0013: 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) AIG_GeomorphNodeVolume val = default(AIG_GeomorphNodeVolume); AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar); AIG_INode val3 = default(AIG_INode); AIG_NodeCluster result = default(AIG_NodeCluster); if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, dimensionIndex, position, ref val) || !((AIG_NodeVolume)val).m_voxelNodeVolume.TryGetPillar(position, ref val2) || !val2.TryGetVoxelNode(position.y, ref val3) || !AIG_NodeCluster.TryGetNodeCluster(val3.ClusterID, ref result)) { EOSLogger.Error("GetNodeFromDimensionPosition: Position is not valid, try again inside an area."); return null; } return result; } public DimensionWarpDefinition GetWarpDefinition(string worldEventObjectFilter) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName != 10 || !base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { EOSLogger.Error($"GetWarpPositions: Didn't find config with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}"); return null; } DimensionWarpDefinition dimensionWarpDefinition = base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.Find((DimensionWarpDefinition def) => def.WorldEventObjectFilter == worldEventObjectFilter); if (dimensionWarpDefinition == null) { EOSLogger.Error($"GetWarpPositions: Didn't find config for {worldEventObjectFilter} with MainLevelLayout {RundownManager.ActiveExpedition.LevelLayoutData}"); return new DimensionWarpDefinition(); } return dimensionWarpDefinition; } public void WarpItem(ItemInLevel item, eDimensionIndex warpToDim, Vector3 warpToPosition) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_002a: 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_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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster && (int)GameStateManager.CurrentStateName == 10 && (Object)(object)item != (Object)null) { AIG_NodeCluster nodeFromDimensionPosition = GetNodeFromDimensionPosition(warpToDim, warpToPosition); if (nodeFromDimensionPosition != null) { item.GetSyncComponent().AttemptPickupInteraction((ePickupItemInteractionType)1, (SNet_Player)null, ((Item)item).pItemData.custom, warpToPosition, Quaternion.identity, nodeFromDimensionPosition.CourseNode, true, true); } else { EOSLogger.Error("WarpTeam: cannot find course node for item to warp"); } } } public void WarpItemsInZone(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, string worldEventObjectFilter) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_00e6: 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_00fe: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster || (int)GameStateManager.CurrentStateName != 10) { return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { EOSLogger.Error("WarpItemsInZone: master - LocalPlayerAgent is null???"); return; } DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter); if (warpDefinition == null) { EOSLogger.Error("WarpItemsInZone: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined"); return; } List<PositionAndLookDir> locations = warpDefinition.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpItemsInZone: no warp position found"); return; } int num = 0; Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator(); while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; ItemInLevel val = ((Il2CppObjectBase)current).TryCast<ItemInLevel>(); if ((Object)(object)val != (Object)null) { AIG_CourseNode courseNode = val.CourseNode; if (val.internalSync.GetCurrentState().placement.droppedOnFloor && courseNode.m_dimension.DimensionIndex == dimensionIndex && courseNode.LayerType == layer && courseNode.m_zone.LocalIndex == localIndex && (!warpDefinition.OnWarp.WarpItemsInZone_OnlyWarpWarpable || val.CanWarp)) { Vector3 warpToPosition = locations[num].Position.ToVector3(); WarpItem(val, dimensionIndex, warpToPosition); } num = (num + 1) % locations.Count; } } } internal void WarpItemsInZone(WardenObjectiveEventData e) { //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_0009: 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_0010: Unknown result type (might be due to invalid IL or missing references) //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) eDimensionIndex dimensionIndex = e.DimensionIndex; LG_LayerType layer = e.Layer; eLocalZoneIndex localIndex = e.LocalIndex; string worldEventObjectFilter = e.WorldEventObjectFilter; WarpItemsInZone(dimensionIndex, layer, localIndex, worldEventObjectFilter); } public void WarpRange(Vector3 rangeOrigin, float range, string worldEventObjectFilter) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //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_00d4: 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_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: 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_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: 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_0138: 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_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) //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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10) { return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { EOSLogger.Error("WarpTeam: LocalPlayerAgent is null"); return; } DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter); if (warpDefinition == null) { EOSLogger.Error("WarpItemsInZone: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined"); return; } List<PositionAndLookDir> locations = warpDefinition.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpAlivePlayersInRange: no warp locations found"); return; } int index = localPlayerAgent.PlayerSlotIndex % locations.Count; Vector3 val = locations[index].Position.ToVector3(); int index2 = locations[index].LookDir % lookDirs.Count; Vector3 val2 = lookDirs[index2]; int num = 0; List<SentryGunInstance> list = new List<SentryGunInstance>(); Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator(); Vector3 val4; while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast<SentryGunInstance>(); if ((Object)(object)val3 != (Object)null) { if (!((ItemEquippable)val3).LocallyPlaced || !((Agent)((Item)val3).Owner).Alive) { continue; } val4 = rangeOrigin - ((Agent)((Item)val3).Owner).Position; if (((Vector3)(ref val4)).magnitude < range) { val4 = rangeOrigin - ((Component)val3).transform.position; if (((Vector3)(ref val4)).magnitude < range || warpDefinition.OnWarp.WarpRange_WarpDeployedSentryOutsideRange) { list.Add(val3); } } } else { if (!SNet.IsMaster) { continue; } ItemInLevel val5 = ((Il2CppObjectBase)current).TryCast<ItemInLevel>(); if ((Object)(object)val5 != (Object)null) { val4 = ((Component)val5).transform.position - rangeOrigin; if (((Vector3)(ref val4)).magnitude < range) { Vector3 warpToPosition = locations[num].Position.ToVector3(); WarpItem(val5, warpDefinition.DimensionIndex, warpToPosition); num = (num + 1) % locations.Count; } } } } list.ForEach(delegate(SentryGunInstance sentryGun) { sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0); }); if (((Agent)localPlayerAgent).Alive) { val4 = rangeOrigin - ((Agent)localPlayerAgent).Position; if (((Vector3)(ref val4)).magnitude < range && !localPlayerAgent.TryWarpTo(warpDefinition.DimensionIndex, val, val2, true)) { EOSLogger.Error($"WarpAlivePlayersInRange: TryWarpTo failed, Position: {val}"); } } } internal void WarpRange(WardenObjectiveEventData e) { //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_0017: Unknown result type (might be due to invalid IL or missing references) Vector3 position = e.Position; float fogTransitionDuration = e.FogTransitionDuration; string worldEventObjectFilter = e.WorldEventObjectFilter; WarpRange(position, fogTransitionDuration, worldEventObjectFilter); } public void WarpTeam(string worldEventObjectFilter) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //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_00d4: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10) { return; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { EOSLogger.Error("WarpTeam: LocalPlayerAgent is null"); return; } DimensionWarpDefinition warpDefinition = GetWarpDefinition(worldEventObjectFilter); if (warpDefinition == null) { EOSLogger.Error("WarpTeam: worldEventObjectFilter '" + worldEventObjectFilter + "' is not defined"); return; } List<PositionAndLookDir> locations = warpDefinition.Locations; if (locations.Count < 1) { EOSLogger.Error("WarpTeam: no warp locations found"); return; } int num = localPlayerAgent.PlayerSlotIndex % locations.Count; Vector3 val = locations[num].Position.ToVector3(); int index = locations[num].LookDir % lookDirs.Count; Vector3 val2 = lookDirs[index]; int num2 = 0; List<SentryGunInstance> list = new List<SentryGunInstance>(); Enumerator<IWarpableObject> enumerator = Dimension.WarpableObjects.GetEnumerator(); while (enumerator.MoveNext()) { IWarpableObject current = enumerator.Current; SentryGunInstance val3 = ((Il2CppObjectBase)current).TryCast<SentryGunInstance>(); if ((Object)(object)val3 != (Object)null) { if (((ItemEquippable)val3).LocallyPlaced) { list.Add(val3); } } else if (SNet.IsMaster && warpDefinition.OnWarp.WarpTeam_WarpAllWarpableBigPickupItems) { ItemInLevel val4 = ((Il2CppObjectBase)current).TryCast<ItemInLevel>(); if ((Object)(object)val4 != (Object)null && val4.CanWarp && val4.internalSync.GetCurrentState().placement.droppedOnFloor) { Vector3 warpToPosition = locations[num2].Position.ToVector3(); WarpItem(val4, warpDefinition.DimensionIndex, warpToPosition); EOSLogger.Warning(((Item)val4).PublicName ?? ""); num2 = (num2 + 1) % locations.Count; } } } list.ForEach(delegate(SentryGunInstance sentryGun) { sentryGun.m_sync.WantItemAction(((Item)sentryGun).Owner, (SyncedItemAction_New)0); }); if (!localPlayerAgent.TryWarpTo(warpDefinition.DimensionIndex, val, val2, true)) { EOSLogger.Error($"WarpTeam: TryWarpTo failed. Position: {val}, playerSlotIndex: {localPlayerAgent.PlayerSlotIndex}, warpLocationIndex: {num}"); } } internal void WarpTeam(WardenObjectiveEventData e) { WarpTeam(e.WorldEventObjectFilter); } private DimensionWarpManager() { //IL_0007: 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_001f: 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) EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpTeam.ToString(), 160u, (Action<WardenObjectiveEventData>)WarpTeam); EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpRange.ToString(), 161u, (Action<WardenObjectiveEventData>)WarpRange); EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_Warp.WarpItemsInZone.ToString(), 162u, (Action<WardenObjectiveEventData>)WarpItemsInZone); } static DimensionWarpManager() { Current = new DimensionWarpManager(); } } [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.*/)] [BepInPlugin("Inas.EOSExt.DimensionWarp", "EOSExt.DimensionWarp", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.DimensionWarp"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.DimensionWarp"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.DimensionWarp loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<DimensionWarpDefinition>)DimensionWarpManager.Current).Init(); } } } namespace EOSExt.DimensionWarp.Definition { public class PositionAndLookDir { public Vec3 Position { get; set; } = new Vec3(); public int LookDir { get; set; } = 0; } 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 DimensionWarpDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public eDimensionIndex DimensionIndex { get; set; } = (eDimensionIndex)0; public OnWarp OnWarp { get; set; } = new OnWarp(); public List<PositionAndLookDir> Locations { get; set; } = new List<PositionAndLookDir>(); } }
plugins/Inas07.EOSExt.EMP.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AK; using Agents; using AmorLib.API; using AmorLib.Networking.StateReplicators; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Unity.IL2CPP; using CellMenu; using EOSExt.EMP.Definition; using EOSExt.EMP.EMPComponent; using EOSExt.EMP.Impl; using EOSExt.EMP.Impl.Handlers; using EOSExt.EMP.Impl.PersistentEMP; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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("Inas07.EOSExt.EMP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+50d45cf69b90cb1c12d02a6d2aa974779beabc8f")] [assembly: AssemblyProduct("Inas07.EOSExt.EMP")] [assembly: AssemblyTitle("Inas07.EOSExt.EMP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.EMP { internal static class AWOUtil { public const string PLUGIN_GUID = "GTFO.AWO"; public static bool IsLoaded { get; private set; } static AWOUtil() { IsLoaded = false; IsLoaded = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("GTFO.AWO", out var _); EOSLogger.Debug($"EOSExt.EMP: AWO Loaded? {IsLoaded}"); } } public class EMPManager : GenericExpeditionDefinitionManager<pEMPDefinition> { private bool _lightHandlersHooked; public static EMPManager Current { get; } public PlayerAgent Player => (SNet.HasLocalPlayer && SNet.LocalPlayer.HasPlayerAgent) ? ((Il2CppObjectBase)SNet.LocalPlayer.PlayerAgent).Cast<PlayerAgent>() : null; internal List<EMPShock> ActiveEMPs { get; } = new List<EMPShock>(); private Dictionary<uint, pEMP> _pEMPs { get; } = new Dictionary<uint, pEMP>(); public IEnumerable<pEMP> pEMPs => _pEMPs.Values; protected override string DEFINITION_NAME => "PersistentEMP"; internal void SetLocalPlayerAgent(PlayerAgent localPlayerAgent) { if ((Object)(object)PlayerpEMPComponent.Current == (Object)null) { ((Component)localPlayerAgent).gameObject.AddComponent<PlayerpEMPComponent>(); } } public void ActivateEMPShock(Vector3 position, float range, float duration) { //IL_0023: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (!GameStateManager.IsInExpedition) { EOSLogger.Error("Tried to activate an EMP when not in level, this shouldn't happen!"); return; } float endTime = Clock.Time + duration; EMPShock eMPShock = new EMPShock(position, range, endTime); foreach (EMPHandler allHandler in EMPHandler.AllHandlers) { if (Vector3.Distance(position, allHandler.position) < range) { allHandler.AddAffectedBy(eMPShock); } } ActiveEMPs.Add(eMPShock); } internal void RemoveInactiveEMPs() { float time = Clock.Time; ActiveEMPs.RemoveAll((EMPShock emp) => emp.endTime < time); } public bool IsPlayerMapEMPD() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player == (Object)null || !GameStateManager.IsInExpedition) { return false; } Vector3 position = ((Agent)Player).Position; foreach (EMPShock activeEMP in ActiveEMPs) { if (Vector3.Distance(position, activeEMP.position) < activeEMP.range) { return true; } } foreach (pEMP pEMP in pEMPs) { if (pEMP.State != ActiveState.ENABLED || !pEMP.ItemToDisable.Map || !(Vector3.Distance(position, pEMP.position) < pEMP.range)) { continue; } EOSLogger.Warning("MapEMPD: by pEMP"); return true; } return false; } protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); if (!base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value)) { return; } foreach (pEMPDefinition definition in value.Definitions) { EOSLogger.Warning(definition.ItemToDisable.ToString()); } } private void HookLightHandlers() { if (_lightHandlersHooked) { return; } _lightHandlersHooked = true; LevelAPI.OnBuildDone += delegate { foreach (LightWorker item in LightAPI.GetLightWorkersInDimension(Enum.GetValues<eDimensionIndex>())) { if (!((Object)(object)item?.Light == (Object)null)) { GameObject gameObject = ((Component)item.Light).gameObject; if (!((Object)(object)gameObject.GetComponent<EMPController>() != (Object)null)) { gameObject.AddComponent<EMPController>().AssignHandler(new EMPLightHandler(item)); } } } }; } public override void Init() { EMPWardenEvents.Init(); Events.InventoryWielded = (Action<InventorySlot>)Delegate.Combine(Events.InventoryWielded, new Action<InventorySlot>(SetupAmmoWeaponHandlers)); pEMPInit(); HookLightHandlers(); } private EMPManager() { } static EMPManager() { Current = new EMPManager(); ClassInjector.RegisterTypeInIl2Cpp<EMPController>(); ClassInjector.RegisterTypeInIl2Cpp<PlayerpEMPComponent>(); } internal void SetupHUDAndFlashlight() { if ((Object)(object)Player == (Object)null) { EOSLogger.Error($"{"SetupHUDAndFlashlight": LocalPlayerAgent is not set!}"); return; } if (EMPPlayerHudHandler.Instance == null) { ((Component)Player).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerHudHandler()); EOSLogger.Log("pEMP: PlayerHud setup completed"); } if (EMPPlayerFlashLightHandler.Instance == null) { ((Component)Player).gameObject.AddComponent<EMPController>().AssignHandler(new EMPPlayerFlashLightHandler()); EOSLogger.Log("pEMP: PlayerFlashlight setup completed"); } } internal void SetupAmmoWeaponHandlers(InventorySlot slot) { //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_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_000a: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (slot - 1 <= 1) { SetupAmmoWeaponHandlerForSlot(slot); } static void SetupAmmoWeaponHandlerForSlot(InventorySlot val) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack; BackpackItem val2 = default(BackpackItem); if (localBackpack.TryGetBackpackItem(val, ref val2)) { if (!((Object)(object)((Component)val2.Instance).gameObject.GetComponent<EMPController>() != (Object)null)) { ((Component)val2.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPGunSightHandler()); EOSLogger.Log($"pEMP: Backpack {val} setup completed"); } } else { EOSLogger.Warning($"Couldn't get item for slot {val}!"); } } } internal void SetupToolHandler() { PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack; BackpackItem val = default(BackpackItem); if (localBackpack.TryGetBackpackItem((InventorySlot)3, ref val)) { if (!((Object)(object)((Component)val.Instance).gameObject.GetComponent<EMPController>() != (Object)null) && (Object)(object)((Component)val.Instance).GetComponent<EnemyScanner>() != (Object)null) { ((Component)val.Instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPBioTrackerHandler()); EOSLogger.Log($"pEMP: Backpack {3} setup completed"); } } else { EOSLogger.Warning($"Couldn't get item for slot {3}!"); } } public void TogglepEMPState(uint pEMPIndex, bool enabled) { if (!_pEMPs.ContainsKey(pEMPIndex)) { EOSLogger.Error($"TogglepEMPState: pEMPIndex {pEMPIndex} not defined"); } else { ActiveState newState = (enabled ? ActiveState.ENABLED : ActiveState.DISABLED); pEMP pEMP = _pEMPs[pEMPIndex]; pEMP.ChangeToState(newState); } } public void TogglepEMPState(WardenObjectiveEventData e) { uint count = (uint)e.Count; bool enabled = e.Enabled; TogglepEMPState(count, enabled); } private void pEMPInit() { LevelAPI.OnBuildStart += delegate { pEMPClear(); InitializepEMPs(); }; LevelAPI.OnLevelCleanup += pEMPClear; } private void pEMPClear() { foreach (pEMP value in _pEMPs.Values) { value.Destroy(); } _pEMPs.Clear(); } private void InitializepEMPs() { if (!base.definitions.ContainsKey(base.CurrentMainLevelLayout)) { return; } GenericExpeditionDefinition<pEMPDefinition> val = base.definitions[base.CurrentMainLevelLayout]; if (val == null || val.Definitions.Count < 1) { return; } foreach (pEMPDefinition definition in val.Definitions) { pEMP pEMP = new pEMP(definition); _pEMPs[definition.pEMPIndex] = pEMP; uint num = EOSNetworking.AllotReplicatorID(); if (num == 0) { EOSLogger.Error("SetuppEMPReplicators: replicator ID depleted, cannot set up!"); continue; } pEMP.SetupReplicator(num); EOSLogger.Debug($"pEMP_{definition.pEMPIndex} initialized"); } } } internal static class EMPWardenEvents { public enum EMPEvents { Instant_Shock = 300, Toggle_PEMP_State } internal static void InstantShock(WardenObjectiveEventData e) { //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_001b: Unknown result type (might be due to invalid IL or missing references) Vector3 position = e.Position; float fogTransitionDuration = e.FogTransitionDuration; float duration = e.Duration; EMPManager.Current.ActivateEMPShock(position, fogTransitionDuration, duration); } internal static void TogglepEMPState(WardenObjectiveEventData e) { EMPManager.Current.TogglepEMPState(e); } internal static void Init() { EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Instant_Shock.ToString(), 300u, (Action<WardenObjectiveEventData>)InstantShock); EOSWardenEventManager.Current.AddEventDefinition(EMPEvents.Toggle_PEMP_State.ToString(), 301u, (Action<WardenObjectiveEventData>)TogglepEMPState); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.EMP", "EOSExt.EMP", "1.2.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.EMP"; public const string VERSION = "1.2.0"; private Harmony m_Harmony; public override void Load() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown m_Harmony = new Harmony("EOSExt.EMP"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<pEMPDefinition>)EMPManager.Current).Init(); } } public static class Events { public static Action<GearPartFlashlight> FlashLightWielded; public static Action<InventorySlot> InventoryWielded; public static Action EnterGSInLevel; } } namespace EOSExt.EMP.Patches { [HarmonyPatch] [HarmonyWrapSafe] internal class Inject_CM_PageMap { [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageMap), "UpdatePlayerData")] private static void Post_CM_PageMap_OnEnable() { //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 && !pageMap.m_mapDisconnected.activeSelf && EMPManager.Current.IsPlayerMapEMPD()) { pageMap.SetMapVisualsIsActive(false); pageMap.SetMapDisconnetedTextIsActive(true); } } } [HarmonyPatch(typeof(EnemyScanner))] internal static class Inject_EnemyScanner { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateDetectedEnemies")] internal static bool Pre_UpdateDetectedEnemies() { EMPBioTrackerHandler instance = EMPBioTrackerHandler.Instance; return instance == null || !instance.IsEMPed(); } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("UpdateTagProgress")] internal static bool Pre_UpdateTagProgress(EnemyScanner __instance) { //IL_0080: 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) if (EMPBioTrackerHandler.Instance == null) { return true; } if (EMPBioTrackerHandler.Instance.IsEMPed()) { ((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; } __instance.m_screen.SetStatusText("Ready to tag"); __instance.m_screen.SetGuixColor(Color.red); return true; } } [HarmonyPatch] internal static class Inject_Events { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryBase), "OnItemEquippableFlashlightWielded")] internal static void Post_OnItemEquippableFlashlightWielded(GearPartFlashlight flashlight) { Events.FlashLightWielded?.Invoke(flashlight); } [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerInventoryLocal), "DoWieldItem")] internal static void Post_DoWieldItem(PlayerInventoryLocal __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) Events.InventoryWielded?.Invoke(((PlayerInventoryBase)__instance).WieldedSlot); } [HarmonyPostfix] [HarmonyPatch(typeof(GS_InLevel), "Enter")] private static void Post_SetupGear(GS_InLevel __instance) { Events.EnterGSInLevel?.Invoke(); } } [HarmonyPatch] internal static class Inject_PlayerAgent { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerAgent), "Setup")] internal static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned) { EMPManager.Current.SetLocalPlayerAgent(__instance); } } } [HarmonyPatch] internal static class Inject_PlayerHUD { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerGuiLayer), "UpdateGUIElementsVisibility")] private static bool Pre_UpdateGUIElementsVisibility() { if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed()) { return false; } return true; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(CellSettingsApply), "ApplyPlayerGhostOpacity")] private static void Pre_ApplyPlayerGhostOpacity(ref float value) { if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed()) { value = 0f; } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(CellSettingsApply), "ApplyHUDAlwaysShowTeammateInfo")] private static void Pre_ApplyHUDAlwaysShowTeammateInfo(ref bool value) { if (EMPPlayerHudHandler.Instance != null && EMPPlayerHudHandler.Instance.IsEMPed()) { value = false; } } } [HarmonyPatch(typeof(PlayerSync))] internal static class Inject_PlayerSync { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch("WantsToSetFlashlightEnabled")] internal static void Pre_WantsToSetFlashlightEnabled(PlayerSync __instance, ref bool enable) { if (EMPPlayerFlashLightHandler.Instance != null && EMPPlayerFlashLightHandler.Instance.IsEMPed()) { enable = false; } } } [HarmonyPatch(typeof(SentryGunInstance))] internal static class Inject_SentryGunInstance { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch("Setup")] internal static void Post_Setup(SentryGunInstance __instance) { ((Component)__instance).gameObject.AddComponent<EMPController>().AssignHandler(new EMPSentryHandler()); } } } namespace EOSExt.EMP.Impl { public sealed class EMPController : MonoBehaviour { private bool _hasHandler; private bool _setup; private float next_remove_time = float.NaN; private const float UPDATE_INTERVAL = 1f; public EMPHandler Handler { get; private set; } public float endTime { get; private set; } public Vector3 Position => ((Component)this).transform.position; private void Update() { if (_hasHandler) { float time = Clock.Time; Handler.Tick(); if (float.IsNaN(next_remove_time) || next_remove_time < time) { Handler.RemoveEndedEMPs(); next_remove_time = time + 1f; } } } [HideFromIl2Cpp] public void AssignHandler(EMPHandler handler) { if (Handler != null) { EOSLogger.Warning("Tried to assign a handler to a controller that already had one!"); return; } Handler = handler; Handler.Setup(((Component)this).gameObject, this); _hasHandler = true; _setup = true; } [HideFromIl2Cpp] public void ForceState(EMPState state) { if (Handler != null) { Handler.ForceState(state); } } private void OnDestroy() { Handler.OnDespawn(); Handler = null; } } public abstract class EMPHandler { protected enum DeviceState { On, Off, Unknown } private static long next_handler_id = 0L; protected DeviceState _deviceState; protected float _stateTimer; private float _delayTimer; private bool _destroyed; protected static Dictionary<long, EMPHandler> Handlers { get; } = new Dictionary<long, EMPHandler>(); public static IEnumerable<EMPHandler> AllHandlers => Handlers.Values; protected long HandlerId { get; private set; } public EMPState State { get; protected set; } protected HashSet<EMPShock> AffectedBy { get; } = new HashSet<EMPShock>(); public GameObject go { get; protected set; } 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 obj = go; return (obj != null) ? obj.transform.position : Vector3.zero; } } protected virtual float FlickerDuration => 0.2f; protected virtual float OnToOffMinDelay => 0f; protected virtual float OnToOffMaxDelay => 0.75f; protected virtual float OffToOnMinDelay => 0.85f; protected virtual float OffToOnMaxDelay => 1.5f; protected virtual bool IsDeviceOnPlayer => false; public virtual bool IsEMPed() { foreach (EMPShock item in AffectedBy) { if (Clock.Time < item.endTime) { return true; } } return false; } public virtual void Setup(GameObject gameObject, EMPController controller) { //IL_0030: 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) go = gameObject; foreach (EMPShock activeEMP in EMPManager.Current.ActiveEMPs) { if (Vector3.Distance(go.transform.position, activeEMP.position) < activeEMP.range) { AddAffectedBy(activeEMP); } } HandlerId = next_handler_id++; if (Handlers.ContainsKey(HandlerId)) { EOSLogger.Warning("What the hell we got a duplicate EMPHandler ID!?"); } Handlers[HandlerId] = this; } public virtual void OnDespawn() { _destroyed = true; AffectedBy.Clear(); Handlers.Remove(HandlerId); go = null; } public void AddAffectedBy(EMPShock empShock) { AffectedBy.Add(empShock); } public void RemoveAffectedBy(EMPShock empShock) { AffectedBy.Remove(empShock); } internal void RemoveEndedEMPs() { float time = Clock.Time; AffectedBy.RemoveWhere((EMPShock emp) => emp.endTime < time); } public void ForceState(EMPState state) { if (State != state) { State = state; _delayTimer = Clock.Time - 1f; _stateTimer = Clock.Time - 1f; switch (state) { case EMPState.Off: _deviceState = DeviceState.Off; DeviceOff(); break; default: _deviceState = DeviceState.Unknown; break; case EMPState.On: _deviceState = DeviceState.On; DeviceOn(); break; } } } public void Tick() { if (_destroyed) { return; } bool flag = IsEMPed(); if (flag && State == EMPState.On) { float randomDelay = Random.GetRandomDelay(OnToOffMinDelay, OnToOffMaxDelay); State = EMPState.FlickerOff; _delayTimer = Clock.Time + randomDelay; _stateTimer = Clock.Time + randomDelay + FlickerDuration; } if (!flag && State == EMPState.Off) { float randomDelay2 = Random.GetRandomDelay(OffToOnMinDelay, OffToOnMaxDelay); State = EMPState.FlickerOn; _delayTimer = Clock.Time + randomDelay2; _stateTimer = Clock.Time + randomDelay2 + FlickerDuration; } switch (State) { case EMPState.On: if (_deviceState != DeviceState.On) { DeviceOn(); _deviceState = DeviceState.On; } break; case EMPState.FlickerOff: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.Off; } } break; case EMPState.Off: if (_deviceState != DeviceState.Off) { DeviceOff(); _deviceState = DeviceState.Off; } break; case EMPState.FlickerOn: if (!(_delayTimer > Clock.Time)) { if (Clock.Time < _stateTimer) { FlickerDevice(); } else { State = EMPState.On; } } break; } OnTick(flag); } protected virtual void OnTick(bool isEMPD) { } protected abstract void FlickerDevice(); protected abstract void DeviceOn(); protected abstract void DeviceOff(); } public class EMPShock { public static readonly ItemToDisable DISABLE_NOTHING = new ItemToDisable { BioTracker = false, PlayerFlashLight = false, PlayerHUD = false, Sentry = false, EnvLight = false, GunSight = false, Map = false }; public virtual ActiveState State => (RemainingTime > 0f) ? ActiveState.ENABLED : ActiveState.DISABLED; public Vector3 position { get; protected set; } public float range { get; protected set; } public float endTime { get; protected set; } public virtual float RemainingTime => endTime - Clock.Time; public virtual ItemToDisable ItemToDisable => new ItemToDisable(); public EMPShock(Vector3 position, float range, float endTime) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) this.position = position; this.range = range; this.endTime = endTime; } public bool InRange(Vector3 position) { //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 Vector3.Distance(position, this.position) < range; } public override bool Equals(object obj) { //IL_000c: 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) return obj is EMPShock eMPShock && position == eMPShock.position && range == eMPShock.range; } public override int GetHashCode() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return HashCode.Combine<ActiveState, Vector3, float, float, float, ItemToDisable>(State, position, range, endTime, RemainingTime, ItemToDisable); } } public enum EMPState { On, FlickerOff, Off, FlickerOn } internal static class Random { internal static System.Random _rand { get; private set; } = new System.Random(); internal static float GetRandomDelay(float min, float max) { return min + GetRandom01() * (max - min); } internal static float GetRandom01() { return (float)_rand.NextDouble(); } internal static int GetRandomRange(int min, int maxPlusOne) { return _rand.Next(min, maxPlusOne); } internal static int Index(int length) { return _rand.Next(0, length); } internal static bool FlickerUtil(int oneInX = 2) { return Index(oneInX) == 0; } } } namespace EOSExt.EMP.Impl.PersistentEMP { public enum ActiveState { DISABLED, ENABLED } public class pEMP : EMPShock { private uint replicatorID; public pEMPDefinition def { get; private set; } public StateReplicator<pEMPState> StateReplicator { get; private set; } public override ActiveState State => (StateReplicator != null) ? StateReplicator.State.status : ActiveState.DISABLED; public override float RemainingTime => base.endTime; public override ItemToDisable ItemToDisable => def?.ItemToDisable ?? EMPShock.DISABLE_NOTHING; private void OnStateChanged(pEMPState oldState, pEMPState newState, bool isRecall) { if (isRecall) { ChangeToStateUnsynced(newState.status); } } private void ChangeToStateUnsynced(ActiveState newState) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) EOSLogger.Debug($"pEMP_{def.pEMPIndex} Change state: {State} -> {newState}"); switch (newState) { case ActiveState.DISABLED: base.endTime = float.NegativeInfinity; break; case ActiveState.ENABLED: base.endTime = float.PositiveInfinity; break; default: throw new NotImplementedException(); } if (!ItemToDisable.EnvLight) { return; } foreach (EMPLightHandler instance in EMPLightHandler.Instances) { switch (newState) { case ActiveState.DISABLED: instance.RemoveAffectedBy(this); break; case ActiveState.ENABLED: if (InRange(instance.position)) { instance.AddAffectedBy(this); } else { instance.RemoveAffectedBy(this); } break; default: throw new NotImplementedException(); } } } public void ChangeToState(ActiveState newState) { ChangeToStateUnsynced(newState); if (SNet.IsMaster) { StateReplicator?.SetState(new pEMPState { status = newState }); } } internal void SetupReplicator(uint replicatorID) { this.replicatorID = replicatorID; StateReplicator = StateReplicator<pEMPState>.Create(replicatorID, new pEMPState { status = ActiveState.DISABLED }, (LifeTimeType)1, (IStateReplicatorHolder<pEMPState>)null); StateReplicator.OnStateChanged += OnStateChanged; } public pEMP(pEMPDefinition def) : base(def.Position.ToVector3(), def.Range, float.NegativeInfinity) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) this.def = new pEMPDefinition(def); } internal void Destroy() { base.endTime = float.NegativeInfinity; StateReplicator = null; def = null; } public override bool Equals(object obj) { return obj is pEMP pEMP2 && def.Equals(pEMP2.def) && replicatorID == pEMP2.replicatorID; } public override int GetHashCode() { return HashCode.Combine(def, replicatorID); } } public struct pEMPState { public ActiveState status; public pEMPState() { status = ActiveState.DISABLED; } public pEMPState(ActiveState status) { this.status = status; } public pEMPState(pEMPState o) { status = o.status; } } } namespace EOSExt.EMP.Impl.Handlers { public class EMPBioTrackerHandler : EMPHandler { private EnemyScanner _scanner; public static EMPBioTrackerHandler Instance { get; private set; } static EMPBioTrackerHandler() { } public override void Setup(GameObject gameObject, EMPController controller) { if (Instance != null) { EOSLogger.Warning("EMP: re-setup EMPBioTrackerHandler"); Instance.OnDespawn(); } base.Setup(gameObject, controller); _scanner = gameObject.GetComponent<EnemyScanner>(); if ((Object)(object)_scanner == (Object)null) { EOSLogger.Error("Couldn't get bio-tracker component!"); } Instance = this; } public override void OnDespawn() { base.OnDespawn(); Instance = null; } protected override void DeviceOff() { ((ItemEquippable)_scanner).Sound.Post(EVENTS.BIOTRACKER_TOOL_LOOP_STOP, true); _scanner.m_graphics.m_display.enabled = false; } protected override void DeviceOn() { _scanner.m_graphics.m_display.enabled = true; } protected override void FlickerDevice() { ((Behaviour)_scanner).enabled = Random.FlickerUtil(); } } public class EMPGunSightHandler : EMPHandler { private static List<EMPGunSightHandler> handlers; public GameObject[] _sightPictures; public static IEnumerable<EMPGunSightHandler> Instances => handlers; static EMPGunSightHandler() { handlers = new List<EMPGunSightHandler>(); LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnBuildStart += Clear; } private void SetupGunSights() { Il2CppArrayBase<Renderer> componentsInChildren = base.go.GetComponentsInChildren<Renderer>(true); if (componentsInChildren != null) { _sightPictures = (from x in (IEnumerable<Renderer>)componentsInChildren where (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null where ((Object)x.sharedMaterial.shader).name.Contains("HolographicSight") select ((Component)x).gameObject).ToArray(); } if (_sightPictures == null || _sightPictures.Length < 1) { EOSLogger.Error("Unable to find sight on " + ((Object)base.go).name + "!"); } } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); SetupGunSights(); handlers.Add(this); } protected override void DeviceOff() { ForEachSights(delegate(GameObject x) { x.SetActive(false); }); } protected override void DeviceOn() { ForEachSights(delegate(GameObject x) { x.SetActive(true); }); } protected override void FlickerDevice() { ForEachSights(delegate(GameObject x) { x.SetActive(Random.FlickerUtil()); }); } private void ForEachSights(Action<GameObject> action) { GameObject[] sightPictures = _sightPictures; foreach (GameObject val in sightPictures) { if ((Object)(object)val != (Object)null) { action?.Invoke(val); } } } private static void Clear() { handlers.Clear(); } } public class EMPLightHandler : EMPHandler { private static Dictionary<IntPtr, EMPLightHandler> handlers; private readonly LightWorker _worker; private ILightModifier _mod; public static IEnumerable<EMPLightHandler> Instances => handlers.Values; static EMPLightHandler() { handlers = new Dictionary<IntPtr, EMPLightHandler>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } private static void Clear() { foreach (EMPLightHandler value in handlers.Values) { ILightModifier mod = value._mod; if (mod != null) { mod.Remove(); } value._mod = null; } handlers.Clear(); } public EMPLightHandler(LightWorker worker) { _worker = worker; } public override void Setup(GameObject gameObject, EMPController controller) { base.Setup(gameObject, controller); if ((Object)(object)_worker?.Light == (Object)null) { EOSLogger.Warning("EMPLightHandler: no light worker"); return; } base.State = EMPState.On; handlers[((Il2CppObjectBase)_worker.Light).Pointer] = this; } protected override void OnTick(bool isEMPD) { base.OnTick(isEMPD); if (base.State == EMPState.Off) { DeviceOff(); } else if (base.State == EMPState.On) { DeviceOn(); } } protected override void FlickerDevice() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_worker?.Light == (Object)null)) { if (_mod == null) { _mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000); } _mod.Intensity = Random.GetRandom01() * _worker.OrigIntensity; } } protected override void DeviceOn() { if (_mod != null) { _mod.Remove(); _mod = null; } } protected override void DeviceOff() { //IL_0064: 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) if (!((Object)(object)_worker?.Light == (Object)null)) { if (_mod == null) { _mod = _worker.AddModifier(_worker.CurrentColor, _worker.CurrentIntensity, _worker.CurrentEnabled, 2000); } _mod.Color = Color.black; _mod.Intensity = 0f; } } } public class EMPPlayerFlashLightHandler : EMPHandler { private PlayerInventoryBase _inventory; private float _originalIntensity; private bool _originalFlashlightState; public static EMPPlayerFlashLightHandler Instance { get; private set; } protected override bool IsDeviceOnPlayer => true; private bool FlashlightEnabled => _inventory.FlashlightEnabled; static EMPPlayerFlashLightHandler() { } public override void Setup(GameObject gameObject, EMPController controller) { if (Instance != null) { EOSLogger.Warning("EMP: re-setup EMPPlayerFlashLightHandler"); Instance.OnDespawn(); } base.Setup(gameObject, controller); _inventory = gameObject.GetComponent<PlayerAgent>().Inventory; if ((Object)(object)_inventory == (Object)null) { EOSLogger.Warning("Player inventory was null!"); } else { base.State = EMPState.On; Events.FlashLightWielded = (Action<GearPartFlashlight>)Delegate.Combine(Events.FlashLightWielded, new Action<GearPartFlashlight>(InventoryEvents_ItemWielded)); } Instance = this; } public override void OnDespawn() { base.OnDespawn(); Events.FlashLightWielded = (Action<GearPartFlashlight>)Delegate.Remove(Events.FlashLightWielded, new Action<GearPartFlashlight>(Instance.InventoryEvents_ItemWielded)); Instance = null; } private void InventoryEvents_ItemWielded(GearPartFlashlight flashlight) { _originalIntensity = GameDataBlockBase<FlashlightSettingsDataBlock>.GetBlock(flashlight.m_settingsID).intensity; } protected override void DeviceOff() { _originalFlashlightState = FlashlightEnabled; if (_originalFlashlightState) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(false, false); } } protected override void DeviceOn() { if (_originalFlashlightState != FlashlightEnabled) { _inventory.Owner.Sync.WantsToSetFlashlightEnabled(_originalFlashlightState, false); } _inventory.m_flashlight.intensity = _originalIntensity; } protected override void FlickerDevice() { if (FlashlightEnabled) { _inventory.m_flashlight.intensity = Random.GetRandom01() * _originalIntensity; } } } public class EMPPlayerHudHandler : EMPHandler { private readonly List<RectTransformComp> _targets = new List<RectTransformComp>(); public static EMPPlayerHudHandler Instance { get; private set; } static EMPPlayerHudHandler() { } public override void Setup(GameObject gameObject, EMPController controller) { if (Instance != null) { EOSLogger.Warning("EMP: re-setup EMPPlayerHudHandler"); Instance.OnDespawn(); } _targets.Clear(); base.Setup(gameObject, controller); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_compass); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_wardenObjective); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.Inventory); _targets.Add((RectTransformComp)(object)GuiManager.PlayerLayer.m_playerStatus); Instance = this; } public override void OnDespawn() { base.OnDespawn(); _targets.Clear(); Instance = null; } private void ForAllComponents(bool enabled) { foreach (RectTransformComp target in _targets) { ((Component)target).gameObject.SetActive(enabled); } } private void ForPlayerNavMarker(bool enabled) { Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Agent)current).IsLocallyOwned) { current.NavMarker.SetMarkerVisible(enabled); } } } private void ForPlayerGhostOpacity(bool enabled) { CellSettingsApply.ApplyPlayerGhostOpacity(enabled ? CellSettingsManager.SettingsData.HUD.Player_GhostOpacity.Value : 0f); } protected override void OnTick(bool isEMPD) { base.OnTick(isEMPD); bool flag = !isEMPD; if (base.State == EMPState.Off) { DeviceOff(); } else if (base.State == EMPState.On) { DeviceOn(); } } protected override void DeviceOff() { ForAllComponents(enabled: false); ForPlayerNavMarker(enabled: false); ForPlayerGhostOpacity(enabled: false); } protected override void DeviceOn() { ForAllComponents(enabled: true); ForPlayerNavMarker(enabled: true); ForPlayerGhostOpacity(enabled: true); } protected override void FlickerDevice() { bool enabled = Random.FlickerUtil(); ForAllComponents(enabled); ForPlayerNavMarker(enabled); ForPlayerGhostOpacity(enabled); } } public class EMPSentryHandler : EMPHandler { private static Color _offColor; private SentryGunInstance _sentry; private SentryGunInstance_ScannerVisuals_Plane _visuals; public static EMPSentryHandler Instance { get; private set; } static EMPSentryHandler() { //IL_0002: 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_0039: Unknown result type (might be due to invalid IL or missing references) _offColor = new Color { r = 0f, g = 0f, b = 0f, a = 0f }; } public override void Setup(GameObject gameObject, EMPController controller) { if (Instance != null) { EOSLogger.Warning("EMP: re-setup EMPSentryHandler"); Instance.OnDespawn(); } base.Setup(gameObject, controller); _sentry = gameObject.GetComponent<SentryGunInstance>(); _visuals = gameObject.GetComponent<SentryGunInstance_ScannerVisuals_Plane>(); if ((Object)(object)_sentry == (Object)null || (Object)(object)_visuals == (Object)null) { EOSLogger.Error($"Missing components on Sentry! Has Sentry?: {(Object)(object)_sentry == (Object)null}, Has Visuals?: {(Object)(object)_visuals == (Object)null}"); } Instance = this; } public override void OnDespawn() { base.OnDespawn(); Instance = null; } 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(_offColor); _visuals.UpdateLightProps(_offColor, 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 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 FlickerDevice() { int randomRange = Random.GetRandomRange(0, 3); _sentry.StopFiring(); switch (randomRange) { 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 EOSExt.EMP.Definition { public class ItemToDisable { public bool BioTracker { get; set; } = true; public bool PlayerHUD { get; set; } = true; public bool PlayerFlashLight { get; set; } = true; public bool EnvLight { get; set; } = true; public bool GunSight { get; set; } = true; public bool Sentry { get; set; } = true; public bool Map { get; set; } = true; public override bool Equals(object obj) { return obj is ItemToDisable itemToDisable && BioTracker == itemToDisable.BioTracker && PlayerHUD == itemToDisable.PlayerHUD && PlayerFlashLight == itemToDisable.PlayerFlashLight && EnvLight == itemToDisable.EnvLight && GunSight == itemToDisable.GunSight && Sentry == itemToDisable.Sentry && Map == itemToDisable.Map; } public override int GetHashCode() { return HashCode.Combine(BioTracker, PlayerHUD, PlayerFlashLight, EnvLight, GunSight, Sentry, Map); } public override string ToString() { return $"ItemToDisable:\nBioTracker: {BioTracker}, PlayerHUD: {PlayerHUD}, PlayerFlashLight: {PlayerFlashLight},\nEnvLight: {EnvLight}, GunSight: {GunSight}, Sentry: {Sentry}, Map: {Map}"; } } public class pEMPDefinition { 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(); public pEMPDefinition() { }//IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown public pEMPDefinition(pEMPDefinition other) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_003e: 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_0055: 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_007e: Expected O, but got Unknown pEMPIndex = other.pEMPIndex; Position = new Vec3 { x = other.Position.x, y = other.Position.y, z = other.Position.z }; Range = other.Range; ItemToDisable = new ItemToDisable { BioTracker = other.ItemToDisable.BioTracker, PlayerHUD = other.ItemToDisable.PlayerHUD, PlayerFlashLight = other.ItemToDisable.PlayerFlashLight, EnvLight = other.ItemToDisable.EnvLight, GunSight = other.ItemToDisable.GunSight, Sentry = other.ItemToDisable.Sentry, Map = other.ItemToDisable.Map }; } public override bool Equals(object obj) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) return obj is pEMPDefinition pEMPDefinition2 && pEMPIndex == pEMPDefinition2.pEMPIndex && Position.ToVector3() == pEMPDefinition2.Position.ToVector3() && Range == pEMPDefinition2.Range && ItemToDisable.Equals(pEMPDefinition2.ItemToDisable); } public override int GetHashCode() { return HashCode.Combine<uint, Vec3, float, ItemToDisable>(pEMPIndex, Position, Range, ItemToDisable); } } } namespace EOSExt.EMP.EMPComponent { public class PlayerpEMPComponent : MonoBehaviour { private float nextUpdateTime = float.NaN; public const float UPDATE_INTERVAL = 0.2f; public static PlayerpEMPComponent Current => (SNet.HasLocalPlayer && SNet.LocalPlayer.HasPlayerAgent) ? ((Component)((Il2CppObjectBase)SNet.LocalPlayer.PlayerAgent).Cast<PlayerAgent>()).GetComponent<PlayerpEMPComponent>() : null; public PlayerAgent player => ((Component)this).gameObject.GetComponent<PlayerAgent>(); private void CheckSetup() { if (!((Object)(object)EMPManager.Current.Player == (Object)null)) { EMPManager.Current.SetupHUDAndFlashlight(); EMPManager.Current.SetupToolHandler(); } } private 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_00af: Unknown result type (might be due to invalid IL or missing references) if ((int)GameStateManager.CurrentStateName != 10 || (!float.IsNaN(nextUpdateTime) && Clock.Time < nextUpdateTime)) { return; } nextUpdateTime = Clock.Time + 0.2f; CheckSetup(); EMPManager.Current.RemoveInactiveEMPs(); if ((Object)(object)player == (Object)null) { return; } foreach (pEMP pEMP in EMPManager.Current.pEMPs) { ItemToDisable itemToDisable = pEMP.ItemToDisable; if (pEMP.State == ActiveState.ENABLED && pEMP.InRange(((Agent)player).Position)) { if (itemToDisable.BioTracker) { EMPBioTrackerHandler.Instance?.AddAffectedBy(pEMP); } if (itemToDisable.PlayerFlashLight) { EMPPlayerFlashLightHandler.Instance?.AddAffectedBy(pEMP); } if (itemToDisable.PlayerHUD) { EMPPlayerHudHandler.Instance?.AddAffectedBy(pEMP); } if (itemToDisable.Sentry) { EMPSentryHandler.Instance?.AddAffectedBy(pEMP); } if (!itemToDisable.GunSight) { continue; } foreach (EMPGunSightHandler instance in EMPGunSightHandler.Instances) { instance.AddAffectedBy(pEMP); } continue; } EMPBioTrackerHandler.Instance?.RemoveAffectedBy(pEMP); EMPPlayerFlashLightHandler.Instance?.RemoveAffectedBy(pEMP); EMPPlayerHudHandler.Instance?.RemoveAffectedBy(pEMP); EMPSentryHandler.Instance?.RemoveAffectedBy(pEMP); foreach (EMPGunSightHandler instance2 in EMPGunSightHandler.Instances) { instance2.RemoveAffectedBy(pEMP); } } } private void OnDestroy() { } static PlayerpEMPComponent() { } } }
plugins/Inas07.EOSExt.EnvTemperature.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using EOSExt.EnvTemperature.Components; using EOSExt.EnvTemperature.Definitions; using EOSExt.EnvTemperature.Patches; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Utilities; using GameData; using GameEvent; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using TMPro; using UnityEngine; using UnityEngine.UI; [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("Inas07.EOSExt.EnvTemperature")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+00ee728818558b44f88b01d48543284e03868873")] [assembly: AssemblyProduct("Inas07.EOSExt.EnvTemperature")] [assembly: AssemblyTitle("Inas07.EOSExt.EnvTemperature")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.EnvTemperature { [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.*/)] [BepInPlugin("Inas.EOSExt.EnvTemperature", "EOSExt.EnvTemperature", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.EnvTemperature"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.EnvTemperature"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.EnvTemperature loaded."); } private void SetupManagers() { ((GenericDefinitionManager<TemperatureDefinition>)TemperatureDefinitionManager.Current).Init(); } } public class TemperatureDefinitionManager : GenericDefinitionManager<TemperatureDefinition> { public static readonly TemperatureZoneDefinition DEFAULT_ZONE_DEF; public const float MIN_TEMP = 0.005f; public const float MAX_TEMP = 1f; public static TemperatureDefinitionManager Current { get; } protected override string DEFINITION_NAME => "EnvTemperature"; private Dictionary<(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex), TemperatureZoneDefinition> zoneDefs { get; } = new Dictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), TemperatureZoneDefinition>(); protected override void AddDefinitions(GenericDefinition<TemperatureDefinition> definition) { List<TemperatureSetting> settings = definition.Definition.Settings; if (settings.Count > 0) { settings.Sort((TemperatureSetting t1, TemperatureSetting t2) => t1.Temperature.CompareTo(t2.Temperature)); bool flag = true; if (settings[0].Temperature < 0f) { EOSLogger.Error($"Found negative temperature: '{settings[0].Temperature}'"); flag = false; } if (settings[settings.Count - 1].Temperature > 1f) { EOSLogger.Error($"Found temperature greater than 1: '{settings[settings.Count - 1].Temperature}'"); flag = false; } if (!flag) { EOSLogger.Error($"Found invalid temperature for MainLevelLayout '{definition.ID}'. Correct it first to make it effective"); return; } if (settings[0].Temperature != 0f) { List<TemperatureSetting> list = new List<TemperatureSetting>(); TemperatureSetting item = new TemperatureSetting(settings[0]) { Temperature = 0f }; list.Add(item); list.AddRange(settings); definition.Definition.Settings = list; settings.Clear(); settings = list; } } foreach (TemperatureZoneDefinition zone in definition.Definition.Zones) { zone.Temperature_Downlimit = Math.Clamp(zone.Temperature_Downlimit, 0.005f, 1f); zone.Temperature_Uplimit = Math.Clamp(zone.Temperature_Uplimit, 0.005f, 1f); if (zone.Temperature_Downlimit > zone.Temperature_Uplimit) { EOSLogger.Error($"Invalid Temperature_Down/Up-limit setting! Downlimit == {zone.Temperature_Downlimit}, Uplimit == {zone.Temperature_Uplimit}"); float temperature_Downlimit = zone.Temperature_Downlimit; zone.Temperature_Downlimit = zone.Temperature_Uplimit; zone.Temperature_Uplimit = temperature_Downlimit; } if (!(zone.Temperature_Downlimit <= zone.Temperature_Normal) || !(zone.Temperature_Normal <= zone.Temperature_Uplimit)) { EOSLogger.Error($"Invalid Temperature_Normal setting! Temperature_Normal == {zone.Temperature_Normal} not in limit range [{zone.Temperature_Downlimit}, {zone.Temperature_Uplimit}] !"); zone.Temperature_Normal = Math.Clamp(zone.Temperature_Normal, zone.Temperature_Downlimit, zone.Temperature_Uplimit); } zone.FluctuationIntensity = Math.Abs(zone.FluctuationIntensity); } base.AddDefinitions(definition); } protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); Clear(); OnBuildDone(); if (PlayerTemperatureManager.TryGetCurrentManager(out var mgr) && base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value)) { mgr.UpdateTemperatureDefinition(value.Definition); mgr.UpdateGUIText(); } } private void OnBuildDone() { if (!base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value)) { return; } value.Definition.Zones.ForEach(delegate(TemperatureZoneDefinition def) { //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_0014: 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_0079: 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_0042: 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) if (zoneDefs.ContainsKey((((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex))) { EOSLogger.Warning($"TemperatureDefinitionManager: duplicate definition found: {(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex)}"); } zoneDefs[(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex)] = def; }); } private void Clear() { zoneDefs.Clear(); } public bool TryGetZoneDefinition(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, out TemperatureZoneDefinition def) { //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) return zoneDefs.TryGetValue((dimensionIndex, layerType, localIndex), out def); } public bool TryGetLevelTemperatureSettings(out List<TemperatureSetting> settings) { if (base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value)) { settings = value.Definition.Settings; return settings != null && settings.Count > 0; } settings = null; return false; } private TemperatureDefinitionManager() { LevelAPI.OnBuildDone += OnBuildDone; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } static TemperatureDefinitionManager() { Current = new TemperatureDefinitionManager(); DEFAULT_ZONE_DEF = new TemperatureZoneDefinition { FluctuationIntensity = 0.0025f }; } } } namespace EOSExt.EnvTemperature.Patches { [HarmonyPatch] internal static class Patch_BulletWeapon { private static TemperatureSetting? m_curSetting; private static Dictionary<uint, float> DefaultReloadTimes; [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(BulletWeaponArchetype), "OnWield")] public static void Post_OnWield(BulletWeaponArchetype __instance) { uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID; if (!DefaultReloadTimes.ContainsKey(persistentID)) { DefaultReloadTimes[persistentID] = __instance.m_archetypeData.DefaultReloadTime; } TemperatureSetting curSetting = m_curSetting; if (curSetting != null && curSetting.SlowDownMultiplier_Reload > 0f) { __instance.m_archetypeData.DefaultReloadTime = DefaultReloadTimes[persistentID] * curSetting.SlowDownMultiplier_Reload; EOSLogger.Debug("Temperature: Slowing down reload!"); } } [HarmonyPostfix] [HarmonyPatch(typeof(BulletWeaponArchetype), "Update")] private static void Post_Update(BulletWeaponArchetype __instance) { TemperatureSetting currentTemperatureSetting = PlayerTemperatureManager.GetCurrentTemperatureSetting(); if (m_curSetting == currentTemperatureSetting) { return; } uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID; if (DefaultReloadTimes.ContainsKey(persistentID)) { float num = DefaultReloadTimes[persistentID]; if (currentTemperatureSetting == null || currentTemperatureSetting.SlowDownMultiplier_Reload <= 0f) { __instance.m_archetypeData.DefaultReloadTime = num; } else { __instance.m_archetypeData.DefaultReloadTime = num * currentTemperatureSetting.SlowDownMultiplier_Reload; } } m_curSetting = currentTemperatureSetting; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(BulletWeaponArchetype), "OnUnWield")] private static void Pre_OnUnWield(BulletWeaponArchetype __instance) { uint persistentID = ((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID; if (DefaultReloadTimes.ContainsKey(persistentID)) { float defaultReloadTime = DefaultReloadTimes[persistentID]; __instance.m_archetypeData.DefaultReloadTime = defaultReloadTime; } } private static void Clear() { DefaultReloadTimes.Clear(); } static Patch_BulletWeapon() { m_curSetting = null; DefaultReloadTimes = new Dictionary<uint, float>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } [HarmonyPatch] internal static class Patch_MWS_ChargeUp_Enter { private static float DefaultChargeTime = 1f; [HarmonyPostfix] [HarmonyPatch(typeof(MWS_ChargeUp), "Enter")] private static void Postfix_Enter(MWS_ChargeUp __instance) { DefaultChargeTime = __instance.m_maxDamageTime; TemperatureSetting currentTemperatureSetting = PlayerTemperatureManager.GetCurrentTemperatureSetting(); if (currentTemperatureSetting != null && currentTemperatureSetting.SlowDownMultiplier_Melee > 0f) { __instance.m_maxDamageTime *= currentTemperatureSetting.SlowDownMultiplier_Melee; } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(MWS_ChargeUp), "Exit")] private static void Pre_Exit(MWS_ChargeUp __instance) { __instance.m_maxDamageTime = DefaultChargeTime; } } [HarmonyPatch] internal static class Patch_Dam_PlayerDamageBase { internal static bool s_disableDialog; [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveFallDamage")] private static bool Pre_ReceiveFallDamage(Dam_PlayerDamageLocal __instance, pMiniDamageData data) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); ((Dam_PlayerDamageBase)__instance).m_nextRegen = Clock.Time + ((Dam_PlayerDamageBase)__instance).Owner.PlayerData.healthRegenStartDelayAfterDamage; if (((Agent)((Dam_PlayerDamageBase)__instance).Owner).IsLocallyOwned) { DramaManager.CurrentState.OnLocalDamage(num); GameEventManager.PostEvent((eGameEvent)13, ((Dam_PlayerDamageBase)__instance).Owner, num, "", (Dictionary<string, string>)null); } else { DramaManager.CurrentState.OnTeammatesDamage(num); } if (((Dam_PlayerDamageBase)__instance).IgnoreAllDamage) { return false; } if (SNet.IsMaster) { if (((Dam_SyncedDamageBase)__instance).RegisterDamage(num)) { ((Dam_SyncedDamageBase)__instance).SendSetDead(true); } else { ((Dam_SyncedDamageBase)__instance).SendSetHealth(((Dam_SyncedDamageBase)__instance).Health); } } __instance.Hitreact(((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax), Vector3.zero, true, !s_disableDialog, false); return false; } } [HarmonyPatch] internal static class Patch_PlayerAgent { [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPatch(typeof(PlayerAgent), "Setup")] private static void Post_Setup(PlayerAgent __instance) { if (((Agent)__instance).IsLocallyOwned && !((Object)(object)((Component)__instance).gameObject.GetComponent<PlayerTemperatureManager>() != (Object)null)) { PlayerTemperatureManager playerTemperatureManager = ((Component)__instance).gameObject.AddComponent<PlayerTemperatureManager>(); playerTemperatureManager.Setup(); } } } [HarmonyPatch] internal static class Patches_PLOC { private const float MIN_MOD = 0.1f; private static float s_moveSpeedMult = 1f; [HarmonyPrefix] [HarmonyPatch(typeof(PLOC_Base), "GetHorizontalVelocityFromInput")] private static void Pre_GetHorizontalVelocityFromInput(ref float moveSpeed) { moveSpeed *= s_moveSpeedMult; } internal static void SetMoveSpeedModifier(float m) { s_moveSpeedMult = Math.Max(0.1f, m); } internal static void ResetMoveSpeedModifier() { s_moveSpeedMult = 1f; } } } namespace EOSExt.EnvTemperature.Definitions { public class TemperatureSetting { public float Temperature { get; set; } = 1f; public float Damage { get; set; } = -1f; public float DamageTick { get; set; } public float SlowDownMultiplier_Reload { get; set; } = -1f; public float SlowDownMultiplier_Melee { get; set; } = -1f; public float SlowDownMultiplier_Move { get; set; } = -1f; public TemperatureSetting() { } public TemperatureSetting(TemperatureSetting o) { Temperature = o.Temperature; Damage = o.Damage; DamageTick = o.DamageTick; SlowDownMultiplier_Reload = o.SlowDownMultiplier_Reload; SlowDownMultiplier_Melee = o.SlowDownMultiplier_Melee; SlowDownMultiplier_Move = o.SlowDownMultiplier_Move; } } public class TemperatureZoneDefinition : GlobalZoneIndex { public float Temperature_Downlimit { get; set; } = 0.005f; public float Temperature_Normal { get; set; } = 0.5f; public float Temperature_Uplimit { get; set; } = 1f; public float FluctuationIntensity { get; set; } = 0f; } public class TemperatureDefinition { public float StartTemperature { get; set; } = 0.5f; public float JumpActionHeatGained { get; set; } public float SprintActionHeatGained { get; set; } public float CrouchActionHeatGained { get; set; } public float StandingActionHeatGained { get; set; } public float LadderClimbingActionHeatGained { get; set; } public List<TemperatureZoneDefinition> Zones { get; set; } = new List<TemperatureZoneDefinition> { new TemperatureZoneDefinition() }; public List<TemperatureSetting> Settings { get; set; } = new List<TemperatureSetting> { new TemperatureSetting() }; } } namespace EOSExt.EnvTemperature.Components { public class PlayerTemperatureManager : MonoBehaviour { public const float DEFAULT_PLAYER_TEMPERATURE = 0.5f; public const float TEMPERATURE_SETTING_UPDATE_TIME = 1f; public const float TEMPERATURE_FLUCTUATE_TIME = 1f; private float m_tempSettingLastUpdateTime = 0f; private float m_lastDamageTime = 0f; private float m_tempFluctuateTime = 0f; private bool m_ShowDamageWarning = true; private TextMeshPro m_TemperatureText; private const string DEFAULT_GUI_TEXT = "SUIT TEMP: <color=orange>{0}</color>"; private string m_GUIText = "SUIT TEMP: <color=orange>{0}</color>"; private readonly Color m_lowTempColor = new Color(0f, 0.5f, 0.5f); private readonly Color m_midTempColor = new Color(1f, 0.64f, 0f); private readonly Color m_highTempColor = new Color(1f, 0.07f, 0.576f); public PlayerAgent PlayerAgent { get; private set; } public TemperatureDefinition? TemperatureDef { get; private set; } public TemperatureSetting? TemperatureSetting { get; private set; } public float PlayerTemperature { get; private set; } = 0.5f; internal void Setup() { //IL_0058: 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_0077: Invalid comparison between Unknown and I4 TemperatureDef = null; PlayerAgent = ((Component)this).gameObject.GetComponent<PlayerAgent>(); LevelAPI.OnBuildDone += OnBuildDone; LevelAPI.OnEnterLevel += OnEnterLevel; EOSLogger.Warning($"GameState: {GameStateManager.CurrentStateName}"); if ((int)GameStateManager.CurrentStateName == 15) { OnBuildDone(); OnEnterLevel(); } } private void OnDestroy() { Object.Destroy((Object)(object)m_TemperatureText); LevelAPI.OnBuildDone -= OnBuildDone; LevelAPI.OnEnterLevel -= OnEnterLevel; } private void SetupGUI() { //IL_006a: 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_00be: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_TemperatureText == (Object)null) { m_TemperatureText = Object.Instantiate<TextMeshPro>(GuiManager.PlayerLayer.m_objectiveTimer.m_titleText); m_TemperatureText.transform.SetParent(((Component)GuiManager.PlayerLayer.m_playerStatus).gameObject.transform, false); ((Component)m_TemperatureText).GetComponent<RectTransform>().anchoredPosition = new Vector2(-5f, 8f); ((Component)m_TemperatureText).gameObject.transform.localPosition = new Vector3(268.2203f, 25.3799f, 0f); ((Component)m_TemperatureText).gameObject.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); } ((Component)m_TemperatureText).gameObject.SetActive(TemperatureDef != null); } internal void UpdateGUIText() { TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("EnvTemperature.Text"); m_GUIText = ((block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : "SUIT TEMP: <color=orange>{0}</color>"); } private void UpdateGui() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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: 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) if (TemperatureDef != null) { ((Component)m_TemperatureText).gameObject.SetActive(true); ((TMP_Text)m_TemperatureText).SetText(string.Format(m_GUIText, (PlayerTemperature * 100f).ToString("N0")), true); if (PlayerTemperature > 0.5f) { ((Graphic)m_TemperatureText).color = Color.Lerp(m_midTempColor, m_highTempColor, (PlayerTemperature - 0.5f) * 2f); } else { ((Graphic)m_TemperatureText).color = Color.Lerp(m_lowTempColor, m_midTempColor, PlayerTemperature * 2f); } ((TMP_Text)m_TemperatureText).ForceMeshUpdate(false, false); } else { ((Component)m_TemperatureText).gameObject.SetActive(false); } } private void UpdateMoveSpeed() { if (TemperatureSetting == null || TemperatureSetting.SlowDownMultiplier_Move <= 0f) { Patches_PLOC.ResetMoveSpeedModifier(); } else { Patches_PLOC.SetMoveSpeedModifier(TemperatureSetting.SlowDownMultiplier_Move); } } private void ResetMoveSpeed() { Patches_PLOC.ResetMoveSpeedModifier(); } public void UpdateTemperatureDefinition(TemperatureDefinition def) { TemperatureDef = def; TemperatureSetting = null; PlayerTemperature = def?.StartTemperature ?? 0.5f; } private void OnBuildDone() { UpdateTemperatureDefinition(((GenericDefinitionManager<TemperatureDefinition>)TemperatureDefinitionManager.Current).GetDefinition(RundownManager.ActiveExpedition.LevelLayoutData)?.Definition ?? null); } private void OnEnterLevel() { PlayerTemperature = ((TemperatureDef != null) ? TemperatureDef.StartTemperature : 0.5f); UpdateGUIText(); SetupGUI(); ResetMoveSpeed(); } private void DealDamage() { if (TemperatureSetting != null && !(TemperatureSetting.Damage < 0f) && !(Time.time - m_lastDamageTime < TemperatureSetting.DamageTick)) { Patch_Dam_PlayerDamageBase.s_disableDialog = true; ((Dam_SyncedDamageBase)PlayerAgent.Damage).FallDamage(TemperatureSetting.Damage); Patch_Dam_PlayerDamageBase.s_disableDialog = false; m_lastDamageTime = Time.time; } } private void UpdateTemperatureSettings() { if (Time.time - m_tempSettingLastUpdateTime < 1f) { return; } if (!TemperatureDefinitionManager.Current.TryGetLevelTemperatureSettings(out var settings)) { TemperatureSetting = null; return; } int num = 0; int num2 = settings.Count - 1; float playerTemperature = PlayerTemperature; while (num < num2) { int num3 = (num + num2) / 2; float temperature = settings[num3].Temperature; float num4 = ((num3 + 1 < settings.Count) ? settings[num3 + 1].Temperature : 1f); if (temperature <= playerTemperature && playerTemperature < num4) { break; } if (playerTemperature < temperature) { num2 = num3 - 1; } else { num = num3 + 1; } } TemperatureSetting = settings[Math.Clamp((num + num2) / 2, 0, settings.Count - 1)]; m_tempSettingLastUpdateTime = Time.time; } private 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_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_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_008c: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected I4, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: 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) if ((int)GameStateManager.CurrentStateName != 10 || TemperatureDef == null || (Object)(object)PlayerAgent == (Object)null) { return; } Vector3 lastMoveDelta = PlayerAgent.Locomotion.LastMoveDelta; float num = ((Vector3)(ref lastMoveDelta)).magnitude / Clock.FixedDelta; float num2 = (PlayerAgent.PlayerData.walkMoveSpeed + PlayerAgent.PlayerData.runMoveSpeed) * 0.5f; float num3 = 0f; PLOC_State currentStateEnum = PlayerAgent.Locomotion.m_currentStateEnum; PLOC_State val = currentStateEnum; switch ((int)val) { case 0: num3 = TemperatureDef.StandingActionHeatGained * Time.deltaTime; break; case 1: num3 = ((!(num <= num2)) ? ((TemperatureDef.CrouchActionHeatGained + TemperatureDef.SprintActionHeatGained) * Time.deltaTime) : (TemperatureDef.CrouchActionHeatGained * Time.deltaTime)); break; case 2: num3 = TemperatureDef.SprintActionHeatGained * Time.deltaTime; break; case 3: num3 = ((!(num <= num2)) ? ((TemperatureDef.JumpActionHeatGained + TemperatureDef.SprintActionHeatGained) * Time.deltaTime) : (TemperatureDef.JumpActionHeatGained * Time.deltaTime)); break; case 7: num3 = 0f; break; case 8: num3 = TemperatureDef.LadderClimbingActionHeatGained * Time.deltaTime; break; } float num4 = TemperatureDef.StartTemperature; LG_Zone zone = ((Agent)PlayerAgent).CourseNode.m_zone; float min = 0.005f; float max = 1f; if (TemperatureDefinitionManager.Current.TryGetZoneDefinition(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex, out var def)) { num4 = def.Temperature_Normal; min = def.Temperature_Downlimit; max = def.Temperature_Uplimit; } else { def = TemperatureDefinitionManager.DEFAULT_ZONE_DEF; } if ((double)Math.Abs(num3) < 1E-05) { if (Time.time - m_tempFluctuateTime > 1f) { float num5 = def.FluctuationIntensity * Random.RandomRange(0f, 1f); if (PlayerTemperature > num4) { PlayerTemperature -= num5; } else { PlayerTemperature += num5; } m_tempFluctuateTime = Time.time; } } else { m_tempFluctuateTime = Time.time; } PlayerTemperature += num3; PlayerTemperature = Math.Clamp(PlayerTemperature, min, max); UpdateTemperatureSettings(); TemperatureSetting? temperatureSetting = TemperatureSetting; if (temperatureSetting != null && temperatureSetting.Damage > 0f) { DealDamage(); } UpdateGui(); UpdateMoveSpeed(); } public static bool TryGetCurrentManager(out PlayerTemperatureManager mgr) { mgr = null; LocalPlayerAgent val = default(LocalPlayerAgent); if (!LocalPlayer.TryGetLocalAgent(ref val)) { EOSLogger.Debug("Temperature: cannot get localplayeragent"); return false; } mgr = ((Component)val).gameObject.GetComponent<PlayerTemperatureManager>(); if ((Object)(object)mgr == (Object)null) { EOSLogger.Error("LocalPlayerAgent does not have `PlayerTemperatureManager`!"); return false; } return true; } public static TemperatureSetting? GetCurrentTemperatureSetting() { if (!TryGetCurrentManager(out var mgr)) { return null; } return mgr.TemperatureSetting; } static PlayerTemperatureManager() { ClassInjector.RegisterTypeInIl2Cpp<PlayerTemperatureManager>(); } } }
plugins/Inas07.EOSExt.ExtraDoor.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.ExtraDoor.Config; using Enemies; using Expedition; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Extensions; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using SNetwork; using UnityEngine; using XXHashing; [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("Inas07.EOSExt.ExtraDoor")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a5104ed29beb6c0446fce0b70afe78132232a184")] [assembly: AssemblyProduct("Inas07.EOSExt.ExtraDoor")] [assembly: AssemblyTitle("Inas07.EOSExt.ExtraDoor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.ExtraDoor { [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.*/)] [BepInPlugin("Inas.EOSExt.ExtraDoor", "EOSExt.ExtraDoor", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.ExtraDoor"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.ExtraDoor"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.ExtraDoor loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<ForceConnectCfg>)ForceConnectManager.Current).Init(); } } internal static class ForceConnectDoorUtils { public static ForceConnect? GetFC(this LG_SecurityDoor fcdoor) { return ((Component)fcdoor).gameObject.GetComponentInParent<ForceConnect>(); } public static List<(LG_ZoneExpander fromExp, LG_ZoneExpander toExp)> GetExpandersBetween(LG_Area fromArea, LG_Area toAreaB) { //IL_0044: 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_006c: 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_008c: 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) List<(LG_ZoneExpander, LG_ZoneExpander)> list = new List<(LG_ZoneExpander, LG_ZoneExpander)>(); Enumerator<LG_ZoneExpander> enumerator = fromArea.m_zoneExpanders.GetEnumerator(); Vector2 val = default(Vector2); Vector2 val2 = default(Vector2); while (enumerator.MoveNext()) { LG_ZoneExpander current = enumerator.Current; Enumerator<LG_ZoneExpander> enumerator2 = toAreaB.m_zoneExpanders.GetEnumerator(); while (enumerator2.MoveNext()) { LG_ZoneExpander current2 = enumerator2.Current; ((Vector2)(ref val))..ctor(((Component)current).transform.position.x, ((Component)current).transform.position.z); ((Vector2)(ref val2))..ctor(((Component)current2).transform.position.x, ((Component)current2).transform.position.z); if (Vector2.Distance(val, val2) <= 0.1f) { list.Add((current, current2)); } } } return list; } public static void FCOnDoorOpenStarted(this LG_SecurityDoor fcdoor) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown if ((int)fcdoor.m_securityDoorType == 2) { LG_LayerType linksToLayerType = fcdoor.LinksToLayerType; LG_LayerType val = linksToLayerType; switch ((int)val) { case 0: fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_HIGH_LOOP, true); break; case 1: fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_EXTREME_LOOP, true); break; case 2: fcdoor.m_sound.Post(EVENTS.BULKHEAD_ENTRANCE_THREAT_OVERLOAD_LOOP, true); break; } } } public static void FCOnDoorIsOpen(this LG_SecurityDoor fcdoor) { ForceConnect fC = fcdoor.GetFC(); EOSLogger.Log($"OnDoorIsOpened: ForceConnect: {fcdoor.LinkedToZoneData}"); if (!((Object)(object)fC != (Object)null)) { return; } List<LevelEventData> eventsOnEnter = fC.Cfg.Setting.EventsOnEnter; EOSLogger.Log("OnDoorIsOpened, FC.EventsOnEnter"); if (eventsOnEnter != null && eventsOnEnter.Count > 0) { eventsOnEnter.ForEach(delegate(LevelEventData e) { ((MonoBehaviour)fcdoor).StartCoroutine(fcdoor.TriggerLevelEventWithDelay(e)); }); } WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnOpenDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } public static void FCOnSyncDoorStatusChange(this LG_SecurityDoor fcdoor, pDoorState state, bool isRecall) { //IL_0022: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0111: 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_0120: Invalid comparison between Unknown and I4 //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected I4, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Invalid comparison between Unknown and I4 //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Invalid comparison between Unknown and I4 //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_01f6: Invalid comparison between Unknown and I4 //IL_0624: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Invalid comparison between Unknown and I4 //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Invalid comparison between Unknown and I4 //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Invalid comparison between Unknown and I4 //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) ForceConnect fC = fcdoor.GetFC(); EOSLogger.Log($"OnSyncDoorStatusChange: m_lastState.hasBeenApproached: {fcdoor.m_lastState.hasBeenApproached}, state.hasBeenApproached: {state.hasBeenApproached}, ForceConnect: {fC}"); if (fcdoor.m_lastState.hasBeenApproached != state.hasBeenApproached && state.hasBeenApproached && (Object)(object)fC != (Object)null && !isRecall) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnApproachDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); fcdoor.LastStatus = state.status; fcdoor.m_lastState = state; return; } fcdoor.Gate.HasBeenOpenedDuringPlay = state.hasBeenOpenedDuringGame; fcdoor.m_graphics.OnDoorState(state, isRecall); fcdoor.m_anim.OnDoorState(state, isRecall); fcdoor.m_locks.OnDoorState(state, isRecall); bool flag = (int)fcdoor.m_securityDoorType == 2; eDoorStatus status = state.status; eDoorStatus val = status; switch (val - 1) { case 0: case 1: case 4: case 5: case 6: case 7: case 8: if ((int)state.status == 8 && fcdoor.OnChainPuzzleActivate != null) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnDoorScanStart), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); if (fcdoor.LinkedToZoneData.PlayScannerVoiceAudio) { fcdoor.m_sound.Post(EVENTS.TTS_PLEASE_STEP_INTO_THE_BIOSCAN, true); } fcdoor.OnChainPuzzleActivate.Invoke(); } if ((int)state.status == 9 && fcdoor.OnChainPuzzleActivate != null) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnDoorScanDone), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); if (fC.Cfg.Setting.PlayScannerVoiceAudio) { fcdoor.m_sound.Post(EVENTS.TTS_BIOSCAN_SEQUENCE_COMPLETED, true); } } if (((int)state.status == 9 || (int)state.status == 5) && (int)fcdoor.m_lastState.status == 3) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnUnlockDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 7)); fcdoor.CheckSetNavmarkerForBulkheadDoors(); break; case 2: { fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 8)); PlaceNavMarkerOnGO navMarkerPlacer2 = fcdoor.m_navMarkerPlacer; if ((Object)(object)navMarkerPlacer2 != (Object)null) { navMarkerPlacer2.SetMarkerVisible(false); } break; } case 3: if ((int)fcdoor.m_lastState.status == 3) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(fC.Cfg.Setting.EventsOnUnlockDoor), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 9)); fcdoor.CheckSetNavmarkerForBulkheadDoors(); break; case 9: { PlaceNavMarkerOnGO navMarkerPlacer = fcdoor.m_navMarkerPlacer; if ((Object)(object)navMarkerPlacer != (Object)null) { navMarkerPlacer.SetMarkerVisible(false); } fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 12 : 6)); ActiveEnemyWaveData activeEnemyWave = fC.Cfg.Setting.ActiveEnemyWave; if (activeEnemyWave == null || !activeEnemyWave.HasActiveEnemyWave) { break; } fcdoor.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_STOP, true); if (isRecall || !SNet.IsMaster) { break; } ForceConnectCfg cfg = fC.Cfg; LG_Zone val2 = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(cfg.DimensionIndex, cfg.To.Layer, cfg.To.LocalIndex, ref val2); AIG_CourseNode courseNode = val2.m_areas[cfg.To.AreaIndex].m_courseNode; Vector3 val3 = ((Component)fcdoor).transform.position + ((Component)fcdoor).transform.forward * -1.5f + Vector3.up * 0.3f; Vector3 gateCrossingVec = fcdoor.Gate.GetGateCrossingVec(); if (activeEnemyWave.EnemyGroupInfrontOfDoor != 0) { EnemyGroupDataBlock block = GameDataBlockBase<EnemyGroupDataBlock>.GetBlock(activeEnemyWave.EnemyGroupInfrontOfDoor); if (block == null) { EOSLogger.Error($"Can not spawn group. EnemyGroupDataBlock.GetBlock(ActiveEnemyWaveData.EnemyGroupInfrontOfDoor = {activeEnemyWave.EnemyGroupInfrontOfDoor}) returned null."); } else { Mastermind.Current.SpawnGroup(val3, courseNode, (EnemyGroupType)2, (eEnemyGroupSpawnType)3, block, -1f, gateCrossingVec, (IReplicator)null); } } if (activeEnemyWave.EnemyGroupInArea == 0) { break; } EnemyGroupDataBlock block2 = GameDataBlockBase<EnemyGroupDataBlock>.GetBlock(activeEnemyWave.EnemyGroupInArea); if (block2 == null) { EOSLogger.Error($"Can not spawn groups.EnemyGroupDataBlock.GetBlock(ActiveEnemyWaveData.EnemyGroupInArea = {activeEnemyWave.EnemyGroupInArea} ) returned null."); } else { for (int i = 0; i < activeEnemyWave.EnemyGroupsInArea; i++) { Mastermind.Current.SpawnGroup(val3, courseNode, (EnemyGroupType)2, (eEnemyGroupSpawnType)0, block2, -1f, default(Vector3), (IReplicator)null); } } break; } case 14: { fcdoor.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)(flag ? 11 : 7)); PlaceNavMarkerOnGO navMarkerPlacer3 = fcdoor.m_navMarkerPlacer; if ((Object)(object)navMarkerPlacer3 != (Object)null) { navMarkerPlacer3.SetMarkerVisible(false); } break; } case 15: if (isRecall && SNet.IsMaster) { fcdoor.m_sync.AttemptDoorInteraction((eDoorInteractionType)0, 0f, 0f, default(Vector3), (Agent)null); } else if (SNet.IsMaster) { fcdoor.m_checkpointPuzzle.AttemptInteract((eChainedPuzzleInteraction)0); } break; } fcdoor.LastStatus = state.status; fcdoor.m_lastState = state; } } public class ForceConnect : MonoBehaviour { internal bool ShouldFlipDoor; private bool _IsDynamicPortalSetup; private AIG_CourseNode _FromNode; private AIG_CourseNode _ToNode; private AIG_CoursePortal _Portal; private bool _PortalEnabled = true; public LG_SecurityDoor LinkedSecDoor { get; internal set; } public ForceConnectCfg Cfg { get; internal set; } private void Update() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_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_0095: Invalid comparison between Unknown and I4 if (!_IsDynamicPortalSetup && (Object)(object)LinkedSecDoor != (Object)null && (int)GameStateManager.CurrentStateName == 10) { LG_Gate gate = LinkedSecDoor.Gate; _Portal = ((LG_ZoneExpander)gate).CoursePortal; _FromNode = ((LG_ZoneExpander)gate).m_linksFrom.m_courseNode; _ToNode = ((LG_ZoneExpander)gate).m_linksTo.m_courseNode; _IsDynamicPortalSetup = true; } else if (_IsDynamicPortalSetup) { eDoorStatus status = LinkedSecDoor.m_sync.GetCurrentSyncState().status; eDoorStatus val = status; if ((int)val != 10) { SetPortalEnabled(enabled: false); } else { SetPortalEnabled(enabled: true); } } } private void SetPortalEnabled(bool enabled) { if (enabled && !_PortalEnabled) { _FromNode.m_portals.Add(_Portal); _ToNode.m_portals.Add(_Portal); _PortalEnabled = true; } else if (!enabled && _PortalEnabled) { RemoveItem(_FromNode.m_portals, _Portal); RemoveItem(_ToNode.m_portals, _Portal); _PortalEnabled = false; } } private void RemoveItem(List<AIG_CoursePortal> portals, AIG_CoursePortal portal) { for (int i = 0; i < portals.Count; i++) { if (((Il2CppObjectBase)portals[i]).Pointer == ((Il2CppObjectBase)portal).Pointer) { portals.RemoveAt(i); break; } } } static ForceConnect() { ClassInjector.RegisterTypeInIl2Cpp<ForceConnect>(); } } public class ForceConnectManager : GenericExpeditionDefinitionManager<ForceConnectCfg> { public enum FCDoorEventType { OpenFCDoor = 900, UnlockFCDoor, CloseFCDoor, LockFCDoor } private Dictionary<string, LG_SecurityDoor> m_doorLookup = new Dictionary<string, LG_SecurityDoor>(); public static ForceConnectManager Current { get; } = new ForceConnectManager(); protected override string DEFINITION_NAME => "ExtraDoor"; public void BuildCfg(ForceConnectCfg cfg) { //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_0032: 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_003a: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) eDimensionIndex dimensionIndex = cfg.DimensionIndex; Door door = cfg.From; Door to = cfg.To; LG_Zone val = default(LG_Zone); LG_Zone val2 = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, door.Layer, door.LocalIndex, ref val) || 0 > door.AreaIndex || door.AreaIndex >= val.m_areas.Count || !Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, to.Layer, to.LocalIndex, ref val2) || 0 > to.AreaIndex || to.AreaIndex >= val2.m_areas.Count) { EOSLogger.Error($"CircularZones Build: Cannot find Zone 'From' or 'To'!\nFrom:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})"); return; } LG_Area fromArea = val.m_areas[door.AreaIndex]; LG_Area toArea = val2.m_areas[to.AreaIndex]; List<(LG_ZoneExpander, LG_ZoneExpander)> expandersBetween = ForceConnectDoorUtils.GetExpandersBetween(fromArea, toArea); if (expandersBetween.Count < 1) { EOSLogger.Error($"ExtraDoor: cannot find gate / plug! From:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})"); } else if (cfg.FromDoorIndex < 0 || cfg.FromDoorIndex >= expandersBetween.Count) { EOSLogger.Error($"ExtraDoor: FromDoorIndex ({cfg.FromDoorIndex}) is out of range [0, {expandersBetween.Count})From:({(cfg.DimensionIndex, door.Layer, door.LocalIndex, (char)(65 + door.AreaIndex))})To:({(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))})"); } else { Setup(expandersBetween[cfg.FromDoorIndex].Item1, expandersBetween[cfg.FromDoorIndex].Item2); } void Setup(LG_ZoneExpander expandFrom, LG_ZoneExpander expandTo) { LG_Plug val3 = ((Il2CppObjectBase)expandFrom).TryCast<LG_Plug>(); LG_Plug val4 = ((Il2CppObjectBase)expandTo).TryCast<LG_Plug>(); if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null) { val3.m_pariedWith = val4; val4.m_pariedWith = val3; ((LG_ZoneExpander)val3).m_isZoneSource = true; expandFrom.ExpanderStatus = (LG_ZoneExpanderStatus)1; expandTo.ExpanderStatus = (LG_ZoneExpanderStatus)1; expandFrom.m_linksTo = expandTo.m_linksFrom; expandTo.m_linksTo = expandFrom.m_linksFrom; GameObject gameObject = ((Component)val3).gameObject; ((Object)gameObject).name = ((Object)gameObject).name + "FORCE PAIR"; ((Component)val3).gameObject.AddComponent<ForceConnect>().Cfg = cfg; } else { LG_Gate gate = expandFrom.GetGate(); switch (cfg.Setting.SecurityGateToEnter) { case GateType.Security: gate.ForceSecurityGate = true; break; case GateType.Apex: gate.ForceApexGate = true; break; case GateType.Bulkhead: case GateType.Bulkhead_Main: gate.ForceSecurityGate = true; gate.ForceBulkheadGate = true; break; } if (((Il2CppObjectBase)fromArea.m_zone).Pointer != ((Il2CppObjectBase)toArea.m_zone).Pointer) { expandFrom.m_isZoneSource = true; expandFrom.ExpanderStatus = (LG_ZoneExpanderStatus)1; expandTo.ExpanderStatus = (LG_ZoneExpanderStatus)1; } GameObject gameObject2 = ((Component)gate).gameObject; ((Object)gameObject2).name = ((Object)gameObject2).name + "FORCE PAIR"; ((Component)gate).gameObject.AddComponent<ForceConnect>().Cfg = cfg; } } } private void Build() { if (base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value)) { value.Definitions.ForEach(BuildCfg); } } private void BuildProgressionPuzzle() { //IL_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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) //IL_00a4: 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_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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected I4, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_01e4: 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_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: 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) LG_Zone val = default(LG_Zone); LG_Zone val2 = default(LG_Zone); foreach (KeyValuePair<string, LG_SecurityDoor> item in m_doorLookup) { LG_SecurityDoor value = item.Value; ForceConnect fC = value.GetFC(); Door door = fC.Cfg.From; Door to = fC.Cfg.To; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(fC.Cfg.DimensionIndex, door.Layer, door.LocalIndex, ref val) || 0 > door.AreaIndex || door.AreaIndex >= val.m_areas.Count || !Builder.CurrentFloor.TryGetZoneByLocalIndex(fC.Cfg.DimensionIndex, to.Layer, to.LocalIndex, ref val2) || 0 > to.AreaIndex || to.AreaIndex >= val2.m_areas.Count || val2.ID <= 0) { continue; } if ((Object)(object)val2.m_sourceExpander == (Object)null) { EOSLogger.Error("Found zone without sourceGate AND ID over 0, id: " + val.ID); continue; } FCProgressionPuzzleToEnter progressionPuzzleToEnter = fC.Cfg.Setting.ProgressionPuzzleToEnter; LG_Layer layer = val2.Layer; eProgressionPuzzleType puzzleType = progressionPuzzleToEnter.PuzzleType; eProgressionPuzzleType val3 = puzzleType; switch (val3 - 1) { case 0: { GateKeyItem randomKey = Builder.CurrentFloor.GetRandomKey(Builder.SessionSeedRandom); LG_Factory.InjectJob((LG_FactoryJob)new LG_BuildKeyItemLockJob(value, randomKey), (BatchName)43); if (progressionPuzzleToEnter.ZonePlacementData.Count > 0) { LG_Zone val8 = CreateKeyItemDistribution(randomKey, progressionPuzzleToEnter.ZonePlacementData[Builder.SessionSeedRandom.Range(0, progressionPuzzleToEnter.ZonePlacementData.Count, "NO_TAG")], layer); ProgressionObjectivesManager.RegisterProgressionObjective(val2.DimensionIndex, val2.Layer.m_type, val2.LocalIndex, ((Il2CppObjectBase)new ProgressionObjective_KeyCard(randomKey, val2, val8)).Cast<IProgressionObjective>()); } break; } case 1: { AIG_CourseNode courseNode = val.m_areas[door.AreaIndex].m_courseNode; LG_DistributeItem val4 = new LG_DistributeItem((ExpeditionFunction)6, 1f, courseNode, (LG_Gate)null) { m_assignedGate = value.Gate }; courseNode.m_zone.DistributionData.GenericFunctionItems.Enqueue(val4); LG_Zone val5 = null; for (int i = 0; i < progressionPuzzleToEnter.PlacementCount; i++) { LG_Zone val6 = layer.m_zones[0]; ZonePlacementWeights val7 = new ZonePlacementWeights(); if (progressionPuzzleToEnter.ZonePlacementData.Count > 0) { FCZonePlacementData fCZonePlacementData = progressionPuzzleToEnter.ZonePlacementData[Builder.SessionSeedRandom.Range(0, progressionPuzzleToEnter.ZonePlacementData.Count, "NO_TAG")]; if (layer.m_zonesByLocalIndex.ContainsKey(((GlobalZoneIndex)fCZonePlacementData).LocalIndex)) { val6 = layer.m_zonesByLocalIndex[((GlobalZoneIndex)fCZonePlacementData).LocalIndex]; val5 = layer.m_zonesByLocalIndex[((GlobalZoneIndex)fCZonePlacementData).LocalIndex]; val7 = fCZonePlacementData.Weights; } else { EOSLogger.Error($"ProgressionPuzzleToEnter, Could NOT find zone with LocalIndex {((GlobalZoneIndex)fCZonePlacementData).LocalIndex} to place powerCell in to enter Zone {val2.LocalIndex}. Faulty zone specified!? DEFAULTING TO THE FIRST ZONE"); } } else { EOSLogger.Error($"ProgressionPuzzleToEnter has NO placement data for power cell going into {layer.m_type} lg_Zone.LocalIndex"); } ((LG_FactoryJob)new LG_Distribute_PickupItemsPerZone(val6, 1f, (ePickupItemType)3, 131u, val7)).Build(); } if ((Object)(object)val5 != (Object)null) { ProgressionObjectivesManager.RegisterProgressionObjective(val2.DimensionIndex, val2.Layer.m_type, val2.LocalIndex, ((Il2CppObjectBase)new ProgressionObjective_GeneratorCell(val2, val5, courseNode.m_zone)).Cast<IProgressionObjective>()); } break; } case 2: value.SetupAsLockedNoKey(progressionPuzzleToEnter.CustomText); break; } } } private LG_Zone CreateKeyItemDistribution(GateKeyItem keyItem, FCZonePlacementData placementData, LG_Layer doorLayer) { //IL_0058: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Expected O, but got Unknown EOSLogger.Log($"CreateKeyItemDistribution, keyItem: {keyItem}, placementData: {placementData}"); LG_Zone val = doorLayer.m_zones[0]; if (doorLayer.m_zonesByLocalIndex.ContainsKey(((GlobalZoneIndex)placementData).LocalIndex)) { val = doorLayer.m_zonesByLocalIndex[((GlobalZoneIndex)placementData).LocalIndex]; } else { EOSLogger.Error($"LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution, Could NOT find zone with LocalIndex {((GlobalZoneIndex)placementData).LocalIndex} to place keycard in to enter Zone {val.LocalIndex} Faulty zone specified!? Dim: {doorLayer.m_dimension.DimensionIndex} | DEFAULTING TO THE FIRST ZONE"); } ResourceContainerSpawnData val2 = new ResourceContainerSpawnData { m_type = (eResourceContainerSpawnType)7, m_keyItem = keyItem }; float num = Builder.BuildSeedRandom.Value("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution_" + keyItem.PublicName); AIG_CourseNode val3 = null; LG_DistributeItem val4 = default(LG_DistributeItem); if (LG_DistributionJobUtils.TryGetExistingZoneFunctionDistribution(val, (ExpeditionFunction)10, Builder.SessionSeedRandom.Value("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution_TryGetZoneFunctionDistribution"), placementData.Weights, ref val4, ref val3, true, "FindContainerFor " + (object)keyItem)) { LG_DistributeResourceContainer val5 = ((Il2CppObjectBase)val4).Cast<LG_DistributeResourceContainer>(); if (val5 != null) { val5.m_packs.Add(val2); val5.m_locked = true; } else { EOSLogger.Error("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution could not cast distItem as LG_DistributeResourceContainer!!"); } } else { val3 = LG_DistributionJobUtils.GetRandomNodeFromZoneForFunction(val, (ExpeditionFunction)10, num, 1f); LG_DistributeResourceContainer val6 = new LG_DistributeResourceContainer((ExpeditionFunction)10, val2, false, val3, Builder.BuildSeedRandom.Range(0, int.MaxValue, "LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer"), Builder.BuildSeedRandom.Value("LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer_Lock"), Builder.BuildSeedRandom.Range(2, 4, "LG_Distribute_ProgressionPuzzles_New_LG_DistributeResourceContainer_StoragePotential")); val3.m_zone.DistributionData.ResourceContainerItems.Enqueue(val6); EOSLogger.Error("LG_Distribute_ProgressionPuzzles.CreateKeyItemDistribution Had to create a new resourceContainer!!"); } iLG_SpawnedInNodeHandler component = ((Component)keyItem.SpawnedItem).GetComponent<iLG_SpawnedInNodeHandler>(); if (component != null) { component.SpawnNode = val3; } return val; } public void RegisterFCDoor(LG_SecurityDoor fcdoor) { ForceConnect fC = fcdoor.GetFC(); if ((Object)(object)fC == (Object)null) { EOSLogger.Error("ExtraDoor: Registering non-forceconnect door"); return; } if (m_doorLookup.ContainsKey(fC.Cfg.WorldEventObjectFilter)) { EOSLogger.Error("ExtraDoor: Duplicate ExtraDoor '" + fC.Cfg.WorldEventObjectFilter + "'"); } m_doorLookup[fC.Cfg.WorldEventObjectFilter] = fcdoor; } public LG_SecurityDoor GetFCDoor(string worldEventObjectFilter) { LG_SecurityDoor value; return m_doorLookup.TryGetValue(worldEventObjectFilter, out value) ? value : null; } private void Cleanup() { m_doorLookup.Clear(); } private void OnEnterLevel() { } private ForceConnectManager() { BatchBuildManager.Current.Add_OnBatchDone((BatchName)5, (Action)Build); BatchBuildManager.Current.Add_OnBatchDone((BatchName)16, (Action)BuildProgressionPuzzle); EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.OpenFCDoor.ToString(), 900u, (Action<WardenObjectiveEventData>)OpenFCDoor); EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.UnlockFCDoor.ToString(), 901u, (Action<WardenObjectiveEventData>)UnlockFCDoor); EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.CloseFCDoor.ToString(), 902u, (Action<WardenObjectiveEventData>)CloseFCDoor); EOSWardenEventManager.Current.AddEventDefinition(FCDoorEventType.LockFCDoor.ToString(), 903u, (Action<WardenObjectiveEventData>)LockFCDoor); LevelAPI.OnEnterLevel += OnEnterLevel; LevelAPI.OnLevelCleanup += Cleanup; } private static void OpenFCDoor(WardenObjectiveEventData e) { if (SNet.IsMaster) { LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter); if ((Object)(object)fCDoor == (Object)null) { EOSLogger.Error("OpenFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'"); } else { fCDoor.ForceOpenSecurityDoor(); } } } private static void UnlockFCDoor(WardenObjectiveEventData e) { if (SNet.IsMaster) { LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter); if ((Object)(object)fCDoor == (Object)null) { EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'"); } else { fCDoor.UseChainedPuzzleOrUnlock(SNet.Master); } } } private static void CloseFCDoor(WardenObjectiveEventData e) { //IL_0059: 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_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_0067: Invalid comparison between Unknown and I4 //IL_0069: 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_0071: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter); if ((Object)(object)fCDoor == (Object)null) { EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'"); return; } pDoorState currentSyncState = fCDoor.m_sync.GetCurrentSyncState(); if ((int)currentSyncState.status != 10 && (int)currentSyncState.status != 16) { return; } LG_Door_Sync val = ((Il2CppObjectBase)fCDoor.m_sync).TryCast<LG_Door_Sync>(); if (!((Object)(object)val == (Object)null)) { pDoorState currentSyncState2 = val.GetCurrentSyncState(); currentSyncState2.status = (eDoorStatus)1; currentSyncState2.hasBeenOpenedDuringGame = false; pDoorState state = currentSyncState2; val.m_stateReplicator.State = state; LG_Gate gate = fCDoor.Gate; gate.HasBeenOpenedDuringPlay = false; gate.IsTraversable = false; ForceConnect fC = fCDoor.GetFC(); DoorSetting setting = fC.Cfg.Setting; if (setting.ActiveEnemyWave != null && setting.ActiveEnemyWave.HasActiveEnemyWave) { fCDoor.m_sound.Post(EVENTS.MONSTER_RUCKUS_FROM_BEHIND_SECURITY_DOOR_LOOP_START, true); } EOSLogger.Debug("Door Closed!"); } } private static void LockFCDoor(WardenObjectiveEventData e) { //IL_006a: 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_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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } LG_SecurityDoor fCDoor = Current.GetFCDoor(e.WorldEventObjectFilter); if ((Object)(object)fCDoor == (Object)null) { EOSLogger.Error("UnlockFCDoor: Cannot find FC door with '" + e.WorldEventObjectFilter + "'"); return; } LG_Door_Sync val = ((Il2CppObjectBase)fCDoor.m_sync).TryCast<LG_Door_Sync>(); if (!((Object)(object)val == (Object)null)) { pDoorState currentSyncState = val.GetCurrentSyncState(); currentSyncState.status = (eDoorStatus)7; pDoorState state = currentSyncState; val.m_stateReplicator.State = state; EOSLogger.Debug("Door Locked!"); } } } } namespace EOSExt.ExtraDoor.Patches { [HarmonyPatch] internal static class CheckDoorFlip { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_BuildSecurityDoorLockJob), "CheckFlip")] private static bool Pre_(LG_BuildSecurityDoorLockJob __instance) { //IL_002f: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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) ForceConnect fC = __instance.m_door.GetFC(); if ((Object)(object)fC == (Object)null) { return true; } LG_SecurityDoor door = __instance.m_door; Vector3 forward = ((Component)door).transform.forward; ForceConnectCfg cfg = fC.Cfg; Door door2 = cfg.From; LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(cfg.DimensionIndex, door2.Layer, door2.LocalIndex, ref val); LG_Area val2 = val.m_areas[door2.AreaIndex]; LG_Area linksFrom = ((LG_ZoneExpander)door.Gate).m_linksFrom; Door to = cfg.To; EOSLogger.Warning($"CheckFilp!\nOri: {((Object)linksFrom).name} -> {((Object)((LG_ZoneExpander)door.Gate).m_linksTo).name}\nShould be: {(cfg.DimensionIndex, door2.Layer, door2.LocalIndex, (char)(65 + door2.AreaIndex))} -> {(cfg.DimensionIndex, to.Layer, to.LocalIndex, (char)(65 + to.AreaIndex))}"); if (door.FlippedForProgresion) { EOSLogger.Error("Door already flipped, skipped ...."); return false; } if (((Il2CppObjectBase)val2).Pointer == ((Il2CppObjectBase)linksFrom).Pointer) { EOSLogger.Error("Flipped!"); door.FlippedForProgresion = true; ((Component)door).transform.rotation = Quaternion.LookRotation(((Component)door).transform.forward * -1f, ((Component)door).transform.up); } return false; } } [HarmonyPatch] internal static class OnSecurityDoorSetup { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor), "Setup")] private static void Postfix(LG_SecurityDoor __instance) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) ForceConnect fC = __instance.GetFC(); if (!((Object)(object)fC != (Object)null)) { return; } ForceConnectCfg cfg = fC.Cfg; Door door = cfg.From; Door to = cfg.To; EOSLogger.Debug($"ForceConnect: {cfg.DimensionIndex}, ({door.Layer}, {door.LocalIndex}, {(ushort)(65 + door.AreaIndex)}) <-> ({to.Layer}, {to.LocalIndex}, {(ushort)(65 + to.AreaIndex)})\nWorldEventObjectFilter: '{cfg.WorldEventObjectFilter}', FromDoorIndex: {cfg.FromDoorIndex}"); ForceConnectManager.Current.RegisterFCDoor(__instance); fC.LinkedSecDoor = __instance; __instance.LinksToLayerType = to.Layer; LG_Door_Sync val = ((Il2CppObjectBase)__instance.m_sync).Cast<LG_Door_Sync>(); val.OnDoorStateChange = Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)__instance.FCOnSyncDoorStatusChange); LG_SecurityDoor_Anim val2 = ((Il2CppObjectBase)__instance.m_anim).TryCast<LG_SecurityDoor_Anim>(); if ((Object)(object)val2 != (Object)null) { val2.OnDoorOpenStarted = Action.op_Implicit((Action)__instance.FCOnDoorOpenStarted); val2.OnDoorIsOpen = Action.op_Implicit((Action)__instance.FCOnDoorIsOpen); return; } LG_ApexDoor_Anim val3 = ((Il2CppObjectBase)__instance.m_anim).TryCast<LG_ApexDoor_Anim>(); if ((Object)(object)val3 != (Object)null) { val3.OnDoorOpenStarted = Action.op_Implicit((Action)__instance.FCOnDoorOpenStarted); val3.OnDoorIsOpen = Action.op_Implicit((Action)__instance.FCOnDoorIsOpen); } else { EOSLogger.Error("LG_SecurityDoor: Cannot cast iLG_Door_Anim"); } } } } namespace EOSExt.ExtraDoor.Patches.SetupFCDoor { [HarmonyPatch] internal static class BuildGate { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_BuildGateJob), "Build")] private static bool Pre_(LG_BuildGateJob __instance, ref bool __result) { //IL_00b1: 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_0160: Invalid comparison between Unknown and I4 //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected I4, but got Unknown //IL_0818: Unknown result type (might be due to invalid IL or missing references) //IL_081e: Invalid comparison between Unknown and I4 //IL_07a9: Unknown result type (might be due to invalid IL or missing references) //IL_07b5: Expected O, but got Unknown //IL_084f: Unknown result type (might be due to invalid IL or missing references) //IL_085b: Expected O, but got Unknown //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0624: Invalid comparison between Unknown and I4 //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_0689: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_0705: Unknown result type (might be due to invalid IL or missing references) //IL_0721: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Unknown result type (might be due to invalid IL or missing references) //IL_076e: Unknown result type (might be due to invalid IL or missing references) //IL_0778: Unknown result type (might be due to invalid IL or missing references) //IL_0791: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) ForceConnect forceConnect = null; forceConnect = ((!((Object)(object)__instance.m_plug != (Object)null)) ? ((Component)__instance.m_gate).gameObject.GetComponent<ForceConnect>() : ((Component)__instance.m_plug).gameObject.GetComponent<ForceConnect>()); if ((Object)(object)forceConnect == (Object)null) { return true; } try { if (((LG_ZoneExpander)__instance.m_gate).m_wasProcessed) { __result = true; return false; } ((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = true; if ((Object)(object)__instance.m_plug != (Object)null) { ((LG_ZoneExpander)__instance.m_gate).m_linksFrom = ((LG_ZoneExpander)__instance.m_plug).m_linksFrom; ((LG_ZoneExpander)__instance.m_gate).ExpanderStatus = ((LG_ZoneExpander)__instance.m_plug).ExpanderStatus; if (((LG_ZoneExpander)__instance.m_plug).CoursePortal != null) { ((LG_ZoneExpander)__instance.m_gate).CoursePortal = ((LG_ZoneExpander)__instance.m_plug).CoursePortal; ((LG_ZoneExpander)__instance.m_gate).CoursePortal.Gate = __instance.m_gate; __instance.m_gate.m_needsBorderLinks = true; ((LG_ZoneExpander)__instance.m_gate).m_linksTo = ((LG_ZoneExpander)__instance.m_plug).m_linksTo; } } else if (((LG_ZoneExpander)__instance.m_gate).CoursePortal != null) { ((LG_ZoneExpander)__instance.m_gate).CoursePortal.Gate = __instance.m_gate; } if ((int)((LG_ZoneExpander)__instance.m_gate).ExpanderStatus == 2) { __instance.SetupCappedGate(); } else { __instance.CalcOpenAtStart(); LG_GateType type = __instance.m_gate.Type; LG_GateType val = type; switch ((int)val) { case 0: case 1: case 2: __instance.CalcOpenAtStart(); if (__instance.m_gate.m_isTraversableFromStart && __instance.m_gate.HasGateWallRemover && Builder.BuildSeedRandom.Value("LG_BuildGateJob") < RundownManager.ActiveExpeditionBalanceData.WeakDoorOpenChanceForWallRemoverUsed) { __instance.m_gate.EnableGateWallRemover(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)); } else { GameObject val2 = null; XXHashSeed seed; if (__instance.m_gate.ForceBulkheadGate) { if (forceConnect.Cfg.Setting.SecurityGateToEnter == GateType.Bulkhead_Main) { seed = __instance.m_rnd.Seed; uint num = ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)); val2 = Builder.ComplexResourceSetBlock.GetMainPathBulkheadGate(__instance.m_gate.Type, num, (SubComplex)5); if ((Object)(object)val2 == (Object)null) { EOSLogger.Error("Could not get main path bulkhead door prefab: defaulting back to a normal bulkhead door! (You're Complex Resource Set probably don't have the main path bulkhead door references set)."); val2 = Builder.ComplexResourceSetBlock.GetBulkheadGate(__instance.m_gate.Type, num, (SubComplex)5); } } else { ComplexResourceSetDataBlock complexResourceSetBlock = Builder.ComplexResourceSetBlock; LG_GateType type2 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock.GetBulkheadGate(type2, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } } else if (__instance.m_gate.ForceApexGate) { ComplexResourceSetDataBlock complexResourceSetBlock2 = Builder.ComplexResourceSetBlock; LG_GateType type3 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock2.GetApexGate(type3, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } else if (__instance.m_gate.ForceSecurityGate) { ComplexResourceSetDataBlock complexResourceSetBlock3 = Builder.ComplexResourceSetBlock; LG_GateType type4 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock3.GetSecurityGate(type4, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } else if (((LG_ZoneExpander)__instance.m_gate).m_isZoneSource) { __instance.m_gate.IsCheckpointDoor = forceConnect.Cfg.Setting.IsCheckpointDoor; LG_Layer val3 = default(LG_Layer); LG_Layer val4 = default(LG_Layer); if (((LG_ZoneExpander)__instance.m_gate).IsLayerSource(ref val3, ref val4)) { ComplexResourceSetDataBlock complexResourceSetBlock4 = Builder.ComplexResourceSetBlock; LG_GateType type5 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock4.GetBulkheadGate(type5, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } else { switch (forceConnect.Cfg.Setting.SecurityGateToEnter) { case GateType.Apex: { ComplexResourceSetDataBlock complexResourceSetBlock7 = Builder.ComplexResourceSetBlock; LG_GateType type8 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock7.GetApexGate(type8, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); break; } case GateType.Security: { ComplexResourceSetDataBlock complexResourceSetBlock6 = Builder.ComplexResourceSetBlock; LG_GateType type7 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock6.GetSecurityGate(type7, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); break; } default: if (forceConnect.Cfg.Setting.SecurityGateToEnter == GateType.Bulkhead_Main) { seed = __instance.m_rnd.Seed; uint num2 = ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)); val2 = Builder.ComplexResourceSetBlock.GetMainPathBulkheadGate(__instance.m_gate.Type, num2, (SubComplex)5); if ((Object)(object)val2 == (Object)null) { EOSLogger.Error("Could not get main path bulkhead door prefab: defaulting back to a normal bulkhead door! (You're Complex Resource Set probably don't have the main path bulkhead door references set)."); val2 = Builder.ComplexResourceSetBlock.GetBulkheadGate(__instance.m_gate.Type, num2, (SubComplex)5); } } else { ComplexResourceSetDataBlock complexResourceSetBlock5 = Builder.ComplexResourceSetBlock; LG_GateType type6 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock5.GetBulkheadGate(type6, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } break; } } } else { ComplexResourceSetDataBlock complexResourceSetBlock8 = Builder.ComplexResourceSetBlock; LG_GateType type9 = __instance.m_gate.Type; seed = __instance.m_rnd.Seed; val2 = complexResourceSetBlock8.GetWeakGate(type9, ((XXHashSeed)(ref seed)).SubSeed(RandomExtensions.NextSubSeed(__instance.m_rnd.Random)), (SubComplex)5); } Vector3 position = ((Component)__instance.m_gate).transform.position; Quaternion val5; if (__instance.m_plugWasFlipped || (int)((LG_ZoneExpander)__instance.m_gate).ExpanderRotation == 3) { val5 = Quaternion.LookRotation(((Component)__instance.m_gate).transform.forward * -1f, Vector3.up); __instance.m_gate.m_hasBeenFlipped = true; } else { val5 = ((Component)__instance.m_gate).transform.rotation; __instance.m_gate.m_hasBeenFlipped = false; } GameObject val6 = Object.Instantiate<GameObject>(val2, position, val5, ((Component)__instance.m_gate).transform); __instance.m_gate.SpawnedDoor = SetupDoor(__instance, val6, forceConnect); __instance.SetupSpawners(val6); __instance.ProcessDivider(val6, __instance.m_gate.m_hasBeenFlipped); Debug.DrawLine(((Component)__instance.m_gate).transform.position, ((LG_ZoneExpander)__instance.m_gate).m_linksFrom.Position, new Color(0f, 0.5f, 1f, 1f), 10000f, false); Debug.DrawLine(((Component)__instance.m_gate).transform.position, ((LG_ZoneExpander)__instance.m_gate).m_linksTo.Position, new Color(0f, 1f, 0.5f, 0.25f), 10000f, false); Debug.DrawRay(val6.transform.position, val6.transform.forward * 10f, new Color(0f, 1f, 0f, 1f), 10000f, false); } LG_Factory.InjectJob((LG_FactoryJob)new LG_LinkAIGateJob(__instance.m_gate), (BatchName)29); break; case 3: Debug.LogError(Object.op_Implicit("ERROR : Do we need to use this anymore?")); break; case 5: { __instance.m_gate.m_isTraversableFromStart = true; ((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = true; LG_Gate gate = __instance.m_gate; ((Object)gate).name = ((Object)gate).name + " freePassage!"; if (__instance.m_plugWasFlipped || (int)((LG_ZoneExpander)__instance.m_gate).ExpanderRotation == 3) { __instance.m_gate.m_hasBeenFlipped = true; } else { __instance.m_gate.m_hasBeenFlipped = false; } LG_Factory.InjectJob((LG_FactoryJob)new LG_LinkAIGateJob(__instance.m_gate), (BatchName)29); break; } } } __result = true; return false; } catch (Exception value) { EOSLogger.Error($"Exception occurred when building Gate: {value}"); EOSLogger.Error("Falling back to vanilla"); ((LG_ZoneExpander)__instance.m_gate).m_wasProcessed = false; return true; } } private static iLG_Door_Core SetupDoor(LG_BuildGateJob __instance, GameObject doorGO, ForceConnect fc) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown iLG_Door_Core val = __instance.SetupDoor(doorGO); if (__instance.m_gate.ForceSecurityGate || __instance.m_gate.ForceApexGate || ((LG_ZoneExpander)__instance.m_gate).m_isZoneSource) { LG_SecurityDoor val2 = ((Il2CppObjectBase)val).Cast<LG_SecurityDoor>(); if (((LG_ZoneExpander)__instance.m_gate).m_linksTo.m_zone.m_settings.m_zoneData.ChainedPuzzleToEnter == 0) { uint chainedPuzzleToEnter = fc.Cfg.Setting.ChainedPuzzleToEnter; if (chainedPuzzleToEnter != 0) { LG_Factory.InjectJob((LG_FactoryJob)new LG_BuildChainedPuzzleDoorLockJob(val2, chainedPuzzleToEnter), (BatchName)43); } else { LG_Factory.InjectJob((LG_FactoryJob)new LG_SimpleDoorLockJob(val2), (BatchName)43); } } if (fc.Cfg.Setting.IsCheckpointDoor) { LG_Factory.InjectJob((LG_FactoryJob)new LG_CheckpointScannerJob(val2), (BatchName)43); } if (fc.Cfg.Setting.ActiveEnemyWave.HasActiveEnemyWave) { val2.SetupActiveEnemyWaveData(fc.Cfg.Setting.ActiveEnemyWave); } } return val; } } } namespace EOSExt.ExtraDoor.Patches.SetupDoor { [HarmonyPatch] internal static class ChainedPuzzles { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_BuildChainedPuzzleDoorLockJob), "Build")] private static bool Pre_(LG_BuildChainedPuzzleDoorLockJob __instance, ref bool __result) { try { LG_SecurityDoor door = ((LG_BuildSecurityDoorLockJob)__instance).m_door; ForceConnect fC = ((LG_BuildSecurityDoorLockJob)__instance).m_door.GetFC(); if ((Object)(object)fC == (Object)null) { return true; } ((LG_BuildSecurityDoorLockJob)__instance).CheckFlip(); ((Object)door).name = ((Object)door).name + "_ChainedPuzzleLock"; uint chainedPuzzleToEnter = fC.Cfg.Setting.ChainedPuzzleToEnter; if (chainedPuzzleToEnter != 0) { door.SetupChainedPuzzleLock(chainedPuzzleToEnter); } __result = true; return false; } catch (Exception value) { EOSLogger.Error($"Exception occurred when building ChainedPuzzleDoorLock: {value}"); EOSLogger.Error("Falling back to vanilla"); return true; } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_SecurityDoor), "SetupChainedPuzzleLock")] private static bool Pre_SetupCPLock(LG_SecurityDoor __instance, uint puzzleDataId) { //IL_004b: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_007b: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) ForceConnect fC = __instance.GetFC(); if ((Object)(object)fC == (Object)null) { return true; } ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(puzzleDataId); Vector3 val = default(Vector3); if (__instance.GetChainedPuzzleStartPosition(ref val)) { ChainedPuzzleInstance val2 = ChainedPuzzleManager.CreatePuzzleInstance(block, ((LG_ZoneExpander)__instance.Gate).m_linksFrom, ((LG_ZoneExpander)__instance.Gate).m_linksTo, val, ((Component)__instance).transform, false); eDoorStatus status = __instance.m_locks.SetupForChainedPuzzle(val2); __instance.m_sync.SetStateUnsynced(new pDoorState { status = status, damageTaken = 0f }); if (block.ChainedPuzzle.Count == 0) { __instance.SetupInstantOpeningDoor(); } if (block.TriggerAlarmOnActivate) { __instance.m_graphics.OnDoorState(new pDoorState { status = (eDoorStatus)4 }, false); __instance.m_mapLookatRevealer.SetLocalGUIObjStatus((eCM_GuiObjectStatus)9); return false; } __instance.m_graphics.OnDoorState(new pDoorState { status = (eDoorStatus)5 }, false); } return false; } } } namespace EOSExt.ExtraDoor.Patches.DisableAlarmShutdownOnTerminal { [HarmonyPatch] internal static class BuildJob_AlarmShutdownOnTerminalJob { [HarmonyPrefix] [HarmonyPatch(typeof(LG_AlarmShutdownOnTerminalJob), "Build")] private static bool Pre_(LG_AlarmShutdownOnTerminalJob __instance) { return (Object)(object)__instance.m_securityDoor.GetFC() == (Object)null; } } [HarmonyPatch] internal static class DoorLock_OnDoorState { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "OnDoorState")] private static bool Pre_(LG_SecurityDoor_Locks __instance, pDoorState state) { //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 //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_door == (Object)null || (int)state.status != 4) { return true; } ForceConnect fC = __instance.m_door.GetFC(); if ((Object)(object)fC == (Object)null) { return true; } ((Interact_Base)__instance.m_intUseKeyItem).SetActive(false); ((Interact_Base)__instance.m_intHack).SetActive(false); ((Interact_Base)__instance.m_intOpenDoor).SetActive(true); __instance.m_intOpenDoor.InteractionMessage = Text.Format(840u, (Object[])(object)new Object[1] { Object.op_Implicit(__instance.ChainedPuzzleToSolve.Data.PublicAlarmName) }); ((Interact_Base)__instance.m_intCustomMessage).SetActive(false); __instance.m_lastStatus = state.status; return false; } } } namespace EOSExt.ExtraDoor.Config { public class Door { public LG_LayerType Layer { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public int AreaIndex { get; set; } = 0; } public class DoorSetting { public GateType SecurityGateToEnter { get; set; } public List<LevelEventData> EventsOnEnter { get; set; } = new List<LevelEventData>(); public List<WardenObjectiveEventData> EventsOnApproachDoor { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnUnlockDoor { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnOpenDoor { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnDoorScanStart { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnDoorScanDone { get; set; } = new List<WardenObjectiveEventData>(); public FCProgressionPuzzleToEnter ProgressionPuzzleToEnter { get; set; } = new FCProgressionPuzzleToEnter(); public uint ChainedPuzzleToEnter { get; set; } public bool IsCheckpointDoor { get; set; } = false; public bool PlayScannerVoiceAudio { get; set; } = true; public ActiveEnemyWaveData ActiveEnemyWave { get; set; } = new ActiveEnemyWaveData(); } public class FCZonePlacementData : GlobalZoneIndex { public ZonePlacementWeights Weights { get; set; } = new ZonePlacementWeights(); } public class FCProgressionPuzzleToEnter { public eProgressionPuzzleType PuzzleType { get; set; } public LocalizedText CustomText { get; set; } = null; public int PlacementCount { get; set; } = 1; public List<FCZonePlacementData> ZonePlacementData { get; set; } = new List<FCZonePlacementData> { new FCZonePlacementData() }; } public enum GateType { Security, Apex, Bulkhead, Bulkhead_Main } public class ForceConnectCfg { public string WorldEventObjectFilter { get; set; } = string.Empty; public eDimensionIndex DimensionIndex { get; set; } public Door From { get; set; } = new Door(); public int FromDoorIndex { get; set; } = 0; public Door To { get; set; } = new Door(); public DoorSetting Setting { get; set; } = new DoorSetting(); } }
plugins/Inas07.EOSExt.LevelSpawnedSentry.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using AK; using Agents; using AmorLib.Networking.StateReplicators; using BepInEx; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using EOSExt.LevelSpawnedSentry.Definition; using EOSExt.LevelSpawnedSentry.Impl; using EOSExt.LevelSpawnedSentry.PlayerGUIMessage; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using FX_EffectSystem; using GTFO.API; using GameData; using GameEvent; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using TenChambers.EventHandlers; 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("Inas07.EOSExt.LevelSpawnedSentry")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0f161294352825f0b0ce3c0b771b1f5a3844c5d8")] [assembly: AssemblyProduct("Inas07.EOSExt.LevelSpawnedSentry")] [assembly: AssemblyTitle("Inas07.EOSExt.LevelSpawnedSentry")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.LevelSpawnedSentry { public class LevelSpawnedSentryManager : GenericExpeditionDefinitionManager<LevelSpawnedSentryDefinition> { public enum LSS_WardenEvents { ChangeLSSState = 910 } public static LevelSpawnedSentryManager Current { get; private set; } protected override string DEFINITION_NAME => "LevelSpawnedSentry"; private Dictionary<string, LSS> LSSDict { get; } = new Dictionary<string, LSS>(); internal List<LSS> LSSInstances { get; } = new List<LSS>(); private void PrepareForBuild() { Clear(); if (!base.definitions.TryGetValue(base.CurrentMainLevelLayout, out var value)) { return; } for (int i = 0; i < value.Definitions.Count; i++) { LevelSpawnedSentryDefinition levelSpawnedSentryDefinition = value.Definitions[i]; LSS lSS = LSS.Instantiate(levelSpawnedSentryDefinition, i); LSSInstances.Add(lSS); if (LSSDict.ContainsKey(levelSpawnedSentryDefinition.WorldEventObjectFilter)) { EOSLogger.Warning("LevelSpawnSentry: found duplicate WorldEventObjectFilter '" + levelSpawnedSentryDefinition.WorldEventObjectFilter + "'"); } LSSDict[levelSpawnedSentryDefinition.WorldEventObjectFilter] = lSS; } } private void Clear() { LSSInstances.ForEach(delegate(LSS i) { i.Destroy(); }); LSSInstances.Clear(); LSSDict.Clear(); } private LevelSpawnedSentryManager() { LevelAPI.OnBuildStart += PrepareForBuild; LevelAPI.OnLevelCleanup += Clear; } static LevelSpawnedSentryManager() { Current = new LevelSpawnedSentryManager(); EOSWardenEventManager.Current.AddEventDefinition(LSS_WardenEvents.ChangeLSSState.ToString(), 910u, (Action<WardenObjectiveEventData>)ChangeLSSState); } private static void ChangeLSSState(WardenObjectiveEventData e) { if (!Current.LSSDict.TryGetValue(e.WorldEventObjectFilter, out var value)) { EOSLogger.Error("ChangeLSSState: Cannot find LSS with name '" + e.WorldEventObjectFilter + "'"); } else if (SNet.IsMaster) { bool targetEnemy = e.EnemyID == 0; bool targetPlayer = e.SustainedEventSlotIndex > 0; bool markerVisible = e.Count == 0; bool canRefill = e.FogSetting == 0; LSSSyncState lSSSyncState = new LSSSyncState(value.State); lSSSyncState.Enabled = e.Enabled; lSSSyncState.TargetEnemy = targetEnemy; lSSSyncState.TargetPlayer = targetPlayer; lSSSyncState.MarkerVisible = markerVisible; lSSSyncState.CanRefill = canRefill; lSSSyncState.Ammo = value.LSSComp.Sentry.Ammo; LSSSyncState state = lSSSyncState; value.StateReplicator.SetState(state); } } } [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.*/)] [BepInPlugin("Inas.EOSExt.LevelSpawnedSentry", "EOSExt.LevelSpawnedSentry", "1.2.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.LevelSpawnedSentry"; public const string VERSION = "1.2.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.LevelSpawnedSentry"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.LevelSpawnedSentry loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<LevelSpawnedSentryDefinition>)LevelSpawnedSentryManager.Current).Init(); } } public class LSS { public static readonly Color OffColor; public static readonly Color TargetBothColor; public static readonly Color TargetPlayerOnlyColor; public static readonly Color TargetEnemyOnlyColor; public static readonly Color DoesNotTargetColor; public const string PUBLIC_NAME_PREFIX = "E0$L$$"; private const float SYNC_ALL_IN = 15f; private static Coroutine s_syncLSSAmmoCoroutine; private LSSTargeted m_LSSTargeted = new LSSTargeted(); public const string LSS_SYNC_EVT = "LSS_SYNC_EVT"; public LevelSpawnedSentryDefinition Def { get; } public int InstanceIndex { get; } public LSSSyncState State => StateReplicator?.State ?? default(LSSSyncState); internal StateReplicator<LSSSyncState> StateReplicator { get; private set; } public LSSComp LSSComp { get; private set; } public int LastSyncedTargetedPlayer => m_LSSTargeted.PlayerSlotIndex; public static Color GetScanningColor(bool targetEnemy, bool targetPlayer) { //IL_0001: 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_0010: 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_0056: 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_005b: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0045: 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) Color val = Color.grey * 0.5f; if (targetEnemy && targetPlayer) { return TargetBothColor; } if (targetEnemy && !targetPlayer) { return TargetEnemyOnlyColor; } if (!targetEnemy && targetPlayer) { return TargetPlayerOnlyColor; } return DoesNotTargetColor; } public static string GetMarkerText(bool targetEnemy, bool targetPlayer) { string empty = string.Empty; string empty2 = string.Empty; if (targetEnemy && targetPlayer) { empty = "LSS.State.Both"; empty2 = "HAVOC"; } else if (targetEnemy && !targetPlayer) { empty = "LSS.State.Normal"; empty2 = "NORMAL"; } else if (!targetEnemy && targetPlayer) { empty = "LSS.State.Player"; empty2 = "HOSTILE"; } else { empty = "LSS.State.Idle"; empty2 = "IDLE"; } TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock(empty); return (block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : empty2; } internal void AssignInstance(LSSComp comp) { if (!comp.IsSetup) { EOSLogger.Error("LSS: Assigning to LSS '" + comp.Def.WorldEventObjectFilter + "' an un-setup LSSComp!"); return; } bool flag = (Object)(object)LSSComp != (Object)null; if (flag) { EOSLogger.Warning("LSS: re-assigning LSSComp to '" + comp.Def.WorldEventObjectFilter + "'!"); } LSSComp = comp; if (flag) { OnStateChanged(State, State, isRecall: false); } } internal void SetupReplicator() { if (StateReplicator != null) { return; } LevelSpawnedSentryDefinition def = Def; uint num = EOSNetworking.AllotReplicatorID(); if (num != 0) { LSSSyncState lSSSyncState = new LSSSyncState(def.InitialState); lSSSyncState.Ammo = def.InitialAmmo; LSSSyncState lSSSyncState2 = lSSSyncState; StateReplicator = StateReplicator<LSSSyncState>.Create(num, lSSSyncState2, (LifeTimeType)1, (IStateReplicatorHolder<LSSSyncState>)null); StateReplicator.OnStateChanged += OnStateChanged; if (SNet.IsMaster) { StateReplicator.SetState(lSSSyncState2); } } } private void OnStateChanged(LSSSyncState oldState, LSSSyncState newState, bool isRecall) { if (isRecall) { EOSLogger.Warning("LSS.OnStateChanged recall! Gonna re-assign LSSComp!"); SpawnLSS_OnRecall(); } else if ((Object)(object)LSSComp == (Object)null) { EOSLogger.Error("LSS.OnStateChanged: LSSComp is null!"); } else { LSSComp.OnStateChanged(oldState, newState, isRecall); } } internal void Destroy() { EOSLogger.Error("LSS Destroyed: " + Def.WorldEventObjectFilter); LevelAPI.OnBuildDone -= SetupReplicator; LevelAPI.OnEnterLevel -= SpawnLSS_OnEnterLevel; StateReplicator?.Unload(); StateReplicator = null; } private void SpawnLSS_OnEnterLevel() { SpawnLSS(Def.InitialAmmo); } private void SpawnLSS_OnRecall() { SpawnLSS(State.Ammo); } private void SpawnLSS(float ammo) { //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) //IL_0029: 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_003e: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } LevelSpawnedSentryDefinition def = Def; Vector3 val = def.Position.ToVector3(); AIG_GeomorphNodeVolume val2 = default(AIG_GeomorphNodeVolume); AIG_VoxelNodePillar val3 = default(AIG_VoxelNodePillar); AIG_INode val4 = default(AIG_INode); AIG_NodeCluster val5 = default(AIG_NodeCluster); if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, def.DimensionIndex, val, ref val2) || !((AIG_NodeVolume)val2).m_voxelNodeVolume.TryGetPillar(val, ref val3) || !val3.TryGetVoxelNode(val.y, ref val4) || !AIG_NodeCluster.TryGetNodeCluster(val4.ClusterID, ref val5)) { EOSLogger.Error("SpawnLSS: Position is not valid, try again inside an area."); return; } AIG_CourseNode courseNode = val5.CourseNode; PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(def.PlayerOfflineGearDBId); if (block == null) { EOSLogger.Error($"SpawnLSS: missing PlayerOfflineGearDataBlock with Id {def.PlayerOfflineGearDBId}"); return; } GearIDRange val6 = new GearIDRange(block.GearJSON); val6.PublicGearName = $"{"E0$L$$"}_{InstanceIndex}"; val6.PlayfabItemId = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name; val6.PlayfabItemInstanceId = $"OfflineGear_LSS_ID_{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID}"; val6.OfflineGearType = (eOfflineGearType)3; ItemDataBlock val7 = ((val6.GetCompID((eGearComponent)3) != 0) ? GameDataBlockBase<ItemDataBlock>.GetBlock(val6.GetCompID((eGearComponent)3)) : null); ItemReplicationManager.SpawnGear(val6, (delItemCallback)null, (ItemMode)3, val, def.Rotation.ToQuaternion(), courseNode, (PlayerAgent)null, ammo, Def.AmmoCap); } private LSS(LevelSpawnedSentryDefinition def, int instanceIndex) { Def = def; InstanceIndex = instanceIndex; } internal static LSS Instantiate(LevelSpawnedSentryDefinition def, int instanceIndex) { LSS lSS = new LSS(def, instanceIndex); LevelAPI.OnBuildDone += lSS.SetupReplicator; LevelAPI.OnEnterLevel += lSS.SpawnLSS_OnEnterLevel; return lSS; } private static IEnumerator s_sync() { int i = 0; WaitForSeconds waitOutOfLevel = new WaitForSeconds(15f); WaitForSeconds waitInLevel = null; while (true) { if ((int)GameStateManager.CurrentStateName == 10) { if (SNet.IsMaster && LevelSpawnedSentryManager.Current.LSSInstances.Count > 0) { if (0 <= i && i < LevelSpawnedSentryManager.Current.LSSInstances.Count) { LSS instance = LevelSpawnedSentryManager.Current.LSSInstances[i]; if ((Object)(object)instance.LSSComp == (Object)null) { EOSLogger.Error("LSSSync: found LSS without LSSComp: " + instance.Def.WorldEventObjectFilter); } else { SentryGunInstance sentry = instance.LSSComp.Sentry; if ((Object)(object)sentry != (Object)null) { LSSSyncState state = instance.StateReplicator.State; if ((double)Math.Abs(sentry.Ammo - state.Ammo) > 0.0001) { LSSSyncState syncState = new LSSSyncState(state) { Ammo = sentry.Ammo }; instance.StateReplicator.SetState(syncState); } } } } if (i == LevelSpawnedSentryManager.Current.LSSInstances.Count - 1) { EOSLogger.Debug($"LSS: master synced {LevelSpawnedSentryManager.Current.LSSInstances.Count} in {15f} seconds"); } i = (i + 1) % LevelSpawnedSentryManager.Current.LSSInstances.Count; } if (waitInLevel == null) { waitInLevel = new WaitForSeconds(15f / (float)Math.Max(1, LevelSpawnedSentryManager.Current.LSSInstances.Count)); } yield return waitInLevel; } else { waitInLevel = null; yield return waitOutOfLevel; } } } static LSS() { //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_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_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_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_0041: 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_0050: Unknown result type (might be due to invalid IL or missing references) OffColor = ColorExt.Hex("#00000000"); TargetBothColor = ColorExt.Hex("FFFA00"); TargetPlayerOnlyColor = ColorExt.Hex("#F0192EFF"); TargetEnemyOnlyColor = ColorExt.Hex("#00895CFF"); DoesNotTargetColor = ColorExt.Hex("#198AF0FF") * 0.5f; s_syncLSSAmmoCoroutine = null; SetupSync(); s_syncLSSAmmoCoroutine = CoroutineManager.StartPersistantCoroutine(CollectionExtensions.WrapToIl2Cpp(s_sync())); EOSLogger.Debug("==========================="); EOSLogger.Debug("LSS Sync coroutine started"); EOSLogger.Debug("==========================="); } internal void OnTargetedPlayer(PlayerAgent player) { m_LSSTargeted.PlayerSlotIndex = ((player != null) ? player.Owner.PlayerSlotIndex() : (-1)); } internal void OnUpdateMaster() { m_LSSTargeted.LSSInstanceIndex = InstanceIndex; NetworkAPI.InvokeEvent<LSSTargeted>("LSS_SYNC_EVT", m_LSSTargeted, (SNet_ChannelType)2); } private static void OnReceive(ulong sender, LSSTargeted data) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) int lSSInstanceIndex = data.LSSInstanceIndex; if (lSSInstanceIndex < 0 || lSSInstanceIndex >= LevelSpawnedSentryManager.Current.LSSInstances.Count) { EOSLogger.Error($"LSS_OnReceive: got packet with invalid instance index {lSSInstanceIndex}, LSSCount: {LevelSpawnedSentryManager.Current.LSSInstances.Count}, CurrentGameState: {GameStateManager.CurrentStateName}"); } else { LSS lSS = LevelSpawnedSentryManager.Current.LSSInstances[lSSInstanceIndex]; lSS.m_LSSTargeted.PlayerSlotIndex = data.PlayerSlotIndex; EOSLogger.Warning($"LSSSync.OnReceive: LSS_{lSSInstanceIndex}, Player_{data.PlayerSlotIndex}"); } } private static void SetupSync() { NetworkAPI.RegisterEvent<LSSTargeted>("LSS_SYNC_EVT", (Action<ulong, LSSTargeted>)OnReceive); EOSLogger.Debug("==========================="); EOSLogger.Debug("LSSTargeted Sync EVT Registered"); EOSLogger.Debug("==========================="); } } [HarmonyPatch] public static class LSSDebug { } } namespace EOSExt.LevelSpawnedSentry.PlayerGUIMessage { public class PlayerGUIMessageManager { private PUI_ObjectiveTimer m_timerLayer; private ISet<int> m_targetedByLSS = new HashSet<int>(); public static PlayerGUIMessageManager Current { get; } public static PlayerGuiLayer PlayerGUILayer => GuiManager.PlayerLayer; internal void Setup(Transform root) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) m_timerLayer = ((Il2CppObjectBase)((GuiLayer)PlayerGUILayer).AddComp("Gui/Player/PUI_ObjectiveTimer", (GuiAnchor)0, new Vector2(0f, -200f), (Transform)null)).Cast<PUI_ObjectiveTimer>(); } internal void OnLocalPlayerTargeted(LSS sentry) { m_targetedByLSS.Add(sentry.InstanceIndex); if (m_targetedByLSS.Count > 0 && !((Component)m_timerLayer).gameObject.active) { TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("LSS.OnPlayerTargeted.GUIText"); SetText((block != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID) : "<color=red>OMG IM SO FKING DEAD</color>"); } } internal void OnLocalPlayerUnTargeted(LSS sentry) { m_targetedByLSS.Remove(sentry.InstanceIndex); if (m_targetedByLSS.Count == 0) { Clear(); } } public void SetText(string text) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 ((Component)m_timerLayer).gameObject.active = true; m_timerLayer.UpdateTimerTitle(text); if ((int)GameStateManager.CurrentStateName == 10) { CoroutineManager.BlinkIn(((Component)m_timerLayer.m_titleText).gameObject, 0f); } } public void Clear() { ((Component)m_timerLayer).gameObject.active = false; m_timerLayer.SetTimerTextEnabled(false); } private void OnLevelCleanup() { Clear(); m_targetedByLSS.Clear(); } private PlayerGUIMessageManager() { LevelAPI.OnBuildStart += OnLevelCleanup; LevelAPI.OnLevelCleanup += OnLevelCleanup; } static PlayerGUIMessageManager() { Current = new PlayerGUIMessageManager(); } } } namespace EOSExt.LevelSpawnedSentry.Patches { [HarmonyPatch] internal static class DisableAnalytic { [HarmonyPrefix] [HarmonyPatch(typeof(AnalyticsManager), "SentryEventsPayload")] private static bool Pre_(SentryGunInstance __instance) { return (Object)(object)__instance != (Object)null && (Object)(object)((Item)__instance).Owner != (Object)null; } [HarmonyPrefix] [HarmonyPatch(typeof(SentryPlaced), "OnGameEvent")] private static bool Pre_(GameEventData data) { return (Object)(object)data.player != (Object)null; } } [HarmonyPatch] internal static class DisableWarp { [HarmonyPrefix] [HarmonyPatch(typeof(SentryGunInstance), "OnWarp")] private static bool Pre_(SentryGunInstance __instance) { return (Object)(object)((Component)__instance).gameObject.GetComponent<LSSComp>() == (Object)null; } } [HarmonyPatch] internal static class Firing { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")] private static bool Pre_FireBullet(SentryGunInstance_Firing_Bullets __instance, bool doDamage, bool targetIsTagged) { //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) //IL_005e: 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_0071: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0242: 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_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0228: 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) iSentrygunInstanceCore core = __instance.m_core; SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null); LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null); if ((Object)(object)lSSComp == (Object)null) { return true; } LSSSyncState state = lSSComp.LSS.State; WeaponHitData val2 = (SentryGunInstance_Firing_Bullets.s_weaponRayData = new WeaponHitData { randomSpread = __instance.m_archetypeData.HipFireSpread, fireDir = __instance.MuzzleAlign.forward }); Vector3 val4 = default(Vector3); if (__instance.m_archetypeData.Sentry_FireTowardsTargetInsteadOfForward && __instance.m_core.TryGetTargetAimPos(ref val4)) { WeaponHitData s_weaponRayData = SentryGunInstance_Firing_Bullets.s_weaponRayData; Vector3 val5 = val4 - __instance.MuzzleAlign.position; s_weaponRayData.fireDir = ((Vector3)(ref val5)).normalized; } if (Weapon.CastWeaponRay(__instance.MuzzleAlign, ref val2, LayerManager.MASK_SENTRYGUN_RAY)) { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = __instance.m_core.Owner; GameObject target = val.m_detection.Target; PlayerAgent val6 = ((target != null) ? target.GetComponent<PlayerAgent>() : null); if (val.m_detection.HasTarget && (Object)(object)val6 != (Object)null) { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = val.m_detection.Target.GetComponent<PlayerAgent>(); } else { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = LocalPlayer.Agent; } SentryGunInstance_Firing_Bullets.s_weaponRayData.damage = (targetIsTagged ? (__instance.m_archetypeData.Damage * __instance.m_archetypeData.Sentry_DamageTagMulti) : __instance.m_archetypeData.Damage); SentryGunInstance_Firing_Bullets.s_weaponRayData.staggerMulti = __instance.m_archetypeData.GetSentryStaggerDamage(targetIsTagged); SentryGunInstance_Firing_Bullets.s_weaponRayData.precisionMulti = __instance.m_archetypeData.PrecisionDamageMulti; SentryGunInstance_Firing_Bullets.s_weaponRayData.damageFalloff = __instance.m_archetypeData.DamageFalloff; SentryGunInstance_Firing_Bullets.s_weaponRayData.vfxBulletHit = __instance.m_vfxBulletHit; BulletWeapon.BulletHit(SentryGunInstance_Firing_Bullets.s_weaponRayData, doDamage, 0f, 0u, true); RaycastHit rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit; FX_Manager.EffectTargetPosition = ((RaycastHit)(ref rayHit)).point; Vector3 position = __instance.MuzzleAlign.position; rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit; Debug.DrawLine(position, ((RaycastHit)(ref rayHit)).point, Color.yellow); } else { FX_Manager.EffectTargetPosition = __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 50f; Debug.DrawLine(__instance.MuzzleAlign.position, __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 10f, Color.green); } Action onBulletFired = __instance.OnBulletFired; if (onBulletFired != null) { onBulletFired.Invoke(); } ((FX_EffectBase)SentryGunInstance_Firing_Bullets.s_tracerPool.AquireEffect()).Play((FX_Trigger)null, __instance.MuzzleAlign.position, Quaternion.LookRotation(SentryGunInstance_Firing_Bullets.s_weaponRayData.fireDir)); EX_SpriteMuzzleFlash muzzleFlash = __instance.m_muzzleFlash; if ((Object)(object)muzzleFlash != (Object)null) { muzzleFlash.Play(); } WeaponShellManager.EjectShell((ShellTypes)3, 1f, (float)Random.RandomRangeInt(3, 5), __instance.ShellEjectAlign); __instance.m_fireBulletTimer = Clock.Time + __instance.m_archetypeData.GetSentryShotDelay(__instance.m_core.Owner, targetIsTagged); return false; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")] private static bool Pre_UpdateFireShotgunSemi(SentryGunInstance_Firing_Bullets __instance, bool isMaster, bool targetIsTagged) { //IL_0062: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) iSentrygunInstanceCore core = __instance.m_core; SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null); LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null); if ((Object)(object)lSSComp == (Object)null) { return true; } LSSSyncState state = lSSComp.LSS.State; if (Clock.Time > __instance.m_fireBulletTimer) { Vector3 position = __instance.MuzzleAlign.position; __instance.TriggerSingleFireAudio(); for (int i = 0; i < __instance.m_archetypeData.ShotgunBulletCount; i++) { float num = __instance.m_segmentSize * (float)i; float num2 = 0f; float num3 = 0f; if (i > 0) { num2 += (float)__instance.m_archetypeData.ShotgunConeSize * Mathf.Cos(num); num3 += (float)__instance.m_archetypeData.ShotgunConeSize * Mathf.Sin(num); } WeaponHitData val2 = (SentryGunInstance_Firing_Bullets.s_weaponRayData = new WeaponHitData { maxRayDist = __instance.MaxRayDist, angOffsetX = num2, angOffsetY = num3, randomSpread = __instance.m_archetypeData.ShotgunBulletSpread, fireDir = __instance.MuzzleAlign.forward }); if (Weapon.CastWeaponRay(__instance.MuzzleAlign, ref val2, position, LayerManager.MASK_SENTRYGUN_RAY)) { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = __instance.m_core.Owner; GameObject target = val.m_detection.Target; PlayerAgent val4 = ((target != null) ? target.GetComponent<PlayerAgent>() : null); if (val.m_detection.HasTarget && (Object)(object)val4 != (Object)null) { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = val.m_detection.Target.GetComponent<PlayerAgent>(); } else { SentryGunInstance_Firing_Bullets.s_weaponRayData.owner = LocalPlayer.Agent; } SentryGunInstance_Firing_Bullets.s_weaponRayData.damage = (targetIsTagged ? (__instance.m_archetypeData.Damage * __instance.m_archetypeData.Sentry_DamageTagMulti) : __instance.m_archetypeData.Damage); SentryGunInstance_Firing_Bullets.s_weaponRayData.staggerMulti = __instance.m_archetypeData.GetSentryStaggerDamage(targetIsTagged); SentryGunInstance_Firing_Bullets.s_weaponRayData.precisionMulti = __instance.m_archetypeData.PrecisionDamageMulti; SentryGunInstance_Firing_Bullets.s_weaponRayData.damageFalloff = __instance.m_archetypeData.DamageFalloff; BulletWeapon.BulletHit(SentryGunInstance_Firing_Bullets.s_weaponRayData, isMaster, 0f, 0u, true); RaycastHit rayHit = SentryGunInstance_Firing_Bullets.s_weaponRayData.rayHit; FX_Manager.EffectTargetPosition = ((RaycastHit)(ref rayHit)).point; } else { FX_Manager.EffectTargetPosition = __instance.MuzzleAlign.position + __instance.MuzzleAlign.forward * 50f; } FX_Manager.PlayLocalVersion = false; ((FX_EffectBase)SentryGunInstance_Firing_Bullets.s_tracerPool.AquireEffect()).Play((FX_Trigger)null, __instance.MuzzleAlign.position, Quaternion.LookRotation(SentryGunInstance_Firing_Bullets.s_weaponRayData.fireDir)); } __instance.UpdateAmmo(-1); Action onBulletFired = __instance.OnBulletFired; if (onBulletFired != null) { onBulletFired.Invoke(); } __instance.m_fireBulletTimer = Clock.Time + (targetIsTagged ? (__instance.m_archetypeData.ShotDelay * __instance.m_archetypeData.Sentry_ShotDelayTagMulti) : __instance.m_archetypeData.ShotDelay); } return false; } } [HarmonyPatch] internal static class OnLSSSpawned { [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance), "OnSpawn")] private static void Post_(SentryGunInstance __instance, pGearSpawnData spawnData) { string data = spawnData.gearIDRange.publicName.data; if (data.StartsWith("E0$L$$")) { List<LSS> lSSInstances = LevelSpawnedSentryManager.Current.LSSInstances; if (!int.TryParse(data.Split('_')[1], out var result) || result < 0 || result >= lSSInstances.Count) { EOSLogger.Error("SentryGunInstance.OnSpawn: got publicName '" + data + "' with in valid instanceIndex"); return; } LSS lSS = lSSInstances[result]; LevelSpawnedSentryManager.Current.LSSInstances[result].AssignInstance(((Component)__instance).gameObject.AddComponent<LSSComp>().Setup(lSS)); Interact_Timed val = ((Il2CppObjectBase)((Item)__instance).PickupInteraction).Cast<Interact_Timed>(); ((Behaviour)val).enabled = false; Dimension.RemoveWarpable(((Il2CppObjectBase)__instance).Cast<IWarpableObject>()); EOSLogger.Warning("LSS OnSpawn: " + lSS.Def.WorldEventObjectFilter); } } } [HarmonyPatch] internal static class OnSetup { [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance), "CheckIsSetup")] private static void Post_CheckSetup(SentryGunInstance __instance) { LSSComp component = ((Component)__instance).gameObject.GetComponent<LSSComp>(); if ((Object)(object)component != (Object)null) { EOSLogger.Warning("LSS CheckSetup: " + component.Def.WorldEventObjectFilter); component.UpdateVisuals(); } } [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance_Detection), "Setup")] private static void Post_D_Setup(SentryGunInstance_Detection __instance) { SentryGunInstance obj = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>(); LSSComp lSSComp = ((obj != null) ? ((Component)obj).gameObject.GetComponent<LSSComp>() : null); if (!((Object)(object)lSSComp == (Object)null)) { __instance.m_targetPlayers = lSSComp.LSS.State.TargetPlayer; } } [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance_ScannerVisuals_Plane), "Setup")] private static void Post_V_Setup(SentryGunInstance_ScannerVisuals_Plane __instance) { if ((Object)(object)__instance.m_scannerPlane == (Object)null || (Object)(object)__instance.m_targetingAlign == (Object)null) { EOSLogger.Error("SentryGunInstance_ScannerVisuals_Plane.Setup: got a null scannerPlane / targetingAlign?"); } SentryGunInstance obj = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>(); LSSComp lSSComp = ((obj != null) ? ((Component)obj).gameObject.GetComponent<LSSComp>() : null); if (!((Object)(object)lSSComp == (Object)null)) { lSSComp.UpdateVisuals(); } } } [HarmonyPatch] internal static class OnPlayerGuiLayerSetup { [HarmonyPostfix] [HarmonyPatch(typeof(PlayerGuiLayer), "Setup")] private static void Post_(PlayerGuiLayer __instance, Transform root, string name) { PlayerGUIMessageManager.Current.Setup(root); } } [HarmonyPatch] internal static class ReceiveToolRefill { } [HarmonyPatch] [HarmonyPatch] [HarmonyPatch] internal static class Targeting { [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance_Sync), "UpdateMaster")] private static void Post_UpdateMaster(SentryGunInstance_Sync __instance) { if (!(Clock.Time - __instance.m_lastSyncTime <= 0.5f)) { SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>(); LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null); if (!((Object)(object)lSSComp == (Object)null)) { lSSComp.LSS.OnUpdateMaster(); } } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance_Sync), "UpdateClient")] private static void Post_UpdateClient(SentryGunInstance_Sync __instance) { if (Clock.Time - __instance.m_lastSyncTime > __instance.m_syncTimeout) { SentryGunInstance val = ((Il2CppObjectBase)__instance.m_core).TryCast<SentryGunInstance>(); LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null); if (!((Object)(object)lSSComp == (Object)null)) { lSSComp.LSS.OnTargetedPlayer(null); } } } [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance), "UpdateMaster")] private static void Post_UpdateMaster(SentryGunInstance __instance) { LSSComp lSSComp = ((__instance != null) ? ((Component)__instance).gameObject.GetComponent<LSSComp>() : null); if ((Object)(object)lSSComp == (Object)null) { return; } if (!lSSComp.LSS.State.Enabled || !lSSComp.LSS.State.TargetPlayer || !__instance.m_detection.HasTarget || (Object)(object)__instance.m_detection.Target == (Object)null) { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); lSSComp.LSS.OnTargetedPlayer(null); return; } PlayerAgent component = __instance.m_detection.Target.GetComponent<PlayerAgent>(); if ((Object)(object)component == (Object)null) { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); lSSComp.LSS.OnTargetedPlayer(null); return; } if (((Agent)component).IsLocallyOwned) { PlayerGUIMessageManager.Current.OnLocalPlayerTargeted(lSSComp.LSS); } else { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); } lSSComp.LSS.OnTargetedPlayer(component); } [HarmonyPostfix] [HarmonyPatch(typeof(SentryGunInstance), "UpdateClient")] private static void Post_UpdateClient(SentryGunInstance __instance) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) LSSComp lSSComp = ((__instance != null) ? ((Component)__instance).gameObject.GetComponent<LSSComp>() : null); if (!((Object)(object)lSSComp == (Object)null)) { LocalPlayerAgent val = default(LocalPlayerAgent); if (!lSSComp.LSS.State.Enabled || !lSSComp.LSS.State.TargetPlayer || !__instance.m_sync.LastSyncData.hasTarget) { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); } else if (!LocalPlayer.TryGetLocalAgent(ref val)) { EOSLogger.Error("Post_UpdateClient: Cannot get local player agent!"); } else if (lSSComp.LSS.LastSyncedTargetedPlayer == ((PlayerAgent)val).Owner.PlayerSlotIndex()) { PlayerGUIMessageManager.Current.OnLocalPlayerTargeted(lSSComp.LSS); } else { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); } } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance), "WantToScan")] private static bool Pre_WantToScan(SentryGunInstance __instance, ref bool __result) { LSSComp component = ((Component)__instance).gameObject.GetComponent<LSSComp>(); if ((Object)(object)component == (Object)null) { return true; } if (!component.LSS.State.Enabled) { __result = false; return false; } return true; } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(SentryGunInstance_Detection), "UpdateDetection")] private static bool Pre_UpdateDetection_OnlyTargetPlayer_Master(SentryGunInstance_Detection __instance) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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) iSentrygunInstanceCore core = __instance.m_core; SentryGunInstance val = ((core != null) ? ((Il2CppObjectBase)core).TryCast<SentryGunInstance>() : null); LSSComp lSSComp = ((val != null) ? ((Component)val).gameObject.GetComponent<LSSComp>() : null); if ((Object)(object)val == (Object)null || (Object)(object)lSSComp == (Object)null) { return true; } if (!lSSComp.LSS.State.Enabled) { PlayerGUIMessageManager.Current.OnLocalPlayerUnTargeted(lSSComp.LSS); return false; } if (lSSComp.LSS.State.TargetEnemy) { return true; } if (Clock.Time > __instance.m_scanningTimer) { Vector3 forward = ((Component)__instance.DetectionSource).transform.forward; Vector3 position = ((Component)__instance.DetectionSource).transform.position; if (__instance.m_core.Ammo >= __instance.m_core.CostOfBullet) { __instance.Target = null; __instance.TargetAimTrans = null; __instance.TargetIsTagged = false; if (__instance.m_targetPlayers) { PlayerAgent val2 = SentryGunInstance_Detection.CheckForPlayerTarget(__instance.m_archetypeData, __instance.DetectionSource, __instance.Target); if ((Object)(object)val2 != (Object)null) { __instance.Target = ((Component)val2).gameObject; __instance.TargetAimTrans = ((Agent)val2).TentacleTarget; } } } if ((Object)(object)__instance.Target != (Object)null) { Vector3 position2 = __instance.Target.transform.position; if (!__instance.HasTarget) { __instance.HasTarget = true; Action onFoundTarget = __instance.OnFoundTarget; if (onFoundTarget != null) { onFoundTarget.Invoke(); } } Debug.DrawLine(position, position2); } else { __instance.HasTarget = false; __instance.TargetIsTagged = false; } } return false; } } } namespace EOSExt.LevelSpawnedSentry.Impl { public class LSSComp : MonoBehaviour { public LSS LSS { get; private set; } public LevelSpawnedSentryDefinition Def => LSS.Def; public SentryGunInstance_ScannerVisuals_Plane Visuals => ((Component)this).gameObject.GetComponent<SentryGunInstance_ScannerVisuals_Plane>(); public SentryGunInstance Sentry => ((Component)this).gameObject.GetComponent<SentryGunInstance>(); public NavMarker marker { get; private set; } public bool IsSetup => LSS != null; internal LSSComp Setup(LSS lss) { //IL_005f: 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_0078: Unknown result type (might be due to invalid IL or missing references) if (!IsSetup) { LSS = lss; LevelSpawnedSentryDefinition def = Def; marker = GuiManager.NavMarkerLayer.PrepareGenericMarker(((Component)this).gameObject); if ((Object)(object)marker != (Object)null) { Color scanningColor = LSS.GetScanningColor(def.InitialState.TargetEnemy, def.InitialState.TargetPlayer); marker.SetStyle((eNavMarkerStyle)0); marker.SetColor(scanningColor); marker.SetVisible(def.InitialState.Enabled); marker.SetTitle(LSS.GetMarkerText(def.InitialState.TargetEnemy, def.InitialState.TargetPlayer)); } UpdateVisuals(); SetCanRefill(def.InitialState.CanRefill); } return this; } public void SetCanRefill(bool canRefill) { Sentry.AmmoMaxCap = (canRefill ? Def.AmmoCap : 0f); } internal void OnStateChanged(LSSSyncState oldState, LSSSyncState newState, bool isRecall) { EOSLogger.Debug($"LSSOnStateChanged \"{Def.WorldEventObjectFilter}\"! OldState: [{oldState}], NewState: {newState}"); SentryGunInstance sentry = Sentry; if (newState.Enabled) { sentry.m_isSetup = true; sentry.m_isScanning = false; sentry.m_startScanTimer = Clock.Time + sentry.m_initialScanDelay; ((ItemEquippable)sentry).Sound.Post(EVENTS.SENTRYGUN_LOW_AMMO_WARNING, true); } else { if (sentry.m_isFiring) { sentry.StopFiring(); } if (sentry.m_isScanning) { sentry.StopScanning(); } sentry.m_isSetup = false; ((ItemEquippable)sentry).Sound.Post(EVENTS.SENTRYGUN_STOP_ALL_LOOPS, true); } iSentrygunInstance_Detection detection = sentry.m_detection; SentryGunInstance_Detection val = ((detection != null) ? ((Il2CppObjectBase)detection).TryCast<SentryGunInstance_Detection>() : null); if ((Object)(object)val != (Object)null) { val.m_targetPlayers = newState.TargetPlayer; } SetCanRefill(newState.CanRefill); UpdateVisuals(); } internal void UpdateVisuals() { //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) //IL_0029: 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_00f0: 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) LSSSyncState state = LSS.State; SentryGunInstance_ScannerVisuals_Plane visuals = Visuals; Color color = (visuals.m_scanningColor = LSS.GetScanningColor(state.TargetEnemy, state.TargetPlayer)); if (state.Enabled) { if (visuals.m_core != null) { visuals.SetVisualStatus((eSentryGunStatus)1, true); } if (state.MarkerVisible) { NavMarker obj = marker; if (obj != null) { obj.SetColor(color); } NavMarker obj2 = marker; if (obj2 != null) { obj2.SetVisible(true); } NavMarker obj3 = marker; if (obj3 != null) { obj3.SetTitle(LSS.GetMarkerText(state.TargetEnemy, state.TargetPlayer)); } } else { NavMarker obj4 = marker; if (obj4 != null) { obj4.SetVisible(false); } } } else { if (visuals.m_core != null) { visuals.m_scannerPlane.SetColor(LSS.OffColor); visuals.UpdateLightProps(LSS.OffColor, false); } NavMarker obj5 = marker; if (obj5 != null) { obj5.SetVisible(false); } } } private void OnDestroy() { GuiManager.NavMarkerLayer.RemoveMarker(marker); marker = null; } static LSSComp() { ClassInjector.RegisterTypeInIl2Cpp<LSSComp>(); } } public struct LSSTargeted { public int LSSInstanceIndex { get; set; } public int PlayerSlotIndex { get; set; } public LSSTargeted() { LSSInstanceIndex = -1; PlayerSlotIndex = -1; } public LSSTargeted(LSSTargeted o) { LSSInstanceIndex = -1; PlayerSlotIndex = -1; LSSInstanceIndex = o.LSSInstanceIndex; PlayerSlotIndex = o.PlayerSlotIndex; } } } namespace EOSExt.LevelSpawnedSentry.Definition { public class LevelSpawnedSentryDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public uint PlayerOfflineGearDBId { get; set; } public eDimensionIndex DimensionIndex { get; set; } public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); public LSSState InitialState { get; set; } = new LSSState(); public float InitialAmmo { get; set; } = 0.5f; public float AmmoCap { get; set; } = 1f; } public class LSSState { public bool Enabled { get; set; } = true; public bool TargetEnemy { get; set; } = true; public bool TargetPlayer { get; set; } = false; public bool MarkerVisible { get; set; } = true; public bool CanRefill { get; set; } = true; public LSSState() { } public LSSState(LSSSyncState o) { Enabled = o.Enabled; TargetEnemy = o.TargetEnemy; TargetPlayer = o.TargetPlayer; MarkerVisible = o.MarkerVisible; CanRefill = o.CanRefill; } public LSSState(LSSState o) { Enabled = o.Enabled; TargetEnemy = o.TargetEnemy; TargetPlayer = o.TargetPlayer; MarkerVisible = o.MarkerVisible; CanRefill = o.CanRefill; } public override string ToString() { return $"Enabled: {Enabled}, TargetEnemy/Player: {TargetEnemy}/{TargetPlayer}, CanRefill: {CanRefill}"; } } public struct LSSSyncState { public bool Enabled { get; set; } public bool TargetEnemy { get; set; } public bool TargetPlayer { get; set; } public bool MarkerVisible { get; set; } public bool CanRefill { get; set; } public float Ammo { get; set; } public LSSSyncState() { Enabled = true; TargetEnemy = true; TargetPlayer = false; MarkerVisible = true; CanRefill = true; Ammo = 0.5f; } public LSSSyncState(LSSSyncState o) { Enabled = true; TargetEnemy = true; TargetPlayer = false; MarkerVisible = true; CanRefill = true; Ammo = 0.5f; Enabled = o.Enabled; TargetEnemy = o.TargetEnemy; TargetPlayer = o.TargetPlayer; MarkerVisible = o.MarkerVisible; CanRefill = o.CanRefill; Ammo = o.Ammo; } public LSSSyncState(LSSState o) { Enabled = true; TargetEnemy = true; TargetPlayer = false; MarkerVisible = true; CanRefill = true; Ammo = 0.5f; Enabled = o.Enabled; TargetEnemy = o.TargetEnemy; TargetPlayer = o.TargetPlayer; MarkerVisible = o.MarkerVisible; CanRefill = o.CanRefill; } public override string ToString() { return $"Enabled: {Enabled}, TargetEnemy/Player: {TargetEnemy}/{TargetPlayer}, CanRefill: {CanRefill}"; } } }
plugins/Inas07.EOSExt.NavigationalSpline.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AssetShards; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.NavigationalSpline.Definition; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GTFO.API; using GameData; using HarmonyLib; using Il2CppSystem; using Microsoft.CodeAnalysis; 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("Inas07.EOSExt.NavigationalSpline")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1417379ed4f80c569c60aeb5bdd37c7cd91aba2a")] [assembly: AssemblyProduct("Inas07.EOSExt.NavigationalSpline")] [assembly: AssemblyTitle("Inas07.EOSExt.NavigationalSpline")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.NavigationalSpline { internal static class Asset { public static GameObject SplineGeneratorGO { get; private set; } internal static void Init() { SplineGeneratorGO = AssetAPI.GetLoadedAsset<GameObject>("Assets/EOSAssets/LG_ChainedPuzzleSplineGenerator.prefab"); } } [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.*/)] [BepInPlugin("Inas.EOSExt.NavigationalSpline", "EOSExt.NavigationalSpline", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.NavigationalSpline"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.NavigationalSpline"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.NavigationalSpline loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<NavigationalSplineDefinition>)NavigationalSplineManager.Current).Init(); } } public class NavigationalSplineManager : GenericExpeditionDefinitionManager<NavigationalSplineDefinition> { public enum WardenEvents_NavigationalSpline { ToggleSplineState = 610 } public static NavigationalSplineManager Current { get; private set; } protected override string DEFINITION_NAME => "NavigationalSpline"; private Dictionary<string, GameObject> SplineGroups { get; } = new Dictionary<string, GameObject>(); private void InstantiateSplines() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if (!base.definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out var value)) { return; } foreach (NavigationalSplineDefinition definition in value.Definitions) { if (SplineGroups.ContainsKey(definition.WorldEventObjectFilter)) { EOSLogger.Error("NavigationalSplineManager: 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<CP_Holopath_Spline>(); val3.m_splineGeneratorPrefab = Asset.SplineGeneratorGO; val3.Setup(false); val3.GeneratePath(spline.From.ToVector3(), spline.To.ToVector3()); if (definition.RevealSpeedMulti > 0f) { val3.m_revealSpeed *= definition.RevealSpeedMulti; } } SplineGroups[definition.WorldEventObjectFilter] = val; } } internal void ToggleSplineState(string WorldEventObjectFilter, int state) { if (!SplineGroups.TryGetValue(WorldEventObjectFilter, out var value)) { EOSLogger.Error("NavigationalSplineManager: cannot find Spline Group with name '" + WorldEventObjectFilter); return; } switch (state) { case 0: { for (int j = 0; j < value.transform.childCount; j++) { CP_Holopath_Spline component2 = ((Component)value.transform.GetChild(j)).gameObject.GetComponent<CP_Holopath_Spline>(); if ((Object)(object)component2 != (Object)null) { component2.SetSplineProgress(0f); component2.Reveal(0f); } } break; } case 1: { for (int k = 0; k < value.transform.childCount; k++) { CP_Holopath_Spline component3 = ((Component)value.transform.GetChild(k)).gameObject.GetComponent<CP_Holopath_Spline>(); if ((Object)(object)component3 != (Object)null) { component3.SetSplineProgress(0.95f); component3.Reveal(0f); } } break; } case 2: { for (int i = 0; i < value.transform.childCount; i++) { CP_Holopath_Spline component = ((Component)value.transform.GetChild(i)).gameObject.GetComponent<CP_Holopath_Spline>(); if ((Object)(object)component != (Object)null) { component.SetVisible(false); } } break; } } } private void Clear() { foreach (GameObject value in SplineGroups.Values) { Object.Destroy((Object)(object)value); } SplineGroups.Clear(); } private NavigationalSplineManager() { LevelAPI.OnBuildDone += InstantiateSplines; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; EOSWardenEventManager.Current.AddEventDefinition(WardenEvents_NavigationalSpline.ToggleSplineState.ToString(), 610u, (Action<WardenObjectiveEventData>)delegate(WardenObjectiveEventData e) { ToggleSplineState(e.WorldEventObjectFilter, e.Count); }); } static NavigationalSplineManager() { Current = new NavigationalSplineManager(); AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)Asset.Init); } } } namespace EOSExt.NavigationalSpline.Definition { public class Spline { public Vec3 From { get; set; } = new Vec3(); public Vec3 To { get; set; } = new Vec3(); } public class NavigationalSplineDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public float RevealSpeedMulti { get; set; } = 1f; public List<Spline> Splines { get; set; } = new List<Spline> { new Spline() }; } }
plugins/Inas07.EOSExt.Reactor.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json.Serialization; using AIGraph; using AK; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.Reactor.Component; using EOSExt.Reactor.Definition; using EOSExt.Reactor.Managers; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.Tweaks.TerminalTweak; using ExtraObjectiveSetup.Utils; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using SNetwork; 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("Inas07.EOSExt.Reactor")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d191ef1fe352fba0ca9af4e27b381f8b2261e6a6")] [assembly: AssemblyProduct("Inas07.EOSExt.Reactor")] [assembly: AssemblyTitle("Inas07.EOSExt.Reactor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.Reactor { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.EOSExt.Reactor", "EOSExt.Reactor", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.Reactor"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown m_Harmony = new Harmony("EOSExt.Reactor"); m_Harmony.PatchAll(); SetupManagers(); SetupExtraWardenEventDefinitions(); ClassInjector.RegisterTypeInIl2Cpp<OverrideReactorComp>(); EOSLogger.Log("ExtraObjectiveSetup.Reactor loaded."); } private void SetupManagers() { ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).Init(); ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).Init(); } private void SetupExtraWardenEventDefinitions() { EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.ReactorStartup.ToString(), 150u, (Action<WardenObjectiveEventData>)WardenEvents.ReactorStartup); EOSWardenEventManager.Current.AddEventDefinition(WardenEvents.EventType.CompleteCurrentVerify.ToString(), 151u, (Action<WardenObjectiveEventData>)WardenEvents.CompleteCurrentVerify); } } } namespace EOSExt.Reactor.Patches { [HarmonyPatch] internal class CommandInterpreter_ReactorVerify { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReactorVerify")] 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 && param1 == connectedReactor.CurrentStateOverrideCode) { __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(typeof(LG_GenericTerminalItem), "GetDetailedInfo")] internal static class GenericTerminalItem_GetDetailedInfo { [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_GetDetailedInfo(LG_GenericTerminalItem __instance, List<string> defaultDetails, ref List<string> __result) { if (__result != null && __result.Count > 0) { return; } string terminalItemKey = __instance.TerminalItemKey; if (terminalItemKey == null || !terminalItemKey.StartsWith("REACTOR_")) { return; } List<string> val = new List<string>(); val.Add("----------------------------------------------------------------"); val.Add("MAIN POWER REACTOR"); if (defaultDetails != null) { Enumerator<string> enumerator = defaultDetails.GetEnumerator(); while (enumerator.MoveNext()) { string current = enumerator.Current; val.Add(current); } } val.Add("----------------------------------------------------------------"); __result = val; } } [HarmonyPatch] internal class OnTerminalStartupSequenceVerify { [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnTerminalStartupSequenceVerify")] private static void Post_ExecuteEventsOnEndOnClientSide(LG_WardenObjective_Reactor __instance) { if (!SNet.IsMaster) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(__instance.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } } } [HarmonyPatch] internal class Reactor_CommandInterpreter { private static bool Handle_ReactorShutdown(LG_ComputerTerminalCommandInterpreter __instance) { LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor); ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { 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 { connectedReactor.AttemptInteract((eReactorInteraction)6, 0f); } return false; } private static bool Handle_ReactorStartup_SpecialCommand(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor; if (__instance.m_terminal.CommandIsHidden(cmd)) { return true; } string itemKey = __instance.m_terminal.ItemKey; OverrideReactorComp component = ((Component)connectedReactor).gameObject.GetComponent<OverrideReactorComp>(); if ((Object)(object)component == (Object)null) { return true; } if (!connectedReactor.ReadyForVerification) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.NotReadyForVerificationOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); return false; } if (component.IsCorrectTerminal(__instance.m_terminal)) { EOSLogger.Log("Reactor Verify Correct!"); if (SNet.IsMaster) { if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax) { connectedReactor.AttemptInteract((eReactorInteraction)5, 0f); } else { connectedReactor.AttemptInteract((eReactorInteraction)3, 0f); } } else { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(connectedReactor.m_currentWaveData.Events, (eWardenObjectiveEventTrigger)3, false, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); } __instance.AddOutput(ReactorStartupOverrideManager.CorrectTerminalOutputText, true); } else { EOSLogger.Log("Reactor Verify Incorrect!"); __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)3, ReactorStartupOverrideManager.IncorrectTerminalOutputText, 4f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0048: 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); } if ((int)cmd == 42) { return Handle_ReactorStartup_SpecialCommand(__instance, cmd); } return true; } } [HarmonyPatch] internal class Reactor_OnBuildDone { [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] 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) { int count = ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes).Count; string[] array = new string[Mathf.Max(count, val.ReactorWaves.Count)]; for (int i = 0; i < array.Length; i++) { array[i] = ((i < count) ? ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[i] : SerialGenerator.GetCodeWord()); } __instance.m_overrideCodes = Il2CppStringArray.op_Implicit(array); } } [HarmonyPostfix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] private static void Post_LG_WardenObjective_Reactor_OnBuildDone(LG_WardenObjective_Reactor __instance) { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 uint num = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).Register(__instance); if (__instance.m_isWardenObjective) { ReactorStartupOverride definition = ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num); if (definition == null) { 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 {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)} is not setup as vanilla ReactorStartup, cannot override"); return; } definition.ObjectiveDB = val; ReactorStartupOverrideManager.Current.Build(__instance, definition); } else { ReactorShutdownDefinition definition2 = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, num); if (definition2 != null) { ReactorShutdownObjectiveManager.Current.Build(__instance, definition2); EOSLogger.Debug($"Reactor Shutdown Instance {(((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance), num)}: custom setup complete"); } } if ((Object)(object)__instance.m_terminal != (Object)null) { TerminalInstanceManager.Current.RegisterReactorTerminal(__instance); } } } [HarmonyPatch] internal class Reactor_OnStateChange { private static void Startup_OnStateChange(LG_WardenObjective_Reactor reactor, pReactorState oldState, pReactorState newState, bool isDropinState) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0054: Unknown result type (might be due to invalid IL or missing references) if (isDropinState) { return; } uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(reactor); ReactorStartupOverride definition = ((InstanceDefinitionManager<ReactorStartupOverride>)ReactorStartupOverrideManager.Current).GetDefinition(reactor.SpawnNode.m_dimension.DimensionIndex, reactor.OriginLayer, reactor.SpawnNode.m_zone.LocalIndex, zoneInstanceIndex); if (definition != null && (int)oldState.status == 0 && (Object)(object)reactor.m_chainedPuzzleToStartSequence != (Object)null) { definition.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } } 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(); def.EventsOnActive.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); 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); } def.EventsOnShutdownPuzzleStarts.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; case 3: reactor.m_progressUpdateEnabled = false; reactor.m_objectiveCompleteTimer = Clock.Time + 5f; def.EventsOnComplete.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); break; } } [HarmonyPrefix] [HarmonyWrapSafe] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateChange")] private static bool Pre_LG_WardenObjective_Reactor_OnStateChange(LG_WardenObjective_Reactor __instance, pReactorState oldState, pReactorState newState, bool isDropinState) { //IL_002e: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_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) //IL_0074: 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_007b: 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_00ef: 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_010e: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_isWardenObjective) { if (ReactorInstanceManager.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 (ReactorInstanceManager.Current.IsShutdownReactor(__instance)) { uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance); ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { 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; } } [HarmonyPatch] internal class Reactor_OnStateCountUpdate { [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnStateCountUpdate")] private static bool Pre_LG_WardenObjective_Reactor_OnStateCountUpdate(LG_WardenObjective_Reactor __instance, int count) { //IL_0148: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown if (__instance.m_isWardenObjective) { return true; } uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(__instance); if (ReactorInstanceManager.Current.IsStartupReactor(__instance)) { return true; } if (ReactorInstanceManager.Current.IsShutdownReactor(__instance)) { ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but its definition is missing, what happened?"); return true; } __instance.m_currentWaveCount = count; if (definition.PutVerificationCodeOnTerminal) { LG_ComputerTerminal instance = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)definition.VerificationCodeTerminal).GlobalZoneIndexTuple(), definition.VerificationCodeTerminal.InstanceIndex); __instance.m_currentWaveData = new ReactorWaveData { HasVerificationTerminal = (definition.PutVerificationCodeOnTerminal && (Object)(object)instance != (Object)null), VerificationTerminalSerial = (((Object)(object)instance != (Object)null) ? instance.ItemKey : string.Empty), Warmup = 1f, WarmupFail = 1f, Wave = 1f, Verify = 1f, VerifyFail = 1f }; } else { __instance.m_currentWaveData = new ReactorWaveData { HasVerificationTerminal = false, VerificationTerminalSerial = string.Empty, Warmup = 1f, WarmupFail = 1f, Wave = 1f, Verify = 1f, VerifyFail = 1f }; } if (__instance.m_overrideCodes != null && !string.IsNullOrEmpty(((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0])) { __instance.CurrentStateOverrideCode = ((Il2CppArrayBase<string>)(object)__instance.m_overrideCodes)[0]; } else { EOSLogger.Error("Reactor_OnStateCountUpdate: code is not built?"); } return false; } EOSLogger.Error("Reactor_OnStateCountUpdate: found built custom reactor but it's neither a startup nor shutdown reactor, what happen?"); return true; } } [HarmonyPatch] internal class Reactor_Update { private static bool _checked; private static TextDataBlock shutdownVerification_GUIText; [HarmonyPrefix] [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "Update")] 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 if (__instance.m_isWardenObjective || (int)__instance.m_currentState.status != 7) { return true; } if (!_checked) { shutdownVerification_GUIText = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.ExtraObjectiveSetup_ReactorShutdown.SecurityVerificationRequired"); _checked = true; } string empty = string.Empty; empty = ((!__instance.m_currentWaveData.HasVerificationTerminal) ? string.Format(Text.Get(1107u), "<color=orange>" + __instance.CurrentStateOverrideCode + "</color>") : string.Format((shutdownVerification_GUIText != null) ? Text.Get(((GameDataBlockBase<TextDataBlock>)(object)shutdownVerification_GUIText).persistentID) : "SECURITY VERIFICATION REQUIRED. USE COMMAND <color=orange>REACTOR_VERIFY</color> AND FIND CODE ON <color=orange>{0}</color>.", __instance.m_currentWaveData.VerificationTerminalSerial)); __instance.SetGUIMessage(true, empty, (ePUIMessageStyle)3, false, "", ""); return false; } } } namespace EOSExt.Reactor.Patches.Shutdown { [HarmonyPatch] internal class Reactor_OnReactorShutdownVerifyChaosDone { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "OnReactorShutdownVerifyChaosDone")] 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; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetGlobalZoneIndex(connectedReactor); uint zoneInstanceIndex = ((InstanceManager<LG_WardenObjective_Reactor>)ReactorInstanceManager.Current).GetZoneInstanceIndex(connectedReactor); ReactorShutdownDefinition definition = ((InstanceDefinitionManager<ReactorShutdownDefinition>)ReactorShutdownObjectiveManager.Current).GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { 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; } } } namespace EOSExt.Reactor.Managers { public sealed class ReactorInstanceManager : InstanceManager<LG_WardenObjective_Reactor> { private HashSet<IntPtr> startupReactor = new HashSet<IntPtr>(); private HashSet<IntPtr> shutdownReactor = new HashSet<IntPtr>(); public static ReactorInstanceManager Current { get; private set; } public override (eDimensionIndex, LG_LayerType, eLocalZoneIndex) GetGlobalZoneIndex(LG_WardenObjective_Reactor instance) { //IL_000b: 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_0026: Unknown result type (might be due to invalid IL or missing references) return (instance.SpawnNode.m_dimension.DimensionIndex, instance.SpawnNode.LayerType, instance.SpawnNode.m_zone.LocalIndex); } public void MarkAsStartupReactor(LG_WardenObjective_Reactor reactor) { if (shutdownReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } startupReactor.Add(((Il2CppObjectBase)reactor).Pointer); } public void MarkAsShutdownReactor(LG_WardenObjective_Reactor reactor) { if (startupReactor.Contains(((Il2CppObjectBase)reactor).Pointer)) { throw new ArgumentException("Invalid: cannot mark a reactor both as startup and shutdown reactor"); } 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); } private void Clear() { //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(); } public void SetupReactorTerminal(LG_WardenObjective_Reactor reactor, TerminalDefinition reactorTerminalData) { reactor.SpawnNode.m_zone.TerminalsSpawnedInZone.Add(reactor.m_terminal); if (reactorTerminalData != null) { reactorTerminalData.LocalLogFiles?.ForEach(delegate(TerminalLogFileData log) { reactor.m_terminal.AddLocalLog(log, true); }); reactorTerminalData.UniqueCommands?.ForEach(delegate(CustomCommand cmd) { EOSTerminalUtils.AddUniqueCommand(reactor.m_terminal, cmd); }); EOSTerminalUtils.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<LayerChainIndex, iWardenObjectiveItem> enumerator = WardenObjectiveManager.Current.m_wardenObjectiveItem.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<LayerChainIndex, iWardenObjectiveItem> current = enumerator.Current; if (current.Key.Layer != layer) { continue; } iWardenObjectiveItem value = current.Value; val = ((value != null) ? ((Il2CppObjectBase)value).TryCast<LG_WardenObjective_Reactor>() : 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; } private ReactorInstanceManager() { LevelAPI.OnLevelCleanup += Clear; } static ReactorInstanceManager() { Current = new ReactorInstanceManager(); } } internal class ReactorShutdownObjectiveManager : InstanceDefinitionManager<ReactorShutdownDefinition> { private List<ReactorShutdownDefinition> builtShutdownPuzzles = new List<ReactorShutdownDefinition>(); public static ReactorShutdownObjectiveManager Current { get; private set; } protected override string DEFINITION_NAME => "ReactorShutdown"; private void GenericObjectiveSetup(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) reactor.m_serialNumber = SerialGenerator.GetUniqueSerialNo(); reactor.m_itemKey = "REACTOR_" + reactor.m_serialNumber; reactor.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(reactor.m_terminalItemComp); reactor.m_terminalItem.Setup(reactor.m_itemKey, (AIG_CourseNode)null); reactor.m_terminalItem.FloorItemStatus = EnumUtil.GetRandomValue<eFloorInventoryObjectStatus>(); reactor.m_overrideCodes = Il2CppStringArray.op_Implicit(new string[1] { SerialGeneratorManager.GetCodeWord(def.CodeWordLength) }); reactor.m_terminal = GOUtil.SpawnChildAndGetComp<LG_ComputerTerminal>(reactor.m_terminalPrefab, reactor.m_terminalAlign); reactor.m_terminal.Setup((TerminalStartStateData)null, (TerminalPlacementData)null); reactor.m_terminal.ConnectedReactor = reactor; ReactorInstanceManager.Current.SetupReactorTerminal(reactor, def.ReactorTerminal); } private void OnLateBuildJob(LG_WardenObjective_Reactor reactor, BaseReactorDefinition reactorDefinition) { //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_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_0047: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) reactor.m_stateReplicator = SNet_StateReplicator<pReactorState, pReactorInteraction>.Create(new iSNet_StateReplicatorProvider<pReactorState, pReactorInteraction>(((Il2CppObjectBase)reactor).Pointer), (eSNetReplicatorLifeTime)1, default(pReactorState), (SNet_ChannelType)2); GenericObjectiveSetup(reactor, (ReactorShutdownDefinition)reactorDefinition); 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); } internal void Build(LG_WardenObjective_Reactor reactor, ReactorShutdownDefinition def) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01cb: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) if (reactor.m_isWardenObjective) { EOSLogger.Error($"ReactorShutdown: Reactor definition for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is already setup by vanilla, won't build."); return; } OnLateBuildJob(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 = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)def.VerificationCodeTerminal).GlobalZoneIndexTuple(), 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" + SerialGeneratorManager.GetCodeWordPrefix(def.UseHardLogFilenameSuffix, false) + ".log"; TerminalLogFileData val = new TerminalLogFileData { FileName = fileName, FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(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 (def.ChainedPuzzleToActive != 0) { ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleToActive); if (block == null) { EOSLogger.Error("ReactorShutdown: ChainedPuzzleToActive is specified but could not find its ChainedPuzzleDatablock definition!"); } else { Vector3 position = ((Component)reactor).transform.position; def.ChainedPuzzleToActiveInstance = ChainedPuzzleManager.CreatePuzzleInstance(block, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform); ChainedPuzzleInstance chainedPuzzleToActiveInstance = def.ChainedPuzzleToActiveInstance; chainedPuzzleToActiveInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (SNet.IsMaster) { reactor.AttemptInteract((eReactorInteraction)6, 0f); } }); } } else { EOSLogger.Debug("ReactorShutdown: Reactor has no ChainedPuzzleToActive, will start shutdown sequence on shutdown command initiation."); } if (def.ChainedPuzzleOnVerification != 0) { ChainedPuzzleDataBlock block2 = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(def.ChainedPuzzleOnVerification); if (block2 == null) { EOSLogger.Error("ReactorShutdown: ChainedPuzzleOnVerification is specified but could not find its ChainedPuzzleDatablock definition! Will complete shutdown on verification"); } Vector3 position2 = ((Component)reactor).transform.position; def.ChainedPuzzleOnVerificationInstance = ChainedPuzzleManager.CreatePuzzleInstance(block2, reactor.SpawnNode.m_area, reactor.m_chainedPuzzleAlign.position, ((Component)reactor).transform); ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = def.ChainedPuzzleOnVerificationInstance; chainedPuzzleOnVerificationInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { if (SNet.IsMaster) { reactor.AttemptInteract((eReactorInteraction)9, 0f); } }); } else { EOSLogger.Debug("ReactorShutdown: ChainedPuzzleOnVerification unspecified, will complete shutdown on verification."); } LG_ComputerTerminal terminal = reactor.m_terminal; iLG_SpawnedInNodeHandler val2 = ((terminal != null) ? ((Component)terminal).GetComponent<iLG_SpawnedInNodeHandler>() : null); if (val2 != null) { val2.SpawnNode = reactor.SpawnNode; } reactor.SetLightsEnabled(reactor.m_lightsWhenOff, false); reactor.SetLightsEnabled(reactor.m_lightsWhenOn, true); builtShutdownPuzzles.Add(def); ReactorInstanceManager.Current.MarkAsShutdownReactor(reactor); EOSLogger.Debug($"ReactorShutdown: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, custom setup completed"); } private void OnLevelCleanup() { builtShutdownPuzzles.ForEach(delegate(ReactorShutdownDefinition def) { ChainedPuzzleInstance chainedPuzzleOnVerificationInstance = (def.ChainedPuzzleToActiveInstance = null); def.ChainedPuzzleOnVerificationInstance = chainedPuzzleOnVerificationInstance; }); builtShutdownPuzzles.Clear(); } private ReactorShutdownObjectiveManager() { LevelAPI.OnLevelCleanup += OnLevelCleanup; LevelAPI.OnBuildStart += OnLevelCleanup; } static ReactorShutdownObjectiveManager() { Current = new ReactorShutdownObjectiveManager(); } } internal class ReactorStartupOverrideManager : InstanceDefinitionManager<ReactorStartupOverride> { private List<ReactorStartupOverride> builtOverride = new List<ReactorStartupOverride>(); public static uint SpecialCmdVerifyTextID { get; private set; } public static uint MainTerminalTextID { get; private set; } public static uint CooldownCommandDescTextID { get; private set; } public static uint InfiniteWaveVerifyTextID { get; private set; } public static uint NotReadyForVerificationOutputTextID { get; private set; } public static uint IncorrectTerminalOutputTextID { get; private set; } public static uint CorrectTerminalOutputTextID { get; private set; } public static string CoolDownCommandDesc => (CooldownCommandDescTextID != 0) ? Text.Get(CooldownCommandDescTextID) : "Confirm Reactor Startup Cooling Protocol"; public static string MainTerminalText => (MainTerminalTextID != 0) ? Text.Get(MainTerminalTextID) : "Main Terminal"; public static string SpecialCmdVerifyText => (SpecialCmdVerifyTextID != 0) ? Text.Get(SpecialCmdVerifyTextID) : "REACTOR COOLING REQUIRED ({0}/{1})\nMANUAL OVERRIDE REQUIRED. USE COMMAND <color=orange>REACTOR_COOLDOWN</color> AT {2}"; public static string InfiniteWaveVerifyText => (InfiniteWaveVerifyTextID != 0) ? Text.Get(InfiniteWaveVerifyTextID) : "VERIFICATION ({0}/{1})."; public static string NotReadyForVerificationOutputText => (NotReadyForVerificationOutputTextID != 0) ? Text.Get(NotReadyForVerificationOutputTextID) : "<color=red>Reactor intensive test in progress, cannot initate cooldown</color>"; public static string CorrectTerminalOutputText => (CorrectTerminalOutputTextID != 0) ? Text.Get(CorrectTerminalOutputTextID) : "<color=red>Reactor stage cooldown completed</color>"; public static string IncorrectTerminalOutputText => (IncorrectTerminalOutputTextID != 0) ? Text.Get(IncorrectTerminalOutputTextID) : "<color=red>Incorrect terminal, cannot initate cooldown</color>"; public static ReactorStartupOverrideManager Current { get; private set; } protected override string DEFINITION_NAME => "ReactorStartup"; public static void FetchOverrideTextDB() { SpecialCmdVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification"); MainTerminalTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName"); CooldownCommandDescTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc"); InfiniteWaveVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave"); NotReadyForVerificationOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output"); IncorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output"); CorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output"); } protected override void AddDefinitions(InstanceDefinitionsForLevel<ReactorStartupOverride> definitions) { definitions.Definitions.ForEach(delegate(ReactorStartupOverride def) { def.Overrides.Sort((WaveOverride o1, WaveOverride o2) => o1.WaveIndex.CompareTo(o2.WaveIndex)); }); base.AddDefinitions(definitions); } internal void Build(LG_WardenObjective_Reactor reactor, ReactorStartupOverride def) { if (!reactor.m_isWardenObjective) { EOSLogger.Error($"ReactorStartup: Reactor Override for reactor {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex} is not setup by vanilla, won't override"); return; } OverrideReactorComp overrideReactorComp = ((Component)reactor).gameObject.AddComponent<OverrideReactorComp>(); overrideReactorComp.ChainedReactor = reactor; overrideReactorComp.overrideData = def; overrideReactorComp.UsingLightEffect = false; overrideReactorComp.Init(); ReactorInstanceManager.Current.MarkAsStartupReactor(reactor); ReactorInstanceManager.Current.SetupReactorTerminal(reactor, def.ReactorTerminal); def.ChainedPuzzleToActiveInstance = reactor.m_chainedPuzzleToStartSequence; if ((Object)(object)def.ChainedPuzzleToActiveInstance != (Object)null) { } builtOverride.Add(def); EOSLogger.Debug($"ReactorStartup: {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Instance_{((BaseInstanceDefinition)def).InstanceIndex}, override completed"); } private void OnLevelCleanup() { builtOverride.ForEach(delegate(ReactorStartupOverride def) { def.ChainedPuzzleToActiveInstance = null; }); builtOverride.Clear(); } private ReactorStartupOverrideManager() { LevelAPI.OnLevelCleanup += OnLevelCleanup; LevelAPI.OnBuildStart += OnLevelCleanup; } static ReactorStartupOverrideManager() { SpecialCmdVerifyTextID = 0u; MainTerminalTextID = 0u; CooldownCommandDescTextID = 0u; InfiniteWaveVerifyTextID = 0u; NotReadyForVerificationOutputTextID = 0u; IncorrectTerminalOutputTextID = 0u; CorrectTerminalOutputTextID = 0u; Current = new ReactorStartupOverrideManager(); EventAPI.OnExpeditionStarted += FetchOverrideTextDB; } } } namespace EOSExt.Reactor.Definition { public class BaseReactorDefinition : BaseInstanceDefinition { [JsonPropertyOrder(-9)] public TerminalDefinition ReactorTerminal { get; set; } = new TerminalDefinition(); [JsonPropertyOrder(-9)] public List<WardenObjectiveEventData> EventsOnActive { get; set; } = new List<WardenObjectiveEventData>(); public CodeWordLength CodeWordLength { get; set; } = (CodeWordLength)4; public bool UseHardLogFilenameSuffix { get; set; } = false; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleToActiveInstance { get; set; } = null; } public class ReactorShutdownDefinition : BaseReactorDefinition { [JsonPropertyOrder(-9)] public uint ChainedPuzzleToActive { get; set; } = 0u; public bool PutVerificationCodeOnTerminal { get; set; } = false; public BaseInstanceDefinition VerificationCodeTerminal { get; set; } = new BaseInstanceDefinition(); public uint ChainedPuzzleOnVerification { get; set; } = 0u; [JsonIgnore] public ChainedPuzzleInstance ChainedPuzzleOnVerificationInstance { get; set; } = null; public List<WardenObjectiveEventData> EventsOnShutdownPuzzleStarts { get; set; } = new List<WardenObjectiveEventData>(); public List<WardenObjectiveEventData> EventsOnComplete { get; set; } = new List<WardenObjectiveEventData>(); } public enum EOSReactorVerificationType { NORMAL, BY_SPECIAL_COMMAND, BY_WARDEN_EVENT } 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 LocalizedText VerifySequenceText { get; set; } = null; [JsonIgnore] public LG_ComputerTerminal VerifyTerminal { get; set; } = null; } public class ReactorStartupOverride : BaseReactorDefinition { public bool StartupOnDrop { get; set; } = false; [JsonIgnore] public WardenObjectiveDataBlock ObjectiveDB { get; set; } = null; public List<WaveOverride> Overrides { get; set; } = new List<WaveOverride> { new WaveOverride() }; } internal class WardenEvents { public enum EventType { ReactorStartup = 150, CompleteCurrentVerify } internal static void ReactorStartup(WardenObjectiveEventData e) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_0081: 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_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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) if (!SNet.IsMaster) { return; } LG_WardenObjective_Reactor val = ReactorInstanceManager.FindVanillaReactor(e.Layer, e.Count); WardenObjectiveDataBlock val2 = default(WardenObjectiveDataBlock); if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(e.Layer, ref val2) || val2 == null) { EOSLogger.Error("CompleteCurrentReactorWave: Cannot get WardenObjectiveDataBlock"); return; } if ((int)val2.Type != 1) { EOSLogger.Error($"CompleteCurrentReactorWave: {e.Layer} is not ReactorStartup. CompleteCurrentReactorWave is invalid."); return; } if ((Object)(object)val == (Object)null) { EOSLogger.Error($"ReactorStartup: Cannot find reactor in {e.Layer}."); return; } eReactorStatus status = val.m_currentState.status; eReactorStatus val3 = status; if ((int)val3 == 0) { if (SNet.IsMaster) { val.AttemptInteract((eReactorInteraction)0, 0f); } val.m_terminal.TrySyncSetCommandHidden((TERM_Command)21); } EOSLogger.Debug($"ReactorStartup: Current reactor wave for {e.Layer} completed"); } internal 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<eWardenObjectiveEventType>)null); } EOSLogger.Debug($"CompleteCurrentReactorWave: Current reactor verify for {e.Layer} completed"); } } } namespace EOSExt.Reactor.Component { public class OverrideReactorComp : MonoBehaviour { private static Color LowTemperature; private static Color HighTemperature; private LG_Light[] _lights; private float _updateTimer; private List<WaveOverride> WaveData = new List<WaveOverride>(); public LG_WardenObjective_Reactor ChainedReactor { get; internal set; } public ReactorStartupOverride overrideData { get; internal set; } public bool UsingLightEffect { get; set; } = true; public WardenObjectiveDataBlock ObjectiveData => overrideData?.ObjectiveDB; public void Init() { if ((Object)(object)ChainedReactor == (Object)null || overrideData == null) { EOSLogger.Error("ReactorOverride not properly initialized!"); return; } 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); } if (WaveData.Count != ObjectiveData.ReactorWaves.Count) { EOSLogger.Error($"WaveData.Count({WaveData.Count}) != ObjectiveData.ReactorWaves.Count({ObjectiveData.ReactorWaves.Count})"); } LevelAPI.OnEnterLevel += OnEnterLevel; } private void OnEnterLevel() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 LG_WardenObjective_Reactor chainedReactor = ChainedReactor; LG_ComputerTerminal terminal = ChainedReactor.m_terminal; if ((int)ObjectiveData.Type != 1) { EOSLogger.Error("Only Reactor Startup is supported"); ((Behaviour)this).enabled = false; return; } if (UsingLightEffect) { _lights = ((IEnumerable<LG_Light>)chainedReactor.SpawnNode.m_lightsInNode).Where((LG_Light x) => (int)x.m_category == 3).ToArray(); chainedReactor.m_lightCollection.RemoveLights(Il2CppReferenceArray<LG_Light>.op_Implicit(_lights)); } if (overrideData.StartupOnDrop && SNet.IsMaster) { chainedReactor.AttemptInteract((eReactorInteraction)0, 0f); terminal.TrySyncSetCommandHidden((TERM_Command)21); } SetupVerifyZoneOverrides(); SetupWaves(); ApplyCodeWordOverrides(); } private void SetupVerifyZoneOverrides() { //IL_00ad: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_045c: 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_049a: Expected O, but got Unknown //IL_049d: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); 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; if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(((GlobalZoneIndex)verifyZone).DimensionIndex, ((GlobalZoneIndex)verifyZone).LayerType, ((GlobalZoneIndex)verifyZone).LocalIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}."); continue; } if (val.TerminalsSpawnedInZone == null || val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()}."); continue; } LG_ComputerTerminal val2 = null; if (verifyZone.InstanceIndex >= 0) { val2 = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstance(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple(), verifyZone.InstanceIndex); } else { List<LG_ComputerTerminal> instancesInZone = ((InstanceManager<LG_ComputerTerminal>)(object)TerminalInstanceManager.Current).GetInstancesInZone(((GlobalZoneIndex)verifyZone).GlobalZoneIndexTuple()); int index = Builder.SessionSeedRandom.Range(0, instancesInZone.Count, "NO_TAG"); val2 = instancesInZone[index]; } if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"VerifyZoneOverride: cannot find target terminal with Terminal Instance Index: {waveDatum}"); } waveDatum.VerifyTerminal = val2; ReactorWaveData waveData = ObjectiveData.ReactorWaves[waveDatum.WaveIndex]; TerminalLogFileData val3 = null; if (waveData.VerifyInOtherZone) { List<LG_ComputerTerminal> list = EOSTerminalUtils.FindTerminal(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal x) => x.ItemKey == waveData.VerificationTerminalSerial)); if (list == null || list.Count < 1) { EOSLogger.Error($"Wave_{waveDatum.WaveIndex}: cannot find vanilla verification terminal in {(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification)}, unable to override"); continue; } LG_ComputerTerminal val4 = list[0]; if ((Object)(object)val4 == (Object)null) { EOSLogger.Error($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Cannot find log terminal"); continue; } string text = waveData.VerificationTerminalFileName.ToUpperInvariant(); val3 = EOSTerminalUtils.GetLocalLog(val4, text); if (val3 == null) { EOSLogger.Error("VerifyZoneOverrides: Cannot find vanilla-generated reactor verify log on terminal..."); continue; } val4.RemoveLocalLog(text); EOSTerminalUtils.ResetInitialOutput(val4); } else { waveData.VerificationTerminalFileName = "reactor_ver" + SerialGenerator.GetCodeWordPrefix() + ".log"; val3 = new TerminalLogFileData { FileName = waveData.VerificationTerminalFileName, FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpper()), Id = 0u } }; EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} - Log generated."); } waveData.HasVerificationTerminal = true; waveData.VerificationTerminalSerial = val2.ItemKey; val2.AddLocalLog(val3, true); EOSTerminalUtils.ResetInitialOutput(val2); EOSLogger.Debug($"VerifyZoneOverrides: Wave_{waveDatum.WaveIndex} verification overriden"); } } private void SetupWaves() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0024: 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_00ef: Unknown result type (might be due to invalid IL or missing references) LG_WardenObjective_Reactor chainedReactor = ChainedReactor; eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex; LG_LayerType layerType = chainedReactor.SpawnNode.LayerType; int num = 0; for (int i = 0; i < WaveData.Count; i++) { ReactorWaveData reactorWave = ObjectiveData.ReactorWaves[i]; WaveOverride waveOverride = WaveData[i]; switch (waveOverride.VerificationType) { case EOSReactorVerificationType.BY_SPECIAL_COMMAND: if (!reactorWave.HasVerificationTerminal) { waveOverride.VerifyTerminal = ChainedReactor.m_terminal; AddVerifyCommand(ChainedReactor.m_terminal); } else { LG_ComputerTerminal val = waveOverride.VerifyTerminal; if ((Object)(object)val == (Object)null) { val = EOSTerminalUtils.FindTerminal(dimensionIndex, layerType, reactorWave.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal terminal) => terminal.ItemKey.Equals(reactorWave.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase)))?[0]; if ((Object)(object)val == (Object)null) { EOSLogger.Error($"SetupWaves: cannot find verify terminal for Wave_{i}, skipped"); break; } waveOverride.VerifyTerminal = val; } val.ConnectedReactor = chainedReactor; val.RemoveLocalLog(reactorWave.VerificationTerminalFileName.ToUpperInvariant()); AddVerifyCommand(val); EOSTerminalUtils.ResetInitialOutput(val); } num++; EOSLogger.Debug($"WaveOverride: Setup as Wave Verification {1} for Wave_{i}"); break; default: EOSLogger.Error($"Unimplemented Verification Type {waveOverride.VerificationType}"); break; case EOSReactorVerificationType.NORMAL: case EOSReactorVerificationType.BY_WARDEN_EVENT: break; } } if (num == ObjectiveData.ReactorWaves.Count) { ChainedReactor.m_terminal.TrySyncSetCommandHidden((TERM_Command)22); } } private void ApplyCodeWordOverrides() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_005f: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_0295: Expected O, but got Unknown bool flag = (int)overrideData.CodeWordLength != 4; bool useHardLogFilenameSuffix = overrideData.UseHardLogFilenameSuffix; if (!flag && !useHardLogFilenameSuffix) { return; } if (flag) { string[] array = new string[((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes).Length]; for (int i = 0; i < array.Length; i++) { array[i] = SerialGeneratorManager.GetCodeWord(overrideData.CodeWordLength); } ChainedReactor.m_overrideCodes = Il2CppStringArray.op_Implicit(array); } foreach (WaveOverride waveDatum in WaveData) { if (waveDatum.WaveIndex < 0 || waveDatum.WaveIndex >= ObjectiveData.ReactorWaves.Count) { continue; } ReactorWaveData waveData = ObjectiveData.ReactorWaves[waveDatum.WaveIndex]; if (!waveData.HasVerificationTerminal) { continue; } LG_ComputerTerminal val = waveDatum.VerifyTerminal; if ((Object)(object)val == (Object)null) { List<LG_ComputerTerminal> list = EOSTerminalUtils.FindTerminal(ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, waveData.ZoneForVerification, (Predicate<LG_ComputerTerminal>)((LG_ComputerTerminal x) => x.ItemKey.Equals(waveData.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase))); if (list == null || list.Count == 0) { EOSLogger.Error($"ApplyCodeWordOverrides: cannot find verify terminal for Wave_{waveDatum.WaveIndex}, skipped"); continue; } val = list[0]; } val.RemoveLocalLog(waveData.VerificationTerminalFileName.ToUpperInvariant()); if (useHardLogFilenameSuffix) { waveData.VerificationTerminalFileName = "reactor_ver" + SerialGeneratorManager.GetCodeWordPrefix(true, false) + ".log"; } TerminalLogFileData val2 = new TerminalLogFileData { FileName = waveData.VerificationTerminalFileName.ToUpperInvariant(), FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get(182408469u), ((Il2CppArrayBase<string>)(object)ChainedReactor.m_overrideCodes)[waveDatum.WaveIndex].ToUpperInvariant()), Id = 0u } }; val.AddLocalLog(val2, true); EOSTerminalUtils.ResetInitialOutput(val); } } private void AddVerifyCommand(LG_ComputerTerminal terminal) { //IL_002a: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown LG_ComputerTerminalCommandInterpreter command = terminal.m_command; if (command.HasRegisteredCommand((TERM_Command)42)) { EOSLogger.Debug("TERM_Command.UniqueCommand5 already registered. 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."); return; } command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", new LocalizedText { UntranslatedText = ReactorStartupOverrideManager.CoolDownCommandDesc, Id = 0u }, (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; } } private void OnDestroy() { LevelAPI.OnEnterLevel -= OnEnterLevel; ChainedReactor = null; overrideData = null; } private 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_0042: 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) if ((int)GameStateManager.CurrentStateName == 10) { eReactorStatus status = ChainedReactor.m_currentState.status; if (UsingLightEffect) { UpdateLight(status, ChainedReactor.m_currentWaveProgress); } UpdateGUIText(status); } } private void UpdateGUIText(eReactorStatus status) { //IL_0068: 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_006b: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Invalid comparison between Unknown and I4 int num = ChainedReactor.m_currentWaveCount - 1; if (num < 0) { return; } WaveOverride waveOverride = WaveData[num]; string format = string.Empty; if (waveOverride.UseCustomVerifyText) { format = ((waveOverride.VerifySequenceText.Id != 0) ? Text.Get(waveOverride.VerifySequenceText.Id) : waveOverride.VerifySequenceText.UntranslatedText); } 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, "<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); } else { if (!waveOverride.UseCustomVerifyText) { format = Text.Get(1105u); } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); } break; case EOSReactorVerificationType.BY_SPECIAL_COMMAND: { string text = (ChainedReactor.m_currentWaveData.HasVerificationTerminal ? ChainedReactor.m_currentWaveData.VerificationTerminalSerial : ReactorStartupOverrideManager.MainTerminalText); if (!waveOverride.UseCustomVerifyText) { format = ReactorStartupOverrideManager.SpecialCmdVerifyText; } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); break; } case EOSReactorVerificationType.BY_WARDEN_EVENT: if (!waveOverride.UseCustomVerifyText) { format = ReactorStartupOverrideManager.InfiniteWaveVerifyText; } ChainedReactor.SetGUIMessage(true, string.Format(format, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, !waveOverride.HideVerificationTimer, "<size=125%>" + Text.Get(1104u), "</size>"); break; } } private void UpdateLight(eReactorStatus status, float progress) { //IL_0028: 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_002a: 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_002c: 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_0048: Expected I4, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!(_updateTimer > Clock.Time)) { _updateTimer = Clock.Time + 0.15f; switch (status - 1) { case 0: SetLightColor(Color.black); break; case 1: SetLightColor(Color.Lerp(LowTemperature, HighTemperature, progress)); break; case 2: SetLightColor(Color.Lerp(HighTemperature, LowTemperature, progress)); break; case 3: SetLightColor(LowTemperature); break; case 4: SetLightColor(LowTemperature); break; } } } private void SetLightColor(Color color) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (UsingLightEffect && _lights != null) { for (int i = 0; i < _lights.Length; i++) { _lights[i].ChangeColor(color); } } } static OverrideReactorComp() { //IL_0005: 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_001e: 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) LowTemperature = ColorExt.Hex("#23E4F2") * 2.5f; HighTemperature = ColorExt.Hex("#F63838") * 12f; } } }
plugins/Inas07.EOSExt.SecDoor.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Unity.IL2CPP; using EOSExt.SecDoor.Definition; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.Utils; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem; using Il2CppSystem.Text; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; 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("Inas07.EOSExt.SecDoor")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b67fbe3cee1f595da8cfc128e308ce23fabae98a")] [assembly: AssemblyProduct("Inas07.EOSExt.SecDoor")] [assembly: AssemblyTitle("Inas07.EOSExt.SecDoor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.SecDoor { [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.*/)] [BepInPlugin("Inas.EOSExt.SecDoor", "EOSExt.SecDoor", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.SecDoor"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("EOSExt.SecDoor"); m_Harmony.PatchAll(); EOSLogger.Log("ExtraObjectiveSetup.SecDoor loaded."); } private void SetupManagers() { ((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).Init(); } } public class InteractGlitchManager : MonoBehaviour { private const string HEX_CHARPOOL = "0123456789ABCDEF"; private const string ERR_CHARPOOL = "$#/-01"; private Random Random = new Random(); private float _Timer; private uint START_SECURITY_SCAN_SEQUENCE_TEXT_ID; private uint HOLD_TEXT_ID; private uint SCAN_UNKNOWN_TEXT_DB; public static InteractGlitchManager Current { get; } internal bool Enabled { get; set; } internal bool CanInteract { get; set; } private StringBuilder _StrBuilder { get; } = new StringBuilder(); internal GlitchMode Mode { get; set; } private Dictionary<IntPtr, LG_SecurityDoor> DoorLocks { get; } = new Dictionary<IntPtr, LG_SecurityDoor>(); private void Update() { if (Enabled && !(_Timer > Clock.Time) && GuiManager.InteractionLayer != null && Mode != GlitchMode.None) { switch (Mode) { case GlitchMode.Style1: GuiManager.InteractionLayer.SetInteractPrompt(GetFormat1(), CanInteract ? Text.Format(HOLD_TEXT_ID, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName((InputAction)6)) }) : string.Empty, (ePUIMessageStyle)0); GuiManager.InteractionLayer.InteractPromptVisible = true; _Timer = Clock.Time + 0.05f; break; case GlitchMode.Style2: { string format = GetFormat2(Text.Get(START_SECURITY_SCAN_SEQUENCE_TEXT_ID)); string format2 = GetFormat2(Text.Get(SCAN_UNKNOWN_TEXT_DB)); GuiManager.InteractionLayer.SetInteractPrompt(format + "<color=red>" + format2 + "</color>", CanInteract ? Text.Format(HOLD_TEXT_ID, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName((InputAction)6)) }) : string.Empty, (ePUIMessageStyle)0); GuiManager.InteractionLayer.InteractPromptVisible = true; _Timer = Clock.Time + 0.075f; break; } } } } private string GetFormat1() { return "<color=red>://Decryption E_RR at: [" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "-" + GetRandomHex() + GetRandomHex() + "]</color>"; } private string GetFormat2(string baseMessage) { _StrBuilder.Clear(); foreach (char c in baseMessage) { if (Random.NextDouble() > 0.009999999776482582 || c == ':') { _StrBuilder.Append(c); } else { _StrBuilder.Append("$#/-01"[Random.Next(0, "$#/-01".Length)]); } } return _StrBuilder.ToString(); } private string GetRandomHex() { return string.Format("{0}{1}", "0123456789ABCDEF"[Random.Next(0, "0123456789ABCDEF".Length)], "0123456789ABCDEF"[Random.Next(0, "0123456789ABCDEF".Length)]); } internal void RegisterDoorLocks(LG_SecurityDoor_Locks locks) { DoorLocks[((Il2CppObjectBase)locks.m_intCustomMessage).Pointer] = locks.m_door; DoorLocks[((Il2CppObjectBase)locks.m_intOpenDoor).Pointer] = locks.m_door; } public GlitchMode GetGlitchMode(Interact_Base interact) { //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_002f: 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_003b: 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_0046: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (!DoorLocks.TryGetValue(((Il2CppObjectBase)interact).Pointer, out var value)) { return GlitchMode.None; } eDimensionIndex dimensionIndex = value.Gate.DimensionIndex; LG_LayerType linksToLayerType = value.LinksToLayerType; eLocalZoneIndex localIndex = value.LinkedToZoneData.LocalIndex; return ((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).GetDefinition(dimensionIndex, linksToLayerType, localIndex)?.GlitchMode ?? GlitchMode.None; } private void Clear() { DoorLocks.Clear(); } private InteractGlitchManager() { START_SECURITY_SCAN_SEQUENCE_TEXT_ID = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.SecurityDoor.StartSecurityScanSequence"))?.persistentID ?? 0; HOLD_TEXT_ID = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.Hold_X"))?.persistentID ?? 0; SCAN_UNKNOWN_TEXT_DB = ((GameDataBlockBase<TextDataBlock>)(object)GameDataBlockBase<TextDataBlock>.GetBlock("InGame.InteractionPrompt.SecurityDoor.StartSecurityScanSequence_ScanUnknown"))?.persistentID ?? 0; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } static InteractGlitchManager() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown ClassInjector.RegisterTypeInIl2Cpp<InteractGlitchManager>(); GameObject val = new GameObject("CONST_InteractGlitchManager"); Object.DontDestroyOnLoad((Object)(object)val); Current = val.AddComponent<InteractGlitchManager>(); } } public class SecDoorIntTextOverrideManager : ZoneDefinitionManager<SecDoorIntTextOverride> { public static SecDoorIntTextOverrideManager Current { get; } protected override string DEFINITION_NAME => "SecDoorIntText"; private SecDoorIntTextOverrideManager() { } static SecDoorIntTextOverrideManager() { Current = new SecDoorIntTextOverrideManager(); } } } namespace EOSExt.SecDoor.Patches { [HarmonyPatch] internal class CustomizeSecDoorInteractionText { [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor), "Setup")] private static void Post_Customize_SecDoor_Interaction_Text(LG_SecurityDoor __instance) { //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_0016: 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_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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) eDimensionIndex dimensionIndex = __instance.Gate.DimensionIndex; LG_LayerType linksToLayerType = __instance.LinksToLayerType; eLocalZoneIndex localIndex = __instance.LinkedToZoneData.LocalIndex; SecDoorIntTextOverride def = ((ZoneDefinitionManager<SecDoorIntTextOverride>)SecDoorIntTextOverrideManager.Current).GetDefinition(dimensionIndex, linksToLayerType, localIndex); LG_SecurityDoor_Locks obj = ((Il2CppObjectBase)__instance.m_locks).Cast<LG_SecurityDoor_Locks>(); Interact_Timed intOpenDoor = ((obj != null) ? obj.m_intOpenDoor : null); if ((Object)(object)intOpenDoor == (Object)null || def == null || def.GlitchMode != GlitchMode.None) { return; } __instance.m_sync.OnDoorStateChange += Action<pDoorState, bool>.op_Implicit((Action<pDoorState, bool>)delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_00ea: 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_012a: Unknown result type (might be due to invalid IL or missing references) string text = (string.IsNullOrEmpty(LocalizedText.op_Implicit(def.TextToReplace)) ? intOpenDoor.InteractionMessage : LocalizedText.op_Implicit(def.TextToReplace)); StringBuilder val = new StringBuilder(); if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(def.Prefix))) { val.Append(LocalizedText.op_Implicit(def.Prefix)).AppendLine(); } val.Append(text); if (!string.IsNullOrEmpty(LocalizedText.op_Implicit(def.Postfix))) { val.AppendLine().Append(LocalizedText.op_Implicit(def.Postfix)); } intOpenDoor.InteractionMessage = ((Object)val).ToString(); EOSLogger.Debug($"SecDoorIntTextOverride: Override IntText. {((GlobalZoneIndex)def).LocalIndex}, {((GlobalZoneIndex)def).LayerType}, {((GlobalZoneIndex)def).DimensionIndex}"); }); } } [HarmonyPatch] internal class InteractGlitch { [HarmonyPostfix] [HarmonyPatch(typeof(Interact_Timed), "OnSelectedChange")] private static void Post_Interact_Timed_OnSelectedChange(Interact_Timed __instance, bool selected) { Handle((Interact_Base)(object)__instance, selected, canInteract: true); } [HarmonyPostfix] [HarmonyPatch(typeof(Interact_MessageOnScreen), "OnSelectedChange")] private static void Post_Interact_MessageOnScreen_OnSelectedChange(Interact_MessageOnScreen __instance, bool selected) { Handle((Interact_Base)(object)__instance, selected, canInteract: false); } [HarmonyPostfix] [HarmonyPatch(typeof(LG_SecurityDoor_Locks), "Setup", new Type[] { typeof(LG_SecurityDoor) })] private static void Post_LG_SecurityDoor_Locks_Setup(LG_SecurityDoor_Locks __instance, LG_SecurityDoor door) { InteractGlitchManager.Current.RegisterDoorLocks(__instance); } private static void Handle(Interact_Base interact, bool selected, bool canInteract) { if (selected) { if (!((Object)(object)interact == (Object)null)) { switch (InteractGlitchManager.Current.GetGlitchMode(interact)) { case GlitchMode.Style1: InteractGlitchManager.Current.Enabled = true; InteractGlitchManager.Current.CanInteract = canInteract; InteractGlitchManager.Current.Mode = GlitchMode.Style1; GuiManager.InteractionLayer.InteractPromptVisible = false; break; case GlitchMode.Style2: InteractGlitchManager.Current.Enabled = true; InteractGlitchManager.Current.CanInteract = canInteract; InteractGlitchManager.Current.Mode = GlitchMode.Style2; GuiManager.InteractionLayer.InteractPromptVisible = false; break; } } } else { InteractGlitchManager.Current.Enabled = false; } } } } namespace EOSExt.SecDoor.Definition { public enum GlitchMode { None, Style1, Style2 } public class SecDoorIntTextOverride : GlobalZoneIndex { public LocalizedText Prefix { get; set; } = null; public LocalizedText Postfix { get; set; } = null; public LocalizedText TextToReplace { get; set; } = null; public GlitchMode GlitchMode { get; set; } = GlitchMode.None; } }
plugins/Inas07.EOSExt.SecuritySensor.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Agents; using AmorLib.Networking; using AmorLib.Networking.StateReplicators; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using EOSExt.SecuritySensor.Component; using EOSExt.SecuritySensor.Definition; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Utils; using GTFO.API; using GTFO.API.Extensions; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; 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("Inas07.EOSExt.SecuritySensor")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+2f74d67cecacc3e9987d12c67507269c3520f47f")] [assembly: AssemblyProduct("Inas07.EOSExt.SecuritySensor")] [assembly: AssemblyTitle("Inas07.EOSExt.SecuritySensor")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EOSExt.SecuritySensor { internal static class Assets { public static GameObject CircleSensor { get; private set; } public static GameObject MovableSensor { get; private set; } public static void Init() { CircleSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/CircleSensor.prefab"); MovableSensor = AssetAPI.GetLoadedAsset<GameObject>("Assets/SecuritySensor/MovableSensor.prefab"); } } [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.*/)] [BepInPlugin("Inas.EOSExt.SecuritySensor", "EOSExt.SecuritySensor", "1.2.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "EOSExt.SecuritySensor"; public const string VERSION = "1.2.0"; private Harmony m_Harmony; public override void Load() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown SetupManagers(); AssetAPI.OnAssetBundlesLoaded += Assets.Init; m_Harmony = new Harmony("EOSExt.SecuritySensor"); m_Harmony.PatchAll(); ClassInjector.RegisterTypeInIl2Cpp<SensorCollider>(); EOSLogger.Log("ExtraObjectiveSetup.SecuritySensor loaded."); } private void SetupManagers() { ((GenericExpeditionDefinitionManager<SensorGroupSettings>)SecuritySensorManager.Current).Init(); } } public class MovableSensor { public GameObject movableGO { get; private set; } public CP_BasicMovable movingComp { get; private set; } private GameObject graphicsGO { get { GameObject obj = movableGO; return (obj != null) ? ((Component)obj.transform.GetChild(0)).gameObject : null; } } public static MovableSensor Instantiate(SensorSettings sensorSetting) { //IL_0088: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00af: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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 (sensorSetting.MovingPosition.Count < 1) { EOSLogger.Error("SensorGroup.Instantiate: At least 1 moving position required to setup T-Sensor!"); return null; } if (EOSNetworking.AllotReplicatorID() == 0) { EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator..."); return null; } MovableSensor movableSensor = new MovableSensor(); movableSensor.movableGO = Object.Instantiate<GameObject>(Assets.MovableSensor); movableSensor.movingComp = movableSensor.movableGO.GetComponent<CP_BasicMovable>(); movableSensor.movingComp.Setup(); Vector3 element = sensorSetting.Position.ToVector3(); Vector3 val = sensorSetting.MovingPosition.First().ToVector3(); Vector3 val2 = sensorSetting.MovingPosition.Last().ToVector3(); IEnumerable<Vector3> source = sensorSetting.MovingPosition.ConvertAll((Vec3 e) => e.ToVector3()).AsEnumerable(); if (!((Vector3)(ref element)).Equals(val)) { source = source.Prepend(element); } if (!((Vector3)(ref element)).Equals(val2)) { source = source.Append(element); } movableSensor.movingComp.ScanPositions = ListExtensions.ToIl2Cpp<Vector3>(source.ToList()); movableSensor.movingComp.m_amountOfPositions = source.Count() - 1; if (sensorSetting.MovingSpeedMulti > 0f) { CP_BasicMovable obj = movableSensor.movingComp; obj.m_movementSpeed *= sensorSetting.MovingSpeedMulti; } return movableSensor; } public void StartMoving() { graphicsGO.SetActive(true); movingComp.SyncUpdate(); movingComp.StartMoving(); } public void ResumeMoving() { graphicsGO.SetActive(true); movingComp.ResumeMovement(); } public void StopMoving() { movingComp.StopMoving(); graphicsGO.SetActive(false); } public void PauseMoving() { movingComp.PauseMovement(); graphicsGO.SetActive(false); } public void Destroy() { Object.Destroy((Object)(object)movableGO); movableGO = null; movingComp = null; } private MovableSensor() { } } public enum SensorEventType { ToggleSensorGroupState = 400, ToggleAllSensorGroups } public sealed class SecuritySensorManager : GenericExpeditionDefinitionManager<SensorGroupSettings> { private List<SensorGroup> sensorGroups = new List<SensorGroup>(); internal static readonly SensorSync SyncTrigger; public static SecuritySensorManager Current { get; private set; } protected override string DEFINITION_NAME => "SecuritySensor"; public void BuildSensorGroup(SensorGroupSettings sensorGroupSettings) { int num = ((sensorGroupSettings.Index == uint.MaxValue) ? sensorGroups.Count : ((int)sensorGroupSettings.Index)); SensorGroup item = SensorGroup.Instantiate(sensorGroupSettings, num); sensorGroups.Add(item); EOSLogger.Debug($"SensorGroup_{num} built"); } private SensorGroup FindSensorGroup(int groupIndex) { return sensorGroups.Find((SensorGroup sg) => sg.SensorGroupIndex == groupIndex); } internal void TriggerSensor(int groupIndex) { SensorGroup sensorGroup = FindSensorGroup(groupIndex); if (sensorGroup == null) { EOSLogger.Error($"TriggerSensor: invalid SensorGroup index {groupIndex}"); return; } sensorGroup.Settings.EventsOnTrigger.ForEach(delegate(WardenObjectiveEventData e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, e.Trigger, true, 0f); }); EOSLogger.Warning($"TriggerSensor: SensorGroup_{groupIndex} triggered"); } private void BuildSecuritySensor() { if (base.definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { base.definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(BuildSensorGroup); } } private void Clear() { sensorGroups.ForEach(delegate(SensorGroup sg) { sg.Destroy(); }); sensorGroups.Clear(); } private void ToggleSensorGroup(WardenObjectiveEventData e) { int count = e.Count; SensorGroup sensorGroup = FindSensorGroup(count); if (sensorGroup == null) { EOSLogger.Error($"ToggleSensorGroup: invalid SensorGroup index {count}"); } else { sensorGroup.ChangeToState(e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED); } } private void ToggleAllSensorGroups(WardenObjectiveEventData e) { ActiveState state = (e.Enabled ? ActiveState.ENABLED : ActiveState.DISABLED); sensorGroups.ForEach(delegate(SensorGroup sg) { sg.ChangeToState(state); }); } private SecuritySensorManager() { LevelAPI.OnBuildStart += delegate { Clear(); BuildSecuritySensor(); }; LevelAPI.OnLevelCleanup += Clear; EventAPI.OnExpeditionStarted += delegate { sensorGroups.ForEach(delegate(SensorGroup sg) { sg.StartMovingMovables(); }); }; EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleSensorGroupState.ToString(), 400u, (Action<WardenObjectiveEventData>)ToggleSensorGroup); EOSWardenEventManager.Current.AddEventDefinition(SensorEventType.ToggleAllSensorGroups.ToString(), 401u, (Action<WardenObjectiveEventData>)ToggleAllSensorGroups); } static SecuritySensorManager() { Current = new SecuritySensorManager(); SyncTrigger = new SensorSync(); if (!((SyncedEvent<int>)SyncTrigger).IsSetup) { ((SyncedEvent<int>)SyncTrigger).Setup(); } } } public class SensorGroup { private List<GameObject> basicSensors = new List<GameObject>(); private List<MovableSensor> movableSensors = new List<MovableSensor>(); public int SensorGroupIndex { get; private set; } public SensorGroupSettings Settings { get; private set; } public StateReplicator<SensorGroupState> StateReplicator { get; private set; } public IEnumerable<GameObject> BasicSensors => basicSensors; public IEnumerable<MovableSensor> MovableSensors => movableSensors; public ActiveState State => StateReplicator?.State.status ?? ActiveState.ENABLED; public void ChangeToState(ActiveState status) { ChangeToStateUnsynced(new SensorGroupState { status = status }); EOSLogger.Debug($"ChangeState: SecuritySensorGroup_{SensorGroupIndex} changed to state {status}"); if (SNet.IsMaster) { StateReplicator?.SetState(new SensorGroupState { status = status }); } } private void OnStateChanged(SensorGroupState oldState, SensorGroupState newState, bool isRecall) { EOSLogger.Warning($"OnStateChanged: isRecall ? {isRecall}"); if (isRecall) { EOSLogger.Debug($"Recalling: SecuritySensorGroup_{SensorGroupIndex} changed to state {newState.status}"); ChangeToStateUnsynced(newState); } else if (oldState.status != newState.status) { ChangeToStateUnsynced(newState); } } private void ChangeToStateUnsynced(SensorGroupState newState) { switch (newState.status) { case ActiveState.ENABLED: basicSensors.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActive(true); }); ResumeMovingMovables(); break; case ActiveState.DISABLED: PauseMovingMovables(); basicSensors.ForEach(delegate(GameObject sensorGO) { sensorGO.SetActive(false); }); break; } } public static SensorGroup Instantiate(SensorGroupSettings sensorGroupSettings, int sensorGroupIndex) { //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_003f: 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) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_023e: 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_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) SensorGroup sensorGroup = new SensorGroup(); sensorGroup.SensorGroupIndex = sensorGroupIndex; sensorGroup.Settings = sensorGroupSettings; foreach (SensorSettings item in sensorGroupSettings.SensorGroup) { Vector3 val = item.Position.ToVector3(); if (val == Vector3.zeroVector) { continue; } GameObject val2 = null; switch (item.SensorType) { case SensorType.BASIC: val2 = Object.Instantiate<GameObject>(Assets.CircleSensor); sensorGroup.basicSensors.Add(val2); break; case SensorType.MOVABLE: { MovableSensor movableSensor = MovableSensor.Instantiate(item); if (movableSensor == null) { EOSLogger.Error("ERROR: failed to build movable sensor"); continue; } val2 = movableSensor.movableGO; sensorGroup.movableSensors.Add(movableSensor); break; } default: EOSLogger.Error($"Unsupported SensorType {item.SensorType}, skipped"); continue; } val2.transform.SetPositionAndRotation(val, Quaternion.identityQuaternion); float num = 0.16216217f; val2.transform.localScale = new Vector3(item.Radius, item.Radius, item.Radius); Transform transform = val2.transform; transform.localPosition += Vector3.up * num; SensorCollider sensorCollider = val2.AddComponent<SensorCollider>(); sensorCollider.Setup(item, sensorGroup); ((Component)val2.transform.GetChild(0).GetChild(1)).gameObject.GetComponentInChildren<Renderer>().material.SetColor("_ColorA", item.Color.ToUnityColor()); Transform child = val2.transform.GetChild(0).GetChild(2); GameObject gameObject = ((Component)child.GetChild(0)).gameObject; gameObject.transform.SetParent((Transform)null); Object.Destroy((Object)(object)gameObject); GameObject val3 = VanillaTMPPros.Instantiate(((Component)child).gameObject); TextMeshPro component = val3.GetComponent<TextMeshPro>(); if ((Object)(object)component != (Object)null) { ((TMP_Text)component).SetText(LocalizedText.op_Implicit(item.Text), true); Color32 val4 = (((TMP_Text)component).m_fontColor32 = Color32.op_Implicit(item.TextColor.ToUnityColor())); ((TMP_Text)component).m_fontColor = Color32.op_Implicit(val4); } else { EOSLogger.Error("NO TEXT!"); } val2.SetActive(true); } uint num2 = EOSNetworking.AllotReplicatorID(); if (num2 == 0) { EOSLogger.Error("SensorGroup.Instantiate: replicator ID depleted, cannot create StateReplicator..."); } else { sensorGroup.StateReplicator = StateReplicator<SensorGroupState>.Create(num2, new SensorGroupState { status = ActiveState.ENABLED }, (LifeTimeType)1, (IStateReplicatorHolder<SensorGroupState>)null); sensorGroup.StateReplicator.OnStateChanged += sensorGroup.OnStateChanged; } return sensorGroup; } 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 void Destroy() { basicSensors.ForEach((Action<GameObject>)Object.Destroy); basicSensors.Clear(); movableSensors.ForEach(delegate(MovableSensor m) { m.Destroy(); }); movableSensors.Clear(); StateReplicator = null; Settings = null; } private SensorGroup() { } } public enum ActiveState { DISABLED, ENABLED } public struct SensorGroupState { public ActiveState status; public SensorGroupState() { status = ActiveState.DISABLED; } public SensorGroupState(SensorGroupState o) { status = o.status; } public SensorGroupState(ActiveState status) { this.status = status; } } public struct MovableSensorLerp { public float lerp; public MovableSensorLerp() { lerp = 0f; } public MovableSensorLerp(MovableSensorLerp o) { lerp = o.lerp; } public MovableSensorLerp(float lerp) { this.lerp = lerp; } } internal sealed class SensorSync : SyncedEvent<int> { public override string GUID => "EOS-SensorTrigger"; protected override void Receive(int packet) { SecuritySensorManager.Current.TriggerSensor(packet); } protected override void ReceiveLocal(int packet) { ((SyncedEvent<int>)this).Receive(packet); } } } namespace EOSExt.SecuritySensor.Patches { [HarmonyPatch] internal class Debug { [HarmonyPostfix] [HarmonyPatch(typeof(LG_CollisionWorldEventTrigger), "Update")] private static void Post(LG_CollisionWorldEventTrigger __instance) { } static Debug() { } } } namespace EOSExt.SecuritySensor.Definition { public class SensorGroupSettings { public uint Index { get; set; } = uint.MaxValue; public List<SensorSettings> SensorGroup { get; set; } = new List<SensorSettings> { new SensorSettings() }; public List<WardenObjectiveEventData> EventsOnTrigger { get; set; } = new List<WardenObjectiveEventData>(); } public enum SensorType { BASIC, MOVABLE } public class SensorSettings { public Vec3 Position { get; set; } = new Vec3(); public float Radius { get; set; } = 2.3f; public EOSColor Color { get; set; } = new EOSColor { r = 99f / 106f, g = 0.1055641f, b = 0f, a = 0.2627451f }; public LocalizedText Text { get; set; } = new LocalizedText { Id = 0u, UntranslatedText = "S:_EC/uR_ITY S:/Ca_N" }; public EOSColor TextColor { get; set; } = new EOSColor { 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<Vec3> MovingPosition { get; set; } = new List<Vec3> { new Vec3() }; } } namespace EOSExt.SecuritySensor.Component { public class SensorCollider : MonoBehaviour { private float nextCheckTime = float.NaN; private SensorSettings settings; private int last_playersInSensor = 0; public static float CHECK_INTERVAL { get; } = 0.1f; private Vector3 Position => ((Component)this).gameObject.transform.position; public SensorGroup Parent { get; internal set; } internal void Setup(SensorSettings sensorSettings, SensorGroup parent) { settings = sensorSettings; Parent = parent; } private 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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 + CHECK_INTERVAL; if (Parent.State != ActiveState.ENABLED) { return; } int num = 0; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!current.Owner.IsBot && ((Agent)current).Alive) { Vector3 val = Position - ((Agent)current).Position; if (((Vector3)(ref val)).magnitude < settings.Radius) { num++; } } } if (num > last_playersInSensor) { ((SyncedEvent<int>)SecuritySensorManager.SyncTrigger).Send(Parent.SensorGroupIndex, (SNet_Player)null, (SNet_ChannelType)2); } last_playersInSensor = num; } private void OnDestroy() { Parent = null; settings = null; } } }
plugins/Inas07.LogsCollector.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using LogsCollector.Collector; using LogsCollector.Patches; using Microsoft.CodeAnalysis; using SSS.UnityFileDebug; 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("Inas07.LogsCollector")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+268adf0c434fa3f99623c8721bc33d76b471537a")] [assembly: AssemblyProduct("Inas07.LogsCollector")] [assembly: AssemblyTitle("Inas07.LogsCollector")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LogsCollector { [BepInPlugin("LogsCollector.Plugin", "LogsCollector", "1.0.0")] public class Plugin : BasePlugin { public const string PluginGuid = "LogsCollector.Plugin"; public const string PluginName = "LogsCollector"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource LogSource; internal static ConfigEntry<bool> Enabled; public override void Load() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown LogSource = ((BasePlugin)this).Log; Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Copy the GTFO session log and the BepInEx logs into BepInEx/logs/<timestamp>/ on every UnityFileDebug.WriteLogToDisk call."); if (!Enabled.Value) { LogSource.LogInfo((object)"Disabled by config, no patch applied."); return; } bool flag = default(bool); try { Harmony val = new Harmony("LogsCollector.Plugin"); val.PatchAll(typeof(WriteLogToDiskPatch)); ManualLogSource logSource = LogSource; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("LogsCollector"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded."); } logSource.LogInfo(val2); } catch (Exception ex) { ManualLogSource logSource2 = LogSource; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to apply WriteLogToDisk patch: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex); } logSource2.LogError(val3); } } } } namespace LogsCollector.Patches { [HarmonyPatch] internal static class WriteLogToDiskPatch { private static HashSet<string> _before; [HarmonyPrefix] [HarmonyPatch(typeof(UnityFileDebug), "WriteLogToDisk")] private static void Pre_WriteLogToDisk() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown try { _before = LogCopier.SnapshotGameLogs(); } catch (Exception ex) { _before = null; ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Snapshot of game logs failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } logSource.LogWarning(val); } } } [HarmonyPostfix] [HarmonyPatch(typeof(UnityFileDebug), "WriteLogToDisk")] private static void Post_WriteLogToDisk() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown HashSet<string> before = _before; _before = null; try { LogCopier.Collect(before); } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Collect failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logSource.LogError(val); } } } } } namespace LogsCollector.Collector { internal static class LogCopier { private const string GameLogPattern = "GTFO.*.txt"; private const string SettingsFileName = "GTFO_Settings.txt"; private const string LogsFolderName = "logs"; private static readonly TimeSpan FallbackWindow = TimeSpan.FromSeconds(60.0); private static readonly string[] BepInExLogFiles = new string[2] { "LogOutput.log", "ErrorLog.log" }; internal static string GameLogDirectory => Application.persistentDataPath; internal static HashSet<string> SnapshotGameLogs() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string gameLogDirectory = GameLogDirectory; if (!Directory.Exists(gameLogDirectory)) { return hashSet; } string[] files = Directory.GetFiles(gameLogDirectory, "GTFO.*.txt", SearchOption.TopDirectoryOnly); foreach (string path in files) { string fileName = Path.GetFileName(path); if (!string.Equals(fileName, "GTFO_Settings.txt", StringComparison.OrdinalIgnoreCase)) { hashSet.Add(fileName); } } return hashSet; } internal static void Collect(HashSet<string> before) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown string text = FindProducedLog(before); string root = Path.Combine(Paths.BepInExRootPath, "logs"); string text2 = EnsureUniqueDirectory(root, BuildDirectoryName(DateTimeOffset.Now)); Directory.CreateDirectory(text2); bool flag = default(bool); if (text == null) { ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { logSource.LogWarning((object)"No GTFO session log found for this call, only BepInEx logs were copied."); } } else if (TryCopyFile(text, text2)) { ManualLogSource logSource2 = Plugin.LogSource; if (logSource2 != null) { BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copied game log: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Path.GetFileName(text)); } logSource2.LogInfo(val); } } else { ManualLogSource logSource3 = Plugin.LogSource; if (logSource3 != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to copy game log: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); } logSource3.LogWarning(val2); } } string[] bepInExLogFiles = BepInExLogFiles; foreach (string text3 in bepInExLogFiles) { string text4 = Path.Combine(Paths.BepInExRootPath, text3); if (!File.Exists(text4)) { continue; } if (TryCopyFile(text4, text2)) { ManualLogSource logSource4 = Plugin.LogSource; if (logSource4 != null) { BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copied: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3); } logSource4.LogInfo(val); } continue; } ManualLogSource logSource5 = Plugin.LogSource; if (logSource5 != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to copy: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text4); } logSource5.LogWarning(val2); } } ManualLogSource logSource6 = Plugin.LogSource; if (logSource6 != null) { BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Logs collected into: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2); } logSource6.LogInfo(val); } } internal static string FindProducedLog(HashSet<string> before) { string gameLogDirectory = GameLogDirectory; if (!Directory.Exists(gameLogDirectory)) { return null; } string text = null; DateTime dateTime = DateTime.MinValue; string text2 = null; DateTime dateTime2 = DateTime.MinValue; DateTime utcNow = DateTime.UtcNow; string[] files = Directory.GetFiles(gameLogDirectory, "GTFO.*.txt", SearchOption.TopDirectoryOnly); foreach (string text3 in files) { string fileName = Path.GetFileName(text3); if (!string.Equals(fileName, "GTFO_Settings.txt", StringComparison.OrdinalIgnoreCase)) { DateTime lastWriteTimeUtc; try { lastWriteTimeUtc = File.GetLastWriteTimeUtc(text3); } catch { continue; } if ((before == null || !before.Contains(fileName)) && lastWriteTimeUtc > dateTime) { dateTime = lastWriteTimeUtc; text = text3; } if (lastWriteTimeUtc > dateTime2 && utcNow - lastWriteTimeUtc <= FallbackWindow) { dateTime2 = lastWriteTimeUtc; text2 = text3; } } } return text ?? text2; } internal static string BuildDirectoryName(DateTimeOffset now) { string text = now.ToString("yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture); string text2 = now.ToString("zzz", CultureInfo.InvariantCulture).Replace(':', '-'); return text + "_" + text2; } internal static string EnsureUniqueDirectory(string root, string name) { string text = Path.Combine(root, name); if (!Directory.Exists(text)) { return text; } for (int i = 2; i < 1000; i++) { text = Path.Combine(root, $"{name}_{i}"); if (!Directory.Exists(text)) { return text; } } return Path.Combine(root, $"{name}_{Guid.NewGuid():N}"); } internal static bool TryCopyFile(string source, string targetDirectory) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown try { if (!File.Exists(source)) { return false; } string path = Path.Combine(targetDirectory, Path.GetFileName(source)); using FileStream fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); using FileStream fileStream2 = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None); fileStream.CopyTo(fileStream2); fileStream2.Flush(); return true; } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(16, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Copy '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(source); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } logSource.LogWarning(val); } return false; } } } }
plugins/Inas07.ThermalSights.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json.Serialization; using BepInEx; using BepInEx.Unity.IL2CPP; using ChainedPuzzles; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.Expedition.Gears; using ExtraObjectiveSetup.JSON; using ExtraObjectiveSetup.Utils; using FirstPersonItem; using GTFO.API; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Microsoft.CodeAnalysis; using ThermalSights.Definition; 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("Inas07.ThermalSights")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1bf61a852f4d3bcf32c33235fecacda1aaf802a3")] [assembly: AssemblyProduct("Inas07.ThermalSights")] [assembly: AssemblyTitle("Inas07.ThermalSights")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ThermalSights { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.ThermalSights", "ThermalSights", "1.1.0")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "ThermalSights"; public const string VERSION = "1.1.0"; private Harmony m_Harmony; public override void Load() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown SetupManagers(); m_Harmony = new Harmony("ThermalSights"); m_Harmony.PatchAll(); EOSLogger.Log("ThermalSights loaded."); } private void SetupManagers() { } } public class TSAManager : GenericDefinitionManager<TSADefinition> { public class PuzzleVisualWrapper { public GameObject GO { get; set; } public Renderer Renderer { get; set; } public float Intensity { get; set; } public float BehindWallIntensity { get; set; } public void SetIntensity(float t) { if (GO.active) { if (Intensity > 0f) { Renderer.material.SetFloat("_Intensity", Intensity * t); } if (BehindWallIntensity > 0f) { Renderer.material.SetFloat("_BehindWallIntensity", BehindWallIntensity * t); } } } } private const bool OUTPUT_THERMAL_SHADER_SETTINGS_ON_WIELD = false; private List<PuzzleVisualWrapper> PuzzleVisuals { get; } = new List<PuzzleVisualWrapper>(); public static TSAManager Current { get; } protected override string DEFINITION_NAME => "ThermalSight"; private Dictionary<uint, Renderer[]> InLevelGearThermals { get; } = new Dictionary<uint, Renderer[]>(); private HashSet<uint> ModifiedInLevelGearThermals { get; } = new HashSet<uint>(); private HashSet<uint> ThermalOfflineGears { get; } = new HashSet<uint>(); public uint CurrentGearPID { get; private set; } = 0u; public void RegisterPuzzleVisual(CP_Bioscan_Core core) { Il2CppArrayBase<Renderer> componentsInChildren = ((Component)core).gameObject.GetComponentsInChildren<Renderer>(true); if (componentsInChildren == null) { return; } List<Renderer> list = ((IEnumerable<Renderer>)componentsInChildren).Where((Renderer comp) => ((Object)((Component)comp).gameObject).name.Equals("Zone")).ToList(); foreach (Renderer item2 in list) { GameObject gameObject = ((Component)item2).gameObject; float intensity = item2.material.GetFloat("_Intensity"); float behindWallIntensity = item2.material.GetFloat("_BehindWallIntensity"); PuzzleVisualWrapper item = new PuzzleVisualWrapper { GO = gameObject, Renderer = item2, Intensity = intensity, BehindWallIntensity = behindWallIntensity }; PuzzleVisuals.Add(item); } } public void RegisterPuzzleVisual(PuzzleVisualWrapper wrapper) { PuzzleVisuals.Add(wrapper); } public void SetPuzzleVisualsIntensity(float t) { PuzzleVisuals.ForEach(delegate(PuzzleVisualWrapper v) { v.SetIntensity(t); }); } private void CleanupPuzzleVisuals() { PuzzleVisuals.Clear(); } protected override void FileChanged(LiveEditEventArgs e) { base.FileChanged(e); InitThermalOfflineGears(); CleanupInLevelGearThermals(keepCurrentGear: true); TrySetThermalSightRenderer(CurrentGearPID); } public override void Init() { InitThermalOfflineGears(); } private void InitThermalOfflineGears() { ThermalOfflineGears.Clear(); foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks()) { if (((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).internalEnabled && ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).name.ToLowerInvariant().EndsWith("_t")) { ThermalOfflineGears.Add(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID); } } EOSLogger.Debug($"Found OfflineGear with thermal sight, count: {ThermalOfflineGears.Count}"); } private bool TryGetInLevelGearThermalRenderersFromItem(ItemEquippable item, uint gearPID, out Renderer[] renderers) { //IL_0084: 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) renderers = null; if (item.GearIDRange == null) { return false; } if (gearPID == 0) { gearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange); } if (gearPID == 0 || !IsGearWithThermal(gearPID)) { return false; } bool flag = false; if (!InLevelGearThermals.ContainsKey(gearPID)) { flag = true; } else { try { Vector3 position = ((Component)InLevelGearThermals[gearPID][0]).gameObject.transform.position; flag = false; } catch { ModifiedInLevelGearThermals.Remove(gearPID); flag = true; } } if (flag) { renderers = (from x in ((IEnumerable<Renderer>)((Component)item).GetComponentsInChildren<Renderer>(true))?.Where((Renderer x) => (Object)(object)x.sharedMaterial != (Object)null && (Object)(object)x.sharedMaterial.shader != (Object)null) where ((Object)x.sharedMaterial.shader).name.ToLower().Contains("Thermal".ToLower()) select x).ToArray() ?? null; if (renderers != null) { if (renderers.Length != 1) { EOSLogger.Warning(((Item)item).PublicName + " contains more than 1 thermal renderers!"); } InLevelGearThermals[gearPID] = renderers; return true; } EOSLogger.Debug(((Item)item).PublicName + ": thermal renderer not found"); return false; } renderers = InLevelGearThermals[gearPID]; return true; } internal bool TrySetThermalSightRenderer(uint gearPID = 0u) { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_014c: 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_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) if (gearPID == 0) { gearPID = CurrentGearPID; } if (!IsGearWithThermal(gearPID)) { return false; } if (ModifiedInLevelGearThermals.Contains(gearPID)) { return true; } if (base.definitions.TryGetValue(gearPID, out var value) && InLevelGearThermals.TryGetValue(gearPID, out var value2)) { 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(EOSColor)) { EOSColor val2 = (EOSColor)propertyInfo.GetValue(shader); val.material.SetVector(text, Color.op_Implicit(val2.ToUnityColor())); } else if (type == typeof(bool)) { bool flag = (bool)propertyInfo.GetValue(shader); val.material.SetFloat(text, flag ? 1f : 0f); } else if (type == typeof(Vec4)) { Vec4 val3 = (Vec4)propertyInfo.GetValue(shader); val.material.SetVector(text, val3.ToVector4()); } } } ModifiedInLevelGearThermals.Add(gearPID); return true; } return false; } internal void OnPlayerItemWielded(FirstPersonItemHolder fpsItemHolder, ItemEquippable item) { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0155: 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_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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01eb: 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_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown if (item.GearIDRange == null) { CurrentGearPID = 0u; return; } CurrentGearPID = ExpeditionGearManager.GetOfflineGearPID(item.GearIDRange); TryGetInLevelGearThermalRenderersFromItem(item, CurrentGearPID, out var _); if (TrySetThermalSightRenderer(CurrentGearPID) || 0 == 0 || !InLevelGearThermals.TryGetValue(CurrentGearPID, out var value)) { return; } Renderer[] array = value; foreach (Renderer val in array) { TSShader tSShader = new TSShader(); PropertyInfo[] properties = tSShader.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; string text = "_" + propertyInfo.Name; if (type == typeof(float)) { propertyInfo.SetValue(tSShader, val.material.GetFloat(text)); } else if (type == typeof(EOSColor)) { Vector4 vector = val.material.GetVector(text); propertyInfo.SetValue(tSShader, (object?)new EOSColor { r = vector.x, g = vector.y, b = vector.z, a = vector.w }); } else if (type == typeof(bool)) { propertyInfo.SetValue(tSShader, val.material.GetFloat(text) == 1f); } else if (type == typeof(Vec4)) { Vector4 vector2 = val.material.GetVector(text); propertyInfo.SetValue(tSShader, (object?)new Vec4 { x = vector2.x, y = vector2.y, z = vector2.z, w = vector2.w }); } } EOSLogger.Log($"GearPID: {CurrentGearPID}, shader setting:\n{EOSJson.Serialize<TSShader>(tSShader)}"); } } public bool IsGearWithThermal(uint gearPID) { return ThermalOfflineGears.Contains(gearPID); } private void CleanupInLevelGearThermals(bool keepCurrentGear = false) { if (!keepCurrentGear || !InLevelGearThermals.ContainsKey(CurrentGearPID)) { InLevelGearThermals.Clear(); } else { Renderer[] value = InLevelGearThermals[CurrentGearPID]; InLevelGearThermals.Clear(); InLevelGearThermals[CurrentGearPID] = value; } ModifiedInLevelGearThermals.Clear(); } internal void SetCurrentThermalSightSettings(float t) { if (InLevelGearThermals.TryGetValue(CurrentGearPID, out var value) && base.definitions.TryGetValue(CurrentGearPID, out var value2)) { Renderer[] array = value; foreach (Renderer val in array) { float zoom = value2.Definition.Shader.Zoom; float offAimPixelZoom = value2.Definition.OffAimPixelZoom; float num = Mathf.Lerp(zoom, offAimPixelZoom, t); val.material.SetFloat("_Zoom", num); } } } private void Clear() { CurrentGearPID = 0u; CleanupInLevelGearThermals(); CleanupPuzzleVisuals(); } private TSAManager() { LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } static TSAManager() { Current = new TSAManager(); } } } namespace ThermalSights.Patches { internal static class CP_Bioscan_Core_Setup { [HarmonyPostfix] [HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")] private static void Post_CaptureBioscanVisual(CP_Bioscan_Core __instance) { TSAManager.Current.RegisterPuzzleVisual(__instance); } } [HarmonyPatch] internal static class FPIS_Aim_Update { public static event Action<FPIS_Aim, float> OnAimUpdate; [HarmonyPostfix] [HarmonyPatch(typeof(FPIS_Aim), "Update")] private static void Post_Aim_Update(FPIS_Aim __instance) { if (!((Object)(object)((FPItemState)__instance).Holder.WieldedItem == (Object)null)) { float num = 1f - FirstPersonItemHolder.m_transitionDelta; if (!TSAManager.Current.IsGearWithThermal(TSAManager.Current.CurrentGearPID)) { num = Math.Max(0.05f, num); } else { TSAManager.Current.SetCurrentThermalSightSettings(num); } TSAManager.Current.SetPuzzleVisualsIntensity(num); FPIS_Aim_Update.OnAimUpdate?.Invoke(__instance, num); } } } [HarmonyPatch] internal static class FirstPersonItemHolder_SetWieldedItem { public static event Action<FirstPersonItemHolder, ItemEquippable> OnItemWielded; [HarmonyPostfix] [HarmonyPatch(typeof(FirstPersonItemHolder), "SetWieldedItem")] private static void Post_SetWieldedItem(FirstPersonItemHolder __instance, ItemEquippable item) { TSAManager.Current.OnPlayerItemWielded(__instance, item); TSAManager.Current.SetPuzzleVisualsIntensity(1f); TSAManager.Current.SetCurrentThermalSightSettings(1f); FirstPersonItemHolder_SetWieldedItem.OnItemWielded?.Invoke(__instance, item); } } } namespace ThermalSights.Definition { 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 EOSColor ReticuleColorA { get; set; } = new EOSColor { r = 1f, g = 1f, b = 1f, a = 1f }; public EOSColor ReticuleColorB { get; set; } = new EOSColor { r = 1f, g = 1f, b = 1f, a = 1f }; public EOSColor ReticuleColorC { get; set; } = new EOSColor { 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; } }