using System; using System.Buffers.Binary; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using AIGraph; using Agents; using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.BounceFeatures.DeathLink; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.MessageLog.Parts; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BoosterImplants; using CellMenu; using ChainedPuzzles; using Clonesoft.Json; using Clonesoft.Json.Converters; using Clonesoft.Json.Serialization; using DropServer.BoosterImplants; using Enemies; using GameData; using Gear; using Globals; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Threading; using Il2CppSystem.Threading.Tasks; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using Player; using ReTFO.Archipelago.Features; using ReTFO.Archipelago.Features.EventHandlers; using ReTFO.Archipelago.Features.FloatingItems; using ReTFO.Archipelago.Features.ObjectiveHandlers; using ReTFO.Archipelago.Features.Pickups; using ReTFO.Archipelago.Features.Terminals; using ReTFO.Archipelago.FeaturesAPI; using ReTFO.Archipelago.ModdedInstanceData; using ReTFO.Archipelago.ModdedInstanceData.Model; using ReTFO.Archipelago.ModdedInstanceData.Processors; using ReTFO.Archipelago.Patches; using ReTFO.Archipelago.Utilities; using SNetwork; using TMPro; using TheArchive; using TheArchive.Core; using TheArchive.Core.Attributes; using TheArchive.Core.Attributes.Feature; using TheArchive.Core.Attributes.Feature.Members; using TheArchive.Core.Attributes.Feature.Patches; using TheArchive.Core.Attributes.Feature.Settings; using TheArchive.Core.FeaturesAPI; using TheArchive.Core.FeaturesAPI.Components; using TheArchive.Core.FeaturesAPI.Settings; using TheArchive.Core.Localization; using TheArchive.Features.Dev; using TheArchive.Interfaces; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Archipelago")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+96f81b2ca47a13e5e387023f31a849bd4d47dc50")] [assembly: AssemblyProduct("Archipelago")] [assembly: AssemblyTitle("Archipelago")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object? value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator { object IEnumerator.Current => _item; T IEnumerator.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => 1; T IReadOnlyList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection.Count => 1; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return EqualityComparer.Default.Equals(_item, (T)value); } int IList.IndexOf(object? value) { if (!EqualityComparer.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return EqualityComparer.Default.Equals(_item, item); } void ICollection.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { if (!EqualityComparer.Default.Equals(_item, item)) { return -1; } return 0; } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { private readonly string k__BackingField; public string Name => k__BackingField; public ExtensionMarkerAttribute(string name) { k__BackingField = name; } } } namespace ReTFO.Archipelago { [ArchiveModule("RoboRyGuy.BetaArchipelago", "BetaArchipelago", "0.0.4")] public class ArchipelagoArchiveModule : IArchiveModule { private IArchiveLogger? m_logger; public ILocalizationService LocalizationService { get; set; } public IArchiveLogger Logger { get { return m_logger ?? throw new NullReferenceException("Module logger was not initalized!"); } set { m_logger = value; } } public void Init() { if (!Plugin.TryGet(out Plugin plugin)) { Logger.Error("Failed to find Plugin while loading Archipelago Archive Module!"); } else { plugin.ArchiveModule = this; } } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] internal class InjectToIl2Cpp : Attribute { public Type[] InterfaceTypes; public InjectToIl2Cpp() { InterfaceTypes = Array.Empty(); } public InjectToIl2Cpp(Type type) { InterfaceTypes = new Type[1] { type }; } public InjectToIl2Cpp(Type[] types) { InterfaceTypes = types; } } [BepInPlugin("RoboRyGuy.BetaArchipelago", "BetaArchipelago", "0.0.4")] [BepInProcess("GTFO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { public const string Name = "BetaArchipelago"; public const string Author = "RoboRyGuy"; public const string GUID = "RoboRyGuy.BetaArchipelago"; public const string Version = "0.0.4"; private static Plugin? _plugin; protected Harmony harmony = new Harmony("RoboRyGuy.BetaArchipelago"); private ArchipelagoArchiveModule? m_archiveModule; private MidManager m_midManager = new MidManager(); public ArchipelagoArchiveModule ArchiveModule { get { return m_archiveModule ?? (m_archiveModule = ArchiveMod.Modules.OfType().First()); } internal set { m_archiveModule = value; } } public IArchiveLogger Logger => ArchiveModule.Logger; public StateTracker? StateTracker { get; internal set; } public MidManager MidManager { get { return m_midManager; } protected set { m_midManager = value; } } public event Action? LateSetup; public static Plugin Get() { return TryGet() ?? throw new NullReferenceException("Tried to retrieve BetaArchipelago, but it was not loaded!"); } public static Plugin? TryGet() { return _plugin ?? (_plugin = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.FirstOrDefault((KeyValuePair p) => p.Key == "RoboRyGuy.BetaArchipelago").Value.Instance as Plugin); } public static bool TryGet([NotNullWhen(true)] out Plugin? plugin) { plugin = TryGet(); return plugin != null; } public override void Load() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown _plugin = this; harmony.PatchAll(((object)this).GetType()); Type[] types = Assembly.GetExecutingAssembly().GetTypes(); InjectRecursive(types); PatchRecursive(types); AddProcessors(MidManager); ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("RoboRyGuy.BetaArchipelago"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!"); } log.LogInfo(val); } public override bool Unload() { harmony.UnpatchSelf(); return true; } private void InjectRecursive(Type[] types) { //IL_0026: 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_003e: Expected O, but got Unknown foreach (Type type in types) { InjectToIl2Cpp customAttribute = type.GetCustomAttribute(); if (customAttribute != null) { if (type.IsAssignableTo(typeof(Il2CppObjectBase))) { RegisterTypeOptions val = new RegisterTypeOptions(); val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(customAttribute.InterfaceTypes)); RegisterTypeOptions val2 = val; ClassInjector.RegisterTypeInIl2Cpp(type, val2); } InjectRecursive(type.GetNestedTypes(AccessTools.all)); } } } private void PatchRecursive(Type[] types) { foreach (Type type in types) { if (((MemberInfo)type).GetCustomAttribute() != null) { harmony.PatchAll(type); PatchRecursive(type.GetNestedTypes(AccessTools.all)); } } } public static void AddProcessors(MidManager midManager) { Expedition.Processor processor = new Expedition.Processor().SubscribedTo(midManager.GetProcessor()); midManager.RegisterProcessor(processor); Layer.Processor processor2 = new Layer.Processor().SubscribedTo(processor); midManager.RegisterProcessor(processor2); Zone.Processor processor3 = new Zone.Processor().SubscribedTo(processor2); midManager.RegisterProcessor(processor3); Terminal.Processor processor4 = new Terminal.Processor().SubscribedTo(processor3); midManager.RegisterProcessor(processor4); Objective.Processor processor5 = new Objective.Processor().SubscribedTo(processor2); midManager.RegisterProcessor(processor5); Event.Processor processor6 = new Event.Processor(); midManager.RegisterProcessor(processor6); } internal void InvokeLateSetup(SNet_Replicator replicator) { this.LateSetup?.Invoke(replicator); } [HarmonyPatch(typeof(SNet_Replication), "RecallBytes")] [HarmonyPrefix] public static void PreRecallBytes(SNet_Replication __instance, Il2CppStructArray bytes, uint size) { } } } namespace ReTFO.Archipelago.Utilities { public class AsyncItemSpawnWrapper { public ISyncedItem? Item { get; private set; } private event Action? OnItemSpawned; public void AddSpawnCallback(Action action) { OnItemSpawned += action; if (Item != null) { this.OnItemSpawned(Item); } } public void QueueDespawn() { AddSpawnCallback(Despawn); static void Despawn(ISyncedItem item) { ((Il2CppObjectBase)item).Cast().ReplicationWrapper.Replicator.Despawn(); } } public void OnSpawn(ISyncedItem item, PlayerAgent _) { Item = item; this.OnItemSpawned?.Invoke(item); } } public sealed class IdConverter : JsonConverter { public override bool CanRead => false; public override bool CanWrite => true; public override bool CanConvert(Type objectType) { if (objectType.IsAssignableTo(typeof(IId))) { return true; } Type[] interfaces = objectType.GetInterfaces(); foreach (Type type in interfaces) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { Type type2 = type.GetGenericArguments()[0]; if (type2.IsAssignableTo(typeof(IId))) { return true; } } } return false; } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (value is IId id) { serializer.Serialize(writer, (object)id.AsId); return; } if (value is IEnumerable source) { List list = (from IId i in source select i.AsId).ToList(); serializer.Serialize(writer, (object)list); return; } throw new JsonException("IdConverter cannot convert type " + value?.GetType().FullName); } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { throw new NotImplementedException("This converter cannot read."); } } public interface IId { long AsId { get; init; } } public interface IIndex { int AsIndex { get; init; } } public interface IKeyed where T : IComparable, IEquatable { T Key { get; } } [InjectToIl2Cpp] public class Il2CppAction : Object { public Action? WrappedAction; public Il2CppAction(Action action) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); WrappedAction = action; } public Il2CppAction(IntPtr pointer) : base(pointer) { } public void Action() { if (WrappedAction != null) { WrappedAction(); } } public static implicit operator Action(Il2CppAction self) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)self).ObjectClass, false, "Action", typeof(void).FullName, Array.Empty()); return new Action((Object)(object)self, il2CppMethod); } } [InjectToIl2Cpp] public class Il2CppAction_int : Object { public Action? WrappedAction; public Il2CppAction_int(Action action) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); WrappedAction = action; } public Il2CppAction_int(IntPtr pointer) : base(pointer) { } public void Action(int value) { if (WrappedAction != null) { WrappedAction(value); } } public static implicit operator Action(Il2CppAction_int self) { IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)self).ObjectClass, false, "Action", typeof(void).FullName, new string[1] { typeof(int).FullName }); return new Action((Object)(object)self, il2CppMethod); } } [InjectToIl2Cpp(typeof(IEnumerable))] public class Il2CppEnumerable : Object { private IEnumerable? wrappedEnumerable; public Il2CppEnumerable(IntPtr ptr) : base(ptr) { } public Il2CppEnumerable(IEnumerable enumerable) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); wrappedEnumerable = enumerable; } public IEnumerator GetEnumerator() { IEnumerator enumerator = wrappedEnumerable?.GetEnumerator() ?? Enumerable.Empty().GetEnumerator(); IEnumerator val = (IEnumerator)((enumerator is IEnumerator) ? enumerator : null); if (val != null) { return val; } return new Il2CppEnumerator(enumerator); } public static implicit operator IEnumerable(Il2CppEnumerable enumerable) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown return new IEnumerable(((Il2CppObjectBase)enumerable).Pointer); } } [InjectToIl2Cpp(typeof(IEnumerator))] public class Il2CppEnumerator : Object { private IEnumerator? wrappedEnumerator; public Object Current { get { object obj = wrappedEnumerator?.Current; return (Object)((obj is Object) ? obj : null); } } public Il2CppEnumerator(IntPtr ptr) : base(ptr) { } public Il2CppEnumerator(IEnumerator enumerator) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); wrappedEnumerator = enumerator; } public bool MoveNext() { return wrappedEnumerator?.MoveNext() ?? false; } public void Reset() { wrappedEnumerator?.Reset(); } public static implicit operator IEnumerator(Il2CppEnumerator enumerable) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown return new IEnumerator(((Il2CppObjectBase)enumerable).Pointer); } } [InjectToIl2Cpp] public class Il2CppFunc_string : Object { public Func? WrappedFunc; public Il2CppFunc_string(Func action) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); WrappedFunc = action; } public Il2CppFunc_string(IntPtr pointer) : base(pointer) { } public string Func() { if (WrappedFunc != null) { return WrappedFunc(); } return null; } public static implicit operator Func(Il2CppFunc_string self) { IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)self).ObjectClass, false, "Func", typeof(string).FullName, Array.Empty()); return new Func((Object)(object)self, il2CppMethod); } } public static class Il2CppListIter { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable where T : notnull { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private List source; public List <>3__source; private Enumerator <>7__wrap1; T IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; if (source == null) { goto IL_0069; } <>7__wrap1 = source.GetEnumerator(); } if (<>7__wrap1.MoveNext()) { T current = <>7__wrap1.Current; <>2__current = current; <>1__state = 1; return true; } <>7__wrap1 = null; goto IL_0069; IL_0069: return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.source = <>3__source; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0<>))] public static IEnumerable Iter(this List? source) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__source = source }; } public static bool Any(this List? source) { return source.Iter().Any(); } public static bool Any(this List source, Func predicate) { return source.Iter().Any(predicate); } public static T First(this List source) { return source.Iter().First(); } public static T First(this List source, Func predicate) { return source.Iter().First(predicate); } public static T? FirstOrDefault(this List source, Func predicate) { return source.Iter().FirstOrDefault(predicate); } public static T? FirstOrDefault(this List source) { return source.Iter().FirstOrDefault(); } public static IEnumerable Select(this List source, Func func) { return source.Iter().Select(func); } public static IEnumerable SelectMany(this List source, Func> func) { return source.Iter().SelectMany(func); } public static IEnumerable Skip(this List source, int count) { return source.Iter().Skip(count); } public static T[] ToArray(this List source) { return source.Iter().ToArray(); } public static List ToList(this List source) { return source.Iter().ToList(); } public static IEnumerable Where(this List source, Func predicate) { return source.Iter().Where(predicate); } } public static class Il2CppQueueIter { public static IEnumerable Iter(this Queue queue) { Queue queue2 = queue; return from i in Enumerable.Range(queue2._head, queue2._size) select queue2._array[i]; } public static T FromEnd(this Queue queue, int indexFromEnd = 0) { return queue._array[queue._head + queue._size - 1 - indexFromEnd]; } } public sealed class InlineConverter : JsonConverter { public override bool CanRead => false; public override bool CanWrite => true; public Type[] TargetTypes { get; set; } public Type[] InlinedTypes { get; set; } public InlineConverter(Type[] targetTypes, Type[] inlinedTypes) { TargetTypes = targetTypes; InlinedTypes = inlinedTypes; } public override bool CanConvert(Type objectType) { Type objectType2 = objectType; if (!TargetTypes.Any((Type t) => t.IsAssignableFrom(objectType2))) { return InlinedTypes.Any((Type t) => t.IsAssignableFrom(objectType2)); } return true; } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown object value2 = value; bool flag = (int)writer.WriteState == 2; if (value2 == null) { if (!flag) { writer.WriteNull(); } return; } bool flag2 = TargetTypes.Any((Type t) => t.IsAssignableFrom(value2.GetType())); JsonObjectContract val = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value2.GetType()); if (!flag) { writer.WriteStartObject(); } try { foreach (JsonProperty property in (Collection)(object)val.Properties) { if (!property.Ignored && property.Readable) { if (!flag2 || !InlinedTypes.Any((Type t) => t.IsAssignableFrom(property.PropertyType))) { writer.WritePropertyName(property.PropertyName); } serializer.Serialize(writer, property.ValueProvider.GetValue(value2)); } } } finally { if (!flag) { writer.WriteEndObject(); } } } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { throw new NotSupportedException("This converter cannot read."); } } public interface INullable { bool IsNull { get; } } public static class LinqUtils { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private int count; public int <>3__count; private IEnumerable source; public IEnumerable <>3__source; private IReadOnlyList 5__2; private List 5__3; private IEnumerator <>7__wrap3; T IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; } 5__2 = null; 5__3 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (count < 0) { throw new ArgumentException("Count cannot be negative"); } if (count == 0) { return false; } 5__2 = source as IReadOnlyList; if (5__2 == null) { 5__3 = new List(); <>7__wrap3 = source.GetEnumerator(); <>1__state = -3; goto IL_00d4; } goto IL_0160; case 1: <>1__state = -3; if (--count != 0) { goto IL_00d4; } goto IL_00e1; case 2: { <>1__state = -4; goto IL_0146; } IL_00d4: if (<>7__wrap3.MoveNext()) { T current = <>7__wrap3.Current; 5__3.Add(current); <>2__current = current; <>1__state = 1; return true; } goto IL_00e1; IL_00e1: <>m__Finally1(); <>7__wrap3 = null; 5__2 = 5__3; 5__3 = null; goto IL_0160; IL_0160: if (count-- > 0) { <>7__wrap3 = 5__2.GetEnumerator(); <>1__state = -4; goto IL_0146; } return false; IL_0146: if (<>7__wrap3.MoveNext()) { T current2 = <>7__wrap3.Current; <>2__current = current2; <>1__state = 2; return true; } <>m__Finally2(); <>7__wrap3 = null; goto IL_0160; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.source = <>3__source; d__.count = <>3__count; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0<>))] public static IEnumerable TakeLooped(this IEnumerable source, int count) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__source = source, <>3__count = count }; } } public sealed class ListConverter : JsonConverter { private class ThisWriter : TextWriter { private JsonWriter writer; public override Encoding Encoding => System.Text.Encoding.Default; public ThisWriter(JsonWriter source) { writer = source; } public override void Write(char value) { writer.WriteRaw(new string(value, 1)); } public override void Write(string? value) { writer.WriteRaw(value); } } public override bool CanRead => false; public override bool CanWrite => true; public int MaxPerLine { get; set; } public ListConverter(int maxPerLine = 20) { MaxPerLine = maxPerLine; } public override bool CanConvert(Type objectType) { return typeof(IEnumerable).IsAssignableFrom(objectType); } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (!(value is IEnumerable source)) { throw new ArgumentException("Expected value to be of type " + typeof(List).FullName + ".", "value"); } if ((int)writer.Formatting != 1) { throw new NotSupportedException("ListConverter was either used on a nested conerted list or during an unformatted serialization. Neither are supported!"); } List list = source.Chunk(MaxPerLine).ToList(); ThisWriter thisWriter = new ThisWriter(writer); if (list.Count == 0) { writer.WriteStartArray(); writer.WriteEndArray(); return; } if (list.Count == 1) { writer.WriteStartArray(); writer.WriteRaw(" "); writer.Formatting = (Formatting)0; serializer.Serialize((TextWriter)thisWriter, (object)list.First().First()); foreach (T item in list.First().Skip(1)) { writer.WriteRaw(", "); serializer.Serialize((TextWriter)thisWriter, (object)item); } writer.WriteEndArray(); writer.Formatting = (Formatting)1; return; } writer.WriteStartArray(); foreach (T[] item2 in list) { serializer.Serialize(writer, (object)item2.First()); writer.Formatting = (Formatting)0; foreach (T item3 in item2.Skip(1)) { writer.WriteRaw(", "); serializer.Serialize((TextWriter)thisWriter, (object)item3); } writer.Formatting = (Formatting)1; } writer.WriteEndArray(); } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { throw new NotImplementedException("This converter cannot read."); } } public class ReadOnlyListDict : IReadOnlyDictionary, IEnumerable>, IEnumerable, IReadOnlyCollection> where I : IIndex, new() { private readonly IReadOnlyList m_list; public T this[I key] => m_list[key.AsIndex]; public IEnumerable Keys => from i in Enumerable.Range(0, m_list.Count) select new I { AsIndex = i }; public IEnumerable Values => m_list; public int Count => m_list.Count; public bool IsReadOnly => true; public ReadOnlyListDict(IReadOnlyList source) { m_list = source; } public bool ContainsKey(I key) { if (key.AsIndex >= 0) { return key.AsIndex < m_list.Count; } return false; } public IEnumerator> GetEnumerator() { return m_list.Select((T v, int i) => new KeyValuePair(new I { AsIndex = i }, v)).GetEnumerator(); } public bool TryGetValue(I key, [MaybeNullWhen(false)] out T value) { if (!ContainsKey(key)) { value = default(T); return false; } value = m_list[key.AsIndex]; return true; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public static class SerializationHelpers { public struct Spannable { public T[] Values { get; init; } public int Start { get; init; } public int Length { get; init; } public Spannable(T[] values, int start, int length) { Values = values; Start = start; Length = length; } public Span AsSpan() { return new Span(Values, Start, Length); } } public static int CalcLengthSize(int value) { if (value != 0) { return Calc7BitEncodedSize(value); } return 1; } public static void WriteLength(Il2CppStructArray bytes, ref int index, int value) { Write7BitEncodedLong(bytes, ref index, value); } public static int ReadLength(Il2CppStructArray bytes, ref int index) { return checked((int)Read7BitEncodedLong(bytes, ref index)); } public static int Calc7BitEncodedSize(long value) { return Calc7BitEncodedSize((ulong)value); } public static int Calc7BitEncodedSize(ulong value) { if ((value & 0xFF00000000000000uL) != 0L) { return 9; } if ((value & 0xFE000000000000L) != 0L) { return 8; } if ((value & 0x1FC0000000000L) != 0L) { return 7; } if ((value & 0x3F800000000L) != 0L) { return 6; } if ((value & 0x7F0000000L) != 0L) { return 5; } if ((value & 0xFE00000) != 0L) { return 4; } if ((value & 0x1FC000) != 0L) { return 3; } if ((value & 0x3F80) != 0L) { return 2; } return 1; } public static int Calc7BitEncodedArraySize(ICollection values) { return Calc7BitEncodedArraySize(values.Cast(), values.Count); } public static int Calc7BitEncodedArraySize(ICollection values) { return Calc7BitEncodedArraySize(values, values.Count); } public static int Calc7BitEncodedArraySize(IEnumerable values, int count) { return Calc7BitEncodedArraySize(values.Cast(), count); } public static int Calc7BitEncodedArraySize(IEnumerable values, int count) { return Calc7BitEncodedSize(count) + values.Sum((ulong i) => Calc7BitEncodedSize(i)); } public static int Calc7BitEncodedMultiArraySize(ICollection> values) { return Calc7BitEncodedMultiArraySize(values.Cast>(), values.Count, values.Sum((ICollection arr) => arr.Count)); } public static int Calc7BitEncodedMultiArraySize(ICollection> values) { return Calc7BitEncodedMultiArraySize(values, values.Count, values.Sum((ICollection arr) => arr.Count)); } public static int Calc7BitEncodedMultiArraySize(IEnumerable> values, int arrCount, int valueCount) { return Calc7BitEncodedMultiArraySize(values.Cast>(), arrCount, valueCount); } public static int Calc7BitEncodedMultiArraySize(IEnumerable> values, int arrCount, int valueCount) { arrCount = ((arrCount != 0) ? (arrCount - 1) : 0); return CalcLengthSize(valueCount + arrCount) + arrCount + values.Sum((IEnumerable arr) => arr.Sum((ulong i) => Calc7BitEncodedSize(i))); } public static void Write7BitEncodedLong(Il2CppStructArray bytes, ref int index, long value) { Write7BitEncodedLong(bytes, ref index, (ulong)value); } public static void Write7BitEncodedLong(Il2CppStructArray bytes, ref int index, ulong value) { for (int i = 0; i < 9; i++) { ((Il2CppArrayBase)(object)bytes)[index++] = (byte)((value & 0x7F) | 0x80); value >>= 7; if (value == 0L) { break; } } if (value == 0L) { int num = index - 1; int num2 = index - 1; byte b2 = (((Il2CppArrayBase)(object)bytes)[num2] = (byte)(((Il2CppArrayBase)(object)bytes)[num2] & 0x7Fu)); ((Il2CppArrayBase)(object)bytes)[num] = b2; } } public static long Read7BitEncodedLong(Il2CppStructArray bytes, ref int index) { return (long)Read7BitEncodedULong(bytes, ref index); } public static ulong Read7BitEncodedULong(Il2CppStructArray bytes, ref int index) { ulong num = 0uL; for (int i = 0; i < 56; i += 7) { byte b = ((Il2CppArrayBase)(object)bytes)[index++]; num |= (ulong)((long)(b & 0x7F) << i); if ((0x80 & b) == 0) { return num; } } return num | ((ulong)((Il2CppArrayBase)(object)bytes)[index++] << 56); } public static void Write7BitEncodedArray(Il2CppStructArray bytes, ref int index, ICollection values) { Write7BitEncodedArray(bytes, ref index, values, values.Count); } public static void Write7BitEncodedArray(Il2CppStructArray bytes, ref int index, ICollection values) { Write7BitEncodedArray(bytes, ref index, values, values.Count); } public static void Write7BitEncodedArray(Il2CppStructArray bytes, ref int index, IEnumerable values, int count) { Write7BitEncodedArray(bytes, ref index, values.Cast(), count); } public unsafe static void Write7BitEncodedArray(Il2CppStructArray bytes, ref int index, IEnumerable values, int count) { byte* ptr = (byte*)IntPtr.Add(((Il2CppObjectBase)bytes).Pointer, 4 * IntPtr.Size).ToPointer(); WriteLength(bytes, ref index, count); foreach (ulong value in values) { Write7BitEncodedLong(bytes, ref index, value); } } public static long[] Read7BitEncodedArray(Il2CppStructArray bytes, ref int index) { int num = ReadLength(bytes, ref index); long[] array = new long[num]; for (int i = 0; i < num; i++) { array[i] = Read7BitEncodedLong(bytes, ref index); } return array; } public static ulong[] Read7BitEncodedUArray(Il2CppStructArray bytes, ref int index) { int num = ReadLength(bytes, ref index); ulong[] array = new ulong[num]; for (int i = 0; i < num; i++) { array[i] = Read7BitEncodedULong(bytes, ref index); } return array; } public static void Write7BitEncodedMultiArray(Il2CppStructArray bytes, ref int index, ICollection> values, int valuesCount) { Write7BitEncodedMultiArray(bytes, ref index, values.Cast>(), values.Count, valuesCount); } public static void Write7BitEncodedMultiArray(Il2CppStructArray bytes, ref int index, ICollection> values, int valuesCount) { Write7BitEncodedMultiArray(bytes, ref index, values, values.Count, valuesCount); } public static void Write7BitEncodedMultiArray(Il2CppStructArray bytes, ref int index, IEnumerable> values, int arrCount, int valuesCount) { Write7BitEncodedMultiArray(bytes, ref index, values.Cast>(), arrCount, valuesCount); } public static void Write7BitEncodedMultiArray(Il2CppStructArray bytes, ref int index, IEnumerable> values, int arrCount, int valuesCount) { Write7BitEncodedArray(bytes, ref index, values.SelectMany((IEnumerable v) => v.Prepend(0uL)).Skip(1), valuesCount + arrCount - 1); } public static Spannable[] Read7BitEncodedMultiArray(Il2CppStructArray bytes, ref int index) { long[] array = Read7BitEncodedArray(bytes, ref index); Spannable[] array2 = new Spannable[1 + array.Count((long i) => i == 0)]; int num = 0; int num2 = 0; for (int j = 0; j < array.Length; j++) { if (array[j] == 0L) { array2[num++] = new Spannable(array, num2, j - num2); num2 = j + 1; } } array2[num] = new Spannable(array, num2, array.Length - num2); return array2; } public static Spannable[] Read7BitEncodedMultiUArray(Il2CppStructArray bytes, ref int index) { ulong[] array = Read7BitEncodedUArray(bytes, ref index); Spannable[] array2 = new Spannable[1 + array.Count((ulong i) => i == 0)]; int num = 0; int num2 = 0; for (int j = 0; j < array.Length; j++) { if (array[j] == 0L) { array2[num++] = new Spannable(array, num2, j - num2); num2 = j + 1; } } return array2; } public static int CalcStringArraySize(ICollection strings) { return CalcStringArraySize(strings, strings.Count); } public static int CalcStringArraySize(IEnumerable strings, int arrSize) { return CalcLengthSize(arrSize) + strings.Sum((Func)CalcStringSize); } public static int CalcStringSize(string? value) { return (value?.Length ?? 0) * 2 + 2; } public unsafe static void WriteStringArray(Il2CppStructArray bytes, ref int index, IEnumerable strings) { WriteLength(bytes, ref index, strings.Count()); byte* ptr = (byte*)IntPtr.Add(((Il2CppObjectBase)bytes).Pointer, IntPtr.Size * 4).ToPointer(); foreach (string @string in strings) { @string.AsSpan().CopyTo(new Span(ptr + index, (((Il2CppArrayBase)(object)bytes).Length - index) / 2)); index += 2 * @string.Length; *(short*)(ptr + index) = 0; index += 2; } } public unsafe static void WriteString(Il2CppStructArray bytes, ref int index, string? value) { byte* ptr = (byte*)IntPtr.Add(((Il2CppObjectBase)bytes).Pointer, IntPtr.Size * 4).ToPointer(); if (value == null) { value = string.Empty; } value.AsSpan().CopyTo(new Span(ptr + index, (((Il2CppArrayBase)(object)bytes).Length - index) / 2)); index += 2 * value.Length; *(short*)(ptr + index) = 0; index += 2; } public unsafe static string[] ReadStringArray(Il2CppStructArray bytes, ref int index) { byte* ptr = (byte*)IntPtr.Add(((Il2CppObjectBase)bytes).Pointer, IntPtr.Size * 4).ToPointer(); int num = ReadLength(bytes, ref index); string[] array = new string[num]; for (num = 0; num < array.Length; num++) { int num2 = index; while (*(ushort*)(ptr + index) != 0) { index += 2; } array[num] = new Span(ptr + num2, (index - num2) / 2).ToString(); index += 2; } return array; } public unsafe static string? ReadString(Il2CppStructArray bytes, ref int index) { byte* ptr = (byte*)IntPtr.Add(((Il2CppObjectBase)bytes).Pointer, IntPtr.Size * 4).ToPointer(); int num = index; while (*(ushort*)(ptr + index) != 0) { index += 2; } string result = ((index <= num) ? null : new Span(ptr + num, (index - num) / 2).ToString()); index += 2; return result; } } public static class SetHelpers { [CompilerGenerated] private sealed class <g__intersectHelper|0_0>d : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private IEnumerable other; public IEnumerable <>3__other; private IReadOnlySet self; public IReadOnlySet <>3__self; private IEnumerator <>7__wrap1; T IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <g__intersectHelper|0_0>d(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = other.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { T current = <>7__wrap1.Current; if (self.Contains(current)) { <>2__current = current; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { <g__intersectHelper|0_0>d <g__intersectHelper|0_0>d; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <g__intersectHelper|0_0>d = this; } else { <g__intersectHelper|0_0>d = new <g__intersectHelper|0_0>d(0); } <g__intersectHelper|0_0>d.self = <>3__self; <g__intersectHelper|0_0>d.other = <>3__other; return <g__intersectHelper|0_0>d; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static bool TryIntersect(this IReadOnlySet self, IEnumerable other, out IEnumerable intersection) { intersection = intersectHelper(self, other); return intersection.Any(); [IteratorStateMachine(typeof(<g__intersectHelper|0_0>d<>))] static IEnumerable intersectHelper(IReadOnlySet self, IEnumerable other) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <g__intersectHelper|0_0>d(-2) { <>3__self = self, <>3__other = other }; } } } public sealed class SimplifiedListConverter : JsonConverter { public override bool CanRead => false; public override bool CanWrite => true; public int MaxPerLine { get; set; } public SimplifiedListConverter(int maxPerLine = 20) { MaxPerLine = maxPerLine; } public override bool CanConvert(Type objectType) { return typeof(IEnumerable).IsAssignableFrom(objectType); } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (!(value is IEnumerable source)) { throw new ArgumentException("Expected value to be of type " + typeof(List).FullName + ".", "value"); } List list = source.Chunk(MaxPerLine).ToList(); if (list.Count == 0) { writer.WriteStartArray(); writer.WriteEndArray(); return; } if (list.Count == 1) { writer.WriteStartArray(); Formatting formatting = writer.Formatting; writer.Formatting = (Formatting)0; if (typeof(T) == typeof(string)) { writer.WriteRaw(" " + string.Join(", ", from i in list.First() select $"\"{i}\"") + " "); } else { writer.WriteRaw(" " + string.Join(", ", from i in list.First() select i?.ToString()) + " "); } writer.WriteEndArray(); writer.Formatting = formatting; return; } List> list2 = ((!(typeof(T) == typeof(string))) ? list.Select((T[] set) => set.Select(delegate(T s) { object obj = s?.ToString(); if (obj == null) { obj = "null"; } return (string)obj; }).ToList()).ToList() : list.Select((T[] set) => set.Select((T s) => $"\"{s}\"").ToList()).ToList()); int max = list2.Max((List set) => set.Max((string s) => s.Length)); writer.WriteStartArray(); foreach (List item in list2) { writer.WriteRawValue(string.Join(", ", item.Select((string s) => s.PadLeft(max)))); } writer.WriteEndArray(); } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { throw new NotImplementedException("This converter cannot read."); } } } namespace ReTFO.Archipelago.Patches { [HarmonyPatch(typeof(CM_SettingsInputField), "OnBtnPressAnywhere")] public static class AutoEnterFeatureSettings { public static void Prefix(CM_SettingsInputField __instance, ref bool __state) { __state = __instance.m_readingActive; } public static void Postfix(CM_SettingsInputField __instance, bool __state) { if (!__instance.m_readingActive && __state) { __instance.SetNewValue(__instance.m_currentValue); } } } [HarmonyPatch] internal static class CatchNetworkSettingsSubmenuPatch { [CompilerGenerated] private sealed class d__4 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Constructor(typeof(SubMenu), new Type[2] { typeof(string), typeof(string) }, false); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__4(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static SubMenu? NetworkSettingsSubMenu { get; set; } [IteratorStateMachine(typeof(d__4))] public static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(-2); } public static void Postfix(SubMenu __instance, string identifier) { StateTracker stateTracker = StateTracker.Get(); if (((Feature)stateTracker).Identifier == identifier) { NetworkSettingsSubMenu = __instance; } } } [HarmonyPatch(typeof(GlobalPopupMessageManager), "ShowPopup")] public static class GlobalPopupPatch { public static void Prefix(GlobalPopupMessageManager __instance, ref PopupMessage message) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)message.PopupType == 1) { message.Header = ((Object)MainMenuGuiLayer.Current.PageRundownNew.m_currentRundownData.StorytellingData.Title).ToString(); } } } [HarmonyPatch(typeof(ItemReplicationManager), "OnItemSpawn")] public static class InvokeItemSpawnCallbackPatch { public static void Postfix(pItemSpawnData spawnData, ItemReplicator replicator) { //IL_0005: 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) int num = ItemReplicationManager.m_callBacks.FindEntry(spawnData.callbackID); if (num != -1 && SNet.IsMaster) { ((Il2CppArrayBase>)(object)ItemReplicationManager.m_callBacks.entries)[num].value.Invoke(((Il2CppObjectBase)replicator.Item).Cast(), (PlayerAgent)null); ItemReplicationManager.RemoveCallback(spawnData.callbackID); } } } [HarmonyPatch] internal static class ModifyRundownMenuPatch { [HarmonyPatch(typeof(CM_PageRundown_New), "Intro_RevealRundown")] [HarmonyAfter(new string[] { "com.dak.MTFO" })] public static class AddResetButtonPatch { public static void Postfix(CM_PageRundown_New __instance) { ((RectTransformComp)__instance.m_matchmakeAllButton).SetVisible(true); __instance.m_matchmakeAllButton.SetText("<#F0F>EXIT ARCHIPELAGO"); __instance.m_matchmakeAllButton.OnBtnPressCallback = new Il2CppAction_int(delegate { StateTracker.Get().Reset(); }); } } [HarmonyPatch] public static class RevealJoinLobbyPatch { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(CM_PageRundown_New), "OnCortexDone", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = AccessTools.Method(typeof(CM_PageRundown_New), "SetPageActive", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] public static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } public static void Postfix(CM_PageRundown_New __instance) { __instance.m_selectionIsRevealed = true; } } public static CM_Item AddButton(CM_PageRundown_New __instance, float offset) { //IL_0000: 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_000b: 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_005e: 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_007a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.down * offset; CM_Item buttonConnect = __instance.m_buttonConnect; GameObject val2 = Object.Instantiate(((Component)buttonConnect).gameObject); val2.transform.parent = ((Component)buttonConnect).transform.parent; CM_Item component = val2.GetComponent(); ((RectTransformComp)component).RectTrans.anchorMin = ((RectTransformComp)buttonConnect).RectTrans.anchorMin; ((RectTransformComp)component).RectTrans.anchorMax = ((RectTransformComp)buttonConnect).RectTrans.anchorMax; ((Transform)((RectTransformComp)component).RectTrans).position = ((Transform)((RectTransformComp)buttonConnect).RectTrans).position + val; ((RectTransformComp)component).Setup(); component.SetupCMItem(); return component; } [HarmonyPatch(typeof(CM_PageRundown_New), "Setup")] [HarmonyPrefix] public static void PreMenuSetup(CM_PageRundown_New __instance) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) CM_Item buttonConnect = __instance.m_buttonConnect; buttonConnect.SetText("Connect to <#F0F>ARCHIPELAGO"); buttonConnect.OnBtnPressCallback += new Il2CppAction_int(delegate { StateTracker.Get().Connect(); }); float offset = ((RectTransformComp)buttonConnect).GetSize().y + 25f; CM_Item val = AddButton(__instance, offset); val.SetText("Server Settings"); val.OnBtnPressCallback += new Il2CppAction_int(delegate { MainMenuGuiLayer.Current.ChangePage((eCM_MenuPage)10, false); SubMenu? networkSettingsSubMenu = CatchNetworkSettingsSubmenuPatch.NetworkSettingsSubMenu; if (networkSettingsSubMenu != null) { networkSettingsSubMenu.Show(); } }); ((Transform)((RectTransformComp)val).RectTrans).SetParent((Transform)(object)((RectTransformComp)buttonConnect).RectTrans, true); } [HarmonyPatch(typeof(CM_PageRundown_New), "Setup")] [HarmonyPostfix] public static void PostMenuSetup(CM_PageRundown_New __instance) { CM_Item buttonConnect = __instance.m_buttonConnect; foreach (Delegate item in (Il2CppArrayBase)(object)((Delegate)buttonConnect.OnBtnPressCallback).GetInvocationList()) { Object target = item.Target; if (((target != null) ? ((Il2CppObjectBase)target).Pointer : IntPtr.Zero) == ((Il2CppObjectBase)__instance).Pointer) { buttonConnect.OnBtnPressCallback -= ((Il2CppObjectBase)item).Cast>(); } } StateTracker.Get().SetupReplication(); } } [HarmonyPatch] internal static class PostLoadGamedataPatch { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(GameDataInit), "Initialize", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = AccessTools.Method(typeof(GameDataInit), "ReInitialize", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] [HarmonyTargetMethods] public static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } [HarmonyPostfix] public static void Postfix() { if (!Plugin.TryGet(out Plugin plugin)) { throw new NotImplementedException("PostLoadGamedataPatch could not access plugin!"); } plugin.MidManager.InvalidateModdedInstanceData(); GameSetupDataBlock val = GameDataBlockBase.GetAllBlocks()[0]; uint num = val.RundownIdsToLoad[0]; val.RundownIdsToLoad = new List(1); val.RundownIdsToLoad.Add(num); } } [HarmonyPatch] [InjectToIl2Cpp] public static class PrivateFeatureSettingsPatch { [AttributeUsage(AttributeTargets.Property)] public class FSOptionallyPrivate : Attribute { } public interface IOptionallyPrivate { bool IsCurrentlyPrivate { get; } } [InjectToIl2Cpp(typeof(iStringInputReceiver))] private class WrappedCustomStringReceiver : Object { [HideFromIl2Cpp] public iStringInputReceiver WrappedReceiver { get; set; } [HideFromIl2Cpp] public Func? IsCurrentlyPrivate { get; set; } public WrappedCustomStringReceiver(IntPtr ptr) : base(ptr) { } public WrappedCustomStringReceiver(iStringInputReceiver wrappedReceiver, Func? isCurrentlyPrivate) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); WrappedReceiver = wrappedReceiver; IsCurrentlyPrivate = isCurrentlyPrivate; } public string GetStringValue(eCellSettingID setting) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return WrappedReceiver.GetStringValue(setting); } public string SetStringValue(eCellSettingID setting, string value) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return WrappedReceiver.SetStringValue(setting, value); } } [HarmonyPatch] public static class ModSettings__SettingsCreationHelper__CreateStringSetting__Patch { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; private Type 5__2; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; Type typeFromHandle = typeof(ModSettings); 5__2 = typeFromHandle.GetNestedType("SettingsCreationHelper", AccessTools.all); <>2__current = AccessTools.Method(5__2, "CreateStringSetting", (Type[])null, (Type[])null); <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = AccessTools.Method(5__2, "CreateNumberSetting", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] [HarmonyTargetMethods] public static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } [HarmonyPostfix] public static void Postfix(FeatureSetting setting) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown FSOptionallyPrivate customAttribute = setting.Prop.GetCustomAttribute(); if (customAttribute == null) { return; } NumberSetting val = (NumberSetting)(object)((setting is NumberSetting) ? setting : null); if (val == null || !val.HasSlider) { object value = AccessTools.Property(typeof(FeatureSetting), "WrappedInstance").GetValue(setting); IOptionallyPrivate unwrappedInstance = value as IOptionallyPrivate; if (unwrappedInstance == null) { throw new NullReferenceException(); } object cM_SettingsItem = setting.CM_SettingsItem; CM_SettingsItem val2 = ((Il2CppObjectBase)((cM_SettingsItem is Object) ? cM_SettingsItem : null)).Cast(); CM_SettingsInputField component = ((Component)val2.m_inputAlign.GetChild(val2.m_inputAlign.childCount - 1)).GetComponent(); WrappedCustomStringReceiver wrappedCustomStringReceiver = new WrappedCustomStringReceiver(component.m_stringReceiver, () => unwrappedInstance.IsCurrentlyPrivate); component.m_stringReceiver = new iStringInputReceiver(((Il2CppObjectBase)wrappedCustomStringReceiver).Pointer); } } } [HarmonyPatch] public static class CM_SettingsInputField__Patch { [HarmonyPatch(typeof(CM_SettingsInputField), "Update")] [HarmonyPostfix] public static void PostUpdate(CM_SettingsInputField __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_readingActive) { return; } WrappedCustomStringReceiver wrappedCustomStringReceiver = ((Il2CppObjectBase)new Object(((Il2CppObjectBase)__instance.m_stringReceiver).Pointer)).TryCast(); if (wrappedCustomStringReceiver != null) { Func? isCurrentlyPrivate = wrappedCustomStringReceiver.IsCurrentlyPrivate; if (isCurrentlyPrivate == null || isCurrentlyPrivate()) { ((TMP_Text)__instance.m_text).SetText(new string('*', ((TMP_Text)__instance.m_text).text.Length), true); } else { ((TMP_Text)__instance.m_text).SetText(__instance.m_currentValue, true); } } } } } } namespace ReTFO.Archipelago.ModdedInstanceData { public class MidManager { public abstract class Processor { public abstract class CallbackBase : Attribute { public abstract Type DataType { get; } public abstract Type DelegateType { get; } } public abstract void UntypedRegisterCallback(Delegate callback); public abstract void UntypedUnregisterCallback(Delegate callback); } public abstract class Processor : Processor where TData : class { [AttributeUsage(AttributeTargets.Method)] public class Callback : CallbackBase { public override Type DataType => typeof(TData); public override Type DelegateType => typeof(Delegate); } public delegate void Delegate(TData data); public abstract void RegisterCallback(Delegate callback); public override void UntypedRegisterCallback(System.Delegate callback) { if (callback is Delegate callback2) { RegisterCallback(callback2); } else { FeatureLogger.Error("Failed to register callback; callback is of wrong delegate type"); } } public abstract void UnregisterCallback(Delegate callback); public override void UntypedUnregisterCallback(System.Delegate callback) { if (callback is Delegate callback2) { UnregisterCallback(callback2); } else { FeatureLogger.Error("Failed to unregister callback; callback is of wrong delegate type"); } } public abstract void Process(TData data); protected virtual void RegisterStaticCallbacks() { BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public; IEnumerable enumerable = from m in AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a) { try { return a.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.OfType(); } }).SelectMany((Type t) => t.GetMethods(bf)) where m.CustomAttributes.Any((CustomAttributeData a) => a.AttributeType.IsAssignableTo(typeof(Callback))) select m; foreach (MethodInfo item in enumerable) { if (!(System.Delegate.CreateDelegate(typeof(Delegate), item) is Delegate callback)) { FeatureLogger.Warning($"Failed to register callback {item.DeclaringType?.FullName}.{item.Name} to event; failed to convert to delegate type"); } else { RegisterCallback(callback); } } } } [DataContract] private struct JsonTag { private List? m_children; [DataMember] public RandomizationTag ID { get; init; } [DataMember] public string Name { get; init; } [DataMember] public string Description { get; init; } [DataMember(EmitDefaultValue = false)] public List? Children { get { return m_children; } init { m_children = ((value == null || value.Count == 0) ? null : value); } } } public bool IsProcessed { get; protected set; } public bool IsProcessing { get; protected set; } protected Dictionary m_processorLookup { get; set; } = new Dictionary(); protected Game.Data? m_gameData { get; set; } protected Game.Processor m_gameProcessor { get; set; } = new Game.Processor(); protected Dictionary m_namedHashes { get; set; } = new Dictionary { { "nriV4wruyGDWJAlthDcQVOnZRc/XrdAjR2fCHXE/E0k=", null } }; private static Guid DownloadsGUID => new Guid("374DE290-123F-4565-9164-39C4925E467B"); public MidManager() { RegisterProcessor(m_gameProcessor); } public void RegisterProcessor(Processor processor) where TData : class { if (!m_processorLookup.TryAdd(typeof(TData), processor)) { Processor processor2 = m_processorLookup[typeof(TData)]; FeatureLogger.Warning($"Cannot add new processor of type: {processor.GetType().Name}; an existing processor of type {processor2.GetType().Name} is already registered for that data type!"); } } public IReadOnlyDictionary GetAllProcessors() { return m_processorLookup; } public Processor GetProcessor() where TData : class { if (m_processorLookup.TryGetValue(typeof(TData), out Processor value)) { if (value is Processor result) { return result; } throw new InvalidCastException("Cannot converted processor of type " + value.GetType().Name + " to " + typeof(Processor).FullName); } throw new KeyNotFoundException("There is no processor for the requested data type: " + typeof(TData).FullName); } public Processor GetProcessor(Type tData) { if (m_processorLookup.TryGetValue(tData, out Processor value)) { Type type = typeof(Processor<>).MakeGenericType(tData); if (type.IsAssignableFrom(value.GetType())) { return value; } throw new InvalidCastException("Cannot converted processor of type " + value.GetType().FullName + " to " + type.FullName); } throw new KeyNotFoundException("There is no processor for the requested data type: " + tData.FullName); } public bool NameHash(string hash, string name) { return m_namedHashes.TryAdd(hash, name); } public void InvalidateModdedInstanceData() { if (IsProcessing) { throw new NotSupportedException("Attempted to invalidate modded instance data while it's processing!"); } IsProcessed = false; m_gameData = null; } public Game.Data GetUnprocessedGameData() { if (m_gameData != null) { return m_gameData; } return m_gameData = new Game.Data(this); } public Game.Data GetProcessedGameData() { ProcessData(); return GetUnprocessedGameData(); } public void ProcessData() { if (IsProcessed) { return; } if (IsProcessing) { throw new NotSupportedException("Process data request received while already processing!"); } FeatureLogger.Notice("Beginning MID generation"); IsProcessing = true; Game.Data unprocessedGameData = GetUnprocessedGameData(); Event.Processor processor = Event.get_EventProcessor(unprocessedGameData); m_gameProcessor.Process(unprocessedGameData); unprocessedGameData.CleanUp(); FeatureLogger.Notice("Checking for winability"); if (DoGraphTraversal(unprocessedGameData, doProcessing: true)) { FeatureLogger.Success("Game is beatable!"); } else { FeatureLogger.Fail("Game is not beatable!"); } using SHA256 sHA = SHA256.Create(); byte[] array = new byte[1]; IEnumerable enumerable = Enumerable.Empty().Concat(from e in unprocessedGameData.GetAllExpeditions() select e.Key).Concat(from r in unprocessedGameData.GetAllRegions() select r.Value.Name) .Concat(from p in unprocessedGameData.GetAllPaths() select p.Value.Name ?? "null") .Concat(from t in unprocessedGameData.GetAllTags() select t.Value.Name); foreach (string item in enumerable) { byte[] bytes = Encoding.UTF8.GetBytes(item); sHA.TransformBlock(bytes, 0, bytes.Length, null, 0); sHA.TransformBlock(array, 0, array.Length, null, 0); } sHA.TransformFinalBlock(array, 0, 0); string text = Convert.ToBase64String(sHA.Hash); if (m_namedHashes.TryGetValue(text, out string value)) { unprocessedGameData.Name = value; } else { unprocessedGameData.Name = text.Substring(0, 10); } unprocessedGameData.IsComplete = true; IsProcessing = false; IsProcessed = true; FeatureLogger.Notice("MID generation completed!"); FeatureLogger.Notice("World Hash: " + text); if (unprocessedGameData.Name == null) { FeatureLogger.Notice("World is Vanilla"); } else { FeatureLogger.Notice("World Name: " + unprocessedGameData.Name); } GameDataBlockBase.FileDirty = true; GameDataBlockBase.FileDirty = true; GameDataBlockBase.FileDirty = true; GameDataBlockBase.FileDirty = true; GameDataBlockBase.FileDirty = true; unprocessedGameData.CleanUp(); } [DllImport("shell32", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] private static extern string SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, nint hToken = 0); public void ExportMidData(string? directory = null) { //IL_02af: 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_02bd: Expected O, but got Unknown //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Expected O, but got Unknown Game.Data processedGameData = GetProcessedGameData(); if (directory == null) { directory = SHGetKnownFolderPath(DownloadsGUID, 0u); } string path = System.IO.Path.Combine(directory, (processedGameData.Name == null) ? "GTFO.ini" : ("GTFO-" + processedGameData.Name + ".ini")); DoGraphTraversal(processedGameData, doProcessing: true, null, null, logDebugInfo: false); List list = new List(); HashSet hashSet = new HashSet(); Queue queue = new Queue(); foreach (KeyValuePair allExpedition in processedGameData.GetAllExpeditions()) { hashSet.Clear(); queue.Clear(); hashSet.Add(Zone.get_StartingRegion(allExpedition.Value)); foreach (PathID connectedPath in processedGameData.LookupRegion(hashSet.First()).ConnectedPaths) { queue.Enqueue(connectedPath); } while (queue.Count > 0) { ReadOnlyPath readOnlyPath = processedGameData.LookupPath(queue.Dequeue()); if (hashSet.Contains(readOnlyPath.EndingRegion)) { continue; } ReadOnlyRegion readOnlyRegion = processedGameData.LookupRegion(readOnlyPath.EndingRegion); if (!readOnlyRegion.Reachable) { continue; } hashSet.Add(readOnlyPath.EndingRegion); foreach (PathID connectedPath2 in readOnlyRegion.ConnectedPaths) { queue.Enqueue(connectedPath2); } } list.Add(new MidExpeditionData { Name = allExpedition.Key, ReachableRegions = hashSet.ToList() }); } var anon = new { Expeditions = list, Tags = (from t in processedGameData.GetAllTags() select new KeyedRandomizationTag(t.Key, t.Value)).ToList(), Regions = (from r in processedGameData.GetAllRegions() select new KeyedRegion(r.Key, r.Value)).ToList(), Paths = (from p in processedGameData.GetAllPaths() select new KeyedPath(p.Key, p.Value)).ToList(), Locations = (from l in processedGameData.GetAllLocations() select new KeyedLocation(l.Key, l.Value)).ToList(), Items = (from i in processedGameData.GetAllItems() select new KeyedItem(i.Key, i.Value)).ToList(), FloatingItems = processedGameData.GetAllFloatingItemIds() }; JsonSerializerSettings val = new JsonSerializerSettings { Formatting = (Formatting)1 }; val.Converters.Add((JsonConverter)new StringEnumConverter()); val.Converters.Add((JsonConverter)(object)new SimplifiedListConverter()); val.Converters.Add((JsonConverter)(object)new SimplifiedListConverter(15)); val.Converters.Add((JsonConverter)(object)new IdConverter()); Type[] targetTypes = new Type[7] { typeof(KeyedRandomizationTag), typeof(KeyedRegion), typeof(ReadOnlyRegion), typeof(KeyedPath), typeof(ReadOnlyPath), typeof(KeyedLocation), typeof(KeyedItem) }; Type[] inlinedTypes = new Type[7] { typeof(RandomizationTagDefinition), typeof(ReadOnlyRegion), typeof(Region), typeof(ReadOnlyPath), typeof(ReTFO.Archipelago.ModdedInstanceData.Model.Path), typeof(Location), typeof(Item) }; val.Converters.Add((JsonConverter)(object)new InlineConverter(targetTypes, inlinedTypes)); string contents = JsonConvert.SerializeObject((object)anon, val); File.WriteAllText(path, contents); } public void ExportTagsToCSV(string? filename = null) { if (filename == null) { filename = System.IO.Path.Combine(SHGetKnownFolderPath(DownloadsGUID, 0u), "gtfoTags.csv"); } IEnumerable contents = Enumerable.Repeat("\"ID\",\"NAME\",\"PARENT\",\"DESCRIPTION\"", 1).Concat(from pair in GetProcessedGameData().GetAllTags() select $"\"{pair.Key.AsId.ToString()}\"\"{pair.Value.Name}\",\"{pair.Value.Parent}\",\"{pair.Value.Description}\""); File.WriteAllLines(filename, contents); } public void ExportTagsToJSON(string? filename = null) { //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) //IL_00e7: Expected O, but got Unknown if (filename == null) { filename = System.IO.Path.Combine(SHGetKnownFolderPath(DownloadsGUID, 0u), "gtfoTags.json"); } Game.Data data = GetProcessedGameData(); Dictionary?> tagsByParent = new Dictionary>(); foreach (KeyValuePair allTag in data.GetAllTags()) { if (tagsByParent.TryGetValue(allTag.Value.Parent, out List value)) { value.Add(allTag.Key); continue; } tagsByParent.Add(allTag.Value.Parent, new List { allTag.Key }); } var anon = new { Tags = MakeJsonRecursive(new RandomizationTag()) }; JsonSerializerSettings val = new JsonSerializerSettings { Formatting = (Formatting)1 }; val.Converters.Add((JsonConverter)(object)new IdConverter()); string contents = JsonConvert.SerializeObject((object)anon, val); File.WriteAllText(filename, contents); List MakeJsonRecursive(RandomizationTag parentTag) { IEnumerable valueOrDefault = tagsByParent.GetValueOrDefault(parentTag, null); return (valueOrDefault ?? Enumerable.Empty()).Select((RandomizationTag t) => new KeyedRandomizationTag(t, data.LookupTagDef(t))).Select(delegate(KeyedRandomizationTag t) { JsonTag result = default(JsonTag); result.ID = t.ID; result.Name = t.Definition.Name; result.Description = t.Definition.Description; result.Children = MakeJsonRecursive(t.ID); return result; }).ToList(); } } public static bool DoGraphTraversal(Game.Data gameData, bool doProcessing = false, ICollection? unlockTags = null, ICollection? goalTags = null, bool logDebugInfo = true) { Game.Data gameData2 = gameData; ICollection goalTags2 = goalTags; if (unlockTags == null) { unlockTags = new List(1) { RootRandomizationTags.get_Tag_UnlockItems(gameData2) }; } if (goalTags2 == null) { goalTags2 = new List(1) { RootRandomizationTags.get_Tag_GoalItems(gameData2) }; } List collectedItems = new List(); Dictionary itemCounts = new Dictionary(); Dictionary categoryCounts = new Dictionary(); List?, SortedList?>> usedItemsPerRegion = (gameData2.IsComplete ? new List, SortedList>>(0) : Enumerable.Repeat(Tuple.Create, SortedList>(null, null), gameData2.GetAllRegions().Count).ToList()); List isReachable = (doProcessing ? null : Enumerable.Repeat(element: false, gameData2.GetAllRegions().Count).ToList()); List list = new List(); if (doProcessing) { foreach (KeyValuePair allRegion in gameData2.GetAllRegions()) { gameData2.SetRegionReachable(allRegion.Key, isReachable: false); } } RegionID menuRegion = gameData2.MenuRegion; ReadOnlyRegion readOnlyRegion = gameData2.LookupRegion(menuRegion); setReachable(menuRegion); foreach (ItemID allFloatingItemId in gameData2.GetAllFloatingItemIds()) { Item item2 = gameData2.LookupItem(allFloatingItemId); RandomizationTagDefinition randomizationTagDefinition = gameData2.LookupTagDef(item2.NameTag); RandomizationTagDefinition randomizationTagDefinition2 = (item2.Tag2.IsNull ? default(RandomizationTagDefinition) : gameData2.LookupTagDef(item2.Tag2)); randomizationTagDefinition.Name.Contains("Expedition Unlock"); if (gameData2.AnyTagMatches(unlockTags, gameData2.LookupItem(allFloatingItemId))) { collectItem(allFloatingItemId); } } foreach (Location item5 in readOnlyRegion.ConnectedLocationIds.Select(gameData2.LookupLocation)) { if (item5.OwningRegionIds.Length == 1 && !item5.ItemID.IsNull) { collectItem(item5.ItemID); } } list.AddRange(readOnlyRegion.ConnectedPaths); int num = 1; while (num > 0) { num = 0; for (int i = 0; i < list.Count; i++) { ReadOnlyPath readOnlyPath = gameData2.LookupPath(list[i]); if (getReachable(readOnlyPath.EndingRegion)) { list.RemoveAt(i--); continue; } int num2 = ((readOnlyPath.ReqItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) ? (itemCount(readOnlyPath.ReqItem.Target) - usedItemCount(readOnlyPath.StartingRegion, readOnlyPath.ReqItem.Target)) : ((readOnlyPath.ReqItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category) ? (catsCount(readOnlyPath.ReqItem.Target) - usedCatsCount(readOnlyPath.StartingRegion, readOnlyPath.ReqItem.Target)) : 0)); int num3 = ((readOnlyPath.AlternateItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) ? itemCount(readOnlyPath.AlternateItem.Target) : ((readOnlyPath.AlternateItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category) ? catsCount(readOnlyPath.AlternateItem.Target) : 0)); if (readOnlyPath.ReqItem.Type != 0 && num2 < readOnlyPath.ReqCount && num3 < 1) { continue; } setReachable(readOnlyPath.EndingRegion); num++; list.AddRange(gameData2.LookupRegion(readOnlyPath.EndingRegion).ConnectedPaths); if (!gameData2.IsComplete) { if (readOnlyPath.ReqItem.Type != 0) { ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem requiredItem; int num4; if (num2 >= readOnlyPath.ReqCount) { requiredItem = readOnlyPath.ReqItem; num4 = (int)readOnlyPath.ReqCount; } else { requiredItem = readOnlyPath.AlternateItem; num4 = 1; } SortedList sortedList = new SortedList(); SortedList sortedList2; if (requiredItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) { sortedList2 = usedItemsPerRegion[readOnlyPath.StartingRegion.AsIndex].Item1; usedItemsPerRegion[readOnlyPath.EndingRegion.AsIndex] = Tuple.Create(sortedList, usedItemsPerRegion[readOnlyPath.StartingRegion.AsIndex].Item2); } else { sortedList2 = usedItemsPerRegion[readOnlyPath.StartingRegion.AsIndex].Item2; usedItemsPerRegion[readOnlyPath.EndingRegion.AsIndex] = Tuple.Create(usedItemsPerRegion[readOnlyPath.StartingRegion.AsIndex].Item1, sortedList); } IEnumerable> enumerable = sortedList2; foreach (KeyValuePair item6 in enumerable ?? Enumerable.Empty>()) { sortedList.Add(item6.Key, item6.Value); } sortedList[requiredItem.Target] = sortedList.GetValueOrDefault(requiredItem.Target, 0) + num4; } else { usedItemsPerRegion[readOnlyPath.EndingRegion.AsIndex] = usedItemsPerRegion[readOnlyPath.StartingRegion.AsIndex]; } if (doProcessing && readOnlyPath.ReqItem.Type != 0) { uint num5 = (uint)((readOnlyPath.ReqItem.Type != ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) ? usedCatsCount(readOnlyPath.StartingRegion, readOnlyPath.ReqItem.Target) : usedItemCount(readOnlyPath.StartingRegion, readOnlyPath.ReqItem.Target)); gameData2.SetPathReqCount(list[i], num5 + readOnlyPath.ReqCount); } } foreach (Location item7 in gameData2.LookupRegion(readOnlyPath.EndingRegion).ConnectedLocationIds.Select(gameData2.LookupLocation)) { if (!item7.OwningRegionIds.Any((RegionID id) => !getReachable(id))) { collectItem(item7.ItemID); } } list.RemoveAt(i--); } } List list2 = (from item in (from pair in gameData2.GetAllLocations() select pair.Value.ItemID into id where !id.IsNull select id).Select(gameData2.LookupItem) where gameData2.AnyTagMatches(goalTags2, item) select item).ToList(); foreach (Item item8 in collectedItems) { list2.Remove(item8); } if (list2.Count == 0) { return true; } if (!logDebugInfo) { return false; } FeatureLogger.Error("Graph traversal failed for game!"); ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); ConsoleManager.ConsoleStream.WriteLine("\n Missing Item" + ((list2.Count > 1) ? "s" : "") + " Required for Completion:"); ConsoleManager.SetConsoleColor(ConsoleColor.White); foreach (Item item9 in list2) { ConsoleManager.ConsoleStream.WriteLine(" - " + gameData2.LookupTagDef(item9.NameTag).Name); } ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); ConsoleManager.ConsoleStream.WriteLine("\n Regions:"); bool flag = false; foreach (KeyValuePair allRegion2 in gameData2.GetAllRegions()) { bool flag2 = getReachable(allRegion2.Key); if (flag2) { ConsoleManager.SetConsoleColor(ConsoleColor.Green); } else { ConsoleManager.SetConsoleColor(ConsoleColor.Red); } ConsoleManager.ConsoleStream.WriteLine($" {(flag2 ? "[ Reachable ]" : "[Unreachable]")} [{allRegion2.Key.AsId.ToString("000")}] {allRegion2.Value.Name}"); flag = true; } if (!flag) { ConsoleManager.ConsoleStream.WriteLine("\n NO REGIONS FOUND"); } ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); ConsoleManager.ConsoleStream.WriteLine("\n Blocked paths:"); PathID[] array = new PathID[list.Count]; list.CopyTo(array); Array.Sort(array); flag = false; PathID[] array2 = array; foreach (PathID id2 in array2) { ReadOnlyPath readOnlyPath2 = gameData2.LookupPath(id2); ConsoleManager.ConsoleStream.WriteLine(); ConsoleManager.ConsoleStream.WriteLine(" Name: " + (readOnlyPath2.Name ?? "None")); ConsoleManager.SetConsoleColor(ConsoleColor.Green); ConsoleManager.ConsoleStream.WriteLine(" Start: [" + readOnlyPath2.StartingRegion.AsId.ToString("000") + "] " + gameData2.LookupRegion(readOnlyPath2.StartingRegion).Name); ConsoleManager.SetConsoleColor(ConsoleColor.Red); ConsoleManager.ConsoleStream.WriteLine(" End: [" + readOnlyPath2.EndingRegion.AsId.ToString("000") + "] " + gameData2.LookupRegion(readOnlyPath2.EndingRegion).Name); ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); if (readOnlyPath2.ReqItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.None) { ConsoleManager.ConsoleStream.WriteLine(" No required item!"); } else if (readOnlyPath2.ReqItem.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) { ConsoleManager.ConsoleStream.WriteLine(" Item: " + (usedItemCount(readOnlyPath2.StartingRegion, readOnlyPath2.ReqItem.Target) + readOnlyPath2.ReqCount).ToString("000") + "x " + gameData2.LookupTagDef(readOnlyPath2.ReqItem.Target).Name); } else { ConsoleManager.ConsoleStream.WriteLine(" Cats: " + (usedCatsCount(readOnlyPath2.StartingRegion, readOnlyPath2.ReqItem.Target) + readOnlyPath2.ReqCount).ToString("000") + "x " + gameData2.LookupTagDef(readOnlyPath2.ReqItem.Target).Name); } if (readOnlyPath2.AlternateItem.Type != 0) { ConsoleManager.ConsoleStream.WriteLine(" Alt: 001x " + gameData2.LookupTagDef(readOnlyPath2.AlternateItem.Target).Name); } flag = true; } if (!flag) { ConsoleManager.ConsoleStream.WriteLine("\n NO BLOCKED PATHS FOUND"); } ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); ConsoleManager.ConsoleStream.WriteLine("\n Notable unfound locations:"); HashSet hashSet = list.Select(gameData2.LookupPath).SelectMany((ReadOnlyPath p) => Enumerable.Empty().Append(p.ReqItem.Target).Append(p.AlternateItem.Target)).ToHashSet(); flag = false; foreach (Location item10 in from pair in gameData2.GetAllLocations() select pair.Value) { if (item10.ItemID.IsNull || item10.OwningRegionIds.All(getReachable)) { continue; } Item item3 = gameData2.LookupItem(item10.ItemID); if (!gameData2.TagMatches(hashSet, item3.PathReqs.Target)) { continue; } ConsoleManager.ConsoleStream.WriteLine(); ConsoleManager.ConsoleStream.WriteLine(" Name: " + gameData2.LookupTagDef(item10.NameTag).Name); ConsoleManager.ConsoleStream.WriteLine(" Item: " + gameData2.LookupTagDef(item3.NameTag).Name); if (!item3.Tag2.IsNull) { ConsoleManager.ConsoleStream.WriteLine(" Cat: " + gameData2.LookupTagDef(item3.Tag2).Name); } if (!item3.Tag3.IsNull) { ConsoleManager.ConsoleStream.WriteLine(" Cat: " + gameData2.LookupTagDef(item3.Tag3).Name); } ConsoleManager.ConsoleStream.WriteLine(" Regions:"); if (item10.OwningRegionIds.Length == 0) { ConsoleManager.SetConsoleColor(ConsoleColor.Red); ConsoleManager.ConsoleStream.WriteLine(" LOCATION HAS NO REGIONS AND CANNOT BE DISCOVERED"); } else { RegionID[] owningRegionIds = item10.OwningRegionIds; for (int k = 0; k < owningRegionIds.Length; k++) { RegionID id3 = owningRegionIds[k]; bool flag3 = getReachable(id3); if (flag3) { ConsoleManager.SetConsoleColor(ConsoleColor.Green); } else { ConsoleManager.SetConsoleColor(ConsoleColor.Red); } ConsoleManager.ConsoleStream.WriteLine($" {(flag3 ? "[ Reachable ]" : "[Unreachable]")} [{id3.AsId.ToString("000")}] {gameData2.LookupRegion(id3).Name}"); } } ConsoleManager.SetConsoleColor(ConsoleColor.Yellow); flag = true; } if (hashSet.Count == 0) { ConsoleManager.ConsoleStream.WriteLine("\n NO NEEDED ITEMS FOUND"); } else if (!flag) { ConsoleManager.ConsoleStream.WriteLine("\n NO NOTABLE LOCATIONS FOUND"); } ConsoleManager.ConsoleStream.WriteLine(); return false; int catsCount(RandomizationTag tag) { return categoryCounts.GetValueOrDefault(tag, 0); } void collectItem(ItemID id) { if (!id.IsNull) { Item item4 = gameData2.LookupItem(id); if (item4.RandData.IsProgression) { collectedItems.Add(item4); ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem pathReqs = item4.PathReqs; if (pathReqs.Type != 0) { if (pathReqs.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Item) { itemCounts[pathReqs.Target] = itemCount(pathReqs.Target) + 1; } else if (pathReqs.Type == ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category) { categoryCounts[pathReqs.Target] = catsCount(pathReqs.Target) + 1; } } } } } bool getReachable(RegionID id) { if (!doProcessing) { return isReachable[id.AsIndex]; } return gameData2.LookupRegion(id).Reachable; } int itemCount(RandomizationTag tag) { return itemCounts.GetValueOrDefault(tag, 0); } void setReachable(RegionID id) { if (doProcessing) { gameData2.SetRegionReachable(id, isReachable: true); } else { isReachable[id.AsIndex] = true; } } int usedCatsCount(RegionID region, RandomizationTag tag) { if (!gameData2.IsComplete) { return usedItemsPerRegion[region.AsIndex].Item2?.GetValueOrDefault(tag, 0) ?? 0; } return 0; } int usedItemCount(RegionID region, RandomizationTag tag) { if (!gameData2.IsComplete) { return usedItemsPerRegion[region.AsIndex].Item1?.GetValueOrDefault(tag, 0) ?? 0; } return 0; } } } } namespace ReTFO.Archipelago.ModdedInstanceData.Processors { public static class Event { public class Data : Layer.Data, IList, ICollection, IEnumerable, IEnumerable { public RegionID EventRegion { get; private init; } public string EventName { get; private init; } protected List? RawEvents { get; private init; } public int EventStart { get; protected set; } public int EventCount { get; protected set; } public IEnumerable Events => from i in Enumerable.Range(EventStart, EventCount) select RawEvents[i]; public int Count => EventCount; public bool IsReadOnly => false; public WardenObjectiveEventData this[int index] { get { if (index < 0 || index >= EventCount) { throw new ArgumentOutOfRangeException("index"); } return RawEvents[EventStart + index]; } set { if (index < 0 || index >= EventCount) { throw new ArgumentOutOfRangeException("index"); } RawEvents[EventStart + index] = value; } } public Data(Layer.Data data, RegionID eventRegion, string eventName, List rawEvents, int eventStart = 0, int eventCount = -1) : base(data) { EventRegion = eventRegion; EventName = eventName; RawEvents = rawEvents; EventStart = eventStart; EventCount = ((eventCount == -1) ? (rawEvents.Count - eventStart) : eventCount); } public Data(Data other) : base(other) { EventRegion = other.EventRegion; EventName = other.EventName; RawEvents = other.RawEvents; EventStart = other.EventStart; EventCount = other.EventCount; } public int IndexOf(WardenObjectiveEventData item) { WardenObjectiveEventData item2 = item; return Enumerable.Range(EventStart, EventCount).FirstOrDefault((int i) => RawEvents[i] == item2, -1); } public void Insert(int index, WardenObjectiveEventData item) { if (index < 0 || index > EventCount) { throw new ArgumentOutOfRangeException("index"); } RawEvents.Insert(EventStart + index, item); int eventCount = EventCount + 1; EventCount = eventCount; } public void RemoveAt(int index) { if (index < 0 || index >= EventCount) { throw new ArgumentOutOfRangeException("index"); } RawEvents.RemoveAt(EventStart + index); int eventCount = EventCount - 1; EventCount = eventCount; } public void Add(WardenObjectiveEventData item) { RawEvents.Insert(EventStart + EventCount, item); int eventCount = EventCount + 1; EventCount = eventCount; } public void Clear() { RawEvents.RemoveRange(EventStart, EventCount); EventCount = 0; } public bool Contains(WardenObjectiveEventData item) { WardenObjectiveEventData item2 = item; return Events.Any((WardenObjectiveEventData i) => i == item2); } public void CopyTo(WardenObjectiveEventData[] array, int arrayIndex) { for (int i = 0; i < EventCount; i++) { array[arrayIndex + i] = RawEvents[EventStart + i]; } } public bool Remove(WardenObjectiveEventData item) { int num = IndexOf(item); if (num < 0) { return false; } RemoveAt(num); return true; } public IEnumerator GetEnumerator() { return Events.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class Wrapper { private readonly Layer.Data layerData; private readonly List events; private int eventStart; private int eventCount; public bool IsDone => eventStart > events.Count; public Wrapper(Layer.Data layerData, List events) { this.layerData = layerData; this.events = events; eventStart = -1; eventCount = 0; Step(); } public Wrapper(Wrapper source) { layerData = source.layerData; events = source.events; eventStart = source.eventStart; eventCount = source.eventCount; } public void Step(bool errorIfHasEvents = false) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 if (errorIfHasEvents && eventCount > 0) { FeatureLogger.Error("Performed step for event processing with \"errorIfHasEvents\""); } eventStart += eventCount + 1; eventCount = 0; while (eventStart + eventCount < events.Count && (int)events[eventStart + eventCount].Type != 999) { eventCount++; } } public void Process(RegionID eventRegion, string eventSource, bool extendIfNecessary = false) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (IsDone) { if (!extendIfNecessary) { return; } events.Add(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)999 }); } Data data = new Data(layerData, eventRegion, eventSource, events, eventStart, eventCount); get_EventProcessor(layerData).Process(data); eventStart = data.EventStart; eventCount = data.EventCount; Step(); } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor EventProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $9DAFA10623A49E693D4D9BEA615A7202 { [SpecialName] public static class $F9136D71CE7F5E8B956EFAA9F642E37E { } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Wrapper WrapEvents(List events) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data ProcessEvents(RegionID eventRegion, string eventSource, List events) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data ProcessEvents(RegionID eventRegion, string eventSource, List events, int eventStart, int eventCount) { throw new NotSupportedException(); } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $0151B882DB6D8E92BCB0A146352EDB96 { } [ExtensionMarker("$0151B882DB6D8E92BCB0A146352EDB96")] public Wrapper WrapOnActivateEvents() { throw new NotSupportedException(); } [ExtensionMarker("$0151B882DB6D8E92BCB0A146352EDB96")] public Wrapper MakeOrWrapOnSolveEvents() { throw new NotSupportedException(); } } public static Processor get_EventProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } public static Wrapper WrapEvents(this Layer.Data layerData, List events) { return new Wrapper(layerData, events); } public static Data ProcessEvents(this Layer.Data layerData, RegionID eventRegion, string eventSource, List events) { Data data = new Data(layerData, eventRegion, eventSource, events); get_EventProcessor(layerData).Process(data); return data; } public static Data ProcessEvents(this Layer.Data layerData, RegionID eventRegion, string eventSource, List events, int eventStart, int eventCount) { Data data = new Data(layerData, eventRegion, eventSource, events, eventStart, eventCount); get_EventProcessor(layerData).Process(data); return data; } public static Wrapper WrapOnActivateEvents(this Objective.Data objectiveData) { WardenObjectiveDataBlock objective = objectiveData.Objective; return objectiveData.WrapEvents(objective.EventsOnActivate ?? (objective.EventsOnActivate = new List(1))); } public static Wrapper MakeOrWrapOnSolveEvents(this Objective.Data objectiveData) { if (!objectiveData.Objective.OnActivateOnSolveItem) { objectiveData.Objective.OnActivateOnSolveItem = true; objectiveData.Objective.EventsOnActivate?.Clear(); } return objectiveData.WrapOnActivateEvents(); } } public static class Expedition { public class Data : Game.Data { public class Comparer : EqualityComparer { public override bool Equals(Data? x, Data? y) { if (x == null) { return y == null; } return y?.IsSameExpedition(x) ?? false; } public override int GetHashCode([DisallowNull] Data obj) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Tuple.Create(((Il2CppObjectBase)obj.Rundown).Pointer, obj.ExpeditionTier, obj.ExpeditionIndex).GetHashCode(); } } public RundownDataBlock Rundown { get; private init; } public eRundownTier ExpeditionTier { get; init; } public int ExpeditionIndex { get; init; } public virtual ExpeditionInTierData Expedition { get { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) eRundownTier expeditionTier = ExpeditionTier; return (ExpeditionInTierData)((expeditionTier - 1) switch { 0 => Rundown.TierA[ExpeditionIndex], 1 => Rundown.TierB[ExpeditionIndex], 2 => Rundown.TierC[ExpeditionIndex], 3 => Rundown.TierD[ExpeditionIndex], 4 => Rundown.TierE[ExpeditionIndex], _ => throw new NotSupportedException($"Unrecognized expedition tier: {ExpeditionTier}"), }); } } public string ExpeditionName => Expedition.GetShortName(ExpeditionIndex); public TagResolver UnlockItemsTag => new TagResolver(this, (Game.Data gd) => gd.LookupOrCreateTag(ExpeditionName + " Unlock Items", "Floating items required to start / progress expedition " + ExpeditionName, RootRandomizationTags.get_Tag_UnlockItems(gd))); public TagResolver GoalItemsTag => new TagResolver(this, (Game.Data gd) => gd.LookupOrCreateTag(ExpeditionName + " Goal Items", "Items indicating a successful full clear of " + ExpeditionName, RootRandomizationTags.get_Tag_GoalItems(gd))); public string ObjectiveStartRegionName => ExpeditionName + " Elevator Landed"; public RegionID ObjectiveStartRegion => LookupOrCreateRegion(ObjectiveStartRegionName); public Data(Game.Data data, RundownDataBlock rundown, eRundownTier expeditionTier, int expeditionIndex) : base(data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) Rundown = rundown; ExpeditionTier = expeditionTier; ExpeditionIndex = expeditionIndex; } public Data(Data other) : base(other) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Rundown = other.Rundown; ExpeditionTier = other.ExpeditionTier; ExpeditionIndex = other.ExpeditionIndex; } public static Data FromCurrentExpedition() { return FromExpedition(RundownManager.ActiveExpedition); } public static Data? TryFromCurrentExpedition() { RundownManager current = RundownManager.Current; return TryFromExpedition((current != null) ? current.m_actExp : null); } public static Data FromExpedition(ExpeditionInTierData expedition) { Game.Data processedGameData = Plugin.Get().MidManager.GetProcessedGameData(); DescriptiveData descriptive = expedition.Descriptive; string text = ((descriptive != null) ? descriptive.Prefix : null); if (text == null || !processedGameData.TryLookupExpedition(text, out Data data)) { string text2 = "Failed to retrieve expedition: " + text; FeatureLogger.Error(text2); throw new ArgumentException(text2); } return data; } public static Data? TryFromExpedition(ExpeditionInTierData? expedition) { Game.Data processedGameData = Plugin.Get().MidManager.GetProcessedGameData(); object obj; if (expedition == null) { obj = null; } else { DescriptiveData descriptive = expedition.Descriptive; obj = ((descriptive != null) ? descriptive.Prefix : null); } string text = (string)obj; if (text == null || !processedGameData.TryLookupExpedition(text, out Data data)) { return null; } return data; } public bool IsSameExpedition(Data other) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (((Il2CppObjectBase)Rundown).Pointer == ((Il2CppObjectBase)other.Rundown).Pointer && ExpeditionTier == other.ExpeditionTier) { return ExpeditionIndex == other.ExpeditionIndex; } return false; } public bool IsCurrentExepdition() { if (RundownManager.ActiveExpedition != null) { return FromCurrentExpedition().IsSameExpedition(this); } return false; } public bool IsCurrentlyInExpedition() { if (IsCurrentExepdition()) { return GameStateManager.IsInExpedition; } return false; } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { [CompilerGenerated] private sealed class <>c__DisplayClass8_0 { public Game.Data data; } protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } public Processor SubscribedTo(MidManager.Processor owner) { owner.RegisterCallback(OnProcessGame); return this; } protected void OnProcessGame(Game.Data data) { <>c__DisplayClass8_0 CS$<>8__locals0 = new <>c__DisplayClass8_0(); CS$<>8__locals0.data = data; Plugin plugin = Plugin.Get(); IEnumerable enumerable = ((IEnumerable)GameDataBlockBase.GetAllBlocks()).SelectMany(UnpackExpeditions); foreach (Data item in enumerable) { if (!((GameDataBlockBase)(object)item.Rundown).internalEnabled || !item.Expedition.Enabled) { continue; } LevelLayoutDataBlock block = GameDataBlockBase.GetBlock(item.Expedition.LevelLayoutData); if (((block == null) ? null : block.Zones?.Count).GetValueOrDefault() == 0) { continue; } SortedList> sortedList = new SortedList> { { "A3", Tuple.Create(27u, "Geomorph Tester", "Geo Test - VS") }, { "A5", Tuple.Create(27u, "Geomorph Tester", "Geo Test - LF") } }; if (!sortedList.TryGetValue(item.ExpeditionName, out var value) || ((GameDataBlockBase)(object)item.Rundown).persistentID != value.Item1 || !(((GameDataBlockBase)(object)item.Rundown).name == value.Item2) || !(item.Expedition.Descriptive.PublicName == value.Item3)) { item.Expedition.Descriptive.Prefix = item.ExpeditionName; item.Expedition.Descriptive.SkipExpNumberInName = true; if (!CS$<>8__locals0.data.TryRegisterExpedition(item.ExpeditionName, item)) { FeatureLogger.Error("Skipping processing for expedition due to duplicate naming: " + item.ExpeditionName); } else { get_ExpeditionProcessor(CS$<>8__locals0.data).Process(item); } } } [IteratorStateMachine(typeof(<>c__DisplayClass8_0.<g__UnpackExpeditions|0>d))] IEnumerable UnpackExpeditions(RundownDataBlock rundown) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass8_0.<g__UnpackExpeditions|0>d(-2) { <>4__this = CS$<>8__locals0, <>3__rundown = rundown }; } } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor ExpeditionProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static Processor get_ExpeditionProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } } public static class Game { public class Data { private class StorageType { public bool IsComplete { get; set; } public string? Name { get; set; } public MidManager Manager { get; init; } = new MidManager(); public Dictionary ExpeditionLookup { get; init; } = new Dictionary(); public List RegionList { get; init; } = new List(); public Dictionary RegionLookup { get; init; } = new Dictionary(); public List PathList { get; init; } = new List(); public List TagDefinitions { get; init; } = new List(); public Dictionary TagLookup { get; init; } = new Dictionary(); public List LocationList { get; init; } = new List(); public Dictionary LocationLookup { get; init; } = new Dictionary(); public List ItemList { get; init; } = new List(); public Dictionary ItemLookup { get; init; } = new Dictionary(); public List FloatingItems { get; init; } = new List(); } public struct RegionInfo : IEquatable { public RegionID Region; public bool IsBad; public override bool Equals(object? obj) { if (obj is RegionInfo regionInfo) { return Region.Equals(regionInfo); } return false; } public bool Equals(RegionInfo info) { return Region.Equals(info.Region); } public static bool operator ==(RegionInfo left, RegionInfo right) { return left.Equals(right); } public static bool operator !=(RegionInfo left, RegionInfo right) { return !left.Equals(right); } public override int GetHashCode() { return Region.GetHashCode(); } } [CompilerGenerated] private sealed class <>c__DisplayClass81_0 { public List> sets; internal HashSet b__1(int i) { return sets[i % sets.Count]; } } [CompilerGenerated] private sealed class d__81 : IEnumerable>, IEnumerable, IEnumerator>, IEnumerator, IDisposable { private int <>1__state; private List <>2__current; private int <>l__initialThreadId; private int neededCount; public int <>3__neededCount; private IEnumerable> placements; public IEnumerable> <>3__placements; private IEnumerator, HashSet>> <>7__wrap1; private IGrouping, HashSet> 5__3; private int 5__4; private List.Enumerator <>7__wrap4; List IEnumerator>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__81(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 1u) { try { if (num == -4 || num == 1) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>7__wrap1 = null; 5__3 = null; <>7__wrap4 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass81_0 CS$<>8__locals0 = new <>c__DisplayClass81_0(); if (neededCount == 0) { return false; } if (!placements.Any()) { FeatureLogger.Error("Failed to unstuff placements: No placements were provided"); return false; } CS$<>8__locals0.sets = placements.Select((IEnumerable ps) => ps.Distinct().ToHashSet()).ToList(); IEnumerable, HashSet>> enumerable = (from i in Enumerable.Range(0, neededCount) select CS$<>8__locals0.sets[i % CS$<>8__locals0.sets.Count]).GroupBy((HashSet s) => s, HashSet.CreateSetComparer()); <>7__wrap1 = enumerable.GetEnumerator(); <>1__state = -3; goto IL_02d5; } case 1: <>1__state = -4; goto IL_0249; case 2: { <>1__state = -3; goto IL_02b7; } IL_02b7: if (5__4-- > 0) { <>2__current = 5__3.Key.Select((RegionInfo info) => info.Region).ToList(); <>1__state = 2; return true; } 5__3 = null; goto IL_02d5; IL_02d5: if (<>7__wrap1.MoveNext()) { 5__3 = <>7__wrap1.Current; 5__4 = 5__3.Count(); if (5__4 <= 0) { FeatureLogger.Exception(new NotSupportedException("Somehow had 0 placements in placement group!?")); } List list = new List(); foreach (RegionInfo item in 5__3.Key) { if (item.IsBad) { list.Add(item); 5__4--; if (5__4 == 0) { break; } } } foreach (RegionInfo item2 in list) { 5__3.Key.Remove(item2); } <>7__wrap4 = list.GetEnumerator(); <>1__state = -4; goto IL_0249; } <>m__Finally1(); <>7__wrap1 = null; return false; IL_0249: if (<>7__wrap4.MoveNext()) { RegionInfo current3 = <>7__wrap4.Current; <>2__current = new List(from info in 5__3.Key.Append(current3) select info.Region); <>1__state = 1; return true; } <>m__Finally2(); <>7__wrap4 = default(List.Enumerator); goto IL_02b7; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } private void <>m__Finally2() { <>1__state = -3; ((IDisposable)<>7__wrap4).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator> IEnumerable>.GetEnumerator() { d__81 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__81(0); } d__.placements = <>3__placements; d__.neededCount = <>3__neededCount; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable>)this).GetEnumerator(); } } public const string s_menuRegionName = "Menu"; private StorageType Storage { get; init; } public bool IsComplete { get { return Storage.IsComplete; } set { Storage.IsComplete = value; } } public string? Name { get { return Storage.Name; } set { Storage.Name = value; } } public MidManager Manager => Storage.Manager; private Dictionary ExpeditionLookup => Storage.ExpeditionLookup; private List RegionList => Storage.RegionList; private Dictionary RegionLookup => Storage.RegionLookup; private List PathList => Storage.PathList; private List TagDefinitions => Storage.TagDefinitions; private Dictionary TagLookup => Storage.TagLookup; private List LocationList => Storage.LocationList; private Dictionary LocationLookup => Storage.LocationLookup; private List ItemList => Storage.ItemList; private Dictionary ItemLookup => Storage.ItemLookup; private List FloatingItems => Storage.FloatingItems; public string MenuRegionName => "Menu"; public RegionID MenuRegion => LookupOrCreateRegion(MenuRegionName); public Data(MidManager manager) { Storage = new StorageType { Manager = manager }; LookupOrCreateRegion(MenuRegionName); AddItem(new Item(LookupOrCreateTag("Empty", "An item used to balance randomization during fill", RootRandomizationTags.get_Tag_Never(this)), new ItemData { IsFiller = true })); } public Data(Data other) { Storage = other.Storage; } public bool TryRegisterExpedition(string name, Expedition.Data data) { if (IsComplete) { FeatureLogger.Warning("Adding late expedition: " + name); } return ExpeditionLookup.TryAdd(name, data); } public IReadOnlyDictionary GetAllExpeditions() { return ExpeditionLookup; } public bool TryLookupExpedition(string name, [NotNullWhen(true)] out Expedition.Data? data) { return ExpeditionLookup.TryGetValue(name, out data); } public RandomizationTag LookupOrCreateTag(string tagName, string tagDesc, Func? parentResolver) { if (!TagLookup.TryGetValue(tagName, out var value)) { if (IsComplete) { FeatureLogger.Warning("Adding late tag: " + tagName); } RandomizationTag parent = parentResolver?.Invoke(this) ?? new RandomizationTag(); RandomizationTag randomizationTag = new RandomizationTag(); randomizationTag.AsIndex = TagDefinitions.Count; value = randomizationTag; TagDefinitions.Add(new RandomizationTagDefinition(tagName, tagDesc, parent)); TagLookup.Add(tagName, value); } return value; } public IReadOnlyDictionary GetAllTags() { return new ReadOnlyListDict(TagDefinitions); } public bool TryLookupTag(string tagName, out RandomizationTag existingTag) { return TagLookup.TryGetValue(tagName, out existingTag); } public RandomizationTagDefinition LookupTagDef(RandomizationTag tag) { return TagDefinitions[tag.AsIndex]; } public bool TagMatches(RandomizationTag parent, RandomizationTag child) { if (parent.IsNull) { throw new ArgumentNullException("parent"); } if (child.IsNull) { throw new ArgumentNullException("child"); } do { if (parent.Equals(child)) { return true; } child = TagDefinitions[child.AsIndex].Parent; } while (!child.IsNull); return false; } public bool TagMatches(RandomizationTag parent, Location loc) { if (!TagMatches(parent, loc.NameTag) && (loc.Tag2.IsNull || !TagMatches(parent, loc.Tag2))) { if (!loc.Tag3.IsNull) { return TagMatches(parent, loc.Tag3); } return false; } return true; } public bool TagMatches(RandomizationTag parent, Item item) { if (!TagMatches(parent, item.NameTag) && (item.Tag2.IsNull || !TagMatches(parent, item.Tag2))) { if (!item.Tag3.IsNull) { return TagMatches(parent, item.Tag3); } return false; } return true; } public bool TagMatches(ICollection parents, RandomizationTag child) { if (child.IsNull) { throw new ArgumentNullException("child"); } if (parents.Count == 0) { return false; } if (parents.Count == 1) { return TagMatches(parents.First(), child); } do { if (parents.Contains(child)) { return true; } child = TagDefinitions[child.AsIndex].Parent; } while (!child.IsNull); return false; } public bool AnyTagMatches(ICollection parents, Location loc) { if (parents.Count == 0) { return false; } if (parents.Count == 1) { return TagMatches(parents.First(), loc); } if (!TagMatches(parents, loc.NameTag) && (loc.Tag2.IsNull || !TagMatches(parents, loc.Tag2))) { if (!loc.Tag3.IsNull) { return TagMatches(parents, loc.Tag3); } return false; } return true; } public bool AllTagsMatch(ICollection parents, Location loc) { if (parents.Count == 0) { return false; } if (TagMatches(parents, loc.NameTag) && (loc.Tag2.IsNull || TagMatches(parents, loc.Tag2))) { if (!loc.Tag3.IsNull) { return TagMatches(parents, loc.Tag3); } return true; } return false; } public bool AnyTagMatches(ICollection parents, Item item) { if (parents.Count == 0) { return false; } if (parents.Count == 1) { return TagMatches(parents.First(), item); } if (!TagMatches(parents, item.NameTag) && (item.Tag2.IsNull || !TagMatches(parents, item.Tag2))) { if (!item.Tag3.IsNull) { return TagMatches(parents, item.Tag3); } return false; } return true; } public bool AllTagsMatch(ICollection parents, Item item) { if (parents.Count == 0) { return false; } if (TagMatches(parents, item.NameTag) && (item.Tag2.IsNull || TagMatches(parents, item.Tag2))) { if (!item.Tag3.IsNull) { return TagMatches(parents, item.Tag3); } return true; } return false; } public RegionID LookupOrCreateRegion(string regionName) { if (!RegionLookup.TryGetValue(regionName, out var value)) { if (IsComplete) { FeatureLogger.Warning("Adding late region: " + regionName); } RegionID regionID = new RegionID(); regionID.AsIndex = RegionList.Count; value = regionID; RegionList.Add(new Region(regionName)); RegionLookup.Add(regionName, value); } return value; } public IReadOnlyDictionary GetAllRegions() { return new ReadOnlyListDict(RegionList); } public bool TryLookupRegion(string regionName, out KeyedRegion region) { if (RegionLookup.TryGetValue(regionName, out var value)) { region = new KeyedRegion(value, LookupRegion(value)); return true; } region = new KeyedRegion(); return false; } public ReadOnlyRegion LookupRegion(RegionID id) { return LookupRegionProtected(id); } public Region LookupRegionProtected(RegionID id) { return RegionList[id.AsIndex]; } public void SetRegionReachable(RegionID id, bool isReachable) { int asIndex = id.AsIndex; if (asIndex < 0 || asIndex >= RegionList.Count) { throw new ArgumentException("Attempted to set reachability for a region which does not exist"); } CollectionsMarshal.AsSpan(RegionList)[id.AsIndex].Reachable = isReachable; } public PathID AddPath(ReadOnlyPath path) { if (IsComplete) { FeatureLogger.Warning("Adding late path: " + (path.Name ?? "NO NAME")); FeatureLogger.Warning(" From " + LookupRegion(path.StartingRegion).Name); FeatureLogger.Warning(" To " + LookupRegion(path.EndingRegion).Name); } if (path.ReqItem.Type != 0 && path.ReqCount == 0) { FeatureLogger.Warning("Adding path with non-None path requirement but it has a reqcount of 0!"); } if (path.StartingRegion.IsNull) { throw new ArgumentNullException("Cannot add path; starting region is null!"); } if (path.EndingRegion.IsNull) { throw new ArgumentNullException("Cannot add path; ending region is null!"); } PathID pathID = new PathID(); pathID.AsIndex = PathList.Count; PathID pathID2 = pathID; PathList.Add(path); LookupRegionProtected(path.StartingRegion).AddPath(pathID2); return pathID2; } public IReadOnlyDictionary GetAllPaths() { return new ReadOnlyListDict(PathList); } public bool TryLookupPath(RegionID start, RegionID end, out ReadOnlyPath path) { path = LookupRegion(start).ConnectedPaths.Select(LookupPath).FirstOrDefault((ReadOnlyPath p) => p.EndingRegion.Equals(end)); return !path.IsNull; } public ReadOnlyPath LookupPath(PathID id) { return PathList[id.AsIndex]; } public void SetPathReqCount(PathID id, uint newCount) { if (IsComplete) { FeatureLogger.Warning($"Late path req modification: PathID {id.AsId}"); } ReTFO.Archipelago.ModdedInstanceData.Model.Path path = PathList[id.AsIndex].MakeMutable(); path.ReqCount = newCount; PathList[id.AsIndex] = path; } public LocationID AddLocation(RandomizationTag nameTag, RegionList regions, LocationData randData) { return AddLocation(nameTag, regions, randData, new ItemID()); } public LocationID AddLocation(RandomizationTag nameTag, RegionList regions, LocationData randData, ItemID item) { return AddLocation(new Location(nameTag, regions, randData) { ItemID = item }); } public LocationID AddLocation(Location location) { if (location.NameTag.IsNull) { throw new ArgumentNullException("Cannot register an item with a null name tag!"); } if (IsComplete) { FeatureLogger.Warning("Adding late location: " + LookupTagDef(location.NameTag).Name); } if (LocationLookup.ContainsKey(location.NameTag)) { FeatureLogger.Error("Failed to add new location: " + LookupTagDef(location.NameTag).Name); return new LocationID(); } LocationID locationID = new LocationID(); locationID.AsIndex = LocationList.Count; LocationID locationID2 = locationID; LocationList.Add(location); LocationLookup.Add(location.NameTag, locationID2); if (location.OwningRegionIds.Distinct().Count() != location.OwningRegionIds.Length) { FeatureLogger.Error("Location is contained in the same region multiple times: " + LookupTagDef(location.NameTag).Name); } RegionID[] owningRegionIds = location.OwningRegionIds; foreach (RegionID regionID in owningRegionIds) { RegionList[regionID.AsIndex].AddLocation(locationID2); } return locationID2; } public IReadOnlyDictionary GetAllLocations() { return new ReadOnlyListDict(LocationList); } public bool TryLookupLocation(RandomizationTag nameTag, out KeyedLocation location) { if (LocationLookup.TryGetValue(nameTag, out var value)) { location = new KeyedLocation(value, LookupLocation(value)); return true; } location = new KeyedLocation(); return false; } public Location LookupLocation(LocationID id) { return LocationList[id.AsIndex]; } public ItemID AddItem(Item item) { if (item.NameTag.IsNull) { throw new ArgumentNullException("Cannot register an item with a null name tag!"); } if (IsComplete) { FeatureLogger.Warning("Adding late item: " + LookupTagDef(item.NameTag).Name); } if (ItemLookup.ContainsKey(item.NameTag)) { string name = TagDefinitions[item.NameTag.AsIndex].Name; throw new ArgumentException("An item with the NameTag " + name + " is already registered!"); } ItemID itemID = new ItemID(); itemID.AsIndex = ItemList.Count; ItemID itemID2 = itemID; ItemList.Add(item); ItemLookup.Add(item.NameTag, itemID2); return itemID2; } public IReadOnlyDictionary GetAllItems() { return new ReadOnlyListDict(ItemList); } public bool TryLookupItem(RandomizationTag name, out KeyedItem item) { if (ItemLookup.TryGetValue(name, out var value)) { item = new KeyedItem(value, LookupItem(value)); return true; } item = new KeyedItem(); return false; } public Item LookupItem(ItemID id) { return ItemList[id.AsIndex]; } public void AddFloatingItem(ItemID id) { if (IsComplete) { FeatureLogger.Warning("Adding late floating item: " + LookupTagDef(LookupItem(id).NameTag).Name); } FloatingItems.Add(id); } public IReadOnlyCollection GetAllFloatingItemIds() { return FloatingItems; } [IteratorStateMachine(typeof(d__81))] public IEnumerable> UnstuffPlacements(IEnumerable> placements, int neededCount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__81(-2) { <>3__placements = placements, <>3__neededCount = neededCount }; } public void CleanUp() { ExpeditionLookup.TrimExcess(); RegionList.TrimExcess(); RegionLookup.TrimExcess(); PathList.TrimExcess(); TagDefinitions.TrimExcess(); TagLookup.TrimExcess(); LocationList.TrimExcess(); LocationLookup.TrimExcess(); ItemList.TrimExcess(); ItemLookup.TrimExcess(); FloatingItems.TrimExcess(); foreach (Region region in RegionList) { region.CleanUp(); } } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor GameProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static Processor get_GameProcessor(Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } } public static class Layer { public class Data : Expedition.Data { public LayerType LayerType { get; private init; } public string LayerName => base.ExpeditionName + " (" + LayerType.GetName() + ")"; public virtual LayerData? LayerDatas { get { if (!LayerType.IsMainLayer) { if (!LayerType.IsSecondaryLayer) { if (!LayerType.IsOverloadLayer) { return null; } return Expedition.ThirdLayerData; } return Expedition.SecondaryLayerData; } return Expedition.MainLayerData; } } public virtual BuildLayerFromData? BuildFromData { get { if (!LayerType.IsSecondaryLayer) { if (!LayerType.IsOverloadLayer) { return null; } return Expedition.BuildThirdFrom; } return Expedition.BuildSecondaryFrom; } } public virtual DimensionInExpeditionData? DimensionEntry { get { if (!LayerType.IsReality) { return Expedition.DimensionDatas.FirstOrDefault((DimensionInExpeditionData d) => d.DimensionIndex == LayerType); } return null; } } public virtual DimensionData? DimensionData { get { DimensionInExpeditionData? dimensionEntry = DimensionEntry; DimensionDataBlock block = GameDataBlockBase.GetBlock((dimensionEntry != null) ? dimensionEntry.DimensionData : 0u); if (block == null) { return null; } return block.DimensionData; } } public virtual uint LayoutID { get { if (!LayerType.IsMainLayer) { if (!LayerType.IsSecondaryLayer) { if (!LayerType.IsOverloadLayer) { DimensionData? dimensionData = DimensionData; if (dimensionData == null) { return 0u; } return dimensionData.LevelLayoutData; } return Expedition.ThirdLayout; } return Expedition.SecondaryLayout; } return Expedition.LevelLayoutData; } } public virtual LevelLayoutDataBlock? Layout => GameDataBlockBase.GetBlock(LayoutID); public Data(Expedition.Data data, LayerType layerType) : base(data) { LayerType = layerType; } public Data(Data other) : base(other) { LayerType = other.LayerType; } public static Data FromLayer(LG_Layer layer) { //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) Expedition.Data data = ReTFO.Archipelago.ModdedInstanceData.Processors.Expedition.Data.FromCurrentExpedition(); LayerType layerType = new LayerType(layer.m_dimension.DimensionIndex, layer.m_type); return new Data(data, layerType); } public static Data FromLayerFlattened(LG_Layer layer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if ((int)layer.m_dimension.DimensionIndex == 0) { return FromLayer(layer); } return get_MainLayer(ReTFO.Archipelago.ModdedInstanceData.Processors.Expedition.Data.FromCurrentExpedition()); } public LG_Layer? GetLG_Layer() { //IL_0010: 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) if (!IsCurrentExepdition()) { return null; } Dimension val = default(Dimension); if (!Dimension.GetDimension((eDimensionIndex)LayerType, ref val)) { return null; } return val.GetLayer((LG_LayerType)LayerType); } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } public Processor SubscribedTo(MidManager.Processor owner) { owner.RegisterCallback(OnProcessExpedition); return this; } protected void OnProcessExpedition(Expedition.Data data) { foreach (Data item in get_AllLayers(data)) { Process(item); } } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor LayerProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $2833969430CAB23CD70890D67B9ADDD5 { [SpecialName] public static class $BBB780E158DEFBC886C4287C5819176C { } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public bool HasMain { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public bool HasSecondary { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public bool HasOverload { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data MainLayer { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public IEnumerable RealLayers { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public IEnumerable DimensionLayers { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public IEnumerable AllLayers { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data GetLayer(LayerType layerType) { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__10 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Data <>2__current; private int <>l__initialThreadId; private Expedition.Data expeditionData; public Expedition.Data <>3__expeditionData; Data IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = new Data(expeditionData, LayerType.Main); <>1__state = 1; return true; case 1: <>1__state = -1; if (get_HasSecondary(expeditionData)) { <>2__current = new Data(expeditionData, LayerType.Secondary); <>1__state = 2; return true; } goto IL_007f; case 2: <>1__state = -1; goto IL_007f; case 3: { <>1__state = -1; break; } IL_007f: if (get_HasOverload(expeditionData)) { <>2__current = new Data(expeditionData, LayerType.Overload); <>1__state = 3; return true; } break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__10 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__10(0); } d__.expeditionData = <>3__expeditionData; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public static Processor get_LayerProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } public static bool get_HasMain(Expedition.Data expeditionData) { return true; } public static bool get_HasSecondary(Expedition.Data expeditionData) { return expeditionData.Expedition.SecondaryLayerEnabled; } public static bool get_HasOverload(Expedition.Data expeditionData) { return expeditionData.Expedition.ThirdLayerEnabled; } public static Data get_MainLayer(Expedition.Data expeditionData) { return new Data(expeditionData, LayerType.Main); } [IteratorStateMachine(typeof(d__10))] public static IEnumerable get_RealLayers(Expedition.Data expeditionData) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() d__10 d__ = new d__10(-2); d__.<>3__expeditionData = expeditionData; return d__; } public static IEnumerable get_DimensionLayers(Expedition.Data expeditionData) { Expedition.Data expeditionData2 = expeditionData; return from e in expeditionData2.Expedition.DimensionDatas where (int)e.DimensionIndex != 22 select new Data(expeditionData2, e.DimensionIndex); } public static IEnumerable get_AllLayers(Expedition.Data expeditionData) { return get_RealLayers(expeditionData).Concat(get_DimensionLayers(expeditionData)); } public static Data GetLayer(this Expedition.Data expeditionData, LayerType layerType) { return new Data(expeditionData, layerType); } } public static class Objective { public class Data : Layer.Data { public int ObjectiveIndex { get; private init; } public WardenObjectiveLayerData ObjectiveData { get { if (ObjectiveIndex != 0) { return LayerDatas.ChainedObjectiveData[ObjectiveIndex - 1]; } return LayerDatas.ObjectiveData; } } public virtual WardenObjectiveDataBlock Objective => GameDataBlockBase.GetBlock(ObjectiveData.DataBlockId) ?? throw new NullReferenceException("Failed to find objective datablock for layer: " + base.LayerName); public Data(Layer.Data data, int objectiveIndex) : base(data) { ObjectiveIndex = objectiveIndex; } public Data(Data other) : base(other) { ObjectiveIndex = other.ObjectiveIndex; } public string ObjectiveName(string? objectiveTypeSummary = null) { return $"{base.LayerName} Objective #{ObjectiveIndex + 1}{((objectiveTypeSummary == null) ? "" : (" (" + objectiveTypeSummary + ")"))}"; } public IWardenObjective GetWardenObjective() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return WardenObjectiveManager.GetWardenObjectiveBehaviour((LG_LayerType)base.LayerType, ObjectiveIndex); } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } public Processor SubscribedTo(MidManager.Processor owner) { owner.RegisterCallback(OnProcessLayer); return this; } protected void OnProcessLayer(Layer.Data data) { if (data.LayerDatas == null) { return; } foreach (Data objectiveData in data.GetObjectiveDatas()) { Process(objectiveData); } } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor ObjectiveProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $9DAFA10623A49E693D4D9BEA615A7202 { [SpecialName] public static class $F9136D71CE7F5E8B956EFAA9F642E37E { } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable GetObjectiveDatas() { throw new NotSupportedException(); } } public static Processor get_ObjectiveProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } public static IEnumerable GetObjectiveDatas(this Layer.Data layerData) { Layer.Data layerData2 = layerData; if (layerData2.LayerDatas == null) { return Enumerable.Empty(); } return from i in Enumerable.Range(0, 1 + (layerData2.LayerDatas.ChainedObjectiveData?.Count ?? 0)) select new Data(layerData2, i); } } public static class Terminal { public class Data : Zone.Data { public int TerminalIndex { get; private init; } public string TerminalName { get { if (!IsStandardTerminal) { if (!IsSpecificTerminal) { throw new NotImplementedException(); } return base.ZoneName + " Terminal (" + SpecificTerminalData.WorldEventObjectFilter + ")"; } return $"{base.ZoneName} Terminal #{TerminalIndex + 1}"; } } public bool IsStandardTerminal => TerminalIndex >= 0; public bool IsSpecificTerminal => TerminalIndex < 0; public TerminalPlacementData StandardTerminalData { get { if (IsSpecificTerminal) { throw new ArgumentException("Attempted to retrieve standard terminal data for specific terminal: " + TerminalName); } ExpeditionZoneData? zone = base.Zone; object obj = ((zone != null) ? zone.TerminalPlacements : null); if (obj == null) { DimensionData? dimensionData = DimensionData; obj = ((dimensionData != null) ? dimensionData.StaticTerminalPlacements : null); } List val = (List)obj; if (val == null) { throw new NullReferenceException("Failed to find standard terminal placement list in zone " + base.ZoneName); } if (TerminalIndex < 0 || TerminalIndex >= val.Count) { throw new ArgumentOutOfRangeException($"Terminal {TerminalIndex} does not exist in standard placement list for zone: {base.ZoneName}"); } return val[TerminalIndex]; } } public SpecificTerminalSpawnData SpecificTerminalData { get { if (IsStandardTerminal) { throw new ArgumentException("Attempted to retrieve specific terminal data for specific terminal: " + TerminalName); } ExpeditionZoneData? zone = base.Zone; List val = ((zone != null) ? zone.SpecificTerminalSpawnDatas : null); if (val == null) { throw new NullReferenceException("Failed to find specific terminal placement list in zone " + base.ZoneName); } int num = -1 - TerminalIndex; if (num < 0 || num >= val.Count) { throw new ArgumentOutOfRangeException($"Terminal {TerminalIndex} does not exist in specific placement list for zone: {base.ZoneName}"); } return val[num]; } } public virtual TerminalStartStateData TerminalStartingStateData { get { if (!IsStandardTerminal) { if (!IsSpecificTerminal) { throw new NotImplementedException(); } return SpecificTerminalData.StartingStateData; } return StandardTerminalData.StartingStateData; } } public virtual List TerminalUniqueCommands { get { if (!IsStandardTerminal) { if (!IsSpecificTerminal) { throw new NotImplementedException(); } return SpecificTerminalData.UniqueCommands; } return StandardTerminalData.UniqueCommands; } } public virtual List TerminalLocalLogs { get { if (!IsStandardTerminal) { if (!IsSpecificTerminal) { throw new NotImplementedException(); } return SpecificTerminalData.LocalLogFiles; } return StandardTerminalData.LocalLogFiles; } } public Data(Zone.Data data, int terminalIndex) : base(data) { TerminalIndex = terminalIndex; } public Data(Data other) : base(other) { TerminalIndex = other.TerminalIndex; } public static IdentifyingLogHandler.IdentifyTerminalResult FromTerminal(LG_ComputerTerminal terminal) { return IdentifyingLogHandler.RetrieveDataFromLog(terminal); } public LG_ComputerTerminal? GetLG_Terminal() { LG_Zone? lG_Zone = GetLG_Zone(); if (lG_Zone == null) { return null; } return lG_Zone.TerminalsSpawnedInZone?.FirstOrDefault((LG_ComputerTerminal t) => (FromTerminal(t).Data?.TerminalIndex ?? 0) == TerminalIndex); } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } public Processor SubscribedTo(MidManager.Processor owner) { owner.RegisterCallback(OnProcessZone); return this; } protected void OnProcessZone(Zone.Data data) { foreach (int item in get_TerminalIndicies(data)) { Process(new Data(data, item)); } } } [SpecialName] public sealed class $9DAFA10623A49E693D4D9BEA615A7202 { [SpecialName] public static class $F9136D71CE7F5E8B956EFAA9F642E37E { } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data FindTerminalByPlacement(TerminalZoneSelectionData placement) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable> PlacementsToTerminalRegions(List> placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable> PlacementsToTerminalRegions(List> placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable> PlacementsToTerminalRegions(IEnumerable> placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable PlacementsToTerminalRegions(List placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable PlacementsToTerminalRegions(IEnumerable placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable PlacementToTerminalRegions(ZonePlacementData placement) { throw new NotSupportedException(); } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor TerminalProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $07060F1A014DE32BC9DAE9AB0EFE08B9 { [SpecialName] public static class $B07C7AC0BE7F4EC51D0D0593FF32C3E1 { } [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] public int StandardTerminalCount { [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] get { throw new NotSupportedException(); } } [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] public int SpecificTerminalCount { [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] get { throw new NotSupportedException(); } } [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] public IEnumerable TerminalIndicies { [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] get { throw new NotSupportedException(); } } [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] public IEnumerable TerminalDatas { [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] get { throw new NotSupportedException(); } } [ExtensionMarker("$B07C7AC0BE7F4EC51D0D0593FF32C3E1")] public Data GetTerminal(int index) { throw new NotSupportedException(); } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $0151B882DB6D8E92BCB0A146352EDB96 { } [ExtensionMarker("$0151B882DB6D8E92BCB0A146352EDB96")] public IEnumerable> ObjectiveToTerminalRegionSets(int count) { throw new NotSupportedException(); } } public static Data FindTerminalByPlacement(this Layer.Data layerData, TerminalZoneSelectionData placement) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return new Data(layerData.FindZoneByIndex(placement.LocalIndex), placement.TerminalIndex); } public static IEnumerable> PlacementsToTerminalRegions(this Layer.Data layerData, List> placements) { Layer.Data layerData2 = layerData; return placements.Select((List ps) => ps.Select((TerminalZoneSelectionData p) => layerData2.FindZoneByIndex(p.LocalIndex).GetTerminal(p.TerminalIndex)).Select(delegate(Data t) { Game.Data.RegionInfo result = default(Game.Data.RegionInfo); result.Region = layerData2.LookupOrCreateRegion(t.TerminalName); result.IsBad = t.TerminalStartingStateData.PasswordProtected; return result; })); } public static IEnumerable> PlacementsToTerminalRegions(this Layer.Data layerData, List> placements) { return layerData.PlacementsToTerminalRegions(placements.Iter>()); } public static IEnumerable> PlacementsToTerminalRegions(this Layer.Data layerData, IEnumerable> placements) { Layer.Data layerData2 = layerData; return placements.Select((List ps) => layerData2.PlacementsToTerminalRegions(ps)); } public static IEnumerable PlacementsToTerminalRegions(this Layer.Data layerData, List placements) { return layerData.PlacementsToTerminalRegions(placements.Iter()); } public static IEnumerable PlacementsToTerminalRegions(this Layer.Data layerData, IEnumerable placements) { Layer.Data layerData2 = layerData; return placements.SelectMany((ZonePlacementData p) => layerData2.PlacementToTerminalRegions(p)); } public static IEnumerable PlacementToTerminalRegions(this Layer.Data layerData, ZonePlacementData placement) { Layer.Data layerData2 = layerData; return get_TerminalDatas(layerData2.FindZoneByPlacement(placement)).Select(delegate(Data t) { Game.Data.RegionInfo result = default(Game.Data.RegionInfo); result.Region = layerData2.LookupOrCreateRegion(t.TerminalName); result.IsBad = t.TerminalStartingStateData.PasswordProtected; return result; }); } public static Processor get_TerminalProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } public static int get_StandardTerminalCount(Zone.Data zoneData) { if (zoneData.Zone == null) { if (zoneData.DimensionData == null) { throw new NotImplementedException(); } if (!zoneData.DimensionData.ForbidTerminalsInDimension) { return zoneData.DimensionData.StaticTerminalPlacements?.Count ?? 0; } return 0; } if (!zoneData.Zone.ForbidTerminalsInZone) { return zoneData.Zone.TerminalPlacements?.Count ?? 0; } return 0; } public static int get_SpecificTerminalCount(Zone.Data zoneData) { if (zoneData.Zone == null) { if (!zoneData.LayerType.IsDimension) { throw new NotImplementedException(); } return 0; } return zoneData.Zone.SpecificTerminalSpawnDatas?.Count ?? 0; } public static IEnumerable get_TerminalIndicies(Zone.Data zoneData) { return Enumerable.Range(-get_SpecificTerminalCount(zoneData), get_SpecificTerminalCount(zoneData) + get_StandardTerminalCount(zoneData)); } public static IEnumerable get_TerminalDatas(Zone.Data zoneData) { Zone.Data zoneData2 = zoneData; return from i in get_TerminalIndicies(zoneData2) select new Data(zoneData2, i); } public static Data GetTerminal(this Zone.Data zoneData, int index) { if (index < -get_SpecificTerminalCount(zoneData) || index >= get_StandardTerminalCount(zoneData)) { FeatureLogger.Error($"Terminal index {index} does not exist in zone: {zoneData.ZoneName}"); index = 0; } return new Data(zoneData, index); } public static IEnumerable> ObjectiveToTerminalRegionSets(this Objective.Data objectiveData, int count) { return objectiveData.UnstuffPlacements(objectiveData.PlacementsToTerminalRegions(objectiveData.ObjectiveData.ZonePlacementDatas), count); } } public static class Zone { public class Data : Layer.Data { public ExpeditionZoneData? Zone { get; private init; } public int ZoneAlias { get { //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) //IL_005b: Expected I4, but got Unknown if (Zone == null) { LevelLayoutDataBlock? layout = Layout; int alias = ((layout != null) ? layout.ZoneAliasStart : 0); DimensionData? dimensionData = DimensionData; return WithOverride(alias, (dimensionData != null) ? dimensionData.StaticAliasOverride : 0); } return WithOverride(Layout.ZoneAliasStart + Zone.LocalIndex, Zone.AliasOverride); } } public string ZoneName => $"{base.LayerName} ZONE_{ZoneAlias}"; public string? CustomGeo { get { if (Zone != null) { return Zone.CustomGeomorph; } return DimensionData.DimensionGeomorph; } } public Data(Layer.Data data, ExpeditionZoneData? zone) : base(data) { Zone = zone; } public Data(Data other) : base(other) { Zone = other.Zone; } private int WithOverride(int alias, int over) { if (over != -1) { return over; } return alias; } public static Data FromZone(LG_Zone zone) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) Layer.Data layerData = Layer.Data.FromLayer(zone.m_layer); return layerData.FindZoneByIndex(zone.LocalIndex); } public LG_Zone? GetLG_Zone() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got I4 //IL_0024->IL0024: Incompatible stack types: O vs I4 //IL_001f->IL0024: Incompatible stack types: I4 vs O //IL_001f->IL0024: Incompatible stack types: O vs I4 LG_Layer lG_Layer = GetLG_Layer(); if (lG_Layer == null) { return null; } object obj = lG_Layer.m_zonesByLocalIndex; ExpeditionZoneData? zone = Zone; int num; if (zone != null) { obj = zone.LocalIndex; num = (int)obj; } else { num = 0; obj = num; num = (int)obj; } int num2 = ((Dictionary)num).FindEntry((eLocalZoneIndex)obj); if (num2 != -1) { return ((Il2CppArrayBase>)(object)lG_Layer.m_zonesByLocalIndex.entries)[num2].value; } return null; } } [AttributeUsage(AttributeTargets.Method)] public class Callback : MidManager.Processor.Callback { } public class Processor : MidManager.Processor { protected event Delegate? Event; public Processor() { RegisterStaticCallbacks(); } public override void RegisterCallback(Delegate callback) { Event += callback; } public override void UnregisterCallback(Delegate callback) { Event -= callback; } public override void Process(Data data) { this.Event?.Invoke(data); } public Processor SubscribedTo(MidManager.Processor owner) { owner.RegisterCallback(OnProcessLayer); return this; } protected void OnProcessLayer(Layer.Data data) { if (data.Layout != null) { Enumerator enumerator = data.Layout.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; Process(new Data(data, current)); } } else { Process(new Data(data, null)); } } } [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public Processor ZoneProcessor { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $2833969430CAB23CD70890D67B9ADDD5 { [SpecialName] public static class $BBB780E158DEFBC886C4287C5819176C { } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data StartingZone { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public RegionID StartingRegion { [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] get { throw new NotSupportedException(); } } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data FindZoneByEvent(WardenObjectiveEventData ev) { throw new NotSupportedException(); } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data FindZoneExact(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zoneIndex) { throw new NotSupportedException(); } [ExtensionMarker("$BBB780E158DEFBC886C4287C5819176C")] public Data FindZoneExact(LayerType layerType, eLocalZoneIndex zoneIndex) { throw new NotSupportedException(); } } [SpecialName] public sealed class $9DAFA10623A49E693D4D9BEA615A7202 { [SpecialName] public static class $F9136D71CE7F5E8B956EFAA9F642E37E { } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data FirstZone { [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable AllZones { [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data FindZoneByPlacement(ZonePlacementData placement) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable> PlacementsToZoneRegions(List> placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable> PlacementsToZoneRegions(IEnumerable> placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable PlacementsToZoneRegions(List placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public IEnumerable PlacementsToZoneRegions(IEnumerable placements) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Game.Data.RegionInfo PlacementToZoneRegion(ZonePlacementData placement) { throw new NotSupportedException(); } [ExtensionMarker("$F9136D71CE7F5E8B956EFAA9F642E37E")] public Data FindZoneByIndex(eLocalZoneIndex zoneIndex) { throw new NotSupportedException(); } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $0151B882DB6D8E92BCB0A146352EDB96 { } [ExtensionMarker("$0151B882DB6D8E92BCB0A146352EDB96")] public IEnumerable> ObjectiveToZoneRegionSets(int count) { throw new NotSupportedException(); } } public static Processor get_ZoneProcessor(Game.Data gameData) { return (Processor)gameData.Manager.GetProcessor(); } public static Data get_StartingZone(Expedition.Data expeditionData) { return get_FirstZone(Layer.get_MainLayer(expeditionData)); } public static RegionID get_StartingRegion(Expedition.Data expeditionData) { return expeditionData.LookupOrCreateRegion(get_StartingZone(expeditionData).ZoneName); } public static Data FindZoneByEvent(this Expedition.Data expeditionData, WardenObjectiveEventData ev) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return expeditionData.FindZoneExact(ev.DimensionIndex, ev.Layer, ev.LocalIndex); } public static Data FindZoneExact(this Expedition.Data expeditionData, eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex zoneIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return expeditionData.FindZoneExact(new LayerType(dimension, layer), zoneIndex); } public static Data FindZoneExact(this Expedition.Data expeditionData, LayerType layerType, eLocalZoneIndex zoneIndex) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return expeditionData.GetLayer(layerType).FindZoneByIndex(zoneIndex); } public static Data get_FirstZone(Layer.Data layerData) { if (layerData.Layout != null) { if ((layerData.Layout.Zones?.Count ?? 0) > 0) { LevelLayoutDataBlock? layout = layerData.Layout; return new Data(layerData, (layout != null) ? layout.Zones[0] : null); } FeatureLogger.Error("Layer has no zones: " + layerData.LayerName); } else if (!layerData.LayerType.IsDimension) { FeatureLogger.Error("Failed to find layout data for layer: " + layerData.LayerName); } return new Data(layerData, null); } public static IEnumerable get_AllZones(Layer.Data layerData) { Layer.Data layerData2 = layerData; if (layerData2.Layout != null) { return layerData2.Layout.Zones.Select((ExpeditionZoneData zone) => new Data(layerData2, zone)); } return Enumerable.Repeat(new Data(layerData2, null), 1); } public static Data FindZoneByPlacement(this Layer.Data layerData, ZonePlacementData placement) { //IL_0001: 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_003f: 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_0032: Unknown result type (might be due to invalid IL or missing references) if (((int)placement.DimensionIndex == 0 && layerData.LayerType.IsReality) || placement.DimensionIndex == layerData.LayerType) { return layerData.FindZoneByIndex(placement.LocalIndex); } return layerData.GetLayer(placement.DimensionIndex).FindZoneByIndex(placement.LocalIndex); } public static IEnumerable> PlacementsToZoneRegions(this Layer.Data layerData, List> placements) { return layerData.PlacementsToZoneRegions(placements.Iter>()); } public static IEnumerable> PlacementsToZoneRegions(this Layer.Data layerData, IEnumerable> placements) { Layer.Data layerData2 = layerData; return placements.Select((List ps) => layerData2.PlacementsToZoneRegions(ps)); } public static IEnumerable PlacementsToZoneRegions(this Layer.Data layerData, List placements) { return layerData.PlacementsToZoneRegions(placements.Iter()); } public static IEnumerable PlacementsToZoneRegions(this Layer.Data layerData, IEnumerable placements) { Layer.Data layerData2 = layerData; return placements.Select((ZonePlacementData p) => layerData2.PlacementToZoneRegion(p)); } public static Game.Data.RegionInfo PlacementToZoneRegion(this Layer.Data layerData, ZonePlacementData placement) { //IL_004e: 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_0061: Invalid comparison between Unknown and I4 Data data = layerData.FindZoneByPlacement(placement); Game.Data.RegionInfo result = default(Game.Data.RegionInfo); result.Region = layerData.LookupOrCreateRegion(data.ZoneName); ExpeditionZoneData? zone = data.Zone; eProgressionPuzzleType? obj; if (zone == null) { obj = null; } else { ProgressionPuzzleData progressionPuzzleToEnter = zone.ProgressionPuzzleToEnter; obj = ((progressionPuzzleToEnter != null) ? new eProgressionPuzzleType?(progressionPuzzleToEnter.PuzzleType) : null); } eProgressionPuzzleType? val = obj; result.IsBad = (int)val.GetValueOrDefault() > 0; return result; } public static Data FindZoneByIndex(this Layer.Data layerData, eLocalZoneIndex zoneIndex) { //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_0016: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (layerData.Layout == null) { if ((int)zoneIndex != 0) { FeatureLogger.Warning("Attempted to find " + Enum.GetName(zoneIndex) + " in dimension with no layout: " + layerData.LayerName); } return new Data(layerData, null); } ExpeditionZoneData val = layerData.Layout.Zones.FirstOrDefault((ExpeditionZoneData z) => z.LocalIndex == zoneIndex); if (val == null) { FeatureLogger.Error("Failed to find " + Enum.GetName(zoneIndex) + " in layer: " + layerData.LayerName); return get_FirstZone(layerData); } return new Data(layerData, val); } public static IEnumerable> ObjectiveToZoneRegionSets(this Objective.Data objectiveData, int count) { return objectiveData.UnstuffPlacements(objectiveData.PlacementsToZoneRegions(objectiveData.ObjectiveData.ZonePlacementDatas), count); } } } namespace ReTFO.Archipelago.ModdedInstanceData.Model { [DataContract] public class Item { [DataMember] public RandomizationTag NameTag { get; init; } [DataMember] public RandomizationTag Tag2 { get; init; } = new RandomizationTag(); [DataMember] public RandomizationTag Tag3 { get; init; } = new RandomizationTag(); [DataMember] public ItemData RandData { get; init; } public RandTest RandMode { get; set; } public virtual Expedition.Data? RequiredExpedition => null; [DataMember] private string? RequiredExpeditionName { get { return RequiredExpedition?.ExpeditionName ?? null; } set { } } [DataMember] public virtual Path.RequiredItem PathReqs => new Path.RequiredItem(Path.RequiredItem.eType.Item, NameTag); public Item(RandomizationTag nameTag, ItemData randData) { NameTag = nameTag; RandData = randData; } public static implicit operator Path.RequiredItem(Item self) { return self.PathReqs; } public virtual void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { } public virtual void OnItemLost(StateTracker stateTracker) { } public virtual void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { } public virtual IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { throw new NotImplementedException(); } } [DataContract] public struct ItemID : INullable, IId, IIndex, IComparable, IEquatable { [DataMember(Name = "Value")] private readonly long m_value; public bool IsNull => m_value == 0; public long AsId { get { return m_value; } init { m_value = value; } } public int AsIndex { get { return checked((int)m_value) - 1; } init { m_value = value + 1; } } public ItemID() { m_value = 0L; } public int CompareTo(ItemID other) { return m_value.CompareTo(other.m_value); } public bool Equals(ItemID other) { return m_value.Equals(other.m_value); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is ItemID other) { return Equals(other); } return false; } public override int GetHashCode() { return m_value.GetHashCode(); } public override string ToString() { return $"ItemID: {m_value}"; } } [DataContract] public struct KeyedItem : INullable { [DataMember] public readonly ItemID ID; [DataMember] public readonly Item Item; public bool IsNull => ID.IsNull; public RandomizationTag NameTag => Item.NameTag; public RandomizationTag Tag2 => Item.Tag2; public RandomizationTag Tag3 => Item.Tag3; public ItemData RandData => Item.RandData; public Path.RequiredItem PathReqs => Item.PathReqs; public KeyedItem() { ID = new ItemID(); Item = null; } public KeyedItem(ItemID id, Item item) { ID = id; Item = item; } public void OnItemObtained(StateTracker stateTracker, long sourceLocationId, PlayerAgent? player) { } public void OnItemLost(StateTracker stateTracker) { } public void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { } public IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { throw new NotImplementedException(); } } [DataContract] public struct ItemData { public enum eType { None = 0, Progression = 1, Useful = 2, Filler = 4, Trap = 8, SkipBalancing = 0x10, Deprioritized = 0x20, RandomLike = 0x40, CollectedByDefault = 0x80 } private readonly eType m_value; [DataMember] public bool IsProgression { get { return (m_value & eType.Progression) != 0; } init { if (value) { m_value |= eType.Progression; } else { m_value &= (eType)(-2); } } } [DataMember] public bool IsUseful { get { return (m_value & eType.Useful) != 0; } init { if (value) { m_value |= eType.Useful; } else { m_value &= (eType)(-3); } } } [DataMember] public bool IsFiller { get { return (m_value & eType.Filler) != 0; } init { if (value) { m_value |= eType.Filler; } else { m_value &= (eType)(-5); } } } [DataMember] public bool IsTrap { get { return (m_value & eType.Trap) != 0; } init { if (value) { m_value |= eType.Trap; } else { m_value &= (eType)(-9); } } } [DataMember] public bool DoSkipBalancing { get { return (m_value & eType.SkipBalancing) != 0; } init { if (value) { m_value |= eType.SkipBalancing; } else { m_value &= (eType)(-17); } } } [DataMember] public bool IsDeprioritized { get { return (m_value & eType.Deprioritized) != 0; } init { if (value) { m_value |= eType.Deprioritized; } else { m_value &= (eType)(-33); } } } [DataMember] public bool CollectedByDefault { get { return (m_value & eType.CollectedByDefault) != 0; } init { if (value) { m_value |= eType.CollectedByDefault; } else { m_value &= (eType)(-129); } } } public bool IsRandomLike { get { return (m_value & eType.RandomLike) != 0; } init { if (value) { m_value |= eType.RandomLike; } else { m_value &= (eType)(-65); } } } public ItemData() { m_value = eType.None; } } public struct LayerType { private int value; public static LayerType Main = (LG_LayerType)0; public static LayerType Secondary = (LG_LayerType)1; public static LayerType Overload = (LG_LayerType)2; public static LayerType Dimension_1 = (eDimensionIndex)1; public static LayerType Dimension_2 = (eDimensionIndex)2; public static LayerType Dimension_3 = (eDimensionIndex)3; public static LayerType Dimension_4 = (eDimensionIndex)4; public static LayerType Dimension_5 = (eDimensionIndex)5; public bool IsReality => !IsDimension; public bool IsMainLayer => this == Main; public bool IsSecondaryLayer => this == Secondary; public bool IsOverloadLayer => this == Overload; public bool IsDimension { get { if (value >= -2) { return value > 0; } return true; } } public LayerType(LG_LayerType layer, eDimensionIndex dimension) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) if ((int)dimension == 0) { this = layer; } else { this = dimension; } } public LayerType(eDimensionIndex dimension, LG_LayerType layer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) if ((int)dimension == 0) { this = layer; } else { this = dimension; } } public static implicit operator LayerType(LG_LayerType layerType) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unsupported input type for neg. //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected I4, but got Unknown LayerType result = default(LayerType); result.value = 0 - layerType; return result; } public static implicit operator LG_LayerType(LayerType layerType) { if (layerType.value > 0) { return (LG_LayerType)0; } return (LG_LayerType)(byte)(-layerType.value); } public static implicit operator LayerType(eDimensionIndex dimensionIndex) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected I4, but got Unknown LayerType result = default(LayerType); result.value = (int)dimensionIndex; return result; } public static implicit operator eDimensionIndex(LayerType layerType) { if (layerType.value < 0) { return (eDimensionIndex)0; } return (eDimensionIndex)layerType.value; } public string GetName() { return value switch { 0 => "Main", -1 => "Secondary", -2 => "Overload", _ => $"Dim #{value}", }; } public static bool operator ==(LayerType left, LayerType right) { return left.Equals(right); } public static bool operator !=(LayerType left, LayerType right) { return !left.Equals(right); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is LayerType layerType) { return value.Equals(layerType.value); } return false; } public override int GetHashCode() { return value.GetHashCode(); } } [DataContract] public class Location { [DataMember] public RandomizationTag NameTag { get; init; } [DataMember] public RandomizationTag Tag2 { get; init; } [DataMember] public RandomizationTag Tag3 { get; init; } [DataMember] public RegionID[] OwningRegionIds { get; init; } [DataMember] public ItemID ItemID { get; set; } = new ItemID(); [DataMember] public LocationData RandData { get; init; } public RandTest RandMode { get; set; } public string? ScoutedItemName { get; set; } public string? ScoutedPlayerName { get; set; } public string? ScoutedGameName { get; set; } public Location(RandomizationTag nameTag, RegionList regions, LocationData randData) { NameTag = nameTag; OwningRegionIds = regions; RandData = randData; } } [DataContract] public struct LocationID : INullable, IId, IIndex, IComparable, IEquatable { [DataMember(Name = "Value")] private readonly long m_value; public bool IsNull => m_value == 0; public long AsId { get { return m_value; } init { m_value = value; } } public int AsIndex { get { return checked((int)m_value) - 1; } init { m_value = value + 1; } } public LocationID() { m_value = 0L; } public int CompareTo(LocationID other) { return m_value.CompareTo(other.m_value); } public bool Equals(LocationID other) { return m_value.Equals(other.m_value); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is LocationID other) { return Equals(other); } return false; } public override int GetHashCode() { return m_value.GetHashCode(); } public override string ToString() { return $"LocationID: {m_value}"; } } [DataContract] public struct KeyedLocation : INullable { [DataMember] public LocationID ID { get; init; } public bool IsNull => ID.IsNull; [DataMember] public Location Location { get; init; } public RandomizationTag NameTag => Location.NameTag; public RegionID[] OwningRegionIds => Location.OwningRegionIds; public ItemID ItemID => Location.ItemID; public LocationData RandData => Location.RandData; public ScoutedItemInfo? ScoutedItem => ScoutedItem; public KeyedLocation() { ID = new LocationID(); Location = null; } public KeyedLocation(LocationID id, Location location) { ID = id; Location = location; } } [DataContract] public struct LocationData { public enum eType { PriorityMask = 3, Default = 0, Priority = 1, Excluded = 2, Trap = 3, AutoDiscover = 4, IsEmpty = 8 } private readonly eType m_value; [DataMember] public eType PriorityMode { get { return m_value & eType.PriorityMask; } init { if (value != (value & eType.PriorityMask)) { throw new ArgumentException("Value assigned to PriorityMode must be a priority type!"); } m_value = value | (m_value & (eType)(-4)); } } public bool IsDefault => PriorityMode == eType.Default; public bool IsPriority => PriorityMode == eType.Priority; public bool IsExcluded => PriorityMode == eType.Excluded; public bool IsTrap => PriorityMode == eType.PriorityMask; public bool IsAutoDiscovered { get { return (m_value & eType.AutoDiscover) != 0; } init { if (value) { m_value |= eType.AutoDiscover; } else { m_value &= (eType)(-5); } } } [DataMember] public bool IsEmpty { get { return (m_value & eType.IsEmpty) != 0; } init { if (value) { m_value |= eType.IsEmpty; } else { m_value &= (eType)(-9); } } } public LocationData() { m_value = eType.Default; } } [DataContract] public struct MidExpeditionData { [DataMember] public string Name { get; set; } [DataMember] public List ReachableRegions { get; set; } } [DataContract] public struct Path : INullable { [DataContract] public struct RequiredItem : INullable { public enum eType { None, Item, Category, Blocked } [DataMember] public eType Type { get; init; } [DataMember] public RandomizationTag Target { get; init; } public bool IsNull => Type == eType.None; public RequiredItem() { Type = eType.None; Target = new RandomizationTag(); } public RequiredItem(eType type, RandomizationTag target) { Type = eType.None; Target = new RandomizationTag(); Type = type; Target = target; } } public class ByStartingRegionComparer : IComparer { public int Compare(Path x, Path y) { int num = x.StartingRegion.CompareTo(y.StartingRegion); if (num == 0) { num = x.EndingRegion.CompareTo(y.EndingRegion); } return num; } } public class ByEndingRegionComparer : IComparer { public int Compare(Path x, Path y) { int num = x.EndingRegion.CompareTo(y.EndingRegion); if (num == 0) { num = x.StartingRegion.CompareTo(y.StartingRegion); } return num; } } [DataMember] public string? Name { get; set; } [DataMember] public RegionID StartingRegion { get; set; } [DataMember] public RegionID EndingRegion { get; set; } [DataMember] public RequiredItem ReqItem { get; set; } [DataMember] public uint ReqCount { get; set; } [DataMember] public RequiredItem AlternateItem { get; set; } public bool IsNull => StartingRegion.Equals(EndingRegion); public Path() { Name = null; StartingRegion = new RegionID(); EndingRegion = new RegionID(); ReqItem = new RequiredItem(); ReqCount = 0u; AlternateItem = new RequiredItem(); } public override string ToString() { return $"{StartingRegion} => {EndingRegion}"; } } [DataContract] public struct PathID : INullable, IId, IIndex, IComparable, IEquatable { [DataMember(Name = "Value")] private readonly long m_value; public bool IsNull => m_value == 0; public long AsId { get { return m_value; } init { m_value = value; } } public int AsIndex { get { return checked((int)m_value) - 1; } init { m_value = value + 1; } } public PathID() { m_value = 0L; } public int CompareTo(PathID other) { return m_value.CompareTo(other.m_value); } public bool Equals(PathID other) { return m_value.Equals(other.m_value); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is PathID other) { return Equals(other); } return false; } public override int GetHashCode() { return m_value.GetHashCode(); } public override string ToString() { return $"PathID: {m_value}"; } } [DataContract] public struct ReadOnlyPath : INullable { [DataMember(Name = "ContainedPath")] private readonly Path m_path; public string? Name => m_path.Name; public RegionID StartingRegion => m_path.StartingRegion; public RegionID EndingRegion => m_path.EndingRegion; public Path.RequiredItem ReqItem => m_path.ReqItem; public uint ReqCount => m_path.ReqCount; public Path.RequiredItem AlternateItem => m_path.AlternateItem; public bool IsNull => m_path.IsNull; public ReadOnlyPath(Path source) { m_path = source; } public override string ToString() { return m_path.ToString(); } public Path MakeMutable() { return m_path; } public static implicit operator ReadOnlyPath(Path source) { return new ReadOnlyPath(source); } } [DataContract] public struct KeyedPath : INullable { [DataMember] public PathID ID { get; init; } public bool IsNull => ID.IsNull; [DataMember] public ReadOnlyPath Path { get; init; } public string? Name => Path.Name; public RegionID StartingRegion => Path.StartingRegion; public RegionID EndingRegion => Path.EndingRegion; public Path.RequiredItem ReqItem => Path.ReqItem; public uint ReqCount => Path.ReqCount; public Path.RequiredItem AlternateItem => Path.AlternateItem; public KeyedPath() { ID = new PathID(); Path = default(ReadOnlyPath); } public KeyedPath(PathID id, ReadOnlyPath path) { ID = id; Path = path; } } [DataContract] public struct RandomizationTag : INullable, IId, IIndex, IComparable, IEquatable { [DataMember(Name = "Value")] private readonly long m_value; public bool IsNull => m_value == 0; public long AsId { get { return m_value; } init { m_value = value; } } public int AsIndex { get { return checked((int)m_value) - 1; } init { m_value = value + 1; } } public RandomizationTag() { m_value = 0L; } public int CompareTo(RandomizationTag other) { return m_value.CompareTo(other.m_value); } public bool Equals(RandomizationTag other) { return m_value.Equals(other.m_value); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is RandomizationTag other) { return Equals(other); } return false; } public override int GetHashCode() { return m_value.GetHashCode(); } public override string ToString() { return $"TagID: {m_value}"; } } [DataContract] public struct RandomizationTagDefinition { [DataMember] public string Name { get; private init; } [DataMember] public string Description { get; private init; } [DataMember] public RandomizationTag Parent { get; private init; } public RandomizationTagDefinition(string name, string description, RandomizationTag parent) { Name = name; Description = description; Parent = parent; } } [DataContract] public struct KeyedRandomizationTag { [DataMember] public readonly RandomizationTag ID; [DataMember] public readonly RandomizationTagDefinition Definition; public KeyedRandomizationTag() { ID = new RandomizationTag(); Definition = default(RandomizationTagDefinition); } public KeyedRandomizationTag(RandomizationTag id, RandomizationTagDefinition definition) { ID = id; Definition = definition; } } public struct TagResolver { public Game.Data DataForSelfResolving { get; init; } public Func Resolver { get; init; } public TagResolver(Game.Data data, Func resolver) { DataForSelfResolving = data; Resolver = resolver; } public RandomizationTag SelfResolve() { return Resolver(DataForSelfResolving); } public static implicit operator Func(TagResolver resolver) { return resolver.Resolver; } public static implicit operator RandomizationTag(TagResolver resolver) { return resolver.SelfResolve(); } } public static class RootRandomizationTags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_All { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_Always { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_Never { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_AllLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_AllItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_UnlockItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_GoalItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_OptionalItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ScanItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_WarpItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $2833969430CAB23CD70890D67B9ADDD5 { [SpecialName] public static class $5667123F7013DAD37BB214B248F3E5D2 { } [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] public TagResolver Tag_UnlockItems_ByExpedition { [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] public TagResolver Tag_GoalItems_ByExpedition { [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_All(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("All", "Enables randomization of all items and locations", null)); } public static TagResolver get_Tag_Always(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Always", "This tag is always in the whitelist", null)); } public static TagResolver get_Tag_Never(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Never", "This tag is always in the blacklist", null)); } public static TagResolver get_Tag_AllLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("All Locations", "Enables randomization of all locations", get_Tag_All(gd))); } public static TagResolver get_Tag_AllItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("All Items", "Enables randomization of all items", get_Tag_All(gd))); } public static TagResolver get_Tag_UnlockItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Unlock Items", "Used internally to identify items needed to access certain groups of regions.", null)); } public static TagResolver get_Tag_GoalItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Goal Items", "Used internally to identify \"goal\" items. All available goal items must be collected for AP to consider the slot won.", get_Tag_Never(gd))); } public static TagResolver get_Tag_OptionalItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Optional Items", "Items which only exist if they are randomized.", get_Tag_AllItems(gd))); } public static TagResolver get_Tag_ScanItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Scan Items", "Items which trigger scans", get_Tag_AllItems(gd))); } public static TagResolver get_Tag_WarpItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Warp Items", "All items which cause players to teleport", get_Tag_AllItems(gd))); } public static TagResolver get_Tag_UnlockItems_ByExpedition(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Unlock Items", "Base tag for unlock items for a specific expedition", get_Tag_UnlockItems(gd))); } public static TagResolver get_Tag_GoalItems_ByExpedition(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Goal Items", "Base tag for goal items for a specific expedition", get_Tag_GoalItems(gd))); } } public struct RandTest { public enum eType { None = 0, Randomlike = 1, Randomized = 2, LocationBlacklisted = 4, LocationNotWhitelisted = 6, ItemExpeditionNotRandomized = 8, ItemBlacklisted = 10, ItemNotWhitelisted = 12, UnusedEmptyLocation = 14 } private readonly eType m_value; public eType Type => m_value & (eType)(-2); public bool IsRandomized => Type == eType.Randomized; public bool IsRandomLike => (m_value & eType.Randomlike) == eType.Randomlike; public bool IsTreatedAsRandom { get { if (!IsRandomized) { return IsRandomLike; } return true; } } public RandTest() { m_value = eType.None; } public RandTest(eType type) { m_value = type; } } [DataContract] public struct Region { private List m_connectedPaths; private List m_connectedLocations; [DataMember] public string Name { get; private init; } public bool Reachable { get; set; } public IReadOnlyCollection ConnectedPaths { get { return m_connectedPaths; } init { m_connectedPaths.AddRange(value); } } public IReadOnlyCollection ConnectedLocations { get { return m_connectedLocations; } init { m_connectedLocations.AddRange(value); } } public Region(string name) { Reachable = false; m_connectedPaths = new List(); m_connectedLocations = new List(); Name = name; } public Region(Region other) { Reachable = false; m_connectedPaths = new List(); m_connectedLocations = new List(); Name = other.Name; Reachable = other.Reachable; ConnectedPaths = other.ConnectedPaths; ConnectedLocations = other.ConnectedLocations; } public void AddPath(PathID pathID) { if (m_connectedPaths.Contains(pathID)) { FeatureLogger.Error($"Cannot add duplicated path {pathID} to region: {Name}"); } else { m_connectedPaths.Add(pathID); } } public void AddLocation(LocationID locationID) { if (m_connectedLocations.Contains(locationID)) { FeatureLogger.Error($"Cannot add duplicate location {locationID.AsId} to region: {Name}"); } else { m_connectedLocations.Add(locationID); } } public void CleanUp() { m_connectedPaths.TrimExcess(); m_connectedLocations.TrimExcess(); } } [DataContract] public struct RegionID : INullable, IId, IIndex, IComparable, IEquatable { [DataMember(Name = "Value")] private readonly long m_value; public bool IsNull => m_value == 0; public long AsId { get { return m_value; } init { m_value = value; } } public int AsIndex { get { return checked((int)m_value) - 1; } init { m_value = value + 1; } } public RegionID() { m_value = 0L; } public int CompareTo(RegionID other) { return m_value.CompareTo(other.m_value); } public bool Equals(RegionID other) { return m_value.Equals(other.m_value); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is RegionID other) { return Equals(other); } return false; } public override int GetHashCode() { return m_value.GetHashCode(); } public override string ToString() { return $"RegionID: {m_value}"; } } [DataContract] public struct KeyedRegion : INullable { [DataMember] public readonly RegionID ID; [DataMember] public ReadOnlyRegion Region; public bool IsNull => ID.IsNull; public KeyedRegion() { ID = new RegionID(); Region = default(ReadOnlyRegion); } public KeyedRegion(RegionID id, ReadOnlyRegion region) { ID = id; Region = region; } } [DataContract] public struct ReadOnlyRegion { [DataMember(Name = "ContainedRegion")] private Region m_region; public string Name => m_region.Name; public bool Reachable => m_region.Reachable; public IReadOnlyCollection ConnectedPaths => m_region.ConnectedPaths; public IReadOnlyCollection ConnectedLocationIds => m_region.ConnectedLocations; public ReadOnlyRegion(Region source) { m_region = source; } public static implicit operator ReadOnlyRegion(Region source) { return new ReadOnlyRegion(source); } public Region MakeMutable() { return new Region(m_region); } } public struct RegionList : IList, ICollection, IEnumerable, IEnumerable, IList, ICollection, IReadOnlyList, IReadOnlyCollection { private RegionID[] value; public int Count => ((ICollection)value).Count; public bool IsReadOnly => ((ICollection)value).IsReadOnly; public bool IsFixedSize => ((IList)value).IsFixedSize; public bool IsSynchronized => ((ICollection)value).IsSynchronized; public object SyncRoot => ((ICollection)value).SyncRoot; object? IList.this[int index] { get { return ((IList)value)[index]; } set { ((IList)this.value)[index] = value; } } public RegionID this[int index] { get { return ((IList)value)[index]; } set { ((IList)this.value)[index] = value; } } public RegionList(RegionID[] value) { this.value = value; } public static implicit operator RegionList(RegionID r) { return new RegionList(new RegionID[1] { r }); } public static implicit operator RegionList(RegionID[] rs) { return new RegionList(rs); } public static implicit operator RegionList(List rs) { return new RegionList(rs.ToArray()); } public static implicit operator RegionID[](RegionList rs) { return rs.value; } public int IndexOf(RegionID item) { return ((IList)value).IndexOf(item); } public void Insert(int index, RegionID item) { ((IList)value).Insert(index, item); } public void RemoveAt(int index) { ((IList)value).RemoveAt(index); } public void Add(RegionID item) { ((ICollection)value).Add(item); } public void Clear() { ((ICollection)value).Clear(); } public bool Contains(RegionID item) { return ((ICollection)value).Contains(item); } public void CopyTo(RegionID[] array, int arrayIndex) { ((ICollection)value).CopyTo(array, arrayIndex); } public bool Remove(RegionID item) { return ((ICollection)value).Remove(item); } public IEnumerator GetEnumerator() { return ((IEnumerable)value).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)value).GetEnumerator(); } public int Add(object? value) { return ((IList)this.value).Add(value); } public bool Contains(object? value) { return ((IList)this.value).Contains(value); } public int IndexOf(object? value) { return ((IList)this.value).IndexOf(value); } public void Insert(int index, object? value) { ((IList)this.value).Insert(index, value); } public void Remove(object? value) { ((IList)this.value).Remove(value); } public void CopyTo(Array array, int index) { ((ICollection)value).CopyTo(array, index); } } } namespace ReTFO.Archipelago.Features { public static class ArchipelagoFeatureGroups { [SpecialName] public sealed class $FA5CA4C8FB765F09369548ABC9DA4644 { [SpecialName] public static class $5B642FDDEBE75B7890A6FDD81284E91D { } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup Archipelago { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup VanillaHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup FloatingHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup ZoneHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup TerminalHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup PickupHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup EventHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] public static FeatureGroup ObjectiveHandlers { [ExtensionMarker("$5B642FDDEBE75B7890A6FDD81284E91D")] get { throw new NotSupportedException(); } } } public const string ArchipelagoFeatureGroupName = "Archipelago"; public const string VanillaHandlersGroupName = "Vanilla Handlers"; public const string FloatingHandlersGroupName = "Floating Handlers"; public const string ZoneHandlersGroupName = "Zone Handlers"; public const string TerminalHandlersGroupName = "Terminal Handlers"; public const string PickupHandlersGroupName = "Pickup Handlers"; public const string EventHandlersGroupName = "Event Handlers"; public const string ObjectiveHandlersGroupName = "Objective Handlers"; public static FeatureGroup get_Archipelago() { return FeatureGroups.GetOrCreateTopLevelGroup("Archipelago", (GroupLocalization)null); } public static FeatureGroup get_VanillaHandlers() { return get_Archipelago().GetOrCreateSubGroup("Vanilla Handlers", false); } public static FeatureGroup get_FloatingHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Floating Handlers", false); } public static FeatureGroup get_ZoneHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Zone Handlers", false); } public static FeatureGroup get_TerminalHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Terminal Handlers", false); } public static FeatureGroup get_PickupHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Pickup Handlers", false); } public static FeatureGroup get_EventHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Event Handlers", false); } public static FeatureGroup get_ObjectiveHandlers() { return get_VanillaHandlers().GetOrCreateSubGroup("Objective Handlers", false); } } [EnableFeatureByDefault] public class ChatHandler : ArchipelagoFeature { public class Settings { [FSDisplayName("Hide Non-Randomized Checks")] [FSDescription("If true, prevent messages for unrandomized from appearing locally, including messages for items which cannot be randomized.")] public bool DoHideTrivialChecks { get; set; } = true; [FSDisplayName("Shorten Received Item Messages")] [FSDescription("If true, show a shortened version of all \"X received Y\" messages")] public bool DoShortenReceivedItemMessages { get; set; } = true; [FSDisplayName("Show Only My Received Items")] [FSDescription("If true, only show \"X received Y\" messages if you are the recipient")] public bool DoShowOnlyMyRecievedItemMessages { get; set; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerChatManager__WantToSentTextMessage__Patch { public static void Postfix(PlayerAgent? fromPlayer, string? message, PlayerAgent? toPlayer) { if (message == null || (Object)(object)toPlayer != (Object)null) { return; } StateTracker stateTracker = StateTracker.Get(); if (stateTracker.ApSession != null) { if (fromPlayer != null && !((Agent)fromPlayer).IsLocallyOwned) { stateTracker.ApSession.Say(fromPlayer.Owner.NickName + ": " + message); } else { stateTracker.ApSession.Say(message); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerChatManager__Setup__Patch { public static void Postfix() { TryRemoveChatLimitations(); } } private static IArchiveLogger? m_featureLogger; private Queue m_messages = new Queue(); private SNet_PacketBufferBytes? m_packet; public override string Name => "Chat Manager"; public override string Description => "Handles chat messages to/from Archipelago"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [FeatureConfig] public static Settings Config { get; set; } public IEnumerable Messages => m_messages; public override void OnEnable() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown base.OnEnable(); Plugin plugin = Plugin.Get(); if (plugin.StateTracker != null) { plugin.StateTracker.OnStateChange += OnStateChanged; if (plugin.StateTracker.ApSession != null) { plugin.StateTracker.ApSession.MessageLog.OnMessageReceived += new MessageReceivedHandler(OnMessageReceived); } } else { plugin.LateSetup += OnLateSetup; } } public override void OnDisable() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown base.OnDisable(); StateTracker stateTracker = StateTracker.Get(); stateTracker.OnStateChange -= OnStateChanged; if (stateTracker.ApSession != null) { stateTracker.ApSession.MessageLog.OnMessageReceived -= new MessageReceivedHandler(OnMessageReceived); } } protected void OnLateSetup(SNet_Replicator replicator) { Action, BufferData> action = OnSNetPacketReceived; m_packet = replicator.CreatePacketBytes(DelegateSupport.ConvertDelegate, BufferData>>((Delegate)action)); StateTracker.Get().OnStateChange += OnStateChanged; } protected void OnStateChanged(StateTracker stateTracker) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (stateTracker.ApSession != null) { stateTracker.ApSession.MessageLog.OnMessageReceived += new MessageReceivedHandler(OnMessageReceived); } } public static string ColorToHex(Color color) { return "#" + (((Color)(ref color)).R >> 4).ToString("X1") + (((Color)(ref color)).G >> 4).ToString("X1") + (((Color)(ref color)).B >> 4).ToString("X1"); } protected void OnSNetPacketReceived(Il2CppStructArray bytes, BufferData data) { StateTracker stateTracker = StateTracker.Get(); if (stateTracker.ApSession == null) { int index = 0; string text = SerializationHelpers.ReadString(bytes, ref index); if (text != null) { StateTracker.LogForLobby(text, localOnly: true); } } } protected void OnMessageReceived(LogMessage message) { //IL_00ff: 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_014a: Expected I4, but got Unknown PlayerSpecificLogMessage val = (PlayerSpecificLogMessage)(object)((message is PlayerSpecificLogMessage) ? message : null); if (val != null && val.IsActivePlayer) { return; } ItemSendLogMessage val2 = (ItemSendLogMessage)(object)((message is ItemSendLogMessage) ? message : null); if (val2 != null) { if (Config.DoHideTrivialChecks) { LocationID locationID = new LocationID(); locationID.AsId = val2.Item.LocationId; LocationID id = locationID; Game.Data processedGameData = StateTracker.Get().MidManager.GetProcessedGameData(); if (!processedGameData.LookupLocation(id).RandMode.IsRandomized) { return; } } if (Config.DoShowOnlyMyRecievedItemMessages && val2.Item.Player.Slot != StateTracker.Get().ApSession.Players.ActivePlayer.Slot) { return; } } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < message.Parts.Length; i++) { if (!(message is ItemSendLogMessage) || !Config.DoShortenReceivedItemMessages || i <= 2) { MessagePart val3 = message.Parts[i]; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendLiteral("<"); handler.AppendFormatted(ColorToHex(val3.Color)); handler.AppendLiteral(">"); stringBuilder2.Append(ref handler); MessagePartType type = val3.Type; switch ((int)type) { case 0: stringBuilder.Append(val3.Text); break; case 1: case 2: case 3: case 4: stringBuilder.Append(""); stringBuilder.Append(val3.Text); stringBuilder.Append(""); break; case 5: stringBuilder.Append(""); stringBuilder.Append(val3.Text); stringBuilder.Append(""); break; } } } stringBuilder.Append(""); m_messages.Enqueue(stringBuilder.ToString()); while (m_messages.Count > 15) { m_messages.Dequeue(); } } public override void Update() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) string result; while (m_messages.TryDequeue(out result)) { StateTracker.LogForLobby(result, localOnly: true); if (SNet.IsMaster) { Il2CppStructArray val = new Il2CppStructArray((long)SerializationHelpers.CalcStringSize(result)); int index = 0; SerializationHelpers.WriteString(val, ref index, result); SNet_PacketBufferBytes? packet = m_packet; if (packet != null) { packet.Send(val, SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendGroup)2, (SNet_SendQuality)2, 4); } } } } public static void TryRemoveChatLimitations() { if ((Object)(object)PlayerChatManager.Current != (Object)null) { PlayerChatManager.Current.m_maxLen = 255; PlayerChatManager.Current.m_forbiddenChars = Il2CppStructArray.op_Implicit(Array.Empty()); } } } [EnableFeatureByDefault] public class CustomObjectiveHandler : ArchipelagoFeature { public enum eObjectiveScope { Expedition, Dimension, Layer, Zone } public class ObjectiveItem { private eObjectiveScope m_scope = eObjectiveScope.Layer; private GlobalZoneIndex m_scopeTarget = new GlobalZoneIndex((eDimensionIndex)0, (LG_LayerType)0, (eLocalZoneIndex)0); private bool m_isActive = true; protected static PUI_GameObjectives GUI => GuiManager.PlayerLayer.WardenObjectives; public int PUI_ID { get; private set; } public bool IsVisible { get; private set; } public int Priority { get; set; } = -100; public eObjectiveScope Scope { get { return m_scope; } set { m_scope = value; CheckScope(TryGetCurrentCourseNode()); } } public GlobalZoneIndex ScopeTarget { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return m_scopeTarget; } set { //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) m_scopeTarget = value; CheckScope(TryGetCurrentCourseNode()); } } public bool IsInScope { get; private set; } public bool IsActive { get { return m_isActive; } set { m_isActive = value; Refresh(force: false); } } public bool SkipStyling { get; set; } public bool SkipBlinking { get; set; } public string ObjectiveTag { get; set; } = "CUSTOM"; public string HeaderText { get; set; } = "CUSTOM SUBOBJECTIVE"; public string SubText { get; set; } = "This is a custom sub objective.\n Hello World!"; public virtual void Setup() { CheckScope(TryGetCurrentCourseNode()); Refresh(); } protected static AIG_CourseNode? TryGetCurrentCourseNode() { PlayerAgent val = default(PlayerAgent); if (PlayerManager.TryGetLocalPlayerAgent(ref val)) { return ((Agent)val).CourseNode; } return null; } public string GetHeaderText() { return HeaderText; } public string GetSubText() { return SubText; } public void ShowNow(bool force = true) { if (!((Feature)ArchipelagoFeatureHelper.GetFeature()).Enabled) { HideNow(); return; } if (!IsVisible) { PUI_ID = -4; while (GUI.m_progressionObjectiveMap.FindEntry(PUI_ID) != -1) { int pUI_ID = PUI_ID + 1; PUI_ID = pUI_ID; } } if (!IsVisible || force) { GUI.SetProgressionObjective(PUI_ID, (Func)new Il2CppFunc_string(GetHeaderText), (Func)new Il2CppFunc_string(GetSubText), Priority, SkipStyling, SkipBlinking, ObjectiveTag); } IsVisible = true; } public void HideNow() { if (IsVisible) { GUI.RemoveProgressionObjective(PUI_ID, false); } IsVisible = false; } public virtual void CheckScope(AIG_CourseNode? localNode) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (localNode == null && Scope != 0) { IsInScope = false; } else { IsInScope = true; if (Scope >= eObjectiveScope.Dimension) { IsInScope = IsInScope && localNode.m_zone.DimensionIndex == ScopeTarget.Dimension; } if (Scope >= eObjectiveScope.Layer) { IsInScope = IsInScope && localNode.LayerType == ScopeTarget.Layer; } if (Scope >= eObjectiveScope.Zone) { IsInScope = IsInScope && localNode.m_zone.LocalIndex == ScopeTarget.Zone; } } Refresh(force: false); } public void Refresh(bool force = true) { if (IsInScope && IsActive) { ShowNow(force); } else { HideNow(); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class ProgressionObjectivesManager__OnLevelCleanup__Patch { public static void Postfix() { foreach (ObjectiveItem value in s_objectives.Values) { value.HideNow(); } s_objectives.Clear(); FeatureLogger.Debug("Cleared custom progression objectives"); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerAgent__SetCourseNode__Patch { public static void Postfix(PlayerAgent __instance) { if (!((Agent)__instance).IsLocallyOwned) { return; } foreach (ObjectiveItem value in s_objectives.Values) { value.CheckScope(((Agent)__instance).CourseNode); } } } private static IArchiveLogger? m_featureLogger = null; private static Dictionary s_objectives = new Dictionary(); public override string Name => "Custom Objective Handler"; public override string Description => "Handles the display of custom objective UI. This is used by several handlers, such as the Reactor Startup handler, to display collected items"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_VanillaHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public override void OnEnable() { base.OnEnable(); AIG_CourseNode localNode = null; PlayerAgent val = default(PlayerAgent); if (PlayerManager.TryGetLocalPlayerAgent(ref val)) { localNode = ((Agent)val).CourseNode; } foreach (KeyValuePair s_objective in s_objectives) { s_objective.Value.CheckScope(localNode); } } public static T GetObjectiveItem(string key) where T : ObjectiveItem, new() { if (s_objectives.TryGetValue(key, out ObjectiveItem value)) { return (T)value; } T val = new T(); s_objectives.Add(key, val); val.Setup(); FeatureLogger.Debug("Registered new objective item: " + key); return val; } } public class DeathLinkHandler : ArchipelagoFeature { public class Settings { [Localized] public enum TriggerType { OnHumanPlayerDowned, OnAnyDowned, OnExpeditionFail } [Localized] public enum EffectType { SpawnTanks, SpawnSnatchers, SpawnNightmareScouts, DealDamage, DeleteResources, DownRandomPlayer, DownRandomHumanPlayer } [FSDisplayName("DeathLink Trigger")] [FSDescription("What in GTFO triggers a DeathLink event to be sent to the multiverse.\n\nOn Human Player Downed\nWhen the number of human (non-bot) players downed meets or multiples the threshold, or on expedition fail.\n\nOn Any Downed\nWhen the number of players (including bots) downed meets or multiples the threshold, or on expedition fail.\n\nOn Expedition Fail\nWhen an expedition ends in failure (not success, not abort).")] public TriggerType Trigger { get; set; } = TriggerType.OnExpeditionFail; [FSDisplayName("DeathLink Trigger Threshold")] [FSDescription("The number of players who must be downed at the same time for the DeathLink to trigger. 1 will trigger anytime someone is downed; 2 on 2, 4, 6, ... downed; 3 on 3, 6, ...; etc ")] public int TriggerThreshold { get; set; } = 2; [FSDisplayName("DeathLink Effect")] [FSDescription("What in GTFO happens when a DeathLink event is received from the multiverse.\n\nSpawn Tanks\nSpawn the supplied number of tanks (immediately aggressive).\n\nSpawn Snatchers\nSpawn the supplied number of snatchers. One is spawned immediately, the rest are chain-spawned in 1-5 minute intervals.\n\nSpawn Nightmare Scouts\nSpawn the supplied number of nightmare scouts (still asleep) in random unoccupied zones.\n\nDeal Damage\nThe supplied percent is dealt as damage to each player, killing them if necessary.\n\nDelete Resources\nThe supplied percent is dealt as damage AND deleted from all gear for each player. If this would kill a player, they are instead left at 1% health.\n\nDown Random Player\nThe supplied number of players are randomly picked and immediately downed.\n\nDown Random Human Player\nThe supplied number of players are immediately downed, randomly picked with a priority for humans.")] public EffectType Effect { get; set; } = EffectType.DownRandomPlayer; [FSDisplayName("DeathLink Effect Number")] [FSDescription("The number used in numerous DeathLink effects. If a percent, scale from 0 to 100.")] public int EffectNumber { get; set; } = 1; [FSDisplayName("DeathLink Cooldown (Seconds)")] [FSDescription("Cooldown after sending or receiving a DeathLink during which another cannot be sent or received.\n\nThis exists because receiving a DeathLink can quickly result in sending a new DeathLink, and because certain DeathLink trigger configs are capable of triggering multiple DeathLinks in quick succession.")] public float Cooldown { get; set; } = 10f; [FSDisplayName("Trigger Now")] [FSDescription("Immediately try to trigger the DeathLink effect. Affects this GTFO lobby only; is restricted by the cooldown")] public FButton TriggerEffectButton { get; set; } = new FButton("Test DeathLink", (string)null, (Action)delegate { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown if (!SNet.IsMaster) { StateTracker.LogForLobby("You cannot trigger a death link; you are not host!", localOnly: true); } else { string hostName = HostName; PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); TryTriggerDeathLink(new DeathLink(hostName, (((localPlayerAgent != null) ? localPlayerAgent.Owner.NickName : null) ?? "Someone") + " hit the \"Test DeathLink\" button.")); } }, false); [FSDisplayName("Show Messages")] [FSDescription("If true, show death messages when sending or receiving a DeathLink event.")] public bool DoShowMessages { get; set; } = true; } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class Dam_PlayerDamageBase__ReceiveSetDead__Patch { public static void Postfix(Dam_PlayerDamageBase __instance, pSetDeadData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) CheckDeath(__instance, data); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class Dam_PlayerDamageLocal__ReceiveSetDead__Patch { public static void Postfix(Dam_PlayerDamageBase __instance, pSetDeadData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) CheckDeath(__instance, data); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class GameStateManager__DoChangeState__Patch { public static void Postfix(eGameStateName nextState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)nextState == 15 && Config.Trigger < (Settings.TriggerType)3) { NotifyDied("Team " + HostName + " marked MIA. Objective failed."); } } } [CompilerGenerated] private static class <>O { public static Action <0>__OnStateTrackerStateChange; public static DeathLinkReceivedHandler <1>__TryTriggerDeathLink; } private static IArchiveLogger? m_featureLogger = null; private static DeathLinkService? s_service = null; private static float LastTriggerTime = 0f; private static float LastSnatcherTime = -1000f; public override string Name => "Death Link"; public override string Description => "Handles death link"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [FeatureConfig] public static Settings Config { get; set; } = null; public static string HostName { get { ArchipelagoSession? apSession = StateTracker.Get().ApSession; object obj = ((apSession != null) ? apSession.Players.ActivePlayer.Name : null); if (obj == null) { SNet_Player master = SNet.Master; obj = ((master != null) ? master.NickName : null) ?? "Admin"; } if (obj == null) { obj = ""; } return (string)obj; } } public override void OnEnable() { //IL_0067: 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: Expected O, but got Unknown base.OnEnable(); StateTracker stateTracker = StateTracker.Get(); stateTracker.OnStateChange += OnStateTrackerStateChange; if (s_service == null) { ArchipelagoSession? apSession = stateTracker.ApSession; s_service = ((apSession != null) ? DeathLinkProvider.CreateDeathLinkService(apSession) : null); } if (s_service != null) { DeathLinkService? obj = s_service; object obj2 = <>O.<1>__TryTriggerDeathLink; if (obj2 == null) { DeathLinkReceivedHandler val = TryTriggerDeathLink; <>O.<1>__TryTriggerDeathLink = val; obj2 = (object)val; } obj.OnDeathLinkReceived += (DeathLinkReceivedHandler)obj2; DeathLinkService? obj3 = s_service; if (obj3 != null) { obj3.EnableDeathLink(); } } } public override void OnDisable() { base.OnDisable(); StateTracker stateTracker = StateTracker.Get(); stateTracker.OnStateChange -= OnStateTrackerStateChange; DeathLinkService? obj = s_service; if (obj != null) { obj.DisableDeathLink(); } } public static void OnStateTrackerStateChange(StateTracker stateTracker) { //IL_0060: 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_006b: Expected O, but got Unknown if (Time.realtimeSinceStartup - Config.Cooldown <= LastTriggerTime) { return; } LastTriggerTime = Time.realtimeSinceStartup; if (s_service == null) { ArchipelagoSession? apSession = StateTracker.Get().ApSession; s_service = ((apSession != null) ? DeathLinkProvider.CreateDeathLinkService(apSession) : null); } if (s_service != null) { DeathLinkService? obj = s_service; object obj2 = <>O.<1>__TryTriggerDeathLink; if (obj2 == null) { DeathLinkReceivedHandler val = TryTriggerDeathLink; <>O.<1>__TryTriggerDeathLink = val; obj2 = (object)val; } obj.OnDeathLinkReceived += (DeathLinkReceivedHandler)obj2; DeathLinkService? obj3 = s_service; if (obj3 != null) { obj3.EnableDeathLink(); } } } public static void TryTriggerDeathLink(DeathLink data) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b9: 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_00d0: 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_00df: 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_00f3: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //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_0131: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_015c: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Expected O, but got Unknown //IL_035e: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } FeatureLogger.Debug("Received DeathLink event"); if (!GameStateManager.IsInExpedition || Time.realtimeSinceStartup + Config.Cooldown <= LastTriggerTime) { return; } LastTriggerTime = Time.realtimeSinceStartup; if (Config.DoShowMessages && data.Cause != null) { StateTracker.LogForLobby("<#F0F>[Death] " + data.Cause, localOnly: false); } switch (Config.Effect) { case Settings.EffectType.SpawnTanks: { WardenObjectiveEventData val7 = new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)9, EnemyWaveData = new GenericEnemyWaveData { AreaDistance = 2, IntelMessage = LocalizedText.op_Implicit(0u), SpawnDelay = 1f, TriggerAlarm = false, WavePopulation = 16u, WaveSettings = 30u, WorldEventObjectFilterSpawnPoint = null }, Delay = 0f }; for (int j = 0; j < Config.EffectNumber; j++) { WorldEventManager.ExecuteEvent(val7, 0f); } break; } case Settings.EffectType.SpawnSnatchers: { WardenObjectiveEventData val5 = new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)9, EnemyWaveData = new GenericEnemyWaveData { AreaDistance = 2, IntelMessage = LocalizedText.op_Implicit(0u), SpawnDelay = 1f, TriggerAlarm = false, WavePopulation = 56u, WaveSettings = 30u, WorldEventObjectFilterSpawnPoint = null }, Delay = MathF.Max(0f, LastSnatcherTime - Time.fixedTime + 60f + Random.Shared.NextSingle() * 240f) }; for (int i = 0; i < Config.EffectNumber; i++) { WorldEventManager.ExecuteEvent(val5, 0f); val5.Delay += 60f + Random.Shared.NextSingle() * 240f; } LastSnatcherTime = Time.fixedTime + val5.Delay; break; } case Settings.EffectType.SpawnNightmareScouts: { HashSet hashSet = AIG_CourseNode.s_allNodes.Select((AIG_CourseNode n) => ((Il2CppObjectBase)n).Pointer).ToHashSet(); Enumerator enumerator = SNet.LobbyPlayers.GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; object obj; if (current == null) { obj = null; } else { SNet_IPlayerAgent playerAgent = current.PlayerAgent; obj = ((playerAgent != null) ? ((Il2CppObjectBase)playerAgent).TryCast() : null); } PlayerAgent agent = (PlayerAgent)obj; PlayerAgent obj2 = agent; if (((obj2 != null) ? ((Agent)obj2).CourseNode : null) == null) { continue; } hashSet.Remove(((Il2CppObjectBase)((Agent)agent).CourseNode).Pointer); foreach (AIG_CourseNode item in ((Agent)agent).CourseNode.m_portals.Select((AIG_CoursePortal p) => p.GetOppositeNode(((Agent)agent).CourseNode))) { hashSet.Remove(((Il2CppObjectBase)item).Pointer); } } int effectNumber3 = Config.EffectNumber; while (effectNumber3-- > 0 && hashSet.Count > 0) { IntPtr intPtr = hashSet.ElementAt(Random.Shared.Next(0, hashSet.Count)); hashSet.Remove(intPtr); AIG_CourseNode val3 = new AIG_CourseNode(intPtr); EnemyAgent.SpawnEnemy(56u, val3.GetRandomPositionInside(), val3, (AgentMode)3); } break; } case Settings.EffectType.DealDamage: { Enumerator enumerator4 = SNet.LobbyPlayers.GetEnumerator(); while (enumerator4.MoveNext()) { SNet_Player current4 = enumerator4.Current; object obj4; if (current4 == null) { obj4 = null; } else { SNet_IPlayerAgent playerAgent3 = current4.PlayerAgent; obj4 = ((playerAgent3 != null) ? ((Il2CppObjectBase)playerAgent3).TryCast() : null); } PlayerAgent val6 = (PlayerAgent)obj4; if (val6 != null) { ((Dam_SyncedDamageBase)val6.Damage).FallDamage((float)Config.EffectNumber * 0.25f); } } break; } case Settings.EffectType.DeleteResources: { Enumerator enumerator3 = SNet.LobbyPlayers.GetEnumerator(); while (enumerator3.MoveNext()) { SNet_Player current3 = enumerator3.Current; object obj3; if (current3 == null) { obj3 = null; } else { SNet_IPlayerAgent playerAgent2 = current3.PlayerAgent; obj3 = ((playerAgent2 != null) ? ((Il2CppObjectBase)playerAgent2).TryCast() : null); } PlayerAgent val4 = (PlayerAgent)obj3; float num = MathF.Min((((val4 != null) ? ((Dam_SyncedDamageBase)val4.Damage).Health : 0f) - 0.25f) * 25f, (float)Config.EffectNumber * 0.25f); if (val4 != null) { ((Dam_SyncedDamageBase)val4.Damage).FallDamage(num); } PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(current3); InventorySlotAmmo standardAmmo = backpack.AmmoStorage.StandardAmmo; standardAmmo.AmmoInPack -= MathF.Min((float)Config.EffectNumber * 4.6f, backpack.AmmoStorage.StandardAmmo.AmmoInPack); InventorySlotAmmo specialAmmo = backpack.AmmoStorage.SpecialAmmo; specialAmmo.AmmoInPack -= MathF.Min((float)Config.EffectNumber * 2.3f, backpack.AmmoStorage.SpecialAmmo.AmmoInPack); InventorySlotAmmo classAmmo = backpack.AmmoStorage.ClassAmmo; classAmmo.AmmoInPack -= MathF.Min((float)Config.EffectNumber * 1.5f, backpack.AmmoStorage.ClassAmmo.AmmoInPack); } break; } case Settings.EffectType.DownRandomPlayer: { List list2 = (from p in SNet.LobbyPlayers select ((Il2CppObjectBase)p.PlayerAgent).Cast() into p where ((Agent)p).Alive select p).ToList(); int effectNumber2 = Config.EffectNumber; while (effectNumber2-- > 0 && list2.Count > 0) { PlayerAgent val2 = list2[Random.Shared.Next(0, list2.Count)]; list2.Remove(val2); ((Dam_SyncedDamageBase)val2.Damage).FallDamage(100000000f); } break; } case Settings.EffectType.DownRandomHumanPlayer: { List list = (from p in SNet.LobbyPlayers where !p.IsBot select ((Il2CppObjectBase)p.PlayerAgent).Cast() into p where ((Agent)p).Alive select p).ToList(); int effectNumber = Config.EffectNumber; while (effectNumber-- > 0 && list.Count > 0) { PlayerAgent val = list[Random.Shared.Next(0, list.Count)]; list.Remove(val); ((Dam_SyncedDamageBase)val.Damage).FallDamage(100000000f); if (effectNumber > 0 && list.Count == 0) { list = (from p in SNet.LobbyPlayers select ((Il2CppObjectBase)p.PlayerAgent).Cast() into p where ((Agent)p).Alive select p).ToList(); } } break; } default: FeatureLogger.Error("Unrecognized DeathLink effect: " + (int)Config.Effect); break; } } public static void NotifyDied(string cause) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown if (SNet.IsMaster && !(Time.realtimeSinceStartup - Config.Cooldown <= LastTriggerTime)) { LastTriggerTime = Time.realtimeSinceStartup; FeatureLogger.Debug("Sending DeathLink event: " + cause); DeathLinkService? obj = s_service; if (obj != null) { obj.SendDeathLink(new DeathLink(HostName, cause)); } if (Config.DoShowMessages) { StateTracker.LogForLobby("<#F0F>[Death] " + cause, localOnly: false); } } } public static void CheckDeath(Dam_PlayerDamageBase __instance, pSetDeadData data) { if (!((Agent)__instance.Owner).Alive) { return; } int num; if (Config.Trigger == Settings.TriggerType.OnAnyDowned) { num = SNet.LobbyPlayers.Where((SNet_Player p) => ((Agent)((Il2CppObjectBase)p.PlayerAgent).Cast()).Alive).Count(); } else { if (Config.Trigger != 0 || __instance.Owner.Owner.IsBot) { return; } num = SNet.LobbyPlayers.Where((SNet_Player p) => !p.IsBot && ((Agent)((Il2CppObjectBase)p.PlayerAgent).Cast()).Alive).Count(); } if (Config.TriggerThreshold == 0 || num % Config.TriggerThreshold == 0) { NotifyDied("Team " + HostName + " suffering casualties. Objective success compromised."); } } } [EnableFeatureByDefault] [InjectToIl2Cpp] public class EnergyLinkHandler : ArchipelagoFeature { public class Settings { private float m_output = 0.75f; private float m_input = 1f; [FSDisplayName("Output Conversion Rate")] [FSDescription("When sending energy to your team, how much is sent? Higher values increase the amount sent.")] public float OutputConversionRate { get { return m_output; } set { m_output = MathF.Max(value, 0f); } } [FSDisplayName("Input Consumption Rate")] [FSDescription("When consuming energy from the team, how much is consumed? Higher values increase the amount consumed.")] public float InputConsumptionRate { get { return m_input; } set { m_input = MathF.Max(value, 0f); } } } [InjectToIl2Cpp] private class EnergyReplicator : Object { public struct pEnergyPacket { public enum eType : byte { Get, Add, Take, Take_NoCancel, Get_Success, Get_Fail, Take_Success, Take_Fail } public readonly eType Type; public readonly BigInteger Amount; public readonly ulong PlayerLookup; public pEnergyPacket(eType type, BigInteger amount, ulong playerLookup) { Type = type; Amount = amount; PlayerLookup = playerLookup; } public int CalcByteSize() { int byteCount = Amount.GetByteCount(); return 1 + SerializationHelpers.CalcLengthSize(byteCount) + byteCount + SerializationHelpers.Calc7BitEncodedSize(PlayerLookup); } public Il2CppStructArray ToBytes(int offset = 0) { Il2CppStructArray val = new Il2CppStructArray((long)(CalcByteSize() + offset)); WriteToBytes(val, ref offset); return val; } public void WriteToBytes(Il2CppStructArray bytes, ref int index) { byte[] array = Amount.ToByteArray(); ((Il2CppArrayBase)(object)bytes)[index++] = (byte)Type; SerializationHelpers.WriteLength(bytes, ref index, array.Length); for (int i = 0; i < array.Length; i++) { ((Il2CppArrayBase)(object)bytes)[index++] = array[i]; } SerializationHelpers.Write7BitEncodedLong(bytes, ref index, PlayerLookup); } public static pEnergyPacket ReadFromBytes(Il2CppStructArray bytes, ref int index) { long num = SerializationHelpers.ReadLength(bytes, ref index); eType type = (eType)((Il2CppArrayBase)(object)bytes)[index++]; byte[] array = new byte[num]; for (int i = 0; i < num; i++) { array[i] = ((Il2CppArrayBase)(object)bytes)[index++]; } ulong playerLookup = SerializationHelpers.Read7BitEncodedULong(bytes, ref index); return new pEnergyPacket(type, new BigInteger(array), playerLookup); } public static pEnergyPacket ReadFromBytes(Il2CppStructArray bytes) { int index = 0; return ReadFromBytes(bytes, ref index); } } private SNet_PacketBufferBytes? m_packet; private SortedList> m_responseTasks = new SortedList>(); public EnergyReplicator(IntPtr ptr) : base(ptr) { } public EnergyReplicator(SNet_Replicator replicator) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceive", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_packet = replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); } [HideFromIl2Cpp] public Task SendRequest(pEnergyPacket.eType type, BigInteger requestAmount) { //IL_0002: 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_006f: Unknown result type (might be due to invalid IL or missing references) pPlayer val = default(pPlayer); ((pPlayer)(ref val)).SetPlayer(PlayerManager.GetLocalPlayerAgent().Owner); pEnergyPacket pEnergyPacket = new pEnergyPacket(type, requestAmount, val.lookup); ushort num = (ushort)(m_responseTasks.Count + 1); TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); while (m_responseTasks.ContainsKey(num)) { num++; } m_responseTasks.Add(num, taskCompletionSource); m_packet.Send(pEnergyPacket.ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData(num, (byte)0)), (SNet_SendQuality)2, 0, SNet.Master); return taskCompletionSource.Task; } public void OnReceive(Il2CppStructArray bytes, BufferData data) { //IL_0016: 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_0032: 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) pEnergyPacket pEnergyPacket = pEnergyPacket.ReadFromBytes(bytes); pPlayer val = default(pPlayer); val.lookup = pEnergyPacket.PlayerLookup; val.IsBot = false; pPlayer val2 = val; SNet_Player player = default(SNet_Player); if (!((pPlayer)(ref val2)).GetPlayer(ref player)) { FeatureLogger.Error("Received energy request, but could not identify response player!"); return; } ushort requestId = data.bufferID; switch (pEnergyPacket.Type) { case pEnergyPacket.eType.Get: GetCurrentEnergy().ContinueWith(delegate(Task t) { SendResponse(player, requestId, t.IsCompletedSuccessfully ? pEnergyPacket.eType.Get_Success : pEnergyPacket.eType.Get_Fail, t.IsCompletedSuccessfully ? t.Result : ((BigInteger)0)); }); break; case pEnergyPacket.eType.Add: AddEnergy(pEnergyPacket.Amount); break; case pEnergyPacket.eType.Take: RequestEnergy(pEnergyPacket.Amount, allowCancel: true).ContinueWith(delegate(Task t) { SendResponse(player, requestId, t.IsCompletedSuccessfully ? pEnergyPacket.eType.Take_Success : pEnergyPacket.eType.Take_Fail, t.IsCompletedSuccessfully ? t.Result : ((BigInteger)0)); }); break; case pEnergyPacket.eType.Take_NoCancel: RequestEnergy(pEnergyPacket.Amount, allowCancel: false).ContinueWith(delegate(Task t) { SendResponse(player, requestId, t.IsCompletedSuccessfully ? pEnergyPacket.eType.Take_Success : pEnergyPacket.eType.Take_Fail, t.IsCompletedSuccessfully ? t.Result : ((BigInteger)0)); }); break; case pEnergyPacket.eType.Get_Success: case pEnergyPacket.eType.Take_Success: m_responseTasks[requestId].SetResult(pEnergyPacket.Amount); m_responseTasks.Remove(requestId); break; case pEnergyPacket.eType.Get_Fail: case pEnergyPacket.eType.Take_Fail: m_responseTasks[requestId].SetCanceled(); m_responseTasks.Remove(requestId); break; default: throw new NotSupportedException($"Request type {pEnergyPacket.Type} not supported!"); } } [HideFromIl2Cpp] public void SendResponse(SNet_Player toPlayer, ushort id, pEnergyPacket.eType type, BigInteger amount) { //IL_0002: 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_0040: Unknown result type (might be due to invalid IL or missing references) pPlayer val = default(pPlayer); PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); ((pPlayer)(ref val)).SetPlayer((localPlayerAgent != null) ? localPlayerAgent.Owner : null); pEnergyPacket pEnergyPacket = new pEnergyPacket(type, amount, val.lookup); m_packet.Send(pEnergyPacket.ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData(id, (byte)0)), (SNet_SendQuality)2, 0, SNet.Master); } } private static IArchiveLogger? m_featureLogger; private EnergyReplicator? m_replicator; public override string Name => "Energy Link"; public override string Description => "Handles energy link. This handler controls all energy in/out, but does not add or remove any by itself."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [FeatureConfig] public static Settings Config { get; set; } public override void OnEnable() { base.OnEnable(); Plugin.Get().LateSetup += delegate(SNet_Replicator replicator) { m_replicator = new EnergyReplicator(replicator); StateTracker.Get().OnStateChange += delegate(StateTracker st) { ArchipelagoSession? apSession = st.ApSession; if (apSession != null) { apSession.DataStorage[$"EnergyLink{st.ApSession.Players.ActivePlayer.Team}"].Initialize(JToken.op_Implicit(0)); } }; }; } private static BigInteger Multiply(BigInteger value, double conversion) { if (value.Sign < 0) { throw new ArgumentException("Cannot use a negative bigint value"); } if (conversion < 0.0) { throw new ArgumentException("Cannot use a negative conversion multiplier"); } byte[] array = value.ToByteArray(); BigInteger result = 0; if (Math.Abs(conversion) < 1.0) { for (int i = 0; i < Math.Min(8, array.Length); i++) { result += (BigInteger)(ulong)(conversion * (double)((ulong)array[i] << i)); } for (int j = 8; j < array.Length; j++) { result += (BigInteger)(ulong)(conversion * (double)((ulong)array[j] << 8)); } } else { for (int k = 0; k < array.Length; k++) { result += (BigInteger)(ulong)(conversion * (double)array[k]); } } return result; } public static async Task GetCurrentEnergy() { if (SNet.IsMaster) { StateTracker stateTracker = StateTracker.Get(); if (stateTracker.ApSession == null) { FeatureLogger.Debug("Due to fake connect, pretending to have a lot of energy"); return 1234567890000000000L; } return Multiply(DataStorageElement.op_Implicit(stateTracker.ApSession.DataStorage[$"EnergyLink{stateTracker.ApSession.Players.ActivePlayer.Team}"]), 1f / Config.InputConsumptionRate); } EnergyLinkHandler feature = ArchipelagoFeatureHelper.GetFeature(); return await feature.m_replicator.SendRequest(EnergyReplicator.pEnergyPacket.eType.Get, 0); } public static async Task RequestEnergy(BigInteger amount, bool allowCancel) { if (SNet.IsMaster) { StateTracker stateTracker = StateTracker.Get(); if (amount.Sign < 0) { throw new ArgumentException("Cannot request less than 0 energy!"); } if (stateTracker.ApSession == null) { FeatureLogger.Debug("Due to fake connect, approving energy request"); return amount; } BigInteger bigInteger = Multiply(amount, 1f / Config.InputConsumptionRate); IDataStorageHelper dataStorage = stateTracker.ApSession.DataStorage; string text = $"EnergyLink{stateTracker.ApSession.Players.ActivePlayer.Team}"; DataStorageElement val2 = (dataStorage[text] -= bigInteger); return DataStorageElement.op_Implicit(val2 + Operation.Max(0)); } EnergyLinkHandler feature = ArchipelagoFeatureHelper.GetFeature(); EnergyReplicator.pEnergyPacket.eType type = (allowCancel ? EnergyReplicator.pEnergyPacket.eType.Take : EnergyReplicator.pEnergyPacket.eType.Take_NoCancel); return await feature.m_replicator.SendRequest(type, amount); } public static async Task AddEnergy(BigInteger amount) { if (SNet.IsMaster) { StateTracker stateTracker = StateTracker.Get(); if (stateTracker.ApSession == null) { FeatureLogger.Debug("Due to fake connect, ignoring energy add request"); return; } if (amount.Sign < 0) { throw new ArgumentException("Cannot add less than 0 energy!"); } IDataStorageHelper dataStorage = stateTracker.ApSession.DataStorage; string text = $"EnergyLink{stateTracker.ApSession.Players.ActivePlayer.Team}"; dataStorage[text] += Multiply(amount, Config.OutputConversionRate); } else { EnergyLinkHandler feature = ArchipelagoFeatureHelper.GetFeature(); await feature.m_replicator.SendRequest(EnergyReplicator.pEnergyPacket.eType.Add, amount); } } } [ForceDisable("Too much overhead.\nPotential memory leak issues.")] public class StatefulFeatureLogger : Feature { [HarmonyPatch] private static class __OnExecute__Patch { public static IEnumerable GetMethodsRecursive(Type type, Type? featureType = null) { Type featureType2 = featureType; if (type.IsAssignableTo(typeof(ArchipelagoFeature))) { featureType2 = type; } IEnumerable enumerable = type.GetNestedTypes().SelectMany((Type t) => GetMethodsRecursive(t, featureType2)); if (featureType2 != null) { IEnumerable second = from m in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.CustomAttributes.Any((CustomAttributeData ca) => ca.AttributeType.IsAssignableTo(typeof(MidManager.Processor.CallbackBase))) select m; IEnumerable second2 = (from t in type.GetNestedTypes() where t.CustomAttributes.Any((CustomAttributeData ca) => ca.AttributeType.IsAssignableTo(typeof(ArchivePatch))) select t).SelectMany((Type t) => t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); enumerable = enumerable.Concat(second).Concat(second2); } return enumerable; } [HarmonyTargetMethods] public static IEnumerable TargetMethods() { return AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a) { try { return a.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.OfType(); } }).SelectMany((Type t) => GetMethodsRecursive(t)); } [HarmonyPrefix] public static void Prefix(IArchiveLogger __state, MethodBase __originalMethod) { __state = ReTFO.Archipelago.FeaturesAPI.FeatureLogger.Current; object? value = Search(__originalMethod.DeclaringType).GetValue(null); ReTFO.Archipelago.FeaturesAPI.FeatureLogger.Current = (IArchiveLogger)((value is IArchiveLogger) ? value : null); static PropertyInfo Search(Type type) { return type.GetProperty("FeatureLogger", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? Search(type.DeclaringType); } } [HarmonyPostfix] public static void Postfix(IArchiveLogger __state, MethodBase __originalMethod) { ReTFO.Archipelago.FeaturesAPI.FeatureLogger.Current = __state; } } private static IArchiveLogger? m_featureLogger; private Harmony? m_harmony; public override string Name => "Stateful Feature Logging"; public override string Description => "Modifies Archipelago features to track which is executing.\nMakes some logs (errors, warnings, etc) appear to come from the currently executing feature."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public Harmony Harmony { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (Harmony)(((object)m_harmony) ?? ((object)new Harmony("RoboRyGuy.BetaArchipelago.StatefulFeatureLogger"))); } protected set { m_harmony = value; } } public override void OnEnable() { Harmony.PatchAll(typeof(__OnExecute__Patch)); } public override void OnDisable() { Harmony.UnpatchSelf(); } } [EnableFeatureByDefault] [AutomatedFeature] [InjectToIl2Cpp] public class StateTracker : ArchipelagoFeature { public enum eState { CleanState, HostConnecting, HostConnected, HostReconnecting, FakeConnect, ConnectedClient, ProxyClient } public class Settings : PrivateFeatureSettingsPatch.IOptionallyPrivate { public bool IsCurrentlyPrivate => HideConnectionDetails; [FSDisplayName("Use Debug Mode")] [FSDescription("Skip connecting to Archipelago and start in debug mode.")] public bool UseDebugMode { get; set; } [FSDisplayName("Hide Connection Details")] [FSDescription("For streamers. Hides connection details while not editing them. Also prevents them from being logged.")] public bool HideConnectionDetails { get; set; } = true; [FSDisplayName("Server Address")] [FSDescription("Address of the server to connect to.\nSupports IPv4 and IPv6 addresses, as well as domain names.")] [PrivateFeatureSettingsPatch.FSOptionallyPrivate] public string ServerAddress { get; set; } = "localhost"; [FSDisplayName("Server Port")] [FSDescription("Port of the server\nValid port numbers are in the 16-bit range (0-65535)\nArchipelago defaults to using port 38281")] [PrivateFeatureSettingsPatch.FSOptionallyPrivate] public ushort Port { get; set; } = 38281; [FSDisplayName("Slot Name")] [FSDescription("Slot in the server to try to connect to.")] [PrivateFeatureSettingsPatch.FSOptionallyPrivate] public string Username { get; set; } = "admin"; [FSDisplayName("Use Password")] [FSDescription("If true, will attempt to authenticate to Archipelago using the below password\nIf false, will try to skip password authentication")] public bool HasPassword { get; set; } [FSDisplayName("Password")] [FSDescription("The password to use when connecting to Archipelago")] [PrivateFeatureSettingsPatch.FSOptionallyPrivate] public string Password { get; set; } = "Password"; [FSDisplayName("Empty Trash")] [FSDescription("Unmark any trash items, revealing their checks in the expedition location counts.")] public FButton EmptyTrashButton { get; set; } = new FButton("Empty Trash", (string)null, (Action)delegate { StateTracker stateTracker = Get(); stateTracker.TrashedLocations.Clear(); stateTracker.SendInteraction(pArchipelagoInteraction.eType.EmptyTrash, 0L, 0); }, false); [FSDisplayName("Export MID Data")] [FSDescription("Export the MID data file to your Downloads folder. The MID data file is a \".ini\" file which can be used to create APWorlds for modded rundowns.\nTo use the MID file, place it into the Players folder (the same folder you normally place YAMLs) and restart the launcher. This will add a new GTFO world which can then be used to play your modded game. This sub-world can be reused by any players running the same mods as you, and should be left in the Players folder at least until your game is generated.")] public FButton ExportMidDataButton { get; set; } = new FButton("Export", (string)null, (Action)delegate { Get().MidManager.ExportMidData(); }, false); [FSDisplayName("Export Tags to CSV")] [FSDescription("Export all tag data as a CSV file to your Downloads folder.\nThe CSV export is for an Excel-style viewing of tags, and is easier to parse programmatically.")] public FButton ExportTagsToCSVButton { get; set; } = new FButton("Export", (string)null, (Action)delegate { Get().MidManager.ExportTagsToCSV(); }, false); [FSDisplayName("Export Tags to JSON")] [FSDescription("Export all tag data as a JSON file to your Downloads folder.\nThe JSON export is for hierarchal viewing of the tags, and can make viewing tags easier if you have a good JSON viewer (such as VS Code). Several websites also have good JSON viewers available for free online without needing to download or install anything.")] public FButton ExportTagsToJSONButton { get; set; } = new FButton("Export", (string)null, (Action)delegate { Get().MidManager.ExportTagsToJSON(); }, false); } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PUI_GameEventLog__OnLevelCleanup__Patch { public static bool Prefix() { return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class WardenObjectiveManager__OnLocalPlayerStartExpedition__Patch { public static void Postfix() { StateTracker feature = ArchipelagoFeatureHelper.GetFeature(); ArchipelagoSession? apSession = feature.ApSession; if (apSession != null) { apSession.SetClientState((ArchipelagoClientState)20); } Expedition.Data data = Expedition.Data.TryFromCurrentExpedition(); if (data == null) { FeatureLogger.Error("Failed to identify expedition on drop; skipping relevant events"); } else { FeatureLogger.Notice("Started expedition: " + data.ExpeditionName); } feature.ItemsInTerminalSystem.Clear(); Game.Data processedGameData = feature.MidManager.GetProcessedGameData(); if (data != null) { foreach (ItemID item2 in feature.ActualItemCounts.SelectMany((KeyValuePair pair) => Enumerable.Repeat(pair.Key, pair.Value))) { Item item = processedGameData.LookupItem(item2); item.OnStartExpeditionWithItem(feature, data); } return; } FeatureLogger.Error(" -> Items not added to terminal system!"); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_ExpeditionIcon_New__SetArtifactHeat__Patch { public static bool Prefix(CM_ExpeditionIcon_New __instance) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_018f: 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) StateTracker stateTracker = Get(); Game.Data gameData = stateTracker.MidManager.GetProcessedGameData(); if (!gameData.TryLookupExpedition(__instance.DataBlock.Descriptive.Prefix, out Expedition.Data data)) { FeatureLogger.Error("Failed to lookup expedition for location count: " + __instance.DataBlock.Descriptive.Prefix); return true; } HashSet traversedRegions = new HashSet(); HashSet locations = new HashSet(); searchRecusive(Zone.get_StartingRegion(data)); List list = (from id in locations select new KeyedLocation(id, gameData.LookupLocation(id)) into l where l.Location.RandMode.IsTreatedAsRandom where !l.RandData.IsExcluded && !l.RandData.IsTrap select l).ToList(); int num = list.Count((KeyedLocation l) => stateTracker.HasLocation(l.ID)); ((TMP_Text)__instance.m_artifactHeatText).SetText($"Found Items: {num} / {list.Count}", true); Color val = default(Color); if (list.Count == 0) { val = Color.grey; } else if (num == list.Count) { ((Color)(ref val))..ctor(0f, 1f, 0f); } else { val = Color.white; } ((TMP_Text)__instance.m_artifactHeatText).SetFaceColor(Color32.op_Implicit(val)); return false; void searchRecusive(RegionID region) { if (!traversedRegions.Add(region)) { return; } ReadOnlyRegion readOnlyRegion = gameData.LookupRegion(region); foreach (LocationID connectedLocationId in readOnlyRegion.ConnectedLocationIds) { locations.Add(connectedLocationId); } foreach (PathID connectedPath in readOnlyRegion.ConnectedPaths) { searchRecusive(gameData.LookupPath(connectedPath).EndingRegion); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class RundownManager__OnExpeditionEnded__Patch { public static void Postfix() { UpdateLocationCounts(); } } public struct pArchipelagoInitState { public string? GameName; public long RootSeed; public string[] ExpeditionNames; public long[] WhitelistTags; public long[] BlacklistTags; public int CalcByteSize() { return SerializationHelpers.CalcStringSize(GameName) + SerializationHelpers.Calc7BitEncodedSize((RootSeed == 0L) ? 1 : RootSeed) + SerializationHelpers.CalcStringArraySize(ExpeditionNames) + SerializationHelpers.Calc7BitEncodedMultiArraySize(new long[2][] { WhitelistTags, BlacklistTags }); } public Il2CppStructArray ToBytes(int offset = 0) { Il2CppStructArray val = new Il2CppStructArray((long)(CalcByteSize() + offset)); WriteToBytes(val, ref offset); return val; } public void WriteToBytes(Il2CppStructArray bytes, ref int index) { SerializationHelpers.WriteString(bytes, ref index, GameName); SerializationHelpers.Write7BitEncodedLong(bytes, ref index, RootSeed); SerializationHelpers.WriteStringArray(bytes, ref index, ExpeditionNames); SerializationHelpers.Write7BitEncodedMultiArray(bytes, ref index, new long[2][] { WhitelistTags, BlacklistTags }, WhitelistTags.Length + BlacklistTags.Length); } public static pArchipelagoInitState ReadFromBytes(Il2CppStructArray bytes, ref int index) { pArchipelagoInitState result = default(pArchipelagoInitState); result.GameName = SerializationHelpers.ReadString(bytes, ref index); result.GameName = null; result.RootSeed = SerializationHelpers.Read7BitEncodedLong(bytes, ref index); result.ExpeditionNames = SerializationHelpers.ReadStringArray(bytes, ref index); SerializationHelpers.Spannable[] array = SerializationHelpers.Read7BitEncodedMultiArray(bytes, ref index); result.WhitelistTags = new long[array[0].Length]; array[0].AsSpan().CopyTo(result.WhitelistTags.AsSpan()); result.BlacklistTags = new long[array[1].Length]; array[1].AsSpan().CopyTo(result.BlacklistTags.AsSpan()); return result; } public static pArchipelagoInitState FromBytes(Il2CppStructArray bytes) { int index = 0; return ReadFromBytes(bytes, ref index); } } public struct pArchipelagoScoutingUpdate { public string[] SlotLookup; public long[] LocationIDs; public long[] SlotIds; public string[] ItemDisplayNames; public int CalcByteSize() { return SerializationHelpers.CalcStringArraySize(SlotLookup) + SerializationHelpers.Calc7BitEncodedMultiArraySize(new long[2][] { LocationIDs, SlotIds }) + SerializationHelpers.CalcStringArraySize(ItemDisplayNames); } public Il2CppStructArray ToBytes(int offset = 0) { Il2CppStructArray val = new Il2CppStructArray((long)(offset + CalcByteSize())); WriteToBytes(val, ref offset); return val; } public void WriteToBytes(Il2CppStructArray bytes, ref int index) { SerializationHelpers.WriteStringArray(bytes, ref index, SlotLookup); long[][] array = new long[2][] { LocationIDs, SlotIds }; SerializationHelpers.Write7BitEncodedMultiArray(bytes, ref index, array, array.Sum((long[] i) => i.Length)); SerializationHelpers.WriteStringArray(bytes, ref index, ItemDisplayNames); } public static pArchipelagoScoutingUpdate FromBytes(Il2CppStructArray bytes, ref int index) { pArchipelagoScoutingUpdate result = default(pArchipelagoScoutingUpdate); result.SlotLookup = SerializationHelpers.ReadStringArray(bytes, ref index); SerializationHelpers.Spannable[] array = SerializationHelpers.Read7BitEncodedMultiArray(bytes, ref index); result.LocationIDs = new long[array[0].Length]; array[0].AsSpan().CopyTo(result.LocationIDs.AsSpan()); result.SlotIds = new long[array[1].Length]; array[1].AsSpan().CopyTo(result.SlotIds.AsSpan()); result.ItemDisplayNames = SerializationHelpers.ReadStringArray(bytes, ref index); return result; } public static pArchipelagoScoutingUpdate FromBytes(Il2CppStructArray bytes) { int index = 0; return FromBytes(bytes, ref index); } } public struct pArchipelagoGeneralState { public long[] LocationsChecked; public long[] TrashedLocations; public long[] ItemIds; public long[] ItemsInTerminalSystem; public int CalcByteSize() { return SerializationHelpers.Calc7BitEncodedMultiArraySize(new long[4][] { LocationsChecked, TrashedLocations, ItemIds, ItemsInTerminalSystem }); } public Il2CppStructArray ToBytes(int offset = 0) { Il2CppStructArray val = new Il2CppStructArray((long)(offset + CalcByteSize())); WriteToBytes(val, ref offset); return val; } public void WriteToBytes(Il2CppStructArray bytes, ref int index) { long[][] array = new long[4][] { LocationsChecked, TrashedLocations, ItemIds, ItemsInTerminalSystem }; SerializationHelpers.Write7BitEncodedMultiArray(bytes, ref index, array, array.Sum((long[] i) => i.Length)); } public static pArchipelagoGeneralState FromBytes(Il2CppStructArray bytes, ref int index) { SerializationHelpers.Spannable[] array = SerializationHelpers.Read7BitEncodedMultiArray(bytes, ref index); pArchipelagoGeneralState pArchipelagoGeneralState = default(pArchipelagoGeneralState); pArchipelagoGeneralState.LocationsChecked = new long[array[0].Length]; pArchipelagoGeneralState.TrashedLocations = new long[array[1].Length]; pArchipelagoGeneralState.ItemIds = new long[array[2].Length]; pArchipelagoGeneralState.ItemsInTerminalSystem = new long[array[3].Length]; pArchipelagoGeneralState result = pArchipelagoGeneralState; array[0].AsSpan().CopyTo(result.LocationsChecked.AsSpan()); array[1].AsSpan().CopyTo(result.TrashedLocations.AsSpan()); array[2].AsSpan().CopyTo(result.ItemIds.AsSpan()); array[3].AsSpan().CopyTo(result.ItemsInTerminalSystem.AsSpan()); return result; } public static pArchipelagoGeneralState FromBytes(Il2CppStructArray bytes) { int index = 0; return FromBytes(bytes, ref index); } } [StructLayout(LayoutKind.Explicit)] public struct pArchipelagoInteraction { public enum eType : ushort { CheckRegion, CheckLocation, MarkTrash, EmptyTrash, CollectItem } [FieldOffset(0)] public eType Type; [FieldOffset(2)] public ushort Count; [FieldOffset(4)] public long Value; public pArchipelagoInteraction(eType type, long value = 0L, ushort count = 0) { Type = type; Value = value; Count = count; } public pArtifactInventoryState ToBytes() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) byte[] array = new byte[12]; BinaryPrimitives.WriteUInt16LittleEndian(array.AsSpan(0, 2), (ushort)Type); BinaryPrimitives.WriteUInt16LittleEndian(array.AsSpan(2, 2), Count); BinaryPrimitives.WriteInt64LittleEndian(array.AsSpan(4, 8), Value); return MemoryMarshal.Read((ReadOnlySpan)array); } public static pArchipelagoInteraction FromBytes(pArtifactInventoryState input) { byte[] array = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref input, 1)).ToArray(); pArchipelagoInteraction result = default(pArchipelagoInteraction); result.Type = (eType)BinaryPrimitives.ReadUInt16LittleEndian(array.AsSpan(0, 2)); result.Count = BinaryPrimitives.ReadUInt16LittleEndian(array.AsSpan(2, 2)); result.Value = BinaryPrimitives.ReadInt64LittleEndian(array.AsSpan(4, 8)); return result; } } [InjectToIl2Cpp(new Type[] { typeof(IReplicatorSupplier), typeof(ICaptureCallbackObject) })] private class ArchipelagoStateReplicator : Object { private const string s_name = "State Tracker Replicator"; private GameObject m_gameObject = new GameObject("State Tracker Replicator"); private SNet_Replicator m_replicator; private StateTracker m_owner; private SNet_PacketBufferBytes m_initStatePacket; private SNet_PacketBufferBytes m_scoutingUpdatePacket; private SNet_PacketBufferBytes m_generalStatePacket; private SNet_PacketBufferBytes m_recallStatePacket; private SNet_Packet m_interactionPacket; private SNet_PacketBufferBytes m_logPacket; public GameObject gameObject => m_gameObject; public string name => "State Tracker Replicator"; public IReplicator Replicator => ((Il2CppObjectBase)m_replicator).Cast(); public SNet_Replicator ConcreteReplicator => m_replicator; public ArchipelagoStateReplicator(IntPtr ptr) : base(ptr) { }//IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown public ArchipelagoStateReplicator(StateTracker owner) : base(ClassInjector.DerivedConstructorPointer()) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); m_owner = owner; m_replicator = ((Il2CppObjectBase)SNet_Replication.AddManagerReplicator(new IReplicatorSupplier(((Il2CppObjectBase)this).Pointer))).Cast(); SNet_SyncManager.RegisterCaptureCallback(new ICaptureCallbackObject(((Il2CppObjectBase)this).Pointer)); IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveInitState", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_initStatePacket = m_replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveScoutingUpdate", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_scoutingUpdatePacket = m_replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveGeneralState", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_generalStatePacket = m_replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveRecallState", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_recallStatePacket = m_replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveInteraction", typeof(void).FullName, new string[1] { typeof(pArtifactInventoryState).FullName }); m_interactionPacket = m_replicator.CreatePacket(new Action((Object)(object)this, il2CppMethod), (Action)null); il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)this).ObjectClass, false, "OnReceiveLog", typeof(void).FullName, new string[2] { typeof(Il2CppStructArray).FullName, typeof(BufferData).FullName }); m_logPacket = m_replicator.CreatePacketBytes(new Action, BufferData>((Object)(object)this, il2CppMethod)); } public IReplicator GetReplicator() { return ((Il2CppObjectBase)m_replicator).Cast(); } public void OnStateCapture() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) Il2CppStructArray val = m_owner.MakeGeneralState().ToBytes(6); Il2CppStructArray keyBytes = ((SNet_Packet)m_recallStatePacket).Replicator.KeyBytes; ((Il2CppArrayBase)(object)val)[0] = ((Il2CppArrayBase)(object)keyBytes)[0]; ((Il2CppArrayBase)(object)val)[1] = ((Il2CppArrayBase)(object)keyBytes)[1]; ((Il2CppArrayBase)(object)val)[2] = ((SNet_Packet)m_recallStatePacket).Index; keyBytes = SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)); ((Il2CppArrayBase)(object)val)[3] = ((Il2CppArrayBase)(object)keyBytes)[0]; ((Il2CppArrayBase)(object)val)[4] = ((Il2CppArrayBase)(object)keyBytes)[1]; ((Il2CppArrayBase)(object)val)[5] = ((Il2CppArrayBase)(object)keyBytes)[2]; SNet.Capture.PrimedBuffer.GetPass((eCapturePass)0).Add(val); } public pStateReplicatorProvider GetProviderSyncStruct() { //IL_0002: 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_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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) pReplicator pRep = default(pReplicator); ((pReplicator)(ref pRep)).SetID(Replicator); pStateReplicatorProvider result = default(pStateReplicatorProvider); result.pRep = pRep; return result; } private void OnReceiveInitState(Il2CppStructArray bytes, BufferData data) { pArchipelagoInitState state = pArchipelagoInitState.FromBytes(bytes); m_owner.ReceiveInitState(state); } private void OnReceiveScoutingUpdate(Il2CppStructArray bytes, BufferData data) { pArchipelagoScoutingUpdate update = pArchipelagoScoutingUpdate.FromBytes(bytes); m_owner.ReceiveScoutingUpdate(update); } private void OnReceiveGeneralState(Il2CppStructArray bytes, BufferData data) { pArchipelagoGeneralState state = pArchipelagoGeneralState.FromBytes(bytes); m_owner.ReceiveGeneralState(state, isRecall: false); } private void OnReceiveRecallState(Il2CppStructArray bytes, BufferData data) { pArchipelagoGeneralState state = pArchipelagoGeneralState.FromBytes(bytes); m_owner.ReceiveGeneralState(state, isRecall: true); } private void OnReceiveInteraction(pArtifactInventoryState bytes) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) pArchipelagoInteraction interaction = pArchipelagoInteraction.FromBytes(bytes); m_owner.ReceiveInteraction(interaction); } private void OnReceiveLog(Il2CppStructArray bytes, BufferData data) { int index = 0; string text = SerializationHelpers.ReadString(bytes, ref index); if (text != null) { LogForLobby(text, localOnly: true); } } public void SendInit(SNet_Player? player = null) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { m_initStatePacket.Send(m_owner.MakeInitState().ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendGroup)2, (SNet_SendQuality)2, 0); } else { m_initStatePacket.Send(m_owner.MakeInitState().ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendQuality)2, 0, player); } } public void SendScouting(pArchipelagoScoutingUpdate? update = null, SNet_Player? player = null) { //IL_0081: 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) pArchipelagoScoutingUpdate valueOrDefault = update.GetValueOrDefault(); if (!update.HasValue) { valueOrDefault = m_owner.MakeScoutingUpdate(); update = valueOrDefault; } if (update.Value.LocationIDs.Length != 0) { if ((Object)(object)player == (Object)null) { m_scoutingUpdatePacket.Send(update.Value.ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendGroup)2, (SNet_SendQuality)2, 0); } else { m_scoutingUpdatePacket.Send(update.Value.ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendQuality)2, 0, player); } } } public void SendGeneral(SNet_Player? player = null) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { m_generalStatePacket.Send(m_owner.MakeGeneralState().ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendGroup)2, (SNet_SendQuality)2, 0); } else { m_generalStatePacket.Send(m_owner.MakeGeneralState().ToBytes(), SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendQuality)2, 0, player); } } public void SendInteraction(pArchipelagoInteraction interaction) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) m_interactionPacket.Send(interaction.ToBytes(), (SNet_ChannelType)0, (SNet_SendQuality)3, (SNet_Player)null); } public void SendLog(string message, SNet_Player? player = null) { //IL_0046: 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) Il2CppStructArray val = new Il2CppStructArray((long)SerializationHelpers.CalcStringSize(message)); int index = 0; SerializationHelpers.WriteString(val, ref index, message); if ((Object)(object)player == (Object)null) { m_logPacket.Send(val, SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendGroup)2, (SNet_SendQuality)2, 4); } else { m_logPacket.Send(val, SNet_PacketBufferBytes.GetBufferDataBytes(new BufferData((ushort)1, (byte)0)), (SNet_SendQuality)2, 4, player); } } } private class UpdateStateEnumerator : IEnumerator { private StateTracker m_owner; public object Current => (object)new WaitForSecondsRealtime(60f); public UpdateStateEnumerator(StateTracker owner) { m_owner = owner; } public bool MoveNext() { if (m_owner.CurrentState == eState.HostConnected || m_owner.CurrentState == eState.FakeConnect) { m_owner.m_stateReplicator.SendGeneral(); } return true; } public void Reset() { } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_SessionHub__AddPlayerToSession__Patch { public static void Prefix(SNet_SessionHub __instance, SNet_Player player) { SNet_Player player2 = player; if (SNet.IsMaster && !player2.IsBot && !SNet.SessionHub.PlayersInSession.Any((SNet_Player p) => ((Il2CppObjectBase)p).Pointer == ((Il2CppObjectBase)player2).Pointer)) { FeatureLogger.Notice("New player is joining session; sending init packet: " + player2.NickName); Get().m_stateReplicator?.SendInit(player2); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_SessionHub__OnJoinedLobby__Patch { public static void Postfix(SNet_SessionHub __instance, SNet_Player player) { if (!SNet.IsMaster || player.IsBot) { return; } StateTracker stateTracker = Get(); if (stateTracker.ApSession != null) { FeatureLogger.Notice("Adding new player to session; sending sync packets: " + player.NickName); stateTracker.m_stateReplicator?.SendGeneral(player); ArchipelagoStateReplicator? stateReplicator = stateTracker.m_stateReplicator; if (stateReplicator != null) { stateReplicator.SendScouting(null, player); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_SessionHub__OnMasterSessionAnswer__Patch { public static bool Prefix(SNet_SessionHub __instance, pMasterAnswer data) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_002e: 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) StateTracker stateTracker = Get(); if ((int)stateTracker.m_cachedMasterAnswer.answer == 0) { FeatureLogger.Notice("Client connection allowed!"); stateTracker.m_cachedMasterAnswer = new pMasterAnswer { answer = (pMasterSessionAnswerType)1 }; return true; } FeatureLogger.Notice("Received master answer; caching and blocking for now"); stateTracker.m_cachedMasterAnswer = data; return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_MasterManager__SearchForMigrationMaster__Patch { public static bool Prefix(SNet_Player masterPlayer) { if (((Il2CppObjectBase)masterPlayer).Pointer != ((Il2CppObjectBase)SNet.LocalPlayer).Pointer) { return true; } return Get().ApSession != null; } } [CompilerGenerated] private sealed class <g__GetVisualData|126_5>d : IEnumerable>, IEnumerable, IEnumerator>, IEnumerator, IDisposable { private int <>1__state; private Tuple <>2__current; private int <>l__initialThreadId; private RundownDataBlock rundown; public RundownDataBlock <>3__rundown; Tuple IEnumerator>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <g__GetVisualData|126_5>d(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = Tuple.Create(rundown.TierA.Count, rundown.StorytellingData.Visuals.TierAVisuals); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = Tuple.Create(rundown.TierB.Count, rundown.StorytellingData.Visuals.TierBVisuals); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = Tuple.Create(rundown.TierC.Count, rundown.StorytellingData.Visuals.TierCVisuals); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = Tuple.Create(rundown.TierD.Count, rundown.StorytellingData.Visuals.TierDVisuals); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = Tuple.Create(rundown.TierE.Count, rundown.StorytellingData.Visuals.TierEVisuals); <>1__state = 5; return true; case 5: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator> IEnumerable>.GetEnumerator() { <g__GetVisualData|126_5>d <g__GetVisualData|126_5>d; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <g__GetVisualData|126_5>d = this; } else { <g__GetVisualData|126_5>d = new <g__GetVisualData|126_5>d(0); } <g__GetVisualData|126_5>d.rundown = <>3__rundown; return <g__GetVisualData|126_5>d; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable>)this).GetEnumerator(); } } private static IArchiveLogger? m_featureLogger = null; private Plugin? m_plugin; public static Version APVersion = new Version(1, 0, 0); private List GameTags = new List(2) { "DeathLink", "EnergyLink" }; protected Dictionary> QueuedItemReplacements = new Dictionary>(); private ArchipelagoStateReplicator? m_stateReplicator; public override string Name => "Archipelago Settings"; public override string Description => "Controls AP many import Archipelago settings."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? ReTFO.Archipelago.Plugin.Get().Logger; } set { m_featureLogger = value; } } public Plugin Plugin { get { return m_plugin ?? (m_plugin = ReTFO.Archipelago.Plugin.Get()); } protected set { m_plugin = value; } } public MidManager MidManager => Plugin.MidManager; public ArchipelagoSession? ApSession { get; protected set; } public Guid SessionGuid { get; protected set; } protected Task? ConnectTask { get; set; } protected Task? LoginTask { get; set; } public long RootSeed { get; protected set; } protected HashSet Expeditions { get; set; } = new HashSet(); protected HashSet WhitelistTags { get; set; } = new HashSet(); protected HashSet BlacklistTags { get; set; } = new HashSet(); public bool RequiresSecondaries { get; protected set; } public bool RequiresOverloads { get; protected set; } protected HashSet FoundRegions { get; init; } = new HashSet(); protected HashSet FoundUnusedRegions { get; init; } = new HashSet(); protected HashSet FoundLocations { get; init; } = new HashSet(); protected HashSet TrashedLocations { get; init; } = new HashSet(); protected Dictionary ActualItemCounts { get; init; } = new Dictionary(); protected Dictionary SessionItemCounts { get; init; } = new Dictionary(); protected List NeededWinItems { get; init; } = new List(); public List> ItemsInTerminalSystem { get; init; } = new List>(); public eState CurrentState { get; set; } [FeatureConfig] public static Settings Config { get; set; } = null; public IReadOnlyDictionary CollectedItemCounts => ActualItemCounts; private pMasterAnswer m_cachedMasterAnswer { get; set; } = new pMasterAnswer { answer = (pMasterSessionAnswerType)1 }; public event Action? OnStateChange; public static StateTracker Get() { return ReTFO.Archipelago.Plugin.Get().StateTracker; } public override void OnEnable() { base.OnEnable(); Plugin.StateTracker = this; } public HashSet ExpeditionsFromNames(ICollection names) { Game.Data processedGameData = MidManager.GetProcessedGameData(); HashSet hashSet = new HashSet(names.Count); foreach (string item in names.Distinct()) { if (processedGameData.TryLookupExpedition(item, out Expedition.Data data)) { hashSet.Add(data); } else { FeatureLogger.Error("Failed to find expedition with name " + item + "; dropping!"); } } return hashSet; } public HashSet TagsFromNames(ICollection names) { Game.Data processedGameData = MidManager.GetProcessedGameData(); HashSet hashSet = new HashSet(names.Count); foreach (string item in names.Distinct()) { if (processedGameData.TryLookupTag(item, out var existingTag)) { hashSet.Add(existingTag); } else { FeatureLogger.Error("Failed to find tag with name " + item + "; dropping!"); } } return hashSet; } public void FakeConnect() { if (CurrentState != 0) { FeatureLogger.Error("Cannot start fake connection; already in state: " + Enum.GetName(CurrentState)); return; } CurrentState = eState.FakeConnect; RootSeed = 0L; Expeditions = ExpeditionsFromNames(new List(7) { "R1B1", "R6A1", "R3A3", "R6B1", "R8C2", "R4D2", "R8E1" }); WhitelistTags = new HashSet { RootRandomizationTags.get_Tag_All(MidManager.GetProcessedGameData()) }; BlacklistTags = new HashSet { UnlockExpeditionHandler_Tags.get_Tag_ExpeditionUnlocks(MidManager.GetProcessedGameData()), LockLobbySlotsHandler_Tags.get_Tag_LobbySlotUnlocks(MidManager.GetProcessedGameData()) }; RequiresSecondaries = true; RequiresOverloads = true; SetupMultiworld(); FeatureLogger.Notice("Due to fake connect, removing all expedition locks."); UnlockExpeditionHandler.UnlockAll(); } public void ClientConnect(pArchipelagoInitState state) { //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_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_017b: Unknown result type (might be due to invalid IL or missing references) if ((int)m_cachedMasterAnswer.answer != 0) { FeatureLogger.Notice("Ignoring init packet; master answer was " + Enum.GetName(m_cachedMasterAnswer.answer)); return; } if (CurrentState == eState.ConnectedClient || CurrentState == eState.ProxyClient) { FeatureLogger.Notice("Ignoring init packet; already set up as a client"); return; } if (state.GameName != MidManager.GetProcessedGameData().Name) { FeatureLogger.Error("Cannot connect as client; the host is playing with different mods than us!"); return; } FeatureLogger.Notice("Received init packet. Preparing to join as client..."); if (CurrentState == eState.CleanState) { FeatureLogger.Notice("Joining as proxy client..."); RootSeed = state.RootSeed; Expeditions = ExpeditionsFromNames(state.ExpeditionNames); WhitelistTags = state.WhitelistTags.Select((long i) => new RandomizationTag { AsId = i }).ToHashSet(); BlacklistTags = state.BlacklistTags.Select((long i) => new RandomizationTag { AsId = i }).ToHashSet(); CurrentState = eState.ProxyClient; SetupMultiworld(); } else { FeatureLogger.Notice("Joining as a connected client..."); if (RootSeed != state.RootSeed) { FeatureLogger.Error("Refused to join as client; root seeds do not match! This indicates the host is connected to a different slot or server."); return; } CurrentState = eState.ConnectedClient; } SNet.SessionHub.OnMasterSessionAnswer(m_cachedMasterAnswer); FeatureLogger.Success("Successfully joined!"); } public void Connect() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown if (Config.UseDebugMode) { FakeConnect(); return; } if (CurrentState != 0) { FeatureLogger.Error("Cannot start new connection; already in state: " + Enum.GetName(CurrentState)); return; } if (ConnectTask != null) { FeatureLogger.Warning("Cannot start new connection; currently waiting to connect to Archipelago"); return; } CurrentState = eState.HostConnecting; SessionGuid = Guid.NewGuid(); ApSession = ArchipelagoSessionFactory.CreateSession(Config.ServerAddress, (int)Config.Port); ApSession.Locations.CheckedLocationsUpdated += (CheckedLocationsUpdatedHandler)delegate(ReadOnlyCollection locs) { foreach (long loc in locs) { FoundLocations.Add(new LocationID { AsId = loc }); } UpdateLocationCounts(); }; ConnectTask = ApSession.ConnectAsync(); } protected void HandleFailedConnection(string debugName, Exception? exception) { FeatureLogger.Error("Failed to " + debugName + " to Archipelago Host!"); if (exception != null) { FeatureLogger.Error("Encountered the following exception:"); FeatureLogger.Exception(exception); } if (CurrentState == eState.HostConnecting) { ApSession = null; CurrentState = eState.CleanState; } else if (CurrentState == eState.HostReconnecting) { ConnectTask = ReconnectDelayed(); } else { FeatureLogger.Warning(" -> Failed to " + debugName + " while not in connecting state?"); } } protected async Task ReconnectDelayed(int delay = 2500) { FeatureLogger.Notice("Attempting to reconnect to Archipelago Host..."); await Task.Delay(delay).ConfigureAwait(continueOnCapturedContext: false); return await ApSession.ConnectAsync().ConfigureAwait(continueOnCapturedContext: false); } public void HandleConnectionResult(Task connectResult) { ConnectTask = null; if (!connectResult.IsCompletedSuccessfully) { ArchipelagoSession? apSession = ApSession; string text = ((apSession != null) ? apSession.Socket.Uri.ToString() : null) ?? "null!"; HandleFailedConnection("connect", Config.HideConnectionDetails ? new Exception("Exception hidden because HideConnectionDetails is enabled!") : connectResult.Exception); if (Config.HideConnectionDetails) { FeatureLogger.Error("Connection debug hidden due to HideConnectionDetails"); return; } FeatureLogger.Error($"Address: {Config.ServerAddress}:{Config.Port}"); FeatureLogger.Error("Calculated URI: " + text); } else { string name = MidManager.GetProcessedGameData().Name; LoginTask = ApSession.LoginAsync((name == null) ? "GTFO" : ("GTFO (" + name + ")"), Config.Username, (ItemsHandlingFlags)7, (Version)null, GameTags.ToArray(), SessionGuid.ToString(), Config.HasPassword ? Config.Password : null, true); } } protected void HandleLoginResult(Task loginTask) { LoginTask = null; if (!loginTask.IsCompletedSuccessfully) { HandleFailedConnection("login", Config.HideConnectionDetails ? new Exception("Exception hidden because HideConnectionDetails is enabled!") : loginTask.Exception); return; } LoginResult result = loginTask.Result; if (ApSession == null) { throw new NullReferenceException("ApSession"); } if (result.Successful) { LoginSuccessful val = (LoginSuccessful)(object)((result is LoginSuccessful) ? result : null); if (val != null) { ApSession.SetClientState((ArchipelagoClientState)20); try { RootSeed = (long)val.SlotData["RootSeed"]; object obj = val.SlotData["ExpeditionNames"]; object obj2 = ((obj is JArray) ? obj : null); Expeditions = ExpeditionsFromNames(((obj2 != null) ? ((JToken)obj2).ToObject>() : null) ?? throw new NullReferenceException("Failed to retrieve expedition names from slot data")); object obj3 = val.SlotData["WhitelistTags"]; object obj4 = ((obj3 is JArray) ? obj3 : null); WhitelistTags = new HashSet(((obj4 == null) ? null : ((JToken)obj4).ToObject>()?.Select((long l) => new RandomizationTag { AsId = l })) ?? throw new NullReferenceException("Failed to retrieve whitelist tags from slot data")); object obj5 = val.SlotData["BlacklistTags"]; object obj6 = ((obj5 is JArray) ? obj5 : null); BlacklistTags = new HashSet(((obj6 == null) ? null : ((JToken)obj6).ToObject>()?.Select((long l) => new RandomizationTag { AsId = l })) ?? throw new NullReferenceException("Failed to retrieve blacklist tags from slot data")); object obj7 = val.SlotData["RequiresSecondaries"]; if (obj7 is bool requiresSecondaries) { RequiresSecondaries = requiresSecondaries; } else { RequiresSecondaries = (long)obj7 != 0; } obj7 = val.SlotData["RequiresOverloads"]; if (obj7 is bool requiresOverloads) { RequiresOverloads = requiresOverloads; } else { RequiresOverloads = (long)obj7 != 0; } } catch (Exception ex) { FeatureLogger.Error("Encountered issues while retrieving slot data!"); FeatureLogger.Exception(ex); ApSession.Socket.DisconnectAsync(); ApSession = null; return; } if (CurrentState == eState.HostConnecting) { CurrentState = eState.HostConnected; SetupMultiworld(); ApSession.SetClientState((ArchipelagoClientState)10); } else if (CurrentState == eState.HostReconnecting) { CurrentState = eState.HostConnected; ApSession.SetClientState((ArchipelagoClientState)20); } FoundLocations.UnionWith(ApSession.Locations.AllLocationsChecked.Select((long v) => new LocationID { AsId = v })); return; } } HandleFailedConnection("authenticate", null); if (Config.HideConnectionDetails) { FeatureLogger.Error("Connection debug is hidden because HideConnectionDetails is enabled."); return; } LoginFailure val2 = (LoginFailure)(object)((result is LoginFailure) ? result : null); if (val2 != null) { string[] errors = val2.Errors; foreach (string text in errors) { FeatureLogger.Error(" -> Error response: " + text); } } FeatureLogger.Error("Tried to connect with following information:"); FeatureLogger.Error("Username: " + Config.Username); FeatureLogger.Error(Config.HasPassword ? ("Password: " + Config.Password) : "No password"); string name = MidManager.GetProcessedGameData().Name; FeatureLogger.Error("Game: " + ((name == null) ? "GTFO" : ("GTFO (" + name + ")"))); } protected void SetupMultiworld() { Game.Data gameData = MidManager.GetProcessedGameData(); WhitelistTags.Add(RootRandomizationTags.get_Tag_Always(gameData)); BlacklistTags.Add(RootRandomizationTags.get_Tag_Never(gameData)); FeatureLogger.Notice("Beginning graph traversal for new rundowns"); HashSet unlockTags = Expeditions.Select((Expedition.Data e) => RootRandomizationTags.get_Tag_UnlockItems_ByExpedition(e).SelfResolve()).ToHashSet(); HashSet goalTags = Expeditions.Select((Expedition.Data e) => RootRandomizationTags.get_Tag_GoalItems_ByExpedition(e).SelfResolve()).ToHashSet(); if (!ReTFO.Archipelago.ModdedInstanceData.MidManager.DoGraphTraversal(gameData, doProcessing: true, unlockTags, goalTags, logDebugInfo: false)) { FeatureLogger.Error("Graph traversal failed! Cancelling connection. View log for details."); ArchipelagoSession? apSession = ApSession; if (apSession != null) { apSession.Socket.DisconnectAsync(); } ApSession = null; CurrentState = eState.CleanState; } else { FeatureLogger.Success("Graph traversal succeeded!"); } TryOverwriteRundowns(); FoundRegions.Clear(); FoundUnusedRegions.Clear(); FoundLocations.Clear(); TrashedLocations.Clear(); ActualItemCounts.Clear(); SessionItemCounts.Clear(); ItemsInTerminalSystem.Clear(); QueuedItemReplacements.Clear(); HashSet reachableRegionIDs = (from r in gameData.GetAllRegions() where r.Value.Reachable select r.Key).ToHashSet(); List> list = (from l in gameData.GetAllLocations() where l.Value.OwningRegionIds.All((RegionID id) => reachableRegionIDs.Contains(id)) select l).ToList(); IEnumerable enumerable = (from l in list select l.Value.ItemID into i where !i.IsNull select i).Concat(gameData.GetAllFloatingItemIds()).Distinct(); foreach (ItemID item5 in enumerable) { Item item = gameData.LookupItem(item5); item.RandMode = TestRandomization(item); } foreach (KeyValuePair item6 in list) { item6.Value.RandMode = TestRandomization(item6.Value); if (item6.Value.RandData.IsEmpty && item6.Value.RandMode.IsRandomized) { item6.Value.RandMode = new RandTest(RandTest.eType.UnusedEmptyLocation); } else if (item6.Value.RandMode.IsRandomized) { if (item6.Value.ItemID.IsNull) { FeatureLogger.Error("Encountered non-empty location with null item ID during randomization: " + gameData.LookupTagDef(item6.Value.NameTag).Name); } else { item6.Value.RandMode = gameData.LookupItem(item6.Value.ItemID).RandMode; } } } HashSet seenItems = new HashSet(); Queue queue = new Queue(); List list2 = (from pair in list select pair.Value into l where l.RandMode.Type == RandTest.eType.UnusedEmptyLocation where l.RandData.IsPriority select l).ToList(); IEnumerable enumerable2 = from id in gameData.GetAllFloatingItemIds() select new KeyedItem(id, gameData.LookupItem(id)) into i where i.Item.RandMode.IsRandomized where i.RandData.IsProgression select i.ID; foreach (ItemID item7 in enumerable2) { queue.Enqueue(item7); } foreach (ItemID item8 in queue) { seenItems.Add(item8); } DistributeItems(list2, queue); list2.Clear(); list2.AddRange(from pair in list select pair.Value into l where l.RandMode.Type == RandTest.eType.UnusedEmptyLocation where l.RandData.IsPriority || l.RandData.IsDefault select l); DistributeItems(list2, queue); list2.Clear(); list2.AddRange(from pair in list select pair.Value into l where l.RandMode.Type == RandTest.eType.UnusedEmptyLocation select l); enumerable2 = from id in gameData.GetAllFloatingItemIds() where !seenItems.Contains(id) select id into i where gameData.LookupItem(i).RandMode.IsRandomized select i; foreach (ItemID item9 in enumerable2) { queue.Enqueue(item9); } foreach (ItemID item10 in queue) { seenItems.Add(item10); } DistributeItems(list2, queue); if (queue.Count > 0) { FeatureLogger.Warning($"Insufficient empty locations for selected floating items. Granting {queue.Count} free items!"); foreach (ItemID item11 in queue) { Item item2 = gameData.LookupItem(item11); if (item2.RandData.CollectedByDefault) { item2.OnItemLost(this); } if (CurrentState == eState.FakeConnect) { CollectItem(item11); } } } foreach (KeyValuePair item12 in list) { if (!item12.Value.RandMode.IsRandomized) { continue; } if (item12.Value.ItemID.IsNull) { FeatureLogger.Error("Encountered randomized empty location during OnItemLost callbacks: " + gameData.LookupTagDef(item12.Value.NameTag).Name); continue; } Item item3 = gameData.LookupItem(item12.Value.ItemID); if (item3.RandData.CollectedByDefault) { item3.OnItemLost(this); } } foreach (ItemID allFloatingItemId in gameData.GetAllFloatingItemIds()) { Item item4 = gameData.LookupItem(allFloatingItemId); if (!item4.RandMode.IsRandomized) { ActualItemCounts[allFloatingItemId] = ActualItemCounts.GetValueOrDefault(allFloatingItemId, 0) + 1; } } if (ApSession != null) { IEnumerable> source = list.Where((KeyValuePair l) => l.Value.RandMode.IsRandomized); ApSession.Locations.ScoutLocationsAsync((HintCreationPolicy)0, source.Select((KeyValuePair l) => l.Key.AsId).ToArray()).ContinueWith(OnLocationsScouted); } RecalcWinItems(); NotifyFoundRegion(gameData.MenuRegionName, PlayerManager.GetLocalPlayerAgent()); this.OnStateChange?.Invoke(this); } public void RecalcWinItems() { NeededWinItems.Clear(); if (CurrentState == eState.ProxyClient) { return; } Game.Data processedGameData = MidManager.GetProcessedGameData(); HashSet parents = new HashSet { RootRandomizationTags.get_Tag_GoalItems(processedGameData) }; HashSet hashSet = new HashSet(); foreach (KeyValuePair allExpedition in processedGameData.GetAllExpeditions()) { if (!Expeditions.Contains(allExpedition.Value, new Expedition.Data.Comparer())) { hashSet.Add(RootRandomizationTags.get_Tag_GoalItems_ByExpedition(allExpedition.Value)); } } foreach (Expedition.Data expedition in Expeditions) { if (!RequiresSecondaries && Layer.get_HasSecondary(expedition)) { hashSet.Add(SharedObjectiveHandler.GetSectorClearedItem(expedition.GetLayer(LayerType.Secondary)).NameTag); } if (!RequiresOverloads && Layer.get_HasOverload(expedition)) { hashSet.Add(SharedObjectiveHandler.GetSectorClearedItem(expedition.GetLayer(LayerType.Overload)).NameTag); } } IEnumerable enumerable = (from l in processedGameData.GetAllLocations() select l.Value.ItemID).Concat(processedGameData.GetAllFloatingItemIds()); foreach (ItemID item2 in enumerable) { if (!item2.IsNull) { Item item = processedGameData.LookupItem(item2); if ((item.RequiredExpedition == null || Expeditions.Contains(item.RequiredExpedition)) && !processedGameData.AnyTagMatches(hashSet, item) && processedGameData.AnyTagMatches(parents, item)) { NeededWinItems.Add(item2); } } } foreach (ItemID item3 in SessionItemCounts.SelectMany((KeyValuePair pair) => Enumerable.Repeat(pair.Key, pair.Value))) { NeededWinItems.Remove(item3); } if (NeededWinItems.Count == 0) { ArchipelagoSession? apSession = ApSession; if (apSession != null) { apSession.SetClientState((ArchipelagoClientState)30); } FeatureLogger.Success("Congratulations, you have won the game!"); } } public void Reset() { ArchipelagoSession? apSession = ApSession; if (apSession != null) { apSession.Socket.DisconnectAsync(); } ApSession = null; ConnectTask = null; LoginTask = null; SNet.Lobbies.LeaveLobby(); uint num = ((Il2CppArrayBase)(object)Global.ActiveRundownIds)[0]; Global.ActiveRundownIds = new Il2CppStructArray(1L); ((Il2CppArrayBase)(object)Global.ActiveRundownIds)[0] = num; MainMenuGuiLayer.Current.PageRundownNew.m_isRevealing = false; MainMenuGuiLayer.Current.PageRundownNew.m_rundownIsRevealed = false; MainMenuGuiLayer.Current.PageRundownNew.m_selectionIsRevealed = false; MainMenuGuiLayer.Current.PageRundownNew.m_dataIsSetup = false; MainMenuGuiLayer.Current.PageRundownNew.m_rundownIntroIsDone = false; MainMenuGuiLayer.Current.PageRundownNew.m_cortexIntroIsDone = false; MainMenuGuiLayer.Current.PageRundownNew.m_selectRundownButton.OnBtnPressCallback.Invoke(0); ((CM_PageBase)MainMenuGuiLayer.Current.PageRundownNew).PostSetup(); MainMenuGuiLayer.Current.ChangePage((eCM_MenuPage)9, false); MainMenuGuiLayer.Current.PageRundownNew.m_selectionIsRevealed = true; CurrentState = eState.CleanState; this.OnStateChange?.Invoke(this); } public RandTest TestRandomization(Location loc) { Game.Data processedGameData = MidManager.GetProcessedGameData(); RandTest.eType type = (processedGameData.AnyTagMatches(BlacklistTags, loc) ? RandTest.eType.LocationBlacklisted : (processedGameData.AnyTagMatches(WhitelistTags, loc) ? RandTest.eType.Randomized : RandTest.eType.LocationNotWhitelisted)); return new RandTest(type); } public RandTest TestRandomization(Item item) { Game.Data processedGameData = MidManager.GetProcessedGameData(); RandTest.eType eType = ((item.RequiredExpedition != null && !Expeditions.Contains(item.RequiredExpedition, new Expedition.Data.Comparer())) ? RandTest.eType.ItemExpeditionNotRandomized : (processedGameData.AnyTagMatches(BlacklistTags, item) ? RandTest.eType.ItemBlacklisted : (processedGameData.AnyTagMatches(WhitelistTags, item) ? RandTest.eType.Randomized : RandTest.eType.ItemNotWhitelisted))); if (item.RandData.IsRandomLike) { eType |= RandTest.eType.Randomlike; } return new RandTest(eType); } public void NotifyFoundRegion(string name, PlayerAgent? player, bool skipInteraction = false) { Game.Data processedGameData = MidManager.GetProcessedGameData(); if (!processedGameData.TryLookupRegion(name, out var region)) { if (!FoundUnusedRegions.Add(name)) { FeatureLogger.Debug("Ignoring region because it is not registered: " + name); } } else { NotifyFoundRegion(region.ID, player, skipInteraction); } } public void NotifyFoundRegion(RegionID regionId, PlayerAgent? player, bool skipInteraction = false) { Game.Data data = MidManager.GetProcessedGameData(); ReadOnlyRegion readOnlyRegion = data.LookupRegion(regionId); if (FoundRegions.Add(regionId)) { FeatureLogger.Debug($"Discovered region [{regionId.AsId}] {readOnlyRegion.Name}"); LocationID[] array = readOnlyRegion.ConnectedLocationIds.Where(isFoundLocation).ToArray(); if (array.Length != 0) { NotifyFoundLocations(array, player); } } bool isFoundLocation(LocationID locID) { if (FoundLocations.Contains(locID)) { return false; } Location location = data.LookupLocation(locID); if (!location.RandData.IsAutoDiscovered) { return false; } if (location.OwningRegionIds.Any((RegionID r) => !FoundRegions.Contains(r))) { return false; } return true; } } public Location NotifyFoundLocation(LocationID id, PlayerAgent? player, bool force = false, bool skipInteraction = false) { Game.Data processedGameData = MidManager.GetProcessedGameData(); Location location = processedGameData.LookupLocation(id); if (!FoundLocations.Add(id)) { return location; } FeatureLogger.Debug($"Discovered Location: [{id.AsId}] {processedGameData.LookupTagDef(location.NameTag).Name}"); if (!skipInteraction) { SendInteraction(pArchipelagoInteraction.eType.CheckLocation, id.AsId, 0); } if (location.RandMode.IsTreatedAsRandom && CurrentState == eState.FakeConnect) { CollectItem(location.ItemID, id, player); LogForLobby("Collected item " + processedGameData.LookupTagDef(processedGameData.LookupItem(location.ItemID).NameTag).Name + " from FakeConnect", localOnly: false); } if (ApSession != null) { ApSession.Locations.CompleteLocationChecksAsync(new long[1] { id.AsId }).ContinueWith(OnLocationChecksCompleted); } UpdateLocationCounts(); return location; } public void NotifyFoundLocations(IEnumerable ids, PlayerAgent? player, bool force = false, bool skipInteraction = false) { Game.Data processedGameData = MidManager.GetProcessedGameData(); List list = new List(); foreach (LocationID id in ids) { Location location = processedGameData.LookupLocation(id); if (!(!FoundLocations.Add(id) || force)) { FeatureLogger.Debug($"Discovered Location: [{id.AsId}] {processedGameData.LookupTagDef(location.NameTag).Name}"); if (!skipInteraction) { SendInteraction(pArchipelagoInteraction.eType.CheckLocation, id.AsId, 0); } if (location.RandMode.IsTreatedAsRandom && CurrentState == eState.FakeConnect) { CollectItem(location.ItemID, id, player); LogForLobby("Collected item " + processedGameData.LookupTagDef(processedGameData.LookupItem(location.ItemID).NameTag).Name + " from FakeConnect", localOnly: false); } if (ApSession != null) { list.Add(id.AsId); } } } if (ApSession != null && list.Count > 0) { ApSession.Locations.CompleteLocationChecksAsync(list.ToArray()).ContinueWith(OnLocationChecksCompleted); } UpdateLocationCounts(); } public void MarkAsTrash(IEnumerable ids, PlayerAgent? player, bool skipInteraction = false) { foreach (LocationID id in ids) { if (TrashedLocations.Add(id) && !skipInteraction) { SendInteraction(pArchipelagoInteraction.eType.MarkTrash, id.AsId, 0); } } UpdateLocationCounts(); } protected void DistributeItems(IReadOnlyList locations, Queue items) { if (items.Count == 0) { return; } double num = 0.2; double num2 = ((items.Count >= locations.Count) ? 1.0 : ((double)items.Count / (double)locations.Count)); long num3 = locations.Count; for (long num4 = 0L; num4 < num3; num4++) { num += num2; if (num >= 1.0) { int index = (int)((num4 + Math.Abs(RootSeed)) % num3); locations[index].ItemID = items.Dequeue(); locations[index].RandMode = new RandTest(RandTest.eType.Randomized); num -= 1.0; Game.Data processedGameData = MidManager.GetProcessedGameData(); processedGameData.TryLookupLocation(locations[index].NameTag, out var _); } } } protected void TryOverwriteRundowns() { //IL_009e: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_01d8: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //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_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_07a7: Unknown result type (might be due to invalid IL or missing references) //IL_0907: Unknown result type (might be due to invalid IL or missing references) //IL_090c: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) //IL_0919: Unknown result type (might be due to invalid IL or missing references) //IL_091f: Unknown result type (might be due to invalid IL or missing references) //IL_0928: Unknown result type (might be due to invalid IL or missing references) if (CurrentState == eState.CleanState) { return; } Game.Data processedGameData = MidManager.GetProcessedGameData(); Queue queue = new Queue(); foreach (Expedition.Data expedition in Expeditions) { ExpeditionInTierData val = ((Il2CppObjectBase)((Object)expedition.Expedition).MemberwiseClone()).Cast(); val.Descriptive.Prefix = expedition.ExpeditionName; val.Descriptive.SkipExpNumberInName = true; val.ExcludeFromMatchmaking = true; val.ExcludeFromProgression = false; val.Descriptive.ProgressionVisualStyle = (eProgressionVisualStyle)0; val.Accessibility = (eExpeditionAccessibility)2; val.HideOnLocked = false; val.UnlockedByExpedition = new ExpeditionIndex { Tier = (eRundownTier)1, Exp = (eBuildAutoExpeditionNumber)0 }; queue.Enqueue(val); } int numRundowns; if (queue.Count < 12) { numRundowns = 1; } else { numRundowns = (int)Math.Ceiling((double)queue.Count * 0.1); } numRundowns = Math.Min(numRundowns, MainMenuGuiLayer.Current.PageRundownNew.m_rundownSelections.Count); Random random = new Random(RootSeed.GetHashCode()); List list = (from i in Enumerable.Range(1, numRundowns) select GameDataBlockBase.GetBlock($"Archipelago {i}")).ToList(); for (int j = 0; j < numRundowns; j++) { RundownDataBlock val2 = list[j]; if (list[j] == null) { int index = j; RundownDataBlock val3 = new RundownDataBlock(); ((GameDataBlockBase)val3).name = $"Archipelago {j + 1}"; list[index] = val3; GameDataBlockBase.AddBlock(list[j], -1); val2 = list[j]; val2.NeverShowRundownTree = false; val2.UseTierUnlockRequirements = false; val2.VanityItemLayerDropDataBlock = 0u; val2.ReqToReachTierA = new RundownTierProgressionData { AllClearedSectors = 0, MainSectors = 0, SecondarySectors = 0, ThirdSectors = 0 }; val2.ReqToReachTierB = val2.ReqToReachTierA; val2.ReqToReachTierC = val2.ReqToReachTierA; val2.ReqToReachTierD = val2.ReqToReachTierA; val2.ReqToReachTierE = val2.ReqToReachTierA; val2.StorytellingData = new RundownStorytellingData { Title = MakeText(((GameDataBlockBase)(object)val2).name + " - Title", ((GameDataBlockBase)(object)val2).name + "\nMULTIVERSE"), ExternalExpTitle = MakeText(((GameDataBlockBase)(object)val2).name + " - ExpTitle", ((GameDataBlockBase)(object)val2).name), SurfaceDescription = MakeText(((GameDataBlockBase)(object)val2).name + " - Surface Description", "\nWORK WITH FELLOW PRISONERS TO RECOVER SECURE ASSETS AND COMPLETE THE RUNDOWN\n\n-----------------------------------\n\nCOORDINATE ACROSS THE MULTIWORLD TO MINIMIZE CASUALTIES AND ACCELERATE PRIORITIES\n\n-----------------------------------\n\nCOLLECT WARDEN ARTIFACTS TO SUPPLEMENT SUCCESS MARGINS AT THE COST OF EMOTIONAL DURESS"), SurfaceIconPosition = new Vector2(0f, 0f), Visuals = new RundownStorytellingVisualData { ColorBackground = Color.magenta }, TextLog = MakeText(((GameDataBlockBase)(object)val2).name + " - Log", "THIS IS ARCHIPELAGO"), TextLogPos = new Vector2(0f, 0f) }; } RundownDataBlock val4 = val2; (val4.TierA ?? (val4.TierA = new List())).Clear(); val4 = val2; (val4.TierB ?? (val4.TierB = new List())).Clear(); val4 = val2; (val4.TierC ?? (val4.TierC = new List())).Clear(); val4 = val2; (val4.TierD ?? (val4.TierD = new List())).Clear(); val4 = val2; (val4.TierE ?? (val4.TierE = new List())).Clear(); } float middle = (float)numRundowns * 0.5f + 0.5f; List list2 = (from w in Enumerable.Repeat(1f, 1).SelectMany((float w) => from wt in Enumerable.Range(1, 5) select w * MathF.Pow(2f, MathF.Abs((float)wt - 2.5f) * 0.4f)).SelectMany((float w) => from wr in Enumerable.Range(1, numRundowns) select w * MathF.Pow(1.3f, MathF.Abs((float)wr - middle) / middle)) .SelectMany((float w) => from wi in Enumerable.Range(0, 5) select w * MathF.Pow(3f, MathF.Abs((float)wi - 2f) * 0.5f)) select w / 7.7999997f).ToList(); float num = list2.Sum(); for (int k = queue.Count; k < list2.Count; k++) { float num2 = num * random.NextSingle(); float num3 = 0f; for (int l = 0; l < list2.Count; l++) { num3 += MathF.Max(list2[l], 0f); if (num3 > num2) { num -= list2[l]; if (list2[l] > 0.3f) { list2[l] = -2f; } else { list2[l] = -1f; } break; } } } for (int m = 0; m < 5; m++) { for (int n = 0; n < numRundowns; n++) { for (int num4 = 0; num4 < 5; num4++) { int index2 = m * numRundowns * 5 + n * 5 + num4; if (list2[index2] > 0f) { ExpeditionInTierData val10 = queue.Dequeue(); switch (m) { case 0: list[n].TierA.Add(val10); break; case 1: list[n].TierB.Add(val10); break; case 2: list[n].TierC.Add(val10); break; case 3: list[n].TierD.Add(val10); break; case 4: list[n].TierE.Add(val10); break; default: throw new NotSupportedException("Attempted to place rundown in a tier outside A-E"); } } } } } if (queue.Count > 0) { throw new NotSupportedException("Failed to populate the correct number of expeditions"); } foreach (Tuple item2 in list.SelectMany(GetVisualData)) { TierVisualData item = item2.Item2; item.Scale = item2.Item1 switch { 0 => 0.4f + 0.4f * random.NextSingle(), 1 => 0.1f, 2 => 0.35f + 0.2f * random.NextSingle(), 3 => 0.5f + 0.22f * random.NextSingle(), 4 => 0.675f + 0.1f * random.NextSingle(), 5 => 0.72f + 0.18f * random.NextSingle(), _ => throw new NotSupportedException("More than 5 expeditions in a single tier!"), }; item2.Item2.Color = Color.HSVToRGB(MathF.Pow(random.NextSingle(), 0.125f), 1f, 1f); } Enumerator enumerator3 = MainMenuGuiLayer.Current.PageRundownNew.m_expIconsAll.GetEnumerator(); while (enumerator3.MoveNext()) { CM_ExpeditionIcon_New current3 = enumerator3.Current; current3.SetStatusTextVisible(true); } List val11 = new List(list.Count); foreach (RundownDataBlock item3 in list) { val11.Add(((GameDataBlockBase)(object)item3).persistentID); } Global.RundownIdToLoad = val11[0]; Global.ActiveRundownIds = ((Il2CppObjectBase)val11.ToArray()).Cast>(); GameDataBlockBase.GetAllBlocks()[0].RundownIdsToLoad = val11; if (MainMenuGuiLayer.Current.PageRundownNew.m_rundownSelections.Count == 8) { List rundownSelections = MainMenuGuiLayer.Current.PageRundownNew.m_rundownSelections; Il2CppStructArray rundownSelectionPositions = MainMenuGuiLayer.Current.PageRundownNew.m_rundownSelectionPositions; for (int num5 = 1; num5 < 6; num5++) { List val12 = rundownSelections; int num6 = num5 + 1; int num7 = num5; CM_RundownSelection val13 = rundownSelections[num5]; CM_RundownSelection val14 = rundownSelections[num5 + 1]; val12[num6] = val13; rundownSelections[num7] = val14; Il2CppStructArray val15 = rundownSelectionPositions; num7 = num5 + 1; num6 = num5; Vector3 val16 = ((Il2CppArrayBase)(object)rundownSelectionPositions)[num5]; Vector3 val17 = ((Il2CppArrayBase)(object)rundownSelectionPositions)[num5 + 1]; ((Il2CppArrayBase)(object)val15)[num7] = val16; ((Il2CppArrayBase)(object)rundownSelectionPositions)[num6] = val17; } } for (int num8 = 0; num8 < numRundowns; num8++) { MainMenuGuiLayer.Current.PageRundownNew.UpdateRundownSelectionButton(MainMenuGuiLayer.Current.PageRundownNew.m_rundownSelections[num8], ((GameDataBlockBase)(object)list[num8]).persistentID); } MainMenuGuiLayer.Current.PageRundownNew.m_selectionIsRevealed = false; if (numRundowns == 1) { MainMenuGuiLayer.Current.PageRundownNew.ResetRundownItems(); MainMenuGuiLayer.Current.PageRundownNew.m_currentRundownData = list[0]; MainMenuGuiLayer.Current.PageRundownNew.PlaceRundown(list[0]); MainMenuGuiLayer.Current.PageRundownNew.UpdateHeaderText(); MainMenuGuiLayer.Current.PageRundownNew._Setup_b__102_0(0); } else { MainMenuGuiLayer.Current.PageRundownNew._Setup_b__102_3(0); } [IteratorStateMachine(typeof(<g__GetVisualData|126_5>d))] static IEnumerable> GetVisualData(RundownDataBlock rundown) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <g__GetVisualData|126_5>d(-2) { <>3__rundown = rundown }; } static LocalizedText MakeText(string name, string text) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //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_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_004e: 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_005c: 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_006a: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00aa: Expected O, but got Unknown //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) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown LanguageData val18 = new LanguageData { ShouldTranslate = false, Translation = text }; TextDataBlock val19 = new TextDataBlock { SkipLocalization = true, MachineTranslation = true, English = text, Description = "Text auto-generated by Archipelago", CharacterMetaData = 1u, French = val18, Italian = val18, German = val18, Spanish = val18, Russian = val18, Portuguese_Brazil = val18, Polish = val18, Japanese = val18, Korean = val18, Chinese_Traditional = val18, Chinese_Simplified = val18, ExportVersion = 6, ImportVersion = 6 }; ((GameDataBlockBase)val19).name = name; ((GameDataBlockBase)val19).internalEnabled = true; TextDataBlock val20 = val19; GameDataBlockBase.AddBlock(val20, -1); return new LocalizedText { Id = ((GameDataBlockBase)(object)val20).persistentID, OldId = 0u, UntranslatedText = text }; } } protected void OnLocationChecksCompleted(Task task) { if (!task.IsCompletedSuccessfully) { FeatureLogger.Error("Failed to complete location checks! Retry not currently implemented..."); } } public void RescoutLocations() { Game.Data processedGameData = MidManager.GetProcessedGameData(); HashSet reachableRegions = (from r in processedGameData.GetAllRegions() where r.Value.Reachable select r.Key).ToHashSet(); IEnumerable> source = from l in processedGameData.GetAllLocations() where l.Value.OwningRegionIds.All(reachableRegions.Contains) select l; long[] array = source.Select((KeyValuePair l) => l.Key.AsId).ToArray(); FeatureLogger.Debug($"Sending location scout request for {array.Length} locations"); ApSession.Locations.ScoutLocationsAsync((HintCreationPolicy)0, array).ContinueWith(OnLocationsScouted); } protected void OnLocationsScouted(Task> task) { Game.Data processedGameData = MidManager.GetProcessedGameData(); if (!task.IsCompletedSuccessfully) { FeatureLogger.Error("Failed to scout locations!"); RescoutLocations(); return; } FeatureLogger.Debug($"Successfully scouted {task.Result.Count} locations"); foreach (KeyValuePair item in task.Result) { Location location = processedGameData.LookupLocation(new LocationID { AsId = ((ItemInfo)item.Value).LocationId }); location.ScoutedItemName = ((ItemInfo)item.Value).ItemDisplayName; location.ScoutedPlayerName = item.Value.Player.Name; location.ScoutedGameName = ((ItemInfo)item.Value).ItemGame; } m_stateReplicator.SendScouting(FormatScoutingUpdate(task.Result.Select, LocationID>((KeyValuePair pair) => new LocationID { AsId = pair.Key }))); } public bool HasLocation(RandomizationTag name, bool includeTrash = true) { if (MidManager.GetProcessedGameData().TryLookupLocation(name, out var location)) { return HasLocation(location.ID, includeTrash); } return false; } public bool HasLocation(LocationID id, bool includeTrash = true) { if (!FoundLocations.Contains(id)) { if (includeTrash) { return TrashedLocations.Contains(id); } return false; } return true; } public void CollectItem(ItemID id, LocationID sourceLocationId = default(LocationID), PlayerAgent? player = null, bool skipInteraction = false) { Game.Data processedGameData = MidManager.GetProcessedGameData(); if (QueuedItemReplacements.TryGetValue(id, out Queue value)) { if (value.Count < 1) { throw new NotSupportedException(); } if (value.Count == 1) { QueuedItemReplacements.Remove(id); } id = value.Dequeue(); } Item item = processedGameData.LookupItem(id); FeatureLogger.Debug($"Collecting item [{id.AsId}] {processedGameData.LookupTagDef(item.NameTag).Name}"); int num = ActualItemCounts.GetValueOrDefault(id, 0) + 1; ActualItemCounts[id] = num; item.OnItemObtained(this, sourceLocationId, player); if (!skipInteraction) { SendInteraction(pArchipelagoInteraction.eType.CollectItem, id.AsId, (ushort)num); } } public void ReplaceItem(ItemID sourceItem, ItemID targetItem) { if (QueuedItemReplacements.TryGetValue(targetItem, out Queue value)) { value.Enqueue(sourceItem); } else { value = new Queue(); value.Enqueue(sourceItem); QueuedItemReplacements[targetItem] = value; } UncollectItem(sourceItem); CollectItem(targetItem, default(LocationID), null, skipInteraction: true); } public void UncollectItem(ItemID id) { Item item = MidManager.GetProcessedGameData().LookupItem(id); int valueOrDefault = ActualItemCounts.GetValueOrDefault(id, 0); if (valueOrDefault <= 0) { FeatureLogger.Error("Cannot uncollect item; it is not currently collected! Item: " + MidManager.GetProcessedGameData().LookupTagDef(item.NameTag).Name); return; } ActualItemCounts[id] = valueOrDefault - 1; item.OnItemLost(this); } public void AddItemToTerminal(Item item) { Game.Data processedGameData = MidManager.GetProcessedGameData(); if (processedGameData.TryLookupItem(item.NameTag, out var item2)) { AddItemToTerminal(item2.ID); } else { FeatureLogger.Error("Failed to add item to terminal: " + processedGameData.LookupTagDef(item.NameTag).Name); } } public void AddItemToTerminal(ItemID item) { Random random = new Random(Tuple.Create(RootSeed, item).GetHashCode()); string newCode; do { newCode = $"{r()}{r()}{r()}-{r()}{r()}{r()}-{r()}{r()}{r()}"; } while (ItemsInTerminalSystem.Any((Tuple pair) => pair.Item2 == newCode)); ItemsInTerminalSystem.Add(Tuple.Create(item, newCode)); char r() { int num = (int)(36.0 * random.NextDouble()); return (char)((num >= 10) ? (65 + (num - 10)) : (48 + num)); } } public override void Update() { Task? connectTask = ConnectTask; if (connectTask != null && connectTask.IsCompleted) { HandleConnectionResult(ConnectTask); } Task? loginTask = LoginTask; if (loginTask != null && loginTask.IsCompleted) { HandleLoginResult(LoginTask); } if (ApSession == null) { return; } if (!ApSession.Socket.Connected && ConnectTask == null) { FeatureLogger.Error("Disconnected from Archipelago! Attempting reconnect..."); CurrentState = eState.HostReconnecting; ConnectTask = ApSession.ConnectAsync(); } while (ApSession.Items.Any()) { try { ItemInfo val = ApSession.Items.DequeueItem(); ItemID itemID = new ItemID(); itemID.AsId = val.ItemId; ItemID itemID2 = itemID; if (itemID2.IsNull) { FeatureLogger.Error("Received null item id from Archipelago server!"); continue; } int num = SessionItemCounts.GetValueOrDefault(itemID2, 0) + 1; SessionItemCounts[itemID2] = num; if (NeededWinItems.Remove(itemID2) && NeededWinItems.Count == 0) { ApSession.SetClientState((ArchipelagoClientState)30); FeatureLogger.Success("Congratulations, you have won the game!"); } if (num > ActualItemCounts.GetValueOrDefault(itemID2, 0)) { if (val.Player.Slot != ApSession.Players.ActivePlayer.Slot || val.LocationId <= 0) { goto IL_01a9; } LocationID locationID = new LocationID(); locationID.AsId = val.LocationId; LocationID id = locationID; Location location = MidManager.GetProcessedGameData().LookupLocation(id); if (location.RandMode.IsRandomized) { goto IL_01a9; } } goto end_IL_0096; IL_01a9: CollectItem(itemID2); end_IL_0096:; } catch (Exception ex) { FeatureLogger.Notice("Encountered unexpected exception while receiving items from Archipelago:"); FeatureLogger.Exception(ex); } } } public static void LogForLobby(string message, bool localOnly) { IEnumerable source = Enumerable.Empty(); CM_PageLoadout pageLoadout = MainMenuGuiLayer.Current.PageLoadout; IEnumerable source2 = source.Append((pageLoadout != null) ? pageLoadout.m_gameEventLog : null); CM_PageMap pageMap = MainMenuGuiLayer.Current.PageMap; IEnumerable source3 = source2.Append((pageMap != null) ? pageMap.m_gameEventLog : null); PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; IEnumerable enumerable = source3.Append((playerLayer != null) ? playerLayer.m_gameEventLog : null); foreach (PUI_GameEventLog item in enumerable) { if (!((Object)(object)item == (Object)null)) { item.AddLogItem(message, (eGameEventChatLogType)2); item.UpdateHeightOffset(); } } if (!localOnly) { Get().m_stateReplicator?.SendLog(message); } } public static void UpdateLocationCounts() { //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Invalid comparison between Unknown and I4 //IL_01ec: 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_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) CM_MenuBar[] array = new CM_MenuBar[6]; CM_PageGearDetails pageGearDetails = MainMenuGuiLayer.Current.PageGearDetails; array[0] = ((pageGearDetails != null) ? ((CM_PageBase)pageGearDetails).m_menuBar : null); CM_PageLoadout pageLoadout = MainMenuGuiLayer.Current.PageLoadout; array[1] = ((pageLoadout != null) ? ((CM_PageBase)pageLoadout).m_menuBar : null); CM_PagePlayerDetails pagePlayerDetails = MainMenuGuiLayer.Current.PagePlayerDetails; array[2] = ((pagePlayerDetails != null) ? ((CM_PageBase)pagePlayerDetails).m_menuBar : null); CM_PageRundown pageRundown = MainMenuGuiLayer.Current.PageRundown; array[3] = ((pageRundown != null) ? ((CM_PageBase)pageRundown).m_menuBar : null); CM_PageRundown_New pageRundownNew = MainMenuGuiLayer.Current.PageRundownNew; array[4] = ((pageRundownNew != null) ? ((CM_PageBase)pageRundownNew).m_menuBar : null); CM_PageSettings pageSettings = MainMenuGuiLayer.Current.PageSettings; array[5] = ((pageSettings != null) ? ((CM_PageBase)pageSettings).m_menuBar : null); IEnumerable enumerable = new <>z__ReadOnlyArray((CM_MenuBar[])(object)array); foreach (CM_MenuBar item in enumerable) { object obj; if (item == null) { obj = null; } else { CM_ExpeditionIcon_New expIcon = item.m_expIcon; obj = ((expIcon != null) ? expIcon.DataBlock : null); } if (obj != null) { item.m_expIcon.SetArtifactHeat(1f); } } if (GameStateManager.IsInExpedition || !((Object)(object)MainMenuGuiLayer.Current.PageRundownNew != (Object)null)) { return; } StateTracker stateTracker = Get(); Enumerator enumerator2 = MainMenuGuiLayer.Current.PageRundownNew.m_expIconsAll.GetEnumerator(); while (enumerator2.MoveNext()) { CM_ExpeditionIcon_New current2 = enumerator2.Current; Expedition.Data data = Expedition.Data.TryFromExpedition(current2.DataBlock); if (data != null) { int valueOrDefault = stateTracker.CollectedItemCounts.GetValueOrDefault(SharedObjectiveHandler.GetSectorClearedItem(Layer.get_MainLayer(data)).ID, 0); int num = (Layer.get_HasSecondary(data) ? stateTracker.CollectedItemCounts.GetValueOrDefault(SharedObjectiveHandler.GetSectorClearedItem(data.GetLayer(LayerType.Secondary)).ID, 0) : 0); int num2 = (Layer.get_HasOverload(data) ? stateTracker.CollectedItemCounts.GetValueOrDefault(SharedObjectiveHandler.GetSectorClearedItem(data.GetLayer(LayerType.Overload)).ID, 0) : 0); eExpeditionIconStatus val = (((int)current2.DataBlock.Accessibility != 2) ? ((eExpeditionIconStatus)0) : ((valueOrDefault <= 0) ? ((eExpeditionIconStatus)2) : ((eExpeditionIconStatus)4))); current2.SetStatus(val, (valueOrDefault == 0) ? "-" : valueOrDefault.ToString(), (num == 0) ? "-" : num.ToString(), (num2 == 0) ? "-" : num2.ToString(), "-", 1f); } } } public void SetupReplication() { if (m_stateReplicator == null) { if (m_stateReplicator == null) { m_stateReplicator = new ArchipelagoStateReplicator(this); } Plugin.InvokeLateSetup(m_stateReplicator.ConcreteReplicator); ((MonoBehaviour)SNet.Current).StartCoroutine((IEnumerator)new Il2CppEnumerator(new UpdateStateEnumerator(this))); } } public pArchipelagoInitState MakeInitState() { pArchipelagoInitState pArchipelagoInitState = default(pArchipelagoInitState); pArchipelagoInitState.GameName = MidManager.GetProcessedGameData().Name; pArchipelagoInitState.RootSeed = RootSeed; pArchipelagoInitState.ExpeditionNames = new string[Expeditions.Count]; pArchipelagoInitState.WhitelistTags = new long[WhitelistTags.Count]; pArchipelagoInitState.BlacklistTags = new long[BlacklistTags.Count]; pArchipelagoInitState result = pArchipelagoInitState; int num = 0; foreach (Expedition.Data expedition in Expeditions) { result.ExpeditionNames[num++] = expedition.ExpeditionName; } num = 0; foreach (RandomizationTag whitelistTag in WhitelistTags) { result.WhitelistTags[num++] = whitelistTag.AsId; } num = 0; foreach (RandomizationTag blacklistTag in BlacklistTags) { result.BlacklistTags[num++] = blacklistTag.AsId; } return result; } public pArchipelagoGeneralState MakeGeneralState() { pArchipelagoGeneralState result = default(pArchipelagoGeneralState); result.LocationsChecked = FoundLocations.Select((LocationID id) => id.AsId).ToArray(); result.TrashedLocations = TrashedLocations.Select((LocationID id) => id.AsId).ToArray(); result.ItemIds = ActualItemCounts.SelectMany((KeyValuePair pair) => Enumerable.Repeat(pair.Key.AsId, pair.Value)).ToArray(); result.ItemsInTerminalSystem = ItemsInTerminalSystem.Select((Tuple pair) => pair.Item1.AsId).ToArray(); return result; } public pArchipelagoScoutingUpdate MakeScoutingUpdate() { return FormatScoutingUpdate(from l in MidManager.GetProcessedGameData().GetAllLocations() where l.Value.ScoutedItemName != null select l into i select i.Key); } public pArchipelagoScoutingUpdate FormatScoutingUpdate(IEnumerable locations) { if (ApSession == null) { throw new NullReferenceException(); } Dictionary dictionary = new Dictionary(); pArchipelagoScoutingUpdate result = default(pArchipelagoScoutingUpdate); result.SlotLookup = new string[ApSession.Players.AllPlayers.Count() * 2]; int num = 0; foreach (PlayerInfo allPlayer in ApSession.Players.AllPlayers) { result.SlotLookup[2 * num] = allPlayer.Name; result.SlotLookup[2 * num + 1] = allPlayer.Game; dictionary.Add(allPlayer.Name, num++); } Game.Data processedGameData = MidManager.GetProcessedGameData(); result.LocationIDs = locations.Select((LocationID id) => id.AsId).ToArray(); result.SlotIds = new long[result.LocationIDs.Length]; result.ItemDisplayNames = new string[result.LocationIDs.Length]; for (int i = 0; i < result.LocationIDs.Length; i++) { LocationID locationID = new LocationID(); locationID.AsId = result.LocationIDs[i]; LocationID id2 = locationID; Location location = processedGameData.LookupLocation(id2); result.SlotIds[i] = dictionary[location.ScoutedPlayerName ?? throw new NullReferenceException()]; result.ItemDisplayNames[i] = location.ScoutedItemName ?? throw new NullReferenceException(); } return result; } protected void SendInteraction(pArchipelagoInteraction.eType type, long value = 0L, ushort count = 0) { if (!SNet.Capture.IsRecalling) { m_stateReplicator.SendInteraction(new pArchipelagoInteraction(type, value, count)); } } public void ReceiveInitState(pArchipelagoInitState state) { ClientConnect(state); } public void ReceiveScoutingUpdate(pArchipelagoScoutingUpdate update) { if (ApSession != null) { FeatureLogger.Debug("Ignoring scouting update; we are connected to AP!"); return; } FeatureLogger.Debug("Received a scouting update."); Game.Data processedGameData = MidManager.GetProcessedGameData(); for (int i = 0; i < update.LocationIDs.Length; i++) { LocationID locationID = new LocationID(); locationID.AsId = update.LocationIDs[i]; LocationID id = locationID; Location location = processedGameData.LookupLocation(id); long num = update.SlotIds[i]; location.ScoutedItemName = update.ItemDisplayNames[i]; location.ScoutedPlayerName = update.SlotLookup[2 * num]; location.ScoutedGameName = update.SlotLookup[2 * num + 1]; } } public void ReceiveGeneralState(pArchipelagoGeneralState state, bool isRecall) { if (!isRecall) { if (ApSession != null) { FeatureLogger.Debug("Ignoring GeneralState packet because we're connected to AP"); return; } if (CurrentState == eState.FakeConnect) { FeatureLogger.Debug("Ignoring GeneralState packet because we're using FakeConnect"); return; } } Game.Data processedGameData = MidManager.GetProcessedGameData(); FoundLocations.UnionWith(state.LocationsChecked.Select((long id) => new LocationID { AsId = id })); TrashedLocations.UnionWith(state.TrashedLocations.Select((long id) => new LocationID { AsId = id })); ItemsInTerminalSystem.Clear(); long[] itemsInTerminalSystem = state.ItemsInTerminalSystem; foreach (long asId in itemsInTerminalSystem) { AddItemToTerminal(new ItemID { AsId = asId }); } Dictionary dictionary = (from i in state.ItemIds group i by i).ToDictionary((IGrouping g) => new ItemID { AsId = g.Key }, (IGrouping g) => g.Count()); foreach (ItemID item in ActualItemCounts.Keys.Union(dictionary.Keys)) { int valueOrDefault = ActualItemCounts.GetValueOrDefault(item, 0); int valueOrDefault2 = dictionary.GetValueOrDefault(item, 0); if (isRecall) { for (int k = valueOrDefault2; k < valueOrDefault; k++) { processedGameData.LookupItem(item).OnItemObtained(this, new LocationID(), null); } } else { for (int l = valueOrDefault; l < valueOrDefault2; l++) { CollectItem(item, default(LocationID), null, skipInteraction: true); } } } } public void ReceiveInteraction(pArchipelagoInteraction interaction) { PlayerAgent player = null; SNet_Player val = default(SNet_Player); if (SNet.Replication.TryGetLastSender(ref val, false)) { SNet_IPlayerAgent playerAgent = val.PlayerAgent; player = ((playerAgent != null) ? ((Il2CppObjectBase)playerAgent).TryCast() : null); } switch (interaction.Type) { case pArchipelagoInteraction.eType.CollectItem: if (ApSession == null && CurrentState != eState.FakeConnect) { ItemID itemID = new ItemID(); itemID.AsId = interaction.Value; ItemID itemID2 = itemID; int num = (ushort)ActualItemCounts.GetValueOrDefault(itemID2, 0); while (num++ < interaction.Count) { CollectItem(itemID2, default(LocationID), null, skipInteraction: true); } } break; case pArchipelagoInteraction.eType.CheckLocation: { LocationID locationID = new LocationID(); locationID.AsId = interaction.Value; LocationID id = locationID; NotifyFoundLocation(id, player, force: false, skipInteraction: true); break; } case pArchipelagoInteraction.eType.MarkTrash: { LocationID locationID = new LocationID(); locationID.AsId = interaction.Value; LocationID item = locationID; MarkAsTrash(new <>z__ReadOnlySingleElementList(item), player, skipInteraction: true); break; } case pArchipelagoInteraction.eType.EmptyTrash: TrashedLocations.Clear(); break; case pArchipelagoInteraction.eType.CheckRegion: { RegionID regionID = new RegionID(); regionID.AsId = interaction.Value; RegionID regionId = regionID; NotifyFoundRegion(regionId, player, skipInteraction: true); break; } default: FeatureLogger.Error($"Received unknown interaction type: {interaction.Type}"); break; } } } } namespace ReTFO.Archipelago.Features.ZoneHandlers { public static class DimensionPortalHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_DimensionPortalScanLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_DimensionPortalScanItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_DimensionPortalWarpLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_DimensionPortalWarpItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_DimensionPortalScanLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Dimension Portal Scan Locations", "Locations checked by powering up a dimension portal (ie R6B1)", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_DimensionPortalScanItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Dimension Portal Scans", "The scan in dimension portal rooms (ie R6B1) which trigger a dimension warp", RootRandomizationTags.get_Tag_ScanItems(gd))); } public static TagResolver get_Tag_DimensionPortalWarpLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Dimension Portal Warp Locations", "Locations checked by triggering a dimension warp using a dimension portal (ie R6B1)", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_DimensionPortalWarpItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Dimension Portal Warps", "A warp normally triggerd by a dimension portal room (ie R6B1)", RootRandomizationTags.get_Tag_WarpItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class DimensionPortalHandler : ArchipelagoFeature { public static class ThisRegions { public static string KeyInsertedRegion(Zone.Data data) { return data.ZoneName + " Dimension Portal Key Inserted"; } public static string ScanCompletedRegion(Zone.Data data) { return data.ZoneName + " Dimension Portal Scan Completed"; } } public static class DimensionPortal_ScanLocation { public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Dimension Portal Scan Location", "A location checked by startinga a dimension portal scan", DimensionPortalHandler_Tags.get_Tag_DimensionPortalScanLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } public class DimensionPortal_ScanItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass6_0 { public LG_ComputerTerminal terminal; public LG_DimensionPortal portal; public StateTracker stateTracker; public DimensionPortal_ScanItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Initiating Dimension Portal Scan", 2f); } internal void b__1() { if ((Object)(object)portal != (Object)null) { terminal.AddLine("Scan commencing. Enjoy?", true); portal.m_portalChainPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)0); portal.OnPortalKeyInsertSequenceDone?.Invoke(portal); } else { terminal.AddLine("<#F00>Failed to find dimension portal! Item returned to terminal.", true); stateTracker.AddItemToTerminal(<>4__this); } } } [CompilerGenerated] private sealed class d__6 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public DimensionPortal_ScanItem <>4__this; private <>c__DisplayClass6_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; DimensionPortal_ScanItem dimensionPortal_ScanItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass6_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; LG_Zone lG_Zone = dimensionPortal_ScanItem.ZoneData.GetLG_Zone(); LG_DimensionPortalRoom val = null; foreach (LG_Area item in ((lG_Zone != null) ? lG_Zone.m_areas.Iter() : null) ?? Enumerable.Empty()) { object obj; if (item == null) { obj = null; } else { LG_Geomorph geomorph = item.m_geomorph; obj = ((geomorph != null) ? ((Component)geomorph).GetComponent() : null); } val = (LG_DimensionPortalRoom)obj; if ((Object)(object)val != (Object)null) { break; } } <>8__1.portal = ((val != null) ? val.m_core : null); <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating Dimension Portal Scan", 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { if ((Object)(object)<>8__1.portal != (Object)null) { <>8__1.terminal.AddLine("Scan commencing. Enjoy?", true); <>8__1.portal.m_portalChainPuzzleInstance.AttemptInteract((eChainedPuzzleInteraction)0); <>8__1.portal.OnPortalKeyInsertSequenceDone?.Invoke(<>8__1.portal); } else { <>8__1.terminal.AddLine("<#F00>Failed to find dimension portal! Item returned to terminal.", true); <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__6 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__6(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Zone.Data ZoneData; public DimensionPortal_ScanItem(Zone.Data data) : base(MakeTag(data), MakeRandData()) { ZoneData = data; } public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Dimension Portal Scan", "A scan used by a dimension portal", DimensionPortalHandler_Tags.get_Tag_DimensionPortalScanItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ZoneData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ZoneData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__6))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } public static class DimensionPortal_WarpLocation { public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Dimension Portal Warp Location", "A location checked by triggering a particular dimension portal's warp", DimensionPortalHandler_Tags.get_Tag_DimensionPortalWarpLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } public class DimensionPortal_WarpItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass6_0 { public LG_ComputerTerminal terminal; public LG_DimensionPortal portal; public StateTracker stateTracker; public DimensionPortal_WarpItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Initiating Dimension Portal Warp", 2f); } internal void b__1() { if ((Object)(object)portal != (Object)null) { terminal.AddLine("Initiating Dimension Warp via Dimension Portal. Goodbye!", true); portal._Setup_b__61_0(); } else { terminal.AddLine("<#F00>Failed to find dimension portal! Item returned to terminal.", true); stateTracker.AddItemToTerminal(<>4__this); } } } [CompilerGenerated] private sealed class d__6 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public DimensionPortal_WarpItem <>4__this; private <>c__DisplayClass6_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; DimensionPortal_WarpItem dimensionPortal_WarpItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass6_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; LG_Zone lG_Zone = dimensionPortal_WarpItem.ZoneData.GetLG_Zone(); LG_DimensionPortalRoom val = null; foreach (LG_Area item in ((lG_Zone != null) ? lG_Zone.m_areas.Iter() : null) ?? Enumerable.Empty()) { object obj; if (item == null) { obj = null; } else { LG_Geomorph geomorph = item.m_geomorph; obj = ((geomorph != null) ? ((Component)geomorph).GetComponent() : null); } val = (LG_DimensionPortalRoom)obj; if ((Object)(object)val != (Object)null) { break; } } <>8__1.portal = ((val != null) ? val.m_core : null); <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating Dimension Portal Warp", 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { if ((Object)(object)<>8__1.portal != (Object)null) { <>8__1.terminal.AddLine("Initiating Dimension Warp via Dimension Portal. Goodbye!", true); <>8__1.portal._Setup_b__61_0(); } else { <>8__1.terminal.AddLine("<#F00>Failed to find dimension portal! Item returned to terminal.", true); <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__6 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__6(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Zone.Data ZoneData; public DimensionPortal_WarpItem(Zone.Data data) : base(MakeTag(data), MakeRandData()) { ZoneData = data; } public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Dimension Portal Warp", "A warp triggerd by a particular dimension portal in the zone", DimensionPortalHandler_Tags.get_Tag_DimensionPortalWarpItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ZoneData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ZoneData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__6))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_DimensionPortal__PortalKeyInsertSequenceDone__Patch { public static bool Prefix(LG_DimensionPortal __instance) { Zone.Data data = Zone.Data.FromZone(__instance.SpawnNode.m_zone); if (data.TryLookupLocation(DimensionPortal_ScanLocation.MakeTag(data), out var location)) { if (StateTracker.Get().NotifyFoundLocation(location.ID, null).RandMode.IsTreatedAsRandom) { return false; } } else { FeatureLogger.Error("Failed to check dimension portal scan location!"); } return true; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_DimensionPortal__Setup__Patch { public static void Postfix(LG_DimensionPortal __instance) { Zone.Data data = Zone.Data.FromZone(__instance.SpawnNode.m_zone); if (data.TryLookupLocation(DimensionPortal_WarpLocation.MakeTag(data), out var loc)) { if (loc.Location.RandMode.IsTreatedAsRandom) { Action action = delegate { StateTracker.Get().NotifyFoundLocation(loc.ID, null); }; __instance.m_portalChainPuzzleInstance.OnPuzzleSolved = new Il2CppAction(action); } } else { FeatureLogger.Error("Failed to create association for Dimension Portal Warp Location!"); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Dimension Portal Handler"; public override string Description => "Handles dimension warps triggered by portals (which require MWPs)\nFor example, this handles the dimension warp in R6B1.\nDimension portals include the warp scan and the actual warp itself as separate items."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ZoneHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetDimensionPortalScanItem(Zone.Data data) { if (data.TryLookupItem(DimensionPortal_ScanItem.MakeTag(data), out var item)) { return item; } Item item2 = new DimensionPortal_ScanItem(data); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetDimensionPortalWarpItem(Zone.Data data) { if (data.TryLookupItem(DimensionPortal_WarpItem.MakeTag(data), out var item)) { return item; } Item item2 = new DimensionPortal_WarpItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Zone.Callback] public void AddZoneWarps(Zone.Data data) { //IL_006d: 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) string? customGeo = data.CustomGeo; if (customGeo != null && customGeo.Contains("_portal_", StringComparison.OrdinalIgnoreCase)) { Zone.Data data2 = Zone.get_FirstZone(data.GetLayer(LayerType.Dimension_1)); ComplexResourceSetDataBlock block = GameDataBlockBase.GetBlock(data.Expedition.Expedition.ComplexResourceData); GameObject val = ((block != null) ? block.GetCustomGeomorph(data.CustomGeo) : null); LG_DimensionPortal val2 = ((val != null) ? val.GetComponentInChildren() : null); if ((Object)(object)val2 != (Object)null) { data2 = data.FindZoneExact(val2.m_targetDimension, val2.m_targetZone) ?? throw new NullReferenceException("Failed to find portal target despite finding portal asset"); } else { FeatureLogger.Warning(data.ZoneName + ": Using default portal location for presumed DimensionPortal"); } RegionID regionID = data.LookupOrCreateRegion(ThisRegions.KeyInsertedRegion(data)); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.LookupOrCreateRegion(data.ZoneName), EndingRegion = regionID, ReqItem = BigPickupHandler.GetBigPickupItem(data, BigPickupHandler.MatterWaveProjectorID).PathReqs, ReqCount = 1u }); KeyedItem dimensionPortalScanItem = GetDimensionPortalScanItem(data); data.AddLocation(DimensionPortal_ScanLocation.MakeTag(data), regionID, DimensionPortal_ScanLocation.MakeRandData(), dimensionPortalScanItem.ID); RegionID regionID2 = data.LookupOrCreateRegion(ThisRegions.ScanCompletedRegion(data)); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2, ReqItem = dimensionPortalScanItem.PathReqs, ReqCount = 1u }); KeyedItem dimensionPortalWarpItem = GetDimensionPortalWarpItem(data); data.AddLocation(DimensionPortal_WarpLocation.MakeTag(data), regionID2, DimensionPortal_WarpLocation.MakeRandData(), dimensionPortalWarpItem.ID); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = data.LookupOrCreateRegion(data2.ZoneName), ReqItem = dimensionPortalWarpItem.PathReqs, ReqCount = 1u }); } } } [EnableFeatureByDefault] [AutomatedFeature] public class SecDoorHandler : ArchipelagoFeature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerAgent__SetCourseNode__Patch { public static void Postfix(PlayerAgent __instance) { Zone.Data data = Zone.Data.FromZone(((Agent)__instance).CourseNode.m_zone); StateTracker.Get().NotifyFoundRegion(data.ZoneName, __instance); } } private static IArchiveLogger? m_featureLogger; public override string Name => "Sec Door Handler"; public override string Description => "Adds sec doors as parths and applies locks to them"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ZoneHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Zone.Callback] public void AddZoneEntrances(Zone.Data data) { //IL_0040: 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_0062: 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_010c: Invalid comparison between Unknown and I4 //IL_00cc: 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_013f: Invalid comparison between Unknown and I4 //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Invalid comparison between Unknown and I4 if (data.Layout != null && data.Zone != null && !(((Il2CppObjectBase)data.Zone).Pointer == ((Il2CppObjectBase)data.Layout.Zones[0]).Pointer)) { Zone.Data data2 = ((data.Zone.BuildFromLocalIndex != data.Zone.LocalIndex) ? data.FindZoneByIndex(data.Zone.BuildFromLocalIndex) : Zone.get_FirstZone(data)); RegionID startingRegion = data.LookupOrCreateRegion(data2.ZoneName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.Name = data.ZoneName + " Main Entry"; path.StartingRegion = startingRegion; path.EndingRegion = data.LookupOrCreateRegion(data.ZoneName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; LayerData layerDatas = data.LayerDatas; if (layerDatas != null && layerDatas.ZonesWithBulkheadEntrance.Contains(data.Zone.LocalIndex)) { path2.ReqItem = BulkheadKeyHandler.GetBulkheadKeyItem(data).PathReqs; path2.ReqCount = 1u; } else if ((int)data.Zone.ProgressionPuzzleToEnter.PuzzleType == 1) { path2.ReqItem = ColoredKeyHandler.GetColoredKeyItem(data).PathReqs; path2.ReqCount = 1u; } else if ((int)data.Zone.ProgressionPuzzleToEnter.PuzzleType == 2) { path2.ReqItem = BigPickupHandler.GetBigPickupItem(data, BigPickupHandler.CellItemID).PathReqs; path2.ReqCount = 1u; } else if ((int)data.Zone.ProgressionPuzzleToEnter.PuzzleType == 3) { path2.ReqItem = new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Blocked, RootRandomizationTags.get_Tag_Never(data)); path2.ReqCount = 1u; } path2.AlternateItem = UnlockEventHandler.GetUnlockEventItem(data).PathReqs; data.AddPath(path2); if (data.Zone.EventsOnApproachDoor.Any()) { string text = data.ZoneName + " OnApproach"; RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID }); data.ProcessEvents(regionID, text, data.Zone.EventsOnApproachDoor); } } } [Layer.Callback] public void AddLayerEntrances(Layer.Data data) { //IL_0038: 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) Layer.Data data2 = data; if (data2.BuildFromData != null) { Zone.Data data3 = Zone.get_FirstZone(data2); Layer.Data layer = data2.GetLayer(data2.BuildFromData.LayerType); Zone.Data data4 = layer.FindZoneByIndex(data2.BuildFromData.Zone); RegionID startingRegion = data2.LookupOrCreateRegion(data4.ZoneName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.Name = data2.LayerName + " Layer Entry"; path.StartingRegion = startingRegion; path.EndingRegion = data2.LookupOrCreateRegion(data3.ZoneName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; if (layer.LayerDatas.BulkheadDoorControllerPlacements.FirstOrDefault((BulkheadDoorPlacementData p) => p.ZoneIndex == data2.BuildFromData.Zone) != null) { path2.ReqItem = BulkheadKeyHandler.GetBulkheadKeyItem(data2).PathReqs; path2.ReqCount = 1u; } else { path2.ReqItem = new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Blocked, RootRandomizationTags.get_Tag_Never(data2)); path2.ReqCount = 1u; } path2.AlternateItem = UnlockEventHandler.GetUnlockEventItem(data3).PathReqs; data2.AddPath(path2); if (data3.Zone.EventsOnApproachDoor.Any()) { string text = data3.ZoneName + " OnApproach"; RegionID regionID = data2.LookupOrCreateRegion(text); data2.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID }); data2.ProcessEvents(regionID, text, data3.Zone.EventsOnApproachDoor); } } } } [EnableFeatureByDefault] [AutomatedFeature] public class TriggerEventsHandler : ArchipelagoFeature { private static IArchiveLogger? m_featureLogger = null; private static Dictionary> WorldEventObjectOverrides = new Dictionary> { { "Evt_Shuttlebox_Interact_R8A1", Tuple.Create(LayerType.Main, (eLocalZoneIndex)4) }, { "WE_Hearsay_Interact_02", Tuple.Create(LayerType.Main, (eLocalZoneIndex)7) } }; private static Dictionary> PathReqsOverride = new Dictionary> { { "Evt_Shuttlebox_Interact_R8A1", (Zone.Data data) => RetrieveBigItemsHandler.GetItem(data.GetObjectiveDatas().ElementAt(0), 1) }, { "WE_Dataextractor_Interact", (Zone.Data data) => BigPickupHandler.GetBigPickupItem(data, 181u) }, { "Evt_Shuttlebox_Interact_R7B1", (Zone.Data data) => BigPickupHandler.GetBigPickupItem(data, 173u) } }; public override string Name => "Trigger Events Handler"; public override string Description => "Triggers processing of trigger eventsTrigger events are the most versatile event type in GTFO, which are activated by world event triggers. These include invisible trigger hitboxes and certain special interactions"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ZoneHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Zone.Callback] public void AddTriggerEvents(Zone.Data data) { //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029c: 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_02c2: 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_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0347: 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_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Expected O, but got Unknown if (data.Zone == null || data.Zone.EventsOnTrigger == null || data.Zone.EventsOnTrigger.Count == 0) { return; } List val = new List(data.Zone.EventsOnTrigger.Count); foreach (WorldEventFromSourceData item in (from e in data.Zone.EventsOnTrigger.Iter() group e by e.WorldEventTriggerObjectFilter).SelectMany((IGrouping g) => g)) { val.Add((WardenObjectiveEventData)(object)item); } data.Zone.EventsOnTrigger.Clear(); int num = 0; for (int i = 1; i <= val.Count; i++) { WorldEventFromSourceData val2 = ((Il2CppObjectBase)val[num]).Cast(); WorldEventFromSourceData val3 = ((i == val.Count) ? null : ((Il2CppObjectBase)val[i]).Cast()); if (val2.WorldEventTriggerObjectFilter == ((val3 != null) ? val3.WorldEventTriggerObjectFilter : null)) { continue; } string worldEventTriggerObjectFilter = val2.WorldEventTriggerObjectFilter; if (worldEventTriggerObjectFilter != null) { Zone.Data data2 = data; if (WorldEventObjectOverrides.TryGetValue(worldEventTriggerObjectFilter, out Tuple value)) { data2 = data.FindZoneExact(value.Item1, value.Item2) ?? throw new Exception("Warden Event Trigger has zone override, but the override zone could not be found"); } ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem requiredItem = new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(); if (PathReqsOverride.TryGetValue(worldEventTriggerObjectFilter, out Func value2)) { requiredItem = value2(data).Item.PathReqs; } string text = data2.ZoneName + " OnTrigger (" + worldEventTriggerObjectFilter + ")"; RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.LookupOrCreateRegion(data2.ZoneName), EndingRegion = regionID }); Event.Data data3 = data.ProcessEvents(regionID, text, val, num, i - num); num = data3.EventStart; i = data3.EventStart + data3.EventCount; } for (int j = num; j < i; j++) { WorldEventFromSourceData val4 = ((Il2CppObjectBase)val[j]).TryCast(); if (val4 != null) { data.Zone.EventsOnTrigger.Add(val4); continue; } data.Zone.EventsOnTrigger.Add(new WorldEventFromSourceData { WorldEventTriggerObjectFilter = worldEventTriggerObjectFilter, AchievementKey = val[j].AchievementKey, ChainPuzzle = val[j].ChainPuzzle, ClearDimension = val[j].ClearDimension, Condition = val[j].Condition, Count = val[j].Count, CustomSubObjective = val[j].CustomSubObjective, CustomSubObjectiveHeader = val[j].CustomSubObjectiveHeader, Delay = val[j].Delay, DialogueID = val[j].DialogueID, DimensionIndex = val[j].DimensionIndex, Duration = val[j].Duration, Enabled = val[j].Enabled, EnemyID = val[j].EnemyID, EnemyWaveData = val[j].EnemyWaveData, FogSetting = val[j].FogSetting, FogTransitionDuration = val[j].FogTransitionDuration, Layer = val[j].Layer, LocalIndex = val[j].LocalIndex, Position = val[j].Position, SoundID = val[j].SoundID, SoundSubtitle = val[j].SoundSubtitle, SustainedEventDelay = val[j].SustainedEventDelay, SustainedEventSlotIndex = val[j].SustainedEventSlotIndex, SustainedEventStateCount = val[j].SustainedEventStateCount, SustainedEventStateDuration = val[j].SustainedEventStateDuration, TerminalCommand = val[j].TerminalCommand, TerminalCommandRule = val[j].TerminalCommandRule, Trigger = val[j].Trigger, Type = val[j].Type, UseStaticBioscanPoints = val[j].UseStaticBioscanPoints, WardenIntel = val[j].WardenIntel, WorldEventObjectFilter = val[j].WorldEventObjectFilter }); } num = i; } } } [EnableFeatureByDefault] [AutomatedFeature] public class ZoneEventsHandler : ArchipelagoFeature { private static IArchiveLogger? m_featureLogger; public override string Name => "Zone Events Handler"; public override string Description => "Triggers processing of several zone-based eventsIncludes the following events:\n - OnBossDeath\n - OnDoorScanDone\n - OnDoorScanStart\n - OnOpenDoor\n - OnPortalWarp\n - OnTerminalDeactivateAlarm\n - OnUnlockDoor"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ZoneHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Zone.Callback] public void AddZoneEvents(Zone.Data data) { RegionID startingRegion = data.LookupOrCreateRegion(data.ZoneName); if (data.Zone != null) { Tuple>[] array = new Tuple>[7] { Tuple.Create>(data.ZoneName + " OnBossDeath", data.Zone.EventsOnBossDeath), Tuple.Create>(data.ZoneName + " OnDoorScanDone", data.Zone.EventsOnDoorScanDone), Tuple.Create>(data.ZoneName + " OnDoorScanStart", data.Zone.EventsOnDoorScanStart), Tuple.Create>(data.ZoneName + " OnOpenDoor", data.Zone.EventsOnOpenDoor), Tuple.Create>(data.ZoneName + " OnPortalWarp", data.Zone.EventsOnPortalWarp), Tuple.Create>(data.ZoneName + " OnTerminalDeactivateAlarm", data.Zone.EventsOnTerminalDeactivateAlarm), Tuple.Create>(data.ZoneName + " OnUnlockDoor", data.Zone.EventsOnUnlockDoor) }; Tuple>[] array2 = array; foreach (Tuple> tuple in array2) { if (tuple.Item2.Any()) { RegionID regionID = data.LookupOrCreateRegion(tuple.Item1); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID }); data.ProcessEvents(regionID, tuple.Item1, tuple.Item2); } } } else if (data.DimensionData != null && data.DimensionData.EventsOnBossDeath.Any()) { string text = data.ZoneName + " OnBossDeath"; RegionID regionID2 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID2 }); data.ProcessEvents(regionID2, text, data.DimensionData.EventsOnBossDeath); } } } } namespace ReTFO.Archipelago.Features.Terminals { public static class APCommandExtractHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TerminalExtractLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_TerminalExtractLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Terminal Extract Locations", "Empty locations checked by running the EXTRACT and RELEASE commands on terminals", RootRandomizationTags.get_Tag_AllLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class APCommandExtractHandler : ArchipelagoFeature { private static class TerminalExtractReleaseLocation { public static TagResolver MakeTag(Terminal.Data data, int count) { Terminal.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.TerminalName} Extract Location #{count}", "A location checked by running the EXTRACT and RELEASE commands on terminals", APCommandExtractHandler_Tags.get_Tag_TerminalExtractLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsEmpty = true; return result; } } private class ExtractCommand : APCommandHandler.SubCommand { public override string HelpText => "EXTRACT high-security item codes from this terminal\nEach terminal contains unique high-security codes\nUse the RELEASE command with high-security item codes to RELEASE items to the MULTIWORLD"; public ExtractCommand() { base.SubCommandName = "EXTRACT"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { terminal.m_command.AddOutput((TerminalLineType)2, "Extracting codes", 3.5f, (TerminalSoundType)0, (TerminalSoundType)2); StateTracker stateTracker = StateTracker.Get(); Game.Data gameData = stateTracker.MidManager.GetProcessedGameData(); IEnumerable> enumerable = MakeItemCodes(stateTracker, terminal); bool flag = false; foreach (Tuple item in enumerable) { bool flag2 = item.Item2.IsNull || item.Item2.ItemID.IsNull || stateTracker.HasLocation(item.Item2.ID, includeTrash: false); Location location = item.Item2.Location; terminal.AddLine("\n |--------------| " + (flag2 ? "" : (" Item: " + itemName())), false); terminal.AddLine(" | " + item.Item1 + " | " + (flag2 ? "-- MODULE EMPTY --" : ("World: " + itemGame())), false); terminal.AddLine(" |--------------| " + (flag2 ? "" : ("Owner: " + itemPlayer())), false); flag = true; string itemGame() { return location.ScoutedGameName ?? "DEBUG"; } string itemName() { return location.ScoutedItemName ?? gameData.LookupTagDef(gameData.LookupItem(location.ItemID).NameTag).Name; } string itemPlayer() { return location.ScoutedPlayerName ?? StateTracker.Config.Username; } } if (flag) { terminal.AddLine("\n -- END OF LIST --", true); } else { terminal.AddLine("\n -- NOTHING TO EXTRACT --", true); } } } private class ReleaseCommand : APCommandHandler.SubCommand { public override string HelpText => "Use a high-security item code from EXTRACT to release an item to the MULTIWORLD\nExample: `AP RELEASE XXXX-XX-XXXX`"; public ReleaseCommand() { base.SubCommandName = "RELEASE"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { string param3 = param2; LG_ComputerTerminal terminal2 = terminal; StateTracker stateTracker = StateTracker.Get(); Tuple pair = MakeItemCodes(stateTracker, terminal2).FirstOrDefault((Tuple p) => string.Compare(p.Item1, param3, StringComparison.OrdinalIgnoreCase) == 0); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); if (pair == null) { terminal2.m_command.AddOutput((TerminalLineType)3, "Releasing item " + param3.ToUpper(), 2.5f, (TerminalSoundType)0, (TerminalSoundType)3); terminal2.AddLine("<#F00>Incorrect item code!", true); return; } terminal2.m_command.AddOutput((TerminalLineType)2, "Releasing item " + param3.ToUpper(), 2.5f, (TerminalSoundType)0, (TerminalSoundType)2); if (pair.Item2.Location.ItemID.IsNull) { terminal2.AddLine("No item to release.", true); return; } terminal2.AddLine("Item released successfully: " + pair.Item2.Location.ScoutedItemName, true); LG_ComputerTerminalCommandInterpreter command = terminal2.m_command; command.OnEndOfQueue += (Action)new Il2CppAction(delegate { StateTracker.Get().NotifyFoundLocation(pair.Item2.ID, terminal2.m_syncedInteractionSource); }); } } private class TrashCommand : APCommandHandler.SubCommand { public override string HelpText => "Mark all items found using the EXTRACT command as trash.\nThis marks them as found in the menu, but does not release them to the multiworld."; public TrashCommand() { base.SubCommandName = "TRASH"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { StateTracker stateTracker = StateTracker.Get(); List list = (from pair in MakeItemCodes(stateTracker, terminal) where !pair.Item2.IsNull && !pair.Item2.ItemID.IsNull && !stateTracker.HasLocation(pair.Item2.ID, includeTrash: false) select pair.Item2.ID).ToList(); stateTracker.MarkAsTrash(list, terminal.m_syncedInteractionSource); terminal.m_command.AddOutput($"You have marked {list.Count} item{((list.Count == 1) ? "" : "s")} as <#F00>TRASH", true); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__AddInitialTerminalOutput__Patch { public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance) { if (!__instance.m_terminal.m_isSetup) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance.m_terminal); if (identifyTerminalResult.Data == null) { if (!identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("Failed to lookup terminal data: " + __instance.m_terminal.ItemKey); } return; } Terminal.Data data = identifyTerminalResult.Data; StateTracker stateTracker = StateTracker.Get(); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); int num = 0; for (int i = 0; i < 3; i++) { RandomizationTag randomizationTag = TerminalExtractReleaseLocation.MakeTag(data, i + 1); if (!processedGameData.TryLookupLocation(randomizationTag, out var location)) { FeatureLogger.Error("Failed to lookup terminal extraction location: " + processedGameData.LookupTagDef(randomizationTag).Name); } else if (!location.ItemID.IsNull && !stateTracker.HasLocation(location.ID)) { num++; } } if (num == 1) { __instance.AddOutput("There is 1 available item on this terminal", false); } else { __instance.AddOutput($"There are {num} available items on this terminal", false); } Queue outputQueue = __instance.m_outputQueue; int num2 = (outputQueue._head + outputQueue.Count - 1) % outputQueue._array.Count; for (int j = 0; j < 5; j++) { int num3 = num2 - 1; if (num3 < 0) { num3 = outputQueue._array.Count - 1; } TerminalLine val = outputQueue._array[num3]; outputQueue._array[num3] = outputQueue._array[num2]; outputQueue._array[num2] = val; num2 = num3; } } } private static IArchiveLogger? m_featureLogger; public const int ItemsPerTerminal = 3; public const float ExtractDelay = 3.5f; public const float ReleaseDelay = 2.5f; private ExtractCommand? m_extractCommand; private ReleaseCommand? m_releaseCommand; private TrashCommand? m_trashCommand; public override string Name => "AP Extract Command"; public override string Description => "Adds the EXTRACT, RELEASE, and TRASH subcommands to the AP command"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public override void OnEnable() { base.OnEnable(); APCommandHandler.RegisterCommand(m_extractCommand ?? (m_extractCommand = new ExtractCommand())); APCommandHandler.RegisterCommand(m_releaseCommand ?? (m_releaseCommand = new ReleaseCommand())); APCommandHandler.RegisterCommand(m_trashCommand ?? (m_trashCommand = new TrashCommand())); } public override void OnDisable() { base.OnDisable(); APCommandHandler.UnregisterCommand(m_extractCommand ?? (m_extractCommand = new ExtractCommand())); APCommandHandler.UnregisterCommand(m_releaseCommand ?? (m_releaseCommand = new ReleaseCommand())); APCommandHandler.UnregisterCommand(m_trashCommand ?? (m_trashCommand = new TrashCommand())); } private static IEnumerable> MakeItemCodes(StateTracker stateTracker, LG_ComputerTerminal terminal) { Terminal.Data data = Terminal.Data.FromTerminal(terminal).Data; if (data == null) { return Enumerable.Empty>(); } SHA256 sHA = SHA256.Create(); Span destination = stackalloc byte[8]; BinaryPrimitives.WriteInt64LittleEndian(destination, stateTracker.RootSeed); sHA.TransformBlock(destination.ToArray(), 0, 8, null, 0); byte[] bytes = Encoding.UTF8.GetBytes(data.TerminalName); sHA.TransformFinalBlock(bytes, 0, bytes.Length); bytes = sHA.Hash; int num = 0; for (int i = 0; i < bytes.Length; i += 4) { num ^= BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(i, 4)); } Random random = new Random(num); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); Tuple[] array = new Tuple[3]; for (int j = 0; j < 3; j++) { RandomizationTag randomizationTag = TerminalExtractReleaseLocation.MakeTag(data, j + 1); if (!processedGameData.TryLookupLocation(randomizationTag, out var location)) { FeatureLogger.Error("Failed to lookup terminal extraction location: " + processedGameData.LookupTagDef(randomizationTag).Name); } array[j] = Tuple.Create($"{r()}{r()}{r()}{r()}-{r()}{r()}-{r()}{r()}{r()}{r()}", location); } return array; char r() { int num2 = (int)(36.0 * random.NextDouble()); return (char)((num2 >= 10) ? (65 + (num2 - 10)) : (48 + num2)); } } [Terminal.Callback] public void AddTerminalItems(Terminal.Data data) { for (int i = 1; i <= 3; i++) { data.AddLocation(TerminalExtractReleaseLocation.MakeTag(data, i), data.LookupOrCreateRegion(data.TerminalName), TerminalExtractReleaseLocation.MakeRandData()); } } } [EnableFeatureByDefault] [AutomatedFeature] public class APCommandHandler : ArchipelagoFeature { public abstract class SubCommand { public string SubCommandName { get; init; } = ""; public abstract string HelpText { get; } public abstract void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2); } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__SetupCommands__Patch { public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_0117: Expected O, but got Unknown //IL_0011: 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_001d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //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_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0088: Expected O, but got Unknown //IL_008d: Expected O, but got Unknown TextDataBlock val = GameDataBlockBase.GetBlock("Archipelago - Command Help"); if (val == null) { TextDataBlock val2 = new TextDataBlock(); ((GameDataBlockBase)val2).internalEnabled = true; ((GameDataBlockBase)val2).name = "Archipelago - Command Help"; val2.SkipLocalization = false; val2.MachineTranslation = true; val2.English = "ARCHIPELAGO utility tool. Run `AP HELP` for more details"; val2.Description = ""; val2.CharacterMetaData = 1u; val2.ImportVersion = 1; val2.ExportVersion = 1; val = val2; TextDataBlock obj = val; TextDataBlock obj2 = val; TextDataBlock obj3 = val; TextDataBlock obj4 = val; TextDataBlock obj5 = val; TextDataBlock obj6 = val; TextDataBlock obj7 = val; TextDataBlock obj8 = val; TextDataBlock obj9 = val; TextDataBlock obj10 = val; TextDataBlock obj11 = val; LanguageData val3 = new LanguageData { Translation = val.English, ShouldTranslate = true }; LanguageData val4 = val3; obj11.Chinese_Simplified = val3; LanguageData val6 = (obj10.Chinese_Traditional = val4); LanguageData val8 = (obj9.Korean = val6); LanguageData val10 = (obj8.Japanese = val8); LanguageData val12 = (obj7.Polish = val10); LanguageData val14 = (obj6.Portuguese_Brazil = val12); LanguageData val16 = (obj5.Russian = val14); LanguageData val18 = (obj4.Spanish = val16); LanguageData val20 = (obj3.German = val18); LanguageData french = (obj2.Italian = val20); obj.French = french; GameDataBlockBase.AddBlock(val, -1); } LocalizedText val22 = new LocalizedText { Id = ((GameDataBlockBase)(object)val).persistentID, OldId = 0u, UntranslatedText = val.English }; __instance.AddCommand((TERM_Command)42, "AP", val22, (TERM_CommandRule)0); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__ReceiveCommand__Patch { public static bool Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, string inputLine, string param1, string param2) { if (!inputLine.StartsWith("AP")) { return true; } __instance.ResetLinesSinceCommand(); __instance.AddOutput(__instance.NewLineStart() + inputLine, false); string text = param1?.ToUpper() ?? string.Empty; if (m_subCommands.TryGetValue(text, out SubCommand value)) { value.Execute(__instance.m_terminal, inputLine, text, param2); } else { if (text.Length > 0) { __instance.AddOutput("<#F00>Sub-commmand not recognized: " + text + "", true); } __instance.AddOutput("Use the command <#FF0>AP HELP to see a list of commands.", true); } return false; } } private static IArchiveLogger? m_featureLogger = null; public const TERM_Command CommandSlot = 42; public const float CommandDelay = 3f; private static Dictionary m_subCommands = new Dictionary(); public override string Name => "AP Command"; public override string Description => "Adds the AP command to terminals, and allows other handlers to add subcommands to AP"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static IReadOnlyDictionary SubCommands => m_subCommands; public override void OnEnable() { base.OnEnable(); LG_ComputerTerminalManager current = LG_ComputerTerminalManager.Current; ValueCollection val = ((current == null) ? null : current.m_terminals?.values); if (val != null) { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current2 = enumerator.Current; LG_ComputerTerminalCommandInterpreter__SetupCommands__Patch.Postfix(current2.m_command); } } } public override void OnDisable() { base.OnDisable(); LG_ComputerTerminalManager current = LG_ComputerTerminalManager.Current; ValueCollection val = ((current == null) ? null : current.m_terminals?.values); if (val != null) { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current2 = enumerator.Current; current2.TrySyncSetCommandHidden((TERM_Command)42); } } } public static void RegisterCommand(SubCommand command) { if (!m_subCommands.TryAdd(command.SubCommandName.ToUpper(), command)) { FeatureLogger.Error("Failed to add duplicate command with name \"" + command.SubCommandName + "\""); } } public static void UnregisterCommand(SubCommand command) { if (!m_subCommands.Remove(command.SubCommandName.ToUpper())) { FeatureLogger.Warning("Could not to remove subcommand \"" + command.SubCommandName + "\" because it was not registered"); } } } [EnableFeatureByDefault] [AutomatedFeature] public class APCommandHelpHandler : ArchipelagoFeature { private class HelpCommand : APCommandHandler.SubCommand { public override string HelpText => "Shows this menu"; public HelpCommand() { base.SubCommandName = "HELP"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { terminal.AddLine("AP is an ARCHIPELAGO utility tool for accessing MUTLTIWORLD items.", true); terminal.AddLine("Available SUBCOMMANDs:", true); foreach (KeyValuePair subCommand2 in APCommandHandler.SubCommands) { terminal.m_command.AddOutputWithPrefixAndTabbedIndentation(subCommand2.Key, subCommand2.Value.HelpText, true); } } } private static IArchiveLogger? m_featureLogger; private HelpCommand? m_helpCommand; public override string Name => "AP Help Command"; public override string Description => "Adds the HELP subcommand to the AP command"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public override void OnEnable() { base.OnEnable(); APCommandHandler.RegisterCommand(m_helpCommand ?? (m_helpCommand = new HelpCommand())); } public override void OnDisable() { base.OnDisable(); APCommandHandler.UnregisterCommand(m_helpCommand ?? (m_helpCommand = new HelpCommand())); } private static string ReleaseLocationName(Terminal.Data data, int count) { return $"{data.TerminalName} Generic Location #{count}"; } } [EnableFeatureByDefault] [AutomatedFeature] public class APCommandItemsHandler : ArchipelagoFeature { private class ClaimItemsHelper { public Action thisAction; public LG_ComputerTerminal terminal; public int currentIndex; public List claimActions = new List(); public ClaimItemsHelper() { thisAction = new Il2CppAction(DoWork); } public void DoWork() { while (currentIndex < claimActions.Count) { claimActions[currentIndex++](); if (terminal.m_command.m_outputQueue.Count > 0) { break; } } if (currentIndex >= claimActions.Count) { LG_ComputerTerminalCommandInterpreter command = terminal.m_command; command.OnEndOfQueue -= thisAction; } } } private class ItemsCommand : APCommandHandler.SubCommand { public override string HelpText => "List the items currently available to YOU. You may optionally provide a single text filter, which is matched by name.\nNote: Available items will vary by expedition"; public ItemsCommand() { base.SubCommandName = "ITEMS"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { string param3 = param2; LG_ComputerTerminalCommandInterpreter command = terminal.m_command; string text = param3; command.AddOutput((TerminalLineType)2, "Fetching currently available items" + ((text != null && text.Length == 0) ? "" : (" matching filter \"" + param3 + "\"")), 2.5f, (TerminalSoundType)0, (TerminalSoundType)2); StateTracker stateTracker = StateTracker.Get(); Game.Data gameData = stateTracker.MidManager.GetProcessedGameData(); string text2 = param3; IEnumerable> enumerable = ((text2 != null && text2.Length != 0) ? stateTracker.ItemsInTerminalSystem.Where((Tuple pair) => gameData.LookupTagDef(gameData.LookupItem(pair.Item1).NameTag).Name.Contains(param3, StringComparison.OrdinalIgnoreCase)) : stateTracker.ItemsInTerminalSystem); if (!enumerable.Any()) { terminal.AddLine(string.Empty, true); terminal.AddLine(" -- NO ITEMS FOUND --", true); return; } terminal.AddLine(string.Empty, true); terminal.AddLine(" ITEM CODE ITEM NAME", false); foreach (Tuple item in enumerable) { terminal.AddLine(item.Item2 + " " + gameData.LookupTagDef(gameData.LookupItem(item.Item1).NameTag).Name, false); } terminal.AddLine(string.Empty, true); } } private class ClaimCommand : APCommandHandler.SubCommand { public override string HelpText => "Retrieve all of YOUR items. Can optionally include a filter\nExample: `AP CLAIM KEY` will claim all items with \"KEY\" in their name"; public ClaimCommand() { base.SubCommandName = "CLAIM"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { string param3 = param2; LG_ComputerTerminal terminal2 = terminal; StateTracker stateTracker = StateTracker.Get(); Game.Data gameData = stateTracker.MidManager.GetProcessedGameData(); List> source = stateTracker.ItemsInTerminalSystem.Where(predicate).ToList(); string firstMessage = ((param3 == null || param3.Trim().Length == 0) ? "Preparing all items to be claimed" : ("Collecting items to be claimed using filter \"" + param3.ToUpper() + "\"")); if (!source.Any()) { terminal2.m_command.AddOutput((TerminalLineType)3, firstMessage, 3f, (TerminalSoundType)0, (TerminalSoundType)3); if (param3 == null || param3.Trim().Length == 0) { terminal2.m_command.AddOutput("<#F00>No items available to be claimed!", true); } else { terminal2.m_command.AddOutput("<#F00>No items matching filter!", true); } return; } List list = source.SelectMany((Tuple p) => gameData.LookupItem(p.Item1).OnRetrieveFromTerminalSystem(stateTracker, terminal2)).ToList(); stateTracker.ItemsInTerminalSystem.RemoveAll(predicate); Action onEndOfQueue = terminal2.m_command.OnEndOfQueue; IEnumerable enumerable = (IEnumerable)((onEndOfQueue != null) ? ((Delegate)onEndOfQueue).GetInvocationList() : null); foreach (Delegate item in enumerable ?? Enumerable.Empty()) { Il2CppAction il2CppAction = ((Il2CppObjectBase)item.Target).TryCast(); if (il2CppAction != null && il2CppAction.WrappedAction?.Target is ClaimItemsHelper claimItemsHelper) { claimItemsHelper.claimActions.AddRange(list.Prepend(postMessage)); return; } } postMessage(); ClaimItemsHelper claimItemsHelper2 = new ClaimItemsHelper { terminal = terminal2, currentIndex = 0, claimActions = list }; LG_ComputerTerminalCommandInterpreter command = terminal2.m_command; command.OnEndOfQueue += claimItemsHelper2.thisAction; void postMessage() { terminal2.m_command.AddOutput((TerminalLineType)2, firstMessage, 3f, (TerminalSoundType)0, (TerminalSoundType)2); } bool predicate(Tuple pair) { if (param3 != null) { return gameData.LookupTagDef(gameData.LookupItem(pair.Item1).NameTag).Name.Contains(param3, StringComparison.OrdinalIgnoreCase); } return true; } } } private class CACommand : ClaimCommand { public override string HelpText => "Alias for CLAIM"; public CACommand() { base.SubCommandName = "CA"; } } private class ClaimCode : APCommandHandler.SubCommand { public override string HelpText => "Claim one of YOUR currently-held items using its code.\nUseful when you want to retrieve exactly one item when items share names."; public ClaimCode() { base.SubCommandName = "CLAIM_CODE"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { string param3 = param2; StateTracker stateTracker = StateTracker.Get(); Tuple tuple = stateTracker.ItemsInTerminalSystem.FirstOrDefault((Tuple pair) => string.Compare(pair.Item2, param3, StringComparison.OrdinalIgnoreCase) == 0); if (tuple == null) { terminal.m_command.AddOutput((TerminalLineType)3, "Searching for item " + param3.ToUpper(), 2f, (TerminalSoundType)0, (TerminalSoundType)3); terminal.m_command.AddOutput("<#F00>Incorrect item code!", true); return; } terminal.m_command.AddOutput((TerminalLineType)2, "Searching for item " + param3.ToUpper(), 2f, (TerminalSoundType)0, (TerminalSoundType)2); ClaimItemsHelper claimItemsHelper = new ClaimItemsHelper { terminal = terminal.m_command.m_terminal, currentIndex = 0, claimActions = stateTracker.MidManager.GetProcessedGameData().LookupItem(tuple.Item1).OnRetrieveFromTerminalSystem(stateTracker, terminal) .ToList() }; LG_ComputerTerminalCommandInterpreter command = terminal.m_command; command.OnEndOfQueue += claimItemsHelper.thisAction; stateTracker.ItemsInTerminalSystem.Remove(tuple); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] private static class DontUnscubscribeMePatch { public static void Prefix(LG_ComputerTerminalCommandInterpreter __instance, ref ClaimItemsHelper? __state) { __state = null; if ((Delegate)(object)__instance.OnEndOfQueue == (Delegate)null) { return; } foreach (Delegate item in (Il2CppArrayBase)(object)((Delegate)__instance.OnEndOfQueue).GetInvocationList()) { Il2CppAction il2CppAction = ((Il2CppObjectBase)item.Target).TryCast(); if (il2CppAction != null && il2CppAction.WrappedAction?.Target is ClaimItemsHelper claimItemsHelper) { __state = claimItemsHelper; break; } } } public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance, ClaimItemsHelper? __state) { if (__state != null && __state.currentIndex < __state.claimActions.Count && __instance.OnEndOfQueue == null) { __instance.OnEndOfQueue += __state.thisAction; } } } private static IArchiveLogger? m_featureLogger; private const float ItemsDelay = 2.5f; private const float ClaimDelay = 2f; private const float ClaimAllDelay = 3f; private ItemsCommand? m_itemsCommand; private ClaimCommand? m_claimCommand; private CACommand? m_caCommand; private ClaimCode? m_claimCodeCommand; public override string Name => "AP Item Commands"; public override string Description => "Adds the ITEMS, CLAIM, CA, and CLAIM_CODE subcommands to the AP command"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public override void OnEnable() { base.OnEnable(); APCommandHandler.RegisterCommand(m_itemsCommand ?? (m_itemsCommand = new ItemsCommand())); APCommandHandler.RegisterCommand(m_claimCommand ?? (m_claimCommand = new ClaimCommand())); APCommandHandler.RegisterCommand(m_caCommand ?? (m_caCommand = new CACommand())); APCommandHandler.RegisterCommand(m_claimCodeCommand ?? (m_claimCodeCommand = new ClaimCode())); } public override void OnDisable() { base.OnDisable(); APCommandHandler.UnregisterCommand(m_itemsCommand ?? (m_itemsCommand = new ItemsCommand())); APCommandHandler.UnregisterCommand(m_claimCommand ?? (m_claimCommand = new ClaimCommand())); APCommandHandler.UnregisterCommand(m_caCommand ?? (m_caCommand = new CACommand())); APCommandHandler.UnregisterCommand(m_claimCodeCommand ?? (m_claimCodeCommand = new ClaimCode())); } } [InjectToIl2Cpp] [EnableFeatureByDefault] [AutomatedFeature] public class IdentifyingLogHandler : ArchipelagoFeature { public struct IdentifyTerminalResult { public bool IsReactorTerminal; public Terminal.Data? Data; public IdentifyTerminalResult(bool isReactor, Terminal.Data? data) { IsReactorTerminal = isReactor; Data = data; } } [InjectToIl2Cpp] private class IdentifyingLogTextDataBlock : TextDataBlock { [HideFromIl2Cpp] public Terminal.Data TerminalData { get; set; } public IdentifyingLogTextDataBlock() : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); } public IdentifyingLogTextDataBlock(IntPtr ptr) : base(ptr) { } } private static IArchiveLogger? m_featureLogger; private const string IdentifyingLogName = "TERMINAL_NAME.LOG"; public override string Name => "Identifying Log Handler"; public override string Description => "Adds identifying logs to terminals. Used by other handlers to identify the terminal during play"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static IdentifyTerminalResult RetrieveDataFromLog(LG_ComputerTerminal terminal) { if ((Object)(object)terminal.ConnectedReactor != (Object)null) { return new IdentifyTerminalResult(isReactor: true, null); } int num = terminal.m_localLogs.FindEntry("TERMINAL_NAME.LOG"); if (num < 0) { AIG_CourseNode spawnNode = terminal.SpawnNode; Zone.Data obj = (((Object)(object)((spawnNode != null) ? spawnNode.m_zone : null) == (Object)null) ? null : Zone.Data.FromZone(terminal.SpawnNode.m_zone)); FeatureLogger.Warning("Failed to find identifying log from " + terminal.ItemKey + " in " + (obj?.ZoneName ?? "ZONE_NULL")); return new IdentifyTerminalResult(isReactor: false, null); } Entry val = ((Il2CppArrayBase>)(object)terminal.m_localLogs.entries)[num]; TextDataBlock block = GameDataBlockBase.GetBlock(val.value.FileContent.Id); IdentifyingLogTextDataBlock identifyingLogTextDataBlock = ((block != null) ? ((Il2CppObjectBase)block).TryCast() : null); if (identifyingLogTextDataBlock == null) { Zone.Data data = Zone.Data.FromZone(terminal.SpawnNode.m_zone); FeatureLogger.Warning("Failed to retrieving identifying data from log for terminal in zone: " + data.ZoneName); return new IdentifyTerminalResult(isReactor: false, null); } return new IdentifyTerminalResult(isReactor: false, identifyingLogTextDataBlock.TerminalData); } [Terminal.Callback] public void AddIdentifyingLog(Terminal.Data data) { //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: 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_01bb: 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_01c1: 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: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_00ee: 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_00ff: 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_0109: Expected O, but got Unknown //IL_010e: Expected O, but got Unknown if (data.TerminalLocalLogs.Count <= 0 || !data.TerminalLocalLogs.Any((TerminalLogFileData l) => l.FileName == "TERMINAL_NAME.LOG")) { string text = data.TerminalName + " Identifying Log"; TextDataBlock val = GameDataBlockBase.GetBlock(text); if (val == null) { IdentifyingLogTextDataBlock obj = new IdentifyingLogTextDataBlock { internalEnabled = true, name = text }; ((TextDataBlock)obj).SkipLocalization = true; ((TextDataBlock)obj).MachineTranslation = true; ((TextDataBlock)obj).English = $"[{data.TerminalIndex}] {data.TerminalName}"; ((TextDataBlock)obj).Description = ""; ((TextDataBlock)obj).CharacterMetaData = 1u; ((TextDataBlock)obj).ImportVersion = 1; ((TextDataBlock)obj).ExportVersion = 1; val = (TextDataBlock)(object)obj; TextDataBlock obj2 = val; TextDataBlock obj3 = val; TextDataBlock obj4 = val; TextDataBlock obj5 = val; TextDataBlock obj6 = val; TextDataBlock obj7 = val; TextDataBlock obj8 = val; TextDataBlock obj9 = val; TextDataBlock obj10 = val; TextDataBlock obj11 = val; TextDataBlock obj12 = val; LanguageData val2 = new LanguageData { Translation = val.English, ShouldTranslate = false }; LanguageData val3 = val2; obj12.Chinese_Simplified = val2; LanguageData val5 = (obj11.Chinese_Traditional = val3); LanguageData val7 = (obj10.Korean = val5); LanguageData val9 = (obj9.Japanese = val7); LanguageData val11 = (obj8.Polish = val9); LanguageData val13 = (obj7.Portuguese_Brazil = val11); LanguageData val15 = (obj6.Russian = val13); LanguageData val17 = (obj5.Spanish = val15); LanguageData val19 = (obj4.German = val17); LanguageData french = (obj3.Italian = val19); obj2.French = french; GameDataBlockBase.AddBlock(val, -1); } IdentifyingLogTextDataBlock identifyingLogTextDataBlock = ((Il2CppObjectBase)val).Cast(); identifyingLogTextDataBlock.TerminalData = data; data.TerminalLocalLogs.Capacity = data.TerminalLocalLogs.Count + 1; data.TerminalLocalLogs.Insert(0, new TerminalLogFileData { FileName = "TERMINAL_NAME.LOG", FileContentOriginalLanguage = (Language)1, FileContent = new LocalizedText { Id = ((GameDataBlockBase)(object)val).persistentID, OldId = 0u, UntranslatedText = val.English }, AttachedAudioByteSize = 0, AttachedAudioFile = 0u, PlayerDialogToTriggerAfterAudio = 0u }); } } } public static class TerminalLogHelper_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_TerminalLogLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_TerminalLogItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_TerminalLogLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Terminal Log Locations", "Locations checked by reading specific terminal logs", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_TerminalLogItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Terminal Log Items", "Items typically obtained by reading specific terminal logs", RootRandomizationTags.get_Tag_AllItems(gd))); } } [InjectToIl2Cpp] [AutomatedFeature] [EnableFeatureByDefault] public class TerminalLogHelper : ArchipelagoFeature { [InjectToIl2Cpp] private class ContainsLocationLogComp : MonoBehaviour { public SortedList StoredLocations = new SortedList(); } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__ReadLog__Patch { public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2) { ContainsLocationLogComp component = ((Component)__instance.m_terminal).GetComponent(); if (!((Object)(object)component == (Object)null) && component.StoredLocations.TryGetValue(param1.ToUpper(), out var value)) { StateTracker.Get().NotifyFoundLocation(value, __instance.m_terminal.m_syncedInteractionSource); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Terminal Log Helper"; public override string Description => "Helper for other handlers\nAssociates terminal logs with locations, so when they're checked that location is checked"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static void AssociateLog(LG_ComputerTerminal terminal, string logName, LocationID locationId) { //IL_01b4: 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_020e: 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_0221: Expected O, but got Unknown logName = logName.ToUpper(); Game.Data processedGameData = Plugin.Get().MidManager.GetProcessedGameData(); ContainsLocationLogComp containsLocationLogComp = ((Component)terminal).GetComponent() ?? ((Component)terminal).gameObject.AddComponent(); if (containsLocationLogComp.StoredLocations.TryGetValue(logName, out var value)) { int count = Math.Max(value.AsId.ToString().Length, locationId.AsId.ToString().Length); string text = new string('0', count); FeatureLogger.Error($"Overwriting location stored in log!\n Old Location: [{value.AsId.ToString(text)}] {processedGameData.LookupTagDef(processedGameData.LookupLocation(value).NameTag).Name} New Location: [{locationId.AsId.ToString(text)}] {processedGameData.LookupTagDef(processedGameData.LookupLocation(locationId).NameTag).Name}"); } containsLocationLogComp.StoredLocations[logName] = locationId; int num = terminal.m_localLogs.FindEntry(logName); if (num == -1) { FeatureLogger.Warning("Failed to look up and overwrite local log while associating log: " + logName); return; } Location location = processedGameData.LookupLocation(locationId); if (location.RandMode.IsTreatedAsRandom) { TerminalLogFileData value2 = ((Il2CppArrayBase>)(object)terminal.m_localLogs.entries)[num].value; value2.FileContent = new LocalizedText { UntranslatedText = "Congratulations! By viewing this log, you have obtained the following item(s):\n " + (location.ScoutedItemName ?? (location.ItemID.IsNull ? "None" : processedGameData.LookupTagDef(processedGameData.LookupItem(location.ItemID).NameTag).Name)), OldId = 0u, Id = 0u }; } } } public static class TerminalPasswordHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_TerminalPasswordLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_TerminalPasswordItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $63BA103E62A55F64C05B172EF249EC99 { [SpecialName] public static class $DE04A58E69D058D9CEE64C49EAD6305E { } [ExtensionMarker("$DE04A58E69D058D9CEE64C49EAD6305E")] public TagResolver Tag_TerminalPasswordLocations_ByTerminal { [ExtensionMarker("$DE04A58E69D058D9CEE64C49EAD6305E")] get { throw new NotSupportedException(); } } [ExtensionMarker("$DE04A58E69D058D9CEE64C49EAD6305E")] public TagResolver Tag_TerminalPasswordItems_ByTerminal { [ExtensionMarker("$DE04A58E69D058D9CEE64C49EAD6305E")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_TerminalPasswordLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Terminal Password Part Locations", "Locations checked by opening logs containing terminal password parts", TerminalLogHelper_Tags.get_Tag_TerminalLogLocations(gd))); } public static TagResolver get_Tag_TerminalPasswordItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Terminal Password Part Item", "A part of a terminal password", TerminalLogHelper_Tags.get_Tag_TerminalLogItems(gd))); } public static TagResolver get_Tag_TerminalPasswordLocations_ByTerminal(Terminal.Data data) { Terminal.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.TerminalName + " Password Locations", "Password part locations for a specific terminal", get_Tag_TerminalPasswordLocations(gd))); } public static TagResolver get_Tag_TerminalPasswordItems_ByTerminal(Terminal.Data data) { Terminal.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.TerminalName + " Password Parts", "Password parts for a specific terminal", get_Tag_TerminalPasswordItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] [InjectToIl2Cpp] public class TerminalPasswordHandler : ArchipelagoFeature { private static class TerminalPasswordPartLocation { public static TagResolver MakeTag(Terminal.Data data, int count) { Terminal.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.TerminalName} Password Part #{count} Location", "Location containng a part of a terminal password", TerminalPasswordHandler_Tags.get_Tag_TerminalPasswordLocations_ByTerminal(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private class TerminalPasswordPartItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass15_0 { public StateTracker stateTracker; public TerminalPasswordPartItem <>4__this; public LG_ComputerTerminal terminal; public LG_ComputerTerminal passwordTerminal; internal void b__0() { stateTracker.AddItemToTerminal(<>4__this); terminal.AddLine((TerminalLineType)2, "Retrieving password", 2f); if ((Object)(object)passwordTerminal == (Object)null) { terminal.AddLine("<#F00>Failed to find password terminal instance! No password to grant.", true); return; } string arg = ProgressionObjective_TerminalPassword.MakePasswordHint(<>4__this.TerminalData, passwordTerminal); terminal.AddLine(string.Format(((Feature)ArchipelagoFeatureHelper.GetFeature()).Localization.Get(1431221909u), arg), true); } } [CompilerGenerated] private sealed class d__15 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public TerminalPasswordPartItem <>4__this; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; TerminalPasswordPartItem terminalPasswordPartItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass15_0 CS$<>8__locals0 = new <>c__DisplayClass15_0 { stateTracker = stateTracker, <>4__this = <>4__this, terminal = terminal, passwordTerminal = terminalPasswordPartItem.TerminalData.GetLG_Terminal() }; if ((Object)(object)CS$<>8__locals0.passwordTerminal == (Object)null) { FeatureLogger.Error("Failed to identify spawned terminal while giving password part!"); } <>2__current = delegate { CS$<>8__locals0.stateTracker.AddItemToTerminal(CS$<>8__locals0.<>4__this); CS$<>8__locals0.terminal.AddLine((TerminalLineType)2, "Retrieving password", 2f); if ((Object)(object)CS$<>8__locals0.passwordTerminal == (Object)null) { CS$<>8__locals0.terminal.AddLine("<#F00>Failed to find password terminal instance! No password to grant.", true); } else { string arg = ProgressionObjective_TerminalPassword.MakePasswordHint(CS$<>8__locals0.<>4__this.TerminalData, CS$<>8__locals0.passwordTerminal); CS$<>8__locals0.terminal.AddLine(string.Format(((Feature)ArchipelagoFeatureHelper.GetFeature()).Localization.Get(1431221909u), arg), true); } }; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__15 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__15(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Terminal.Data TerminalData { get; set; } public int PartNumber { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, TerminalPasswordHandler_Tags.get_Tag_TerminalPasswordItems_ByTerminal(TerminalData)); public TerminalPasswordPartItem(Terminal.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { TerminalData = data; PartNumber = count; } public static TagResolver MakeTag(Terminal.Data data, int count) { Terminal.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.TerminalName} Password Part #{count}", "A part of a terminal password", TerminalPasswordHandler_Tags.get_Tag_TerminalPasswordItems_ByTerminal(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (TerminalData.IsCurrentlyInExpedition()) { OnStartExpeditionWithItem(stateTracker, TerminalData); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (TerminalData.IsSameExpedition(data)) { LG_ComputerTerminal lG_Terminal = TerminalData.GetLG_Terminal(); if ((Object)(object)lG_Terminal == (Object)null) { FeatureLogger.Error("Failed to identify spawned terminal while giving password part!"); } else { ProgressionObjective_TerminalPassword.Update(TerminalData, lG_Terminal); } } } [IteratorStateMachine(typeof(d__15))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_TerminalPasswordLinkerJob__Build__Patch { public static void Postfix(LG_TerminalPasswordLinkerJob __instance) { IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance.m_lockedTerminal); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("A reactor terminal is password locked; Archipelago can't currently support this!"); } else { FeatureLogger.Error("Null terminal data for password link job!"); } return; } for (int i = 0; i < __instance.m_terminalsWithPasswordParts.Count; i++) { LG_ComputerTerminal val = __instance.m_terminalsWithPasswordParts[i]; RandomizationTag nameTag = TerminalPasswordPartLocation.MakeTag(data, i + 1); if (!data.TryLookupLocation(nameTag, out var location)) { FeatureLogger.Error("Failed to lookup password part location during association!"); break; } List> list = ((IEnumerable>)val.m_localLogs.entries).Where(delegate(Entry e) { bool? obj; if (e == null) { obj = null; } else { TerminalLogFileData value = e.value; obj = ((value == null) ? null : value.FileName?.StartsWith("KEY", StringComparison.OrdinalIgnoreCase)); } bool? flag = obj; return flag.GetValueOrDefault(); }).ToList(); if (list.Count == 0) { FeatureLogger.Error("Failed to find any logs for password part location: " + data.LookupTagDef(location.NameTag).Name); } else { TerminalLogHelper.AssociateLog(val, list[0].value.FileName, location.ID); } if (list.Count > 1) { FeatureLogger.Warning("Found multiple possible logs for password part location, using first: " + data.LookupTagDef(location.NameTag).Name); } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__TryUnlockingTerminal__Patch { public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance) { LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.IsPasswordProtected) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(terminal); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (!identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("Unlocked unknown terminal!"); } } else { StateTracker.Get().NotifyFoundRegion(data.TerminalName, terminal.m_syncedInteractionSource); ProgressionObjective_TerminalPassword.Update(data, terminal); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminal__OnFactoryBuildDone__Patch { public static void Postfix(LG_ComputerTerminal __instance) { if (!Object.op_Implicit((Object)(object)__instance) || !__instance.IsPasswordProtected) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("A reactor terminal is password locked; Archipelago can't currently support this!"); } else { FeatureLogger.Error("Null terminal data for password link job!"); } } else { ProgressionObjective_TerminalPassword.Setup(data, __instance); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminal__OnPostRecall__Patch { public static void Postfix(LG_ComputerTerminal __instance) { if (!__instance.IsPasswordProtected) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (!identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("Failed to identify locked terminal post recall!"); } } else { ProgressionObjective_TerminalPassword.Update(data, __instance); StateTracker.Get().AddItemToTerminal(GetTerminalPasswordPartItem(data).ID); } } } public class ProgressionObjective_TerminalPassword : CustomObjectiveHandler.ObjectiveItem { public static string MakeKey(Terminal.Data data, LG_ComputerTerminal _) { return data.TerminalName; } public static void Setup(Terminal.Data data, LG_ComputerTerminal terminal) { CustomObjectiveHandler.GetObjectiveItem(MakeKey(data, terminal)).SetupWithData(data, terminal); } public static void Update(Terminal.Data data, LG_ComputerTerminal terminal) { CustomObjectiveHandler.GetObjectiveItem(MakeKey(data, terminal)).UpdateInternal(data, terminal); } public override void Setup() { base.IsActive = false; base.Scope = CustomObjectiveHandler.eObjectiveScope.Zone; base.ObjectiveTag = "PASSWORD"; base.HeaderText = "TERMINAL PASSWORD OBJECTIVE"; base.SubText = "Retrieving data..."; base.Setup(); } public void SetupWithData(Terminal.Data data, LG_ComputerTerminal terminal) { //IL_0018: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) base.HeaderText = data.TerminalName; base.ScopeTarget = new GlobalZoneIndex(terminal.SpawnNode.m_zone.DimensionIndex, terminal.SpawnNode.LayerType, terminal.SpawnNode.m_zone.LocalIndex); base.SubText = "Current known password: " + MakePasswordHint(data, terminal); Refresh(); } public void UpdateInternal(Terminal.Data data, LG_ComputerTerminal terminal) { base.IsActive = terminal.IsPasswordProtected; base.SubText = "Current known password: " + MakePasswordHint(data, terminal); Refresh(); } public static string MakePasswordHint(Terminal.Data data, LG_ComputerTerminal terminal) { Terminal.Data data2 = data; StateTracker stateTracker = StateTracker.Get(); string password = terminal.m_password; if (data2.TerminalStartingStateData.TerminalZoneSelectionDatas.Count == 0) { return password; } int passwordPartCount = data2.TerminalStartingStateData.PasswordPartCount; int perPartCount = password.Length / passwordPartCount; int remainingCount = password.Length % passwordPartCount; IEnumerable values = Enumerable.Range(1, passwordPartCount).Select(isObtained).Select((bool o, int i) => (!o) ? hide(i) : reveal(i)); return string.Join("", values); string hide(int i) { return new string('–', len(i)); } bool isObtained(int i) { return stateTracker.CollectedItemCounts.GetValueOrDefault(GetTerminalPasswordPartItem(data2, i).ID, 0) > 0; } int len(int i) { if (i >= remainingCount) { return perPartCount; } return perPartCount + 1; } string reveal(int i) { return password.Substring(start(i), len(i)); } int start(int i) { return perPartCount * i + Math.Min(remainingCount, i); } } public override void CheckScope(AIG_CourseNode? localNode = null) { base.CheckScope(localNode); if (base.IsInScope && base.Scope == CustomObjectiveHandler.eObjectiveScope.Zone) { base.Scope = CustomObjectiveHandler.eObjectiveScope.Layer; base.IsActive = true; } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Terminal Password Handler"; public override string Description => "Adds passwords to terminals\nMarks terminal password logs so that the correct location is checked when they're opened"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Terminal.Callback] public void AddPasswordPartItems(Terminal.Data data) { if (!data.TerminalStartingStateData.PasswordProtected) { return; } if (data.TerminalStartingStateData.TerminalZoneSelectionDatas.Count == 0) { FeatureLogger.Warning("Terminal has no placement positions for password parts: " + data.TerminalName); KeyedItem terminalPasswordPartItem = GetTerminalPasswordPartItem(data); return; } IEnumerable> enumerable = data.UnstuffPlacements(data.PlacementsToTerminalRegions(data.TerminalStartingStateData.TerminalZoneSelectionDatas), data.TerminalStartingStateData.PasswordPartCount); int num = 0; foreach (List item in enumerable) { num++; KeyedItem terminalPasswordPartItem2 = GetTerminalPasswordPartItem(data, num); data.AddLocation(TerminalPasswordPartLocation.MakeTag(data, num), item, TerminalPasswordPartLocation.MakeRandData(), terminalPasswordPartItem2.ID); } } public static KeyedItem GetTerminalPasswordPartItem(Terminal.Data data, int count = 1) { if (data.TryLookupItem(TerminalPasswordPartItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new TerminalPasswordPartItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } } [EnableFeatureByDefault] [AutomatedFeature] public class UniqueCommandsHandler : ArchipelagoFeature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminalCommandInterpreter__ReceiveCommand__Patch { public static void Postfix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd, bool __runOriginal) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_0048: 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_0051: Expected I4, but got Unknown if (!__runOriginal) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance.m_terminal); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (!identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("Null terminal data for unique command detection!"); } } else if ((int)cmd >= 38 && (int)cmd <= 42) { StateTracker.Get().NotifyFoundRegion(GetUniqueCommandRegionName(data, data.TerminalUniqueCommands[cmd - 38]), __instance.m_terminal.m_syncedInteractionSource); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Unique Command Handler"; public override string Description => "Adds unique terminal commands and events triggered by those commands to Archipelago"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Terminal.Callback] public void AddUniqueCommandEvents(Terminal.Data data) { Enumerator enumerator = data.TerminalUniqueCommands.GetEnumerator(); while (enumerator.MoveNext()) { CustomTerminalCommand current = enumerator.Current; string uniqueCommandRegionName = GetUniqueCommandRegionName(data, current); RegionID regionID = data.LookupOrCreateRegion(uniqueCommandRegionName); CustomTerminalCommand val = current; data.ProcessEvents(regionID, uniqueCommandRegionName, val.CommandEvents ?? (val.CommandEvents = new List(1))); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.LookupOrCreateRegion(data.TerminalName), EndingRegion = regionID }); } } public static string GetUniqueCommandRegionName(Terminal.Data data, CustomTerminalCommand command) { return data.TerminalName + " " + command.Command; } } [EnableFeatureByDefault] [AutomatedFeature] public class UseTerminalHandler : ArchipelagoFeature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminal__OnInteract__Patch { public static void Postfix(LG_ComputerTerminal __instance) { if (__instance.IsPasswordProtected) { return; } IdentifyingLogHandler.IdentifyTerminalResult identifyTerminalResult = Terminal.Data.FromTerminal(__instance); Terminal.Data data = identifyTerminalResult.Data; if (data == null) { if (!identifyTerminalResult.IsReactorTerminal) { FeatureLogger.Error("Entered unknown terminal!"); } } else { StateTracker.Get().NotifyFoundRegion(data.TerminalName, __instance.m_syncedInteractionSource); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Terminal Region Handler"; public override string Description => "Identifies when a terminal region is accessed during play and connects terminal regions to the graph"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_TerminalHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Terminal.Callback] public void AddTerminalRegions(Terminal.Data data) { ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.StartingRegion = data.LookupOrCreateRegion(data.ZoneName); path.EndingRegion = data.LookupOrCreateRegion(data.TerminalName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; if (data.TerminalStartingStateData.PasswordProtected && data.TerminalStartingStateData.TerminalZoneSelectionDatas.Count > 0) { path2.ReqItem = TerminalPasswordHandler.GetTerminalPasswordPartItem(data).PathReqs; path2.ReqCount = (uint)data.TerminalStartingStateData.PasswordPartCount; } data.AddPath(path2); } } } namespace ReTFO.Archipelago.Features.Pickups { [EnableFeatureByDefault] [AutomatedFeature] public class BigPickupHandler : ArchipelagoFeature { private class BigPickupItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass14_0 { public LG_ComputerTerminal terminal; public string itemName; public AsyncItemSpawnWrapper wrapper; public StateTracker stateTracker; public BigPickupItem <>4__this; public PlayerAgent player; public Vector3 position; public Quaternion rotation; public AIG_CourseNode node; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving " + itemName, 2f); } internal void b__1() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) ISyncedItem? item = wrapper.Item; CarryItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn " + itemName + "!"); stateTracker.AddItemToTerminal(<>4__this); terminal.AddLine("<#F00>Failed to retrieve " + itemName + "! It has been re-added to terminal system.", true); } else { val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)1, player.Owner, default(pItemData_Custom), position, rotation, node, true, true); val.m_navMarkerPlacer.SetMarkerVisible(true); val.m_terminalItem.PlayPing(); terminal.AddLine(itemName + " has been placed somewhere nearby", true); } } } [CompilerGenerated] private sealed class d__14 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public BigPickupItem <>4__this; private <>c__DisplayClass14_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__14(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_01cb: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; BigPickupItem bigPickupItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass14_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; <>c__DisplayClass14_0 <>c__DisplayClass14_ = <>8__1; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(15, 2); defaultInterpolatedStringHandler.AppendLiteral("Big Pickup #"); defaultInterpolatedStringHandler.AppendFormatted(((GameDataBlockBase)(object)bigPickupItem.ItemDataBlock)?.persistentID ?? 0); defaultInterpolatedStringHandler.AppendLiteral(" \""); ItemDataBlock? itemDataBlock = bigPickupItem.ItemDataBlock; defaultInterpolatedStringHandler.AppendFormatted(((itemDataBlock != null) ? itemDataBlock.publicName : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral("\""); <>c__DisplayClass14_.itemName = defaultInterpolatedStringHandler.ToStringAndClear(); <>8__1.wrapper = bigPickupItem.TrySpawnAsync(); <>8__1.node = <>8__1.terminal.SpawnNode; Random random = new Random(Guid.NewGuid().GetHashCode()); <>8__1.player = <>8__1.terminal.m_syncedInteractionSource; <>8__1.position = <>8__1.player.FPSCamera.Position; Vector3 flatRight = ((LookCameraController)<>8__1.player.FPSCamera).FlatRight; Vector3 val = Quaternion.AngleAxis(30f + random.NextSingle() * 120f, Vector3.up) * flatRight; Quaternion val2 = Quaternion.FromToRotation(val, Vector3.down); Quaternion val3 = Quaternion.Lerp(Quaternion.identity, val2, 0.4f + random.NextSingle() * 0.4f); Vector3 val4 = val3 * val; RaycastHit val5 = default(RaycastHit); if (Physics.Raycast(<>8__1.position, val4, ref val5, 10f, 1)) { <>8__1.position = ((RaycastHit)(ref val5)).point; } <>8__1.rotation = Quaternion.AngleAxis(360f * random.NextSingle(), Vector3.up); <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving " + <>8__1.itemName, 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) ISyncedItem? item = <>8__1.wrapper.Item; CarryItemPickup_Core val6 = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val6 == (Object)null) { <>8__1.wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn " + <>8__1.itemName + "!"); <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); <>8__1.terminal.AddLine("<#F00>Failed to retrieve " + <>8__1.itemName + "! It has been re-added to terminal system.", true); } else { val6.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)1, <>8__1.player.Owner, default(pItemData_Custom), <>8__1.position, <>8__1.rotation, <>8__1.node, true, true); val6.m_navMarkerPlacer.SetMarkerVisible(true); val6.m_terminalItem.PlayPing(); <>8__1.terminal.AddLine(<>8__1.itemName + " has been placed somewhere nearby", true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__14 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__14(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Expedition.Data Data { get; set; } public ItemDataBlock? ItemDataBlock { get; set; } public BigPickupItem(Expedition.Data data, ItemDataBlock? item) : base(MakeTag(data, item), MakeRandData(item)) { Data = data; ItemDataBlock = item; } public static TagResolver MakeTag(Expedition.Data data, ItemDataBlock? item) { Expedition.Data data2 = data; ItemDataBlock item2 = item; return new TagResolver(data2, delegate(Game.Data gd) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(10, 3); defaultInterpolatedStringHandler.AppendFormatted(data2.ExpeditionName); defaultInterpolatedStringHandler.AppendLiteral(" Item #"); defaultInterpolatedStringHandler.AppendFormatted(((GameDataBlockBase)(object)item2)?.persistentID ?? 0); defaultInterpolatedStringHandler.AppendLiteral(" ("); ItemDataBlock obj = item2; defaultInterpolatedStringHandler.AppendFormatted(((obj != null) ? obj.publicName : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(")"); return gd.LookupOrCreateTag(defaultInterpolatedStringHandler.ToStringAndClear(), "A particular big pickup item", PickupHelper_Tags.get_Tag_BigPickupItems(gd)); }); } public static ItemData MakeRandData(ItemDataBlock? item) { ItemData result = new ItemData(); result.IsProgression = true; result.IsRandomLike = (((GameDataBlockBase)(object)item)?.persistentID ?? 0) == CellItemID; return result; } private AsyncItemSpawnWrapper TrySpawnAsync() { //IL_0010: 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_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) AsyncItemSpawnWrapper asyncItemSpawnWrapper = new AsyncItemSpawnWrapper(); if (ItemDataBlock != null) { pItemData val = default(pItemData); val.itemID_gearCRC = ((GameDataBlockBase)(object)ItemDataBlock).persistentID; ItemReplicationManager.SpawnItem(val, delItemCallback.op_Implicit((Action)asyncItemSpawnWrapper.OnSpawn), (ItemMode)2, Vector3.zero, Quaternion.identity, (AIG_CourseNode)null, (PlayerAgent)null); } return asyncItemSpawnWrapper; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { PlayerAgent player2 = player; if (Data.IsCurrentlyInExpedition()) { if (base.RandMode.IsRandomLike && !base.RandMode.IsRandomized && (Object)(object)player2 != (Object)null) { AsyncItemSpawnWrapper asyncItemSpawnWrapper = TrySpawnAsync(); asyncItemSpawnWrapper.AddSpawnCallback(AttemptPickup); } else { stateTracker.AddItemToTerminal(this); } } void AttemptPickup(ISyncedItem item) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_002b: 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) ((Il2CppObjectBase)item).Cast().m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, player2.Owner, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (Data.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__14))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__14(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Big Pickups Handler"; public override string Description => "Provides utilites used by other features to manage big pickups"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static uint CellItemID => 131u; public static uint MatterWaveProjectorID => 166u; public static KeyedItem GetBigPickupItem(Expedition.Data data, uint itemDataBlockId) { ItemDataBlock block = GameDataBlockBase.GetBlock(itemDataBlockId); if (block == null) { FeatureLogger.Error($"Failed to find big pickup #{itemDataBlockId}: {data.ExpeditionName}"); } if (data.TryLookupItem(BigPickupItem.MakeTag(data, block), out var item)) { return item; } Item item2 = new BigPickupItem(data, block); return new KeyedItem(data.AddItem(item2), item2); } } public static class BigPickupZoneDistributionsHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_BigPickupZoneDistributionLocation { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_BigPickupZoneDistributionLocation(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Big Pickup Zone Distribution Location", "Locations filled with misc big pickup items spawned inside a specific zone", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class BigPickupZoneDistributionsHandler : ArchipelagoFeature { private static class BigPickupZoneDistributionLocation { public static TagResolver MakeTag(Zone.Data data, int count) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ZoneName} Big Pickup #{count}", "A big pickup location spawned randomly in a zone", BigPickupZoneDistributionsHandler_Tags.get_Tag_BigPickupZoneDistributionLocation(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_PopulateFunctionMarkersInZoneJob__BuildPickupItems__Patch { public static void Prefix(LG_PopulateFunctionMarkersInZoneJob __instance) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 Queue itemQueue = __instance.m_distributionData.PickupItems.m_itemQueue; if (itemQueue._head != 0 || itemQueue.Count == 0) { return; } Zone.Data data = Zone.Data.FromZone(__instance.m_zone); int num = 0; foreach (LG_DistributePickUpItem item in __instance.m_distributionData.PickupItems.m_itemQueue.Iter()) { if ((int)item.m_type == 3 && (int)((LG_DistributeItem)item).m_function == 12 && item.m_bigPickupData != null) { RandomizationTag nameTag = BigPickupZoneDistributionLocation.MakeTag(data, ++num); if (data.TryLookupLocation(nameTag, out var location)) { PickupHelper.AssociateDistributionWithLocation(item, location.ID); } else { FeatureLogger.Error("Failed to create association for location: " + data.LookupTagDef(location.Location.NameTag).Name); } } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Big Pickups Zone Distributions"; public override string Description => "Handles items spawned via Big Pickup Zone Distributions.\nThis is the system which spawns most big pickups. The other two major big pickup spawning systems are Warden Objectives (which can spawn big pickups based on the objective type) and Cells spawned as part of Zone Progression Puzzles"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Zone.Callback] public void AddBigPickups(Zone.Data data) { RegionID regionID = data.LookupOrCreateRegion(data.ZoneName); int num = 0; ExpeditionZoneData? zone = data.Zone; int num2; if (zone == null) { DimensionData? dimensionData = data.DimensionData; num2 = (int)((dimensionData != null) ? dimensionData.StaticBigPickupDistributionInZone : 0); } else { num2 = (int)zone.BigPickupDistributionInZone; } uint num3 = (uint)num2; BigPickupDistributionDataBlock block = GameDataBlockBase.GetBlock(num3); if (block != null) { float num4 = 0f; int num5 = 0; while (num4 + block.SpawnData[num5].Weight <= (float)block.SpawnsPerZone) { KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, block.SpawnData[num5].ItemID); data.AddLocation(BigPickupZoneDistributionLocation.MakeTag(data, ++num), regionID, BigPickupZoneDistributionLocation.MakeRandData(), bigPickupItem.ID); num4 += block.SpawnData[num5].Weight; num5 = (num5 + 1) % block.SpawnData.Count; } } ExpeditionZoneData? zone2 = data.Zone; List val = ((zone2 != null) ? zone2.SpecificPickupSpawningDatas : null); if (val == null) { return; } Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { SpecificPickupSpawnData current = enumerator.Current; if (current.WorldEventObjectFilter != null && current.PickupToSpawn != 0) { KeyedItem bigPickupItem2 = BigPickupHandler.GetBigPickupItem(data, current.PickupToSpawn); data.AddLocation(BigPickupZoneDistributionLocation.MakeTag(data, ++num), regionID, BigPickupZoneDistributionLocation.MakeRandData(), bigPickupItem2.ID); } } } } public static class BulkheadKeyHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_BulkheadKeyLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_BulkheadKeyItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_BulkheadKeyLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Bulkhead Key Locations", "Locations checked by picking up bulkhead keys", PickupHelper_Tags.get_Tag_SmallPickupLocations(gd))); } public static TagResolver get_Tag_BulkheadKeyItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Bulkhead Key Items", "The bulkhead key item itself", PickupHelper_Tags.get_Tag_SmallPickupItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class BulkheadKeyHandler : ArchipelagoFeature { private static class BulkheadKeyLocation { public static TagResolver MakeTag(Layer.Data data, int count) { Layer.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.LayerName} Bulkhead Key Spawn #{count}", "A bulkhead key spawn location", BulkheadKeyHandler_Tags.get_Tag_BulkheadKeyLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private class BulkheadKeyItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass11_0 { public LG_ComputerTerminal terminal; public AsyncItemSpawnWrapper wrapper; public StateTracker stateTracker; public BulkheadKeyItem <>4__this; public SNet_Player player; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving bulkhead key", 2f); } internal void b__1() { //IL_0074: 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_007d: 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_0086: 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) ISyncedItem? item = wrapper.Item; KeyItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { if (SNet.IsMaster) { stateTracker.AddItemToTerminal(<>4__this); wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn key item while spawning bulkhead keycard!"); terminal.AddLine("<#F00>Failed to retrieve key! It has been re-added to terminal system.", true); } } else { val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); terminal.AddLine("Key \"" + ((Item)val).PublicName + "\" has been given to " + player.NickName, true); } } } [CompilerGenerated] private sealed class d__11 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public BulkheadKeyItem <>4__this; private <>c__DisplayClass11_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__11(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; BulkheadKeyItem bulkheadKeyItem = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass11_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; <>8__1.wrapper = bulkheadKeyItem.SpawnItemAsync(); <>8__1.player = <>8__1.terminal.m_syncedInteractionSource.Owner; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving bulkhead key", 2f); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0074: 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_007d: 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_0086: 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) ISyncedItem? item = <>8__1.wrapper.Item; KeyItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { if (SNet.IsMaster) { <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); <>8__1.wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn key item while spawning bulkhead keycard!"); <>8__1.terminal.AddLine("<#F00>Failed to retrieve key! It has been re-added to terminal system.", true); } } else { val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, <>8__1.player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); <>8__1.terminal.AddLine("Key \"" + ((Item)val).PublicName + "\" has been given to " + <>8__1.player.NickName, true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__11 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__11(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private const uint BULKHEAD_KEY_ID = 146u; public Expedition.Data ExpeditionData { get; set; } public BulkheadKeyItem(Expedition.Data data) : base(MakeTag(data), MakeRandData()) { ExpeditionData = data; } public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Bulkhead Key Item", "A bulkhead key for a particular expedition", BulkheadKeyHandler_Tags.get_Tag_BulkheadKeyItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; result.IsRandomLike = true; return result; } private AsyncItemSpawnWrapper SpawnItemAsync() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) AsyncItemSpawnWrapper asyncItemSpawnWrapper = new AsyncItemSpawnWrapper(); if (SNet.IsMaster) { pItemData val = default(pItemData); val.itemID_gearCRC = 146u; ItemReplicationManager.SpawnItem(val, delItemCallback.op_Implicit((Action)asyncItemSpawnWrapper.OnSpawn), (ItemMode)2, Vector3.zero, Quaternion.identity, (AIG_CourseNode)null, (PlayerAgent)null); } return asyncItemSpawnWrapper; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player = null) { PlayerAgent player2 = player; if (!ExpeditionData.IsCurrentlyInExpedition()) { return; } if (!base.RandMode.IsRandomized && (Object)(object)player2 != (Object)null) { AsyncItemSpawnWrapper asyncItemSpawnWrapper = SpawnItemAsync(); asyncItemSpawnWrapper.AddSpawnCallback(delegate(ISyncedItem item) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002d: 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) KeyItemPickup_Core val = ((Il2CppObjectBase)item).Cast(); val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, player2.Owner, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); }); } else { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ExpeditionData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__11))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__11(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_ProgressionPuzzles__CreateKeyItemDistribution__Patch { public static void Postfix(LG_Distribute_ProgressionPuzzles __instance, GateKeyItem keyItem, ZonePlacementData placementData) { ZonePlacementData placementData2 = placementData; if (__instance.m_layer.m_buildData.m_layerGameData == null) { return; } Layer.Data data = Layer.Data.FromLayer(__instance.m_layer); for (int i = 0; i < __instance.m_layer.m_buildData.m_layerGameData.BulkheadKeyPlacements.Count; i++) { if (__instance.m_layer.m_buildData.m_layerGameData.BulkheadKeyPlacements[i].Any((ZonePlacementData p) => ((Il2CppObjectBase)p).Pointer == ((Il2CppObjectBase)placementData2).Pointer)) { if (data.TryLookupLocation(BulkheadKeyLocation.MakeTag(data, i + 1), out var location)) { PickupHelper.AssociateItem((ItemInLevel)(object)keyItem.keyPickupCore, location.ID); } else { FeatureLogger.Error("Failed to create association for bulkhead key location in layer: " + data.LayerName); } return; } } if (keyItem.PublicName.Contains("bulkhead", StringComparison.OrdinalIgnoreCase)) { FeatureLogger.Error("Failed to identify placement for bulkhead key!"); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Bulkhead Key Handler"; public override string Description => "Handles processing, despawning, and spawning bulkhead keys as part of randomization"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetBulkheadKeyItem(Expedition.Data data) { if (data.TryLookupItem(BulkheadKeyItem.MakeTag(data), out var item)) { return item; } Item item2 = new BulkheadKeyItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Layer.Callback] public void AddBulkheadKeys(Layer.Data data) { if (data.LayerDatas == null) { return; } KeyedItem bulkheadKeyItem = GetBulkheadKeyItem(data); for (int i = 0; i < data.LayerDatas.BulkheadKeyPlacements.Count; i++) { if (data.LayerDatas.BulkheadKeyPlacements[i].Any()) { data.AddLocation(BulkheadKeyLocation.MakeTag(data, i + 1), (from info in data.PlacementsToZoneRegions(data.LayerDatas.BulkheadKeyPlacements[i]) select info.Region).Distinct().ToArray(), BulkheadKeyLocation.MakeRandData(), bulkheadKeyItem.ID); } } } } public static class ColoredKeyHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ColoredKeyLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ColoredKeyItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ColoredKeyLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Colored Key Locations", "Locations checked by picking up Colored keys", PickupHelper_Tags.get_Tag_SmallPickupLocations(gd))); } public static TagResolver get_Tag_ColoredKeyItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Colored Key Items", "The Colored key item itself", PickupHelper_Tags.get_Tag_SmallPickupItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ColoredKeyHandler : ArchipelagoFeature { public class Settings { [Localized] public enum eRetrievalType { ToTerminal, ToHost, ToRandom, ToDoor } [FSDisplayName("Retrieval Type")] [FSDescription("Determines what happens when receiving a Colored Key from the Multiworld.\n\nTo Terminal\nPlace the key in the relevant terminal system, from which it can be retrieved at any time.\n\nTo Host\nGive the key directly to the host, either immediately when receiving it or when the level starts.\n\nTo Random\nGive the key directly to a randomly-chosen non-bot player.\n\nTo Door\nImmediately unlock the associated door.")] public eRetrievalType RetrievalType { get; set; } } private static class ColoredKeyLocation { public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Colored Key Location", "A colored key spawn location", ColoredKeyHandler_Tags.get_Tag_ColoredKeyLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private class ColoredKeyItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass11_0 { public LG_ComputerTerminal terminal; public AsyncItemSpawnWrapper wrapper; public StateTracker stateTracker; public ColoredKeyItem <>4__this; public SNet_Player player; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving colored key", 2f); } internal void b__1() { //IL_0074: 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_007d: 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_0086: 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) ISyncedItem? item = wrapper.Item; KeyItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { if (SNet.IsMaster) { stateTracker.AddItemToTerminal(<>4__this); FeatureLogger.Error("Failed to spawn key item while spawning colored keycard!"); terminal.AddLine("<#F00>Failed to retrieve key! It has been re-added to terminal system.", true); wrapper.QueueDespawn(); } } else { val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); terminal.AddLine("Key \"" + ((Item)val).PublicName + "\" has been given to " + player.NickName, true); } } } [CompilerGenerated] private sealed class d__11 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public ColoredKeyItem <>4__this; private <>c__DisplayClass11_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__11(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ColoredKeyItem coloredKeyItem = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass11_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; <>8__1.wrapper = coloredKeyItem.TrySpawnKey(); <>8__1.player = <>8__1.terminal.m_syncedInteractionSource.Owner; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving colored key", 2f); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0074: 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_007d: 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_0086: 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) ISyncedItem? item = <>8__1.wrapper.Item; KeyItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { if (SNet.IsMaster) { <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); FeatureLogger.Error("Failed to spawn key item while spawning colored keycard!"); <>8__1.terminal.AddLine("<#F00>Failed to retrieve key! It has been re-added to terminal system.", true); <>8__1.wrapper.QueueDespawn(); } } else { val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, <>8__1.player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); <>8__1.terminal.AddLine("Key \"" + ((Item)val).PublicName + "\" has been given to " + <>8__1.player.NickName, true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__11 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__11(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Zone.Data ZoneData { get; set; } public ColoredKeyItem(Zone.Data data) : base(MakeTag(data), MakeRandData()) { ZoneData = data; } public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Colored Key Item", "A colored key", ColoredKeyHandler_Tags.get_Tag_ColoredKeyItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public AsyncItemSpawnWrapper TrySpawnKey() { //IL_006b: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) LG_Zone lG_Zone = ZoneData.GetLG_Zone(); if ((Object)(object)lG_Zone == (Object)null) { FeatureLogger.Error("Failed to retrieve zone while spawning colored keycard!"); } object obj; if (lG_Zone == null) { obj = null; } else { LG_Gate sourceGate = lG_Zone.m_sourceGate; obj = ((sourceGate != null) ? ((Il2CppObjectBase)sourceGate.SpawnedDoor).TryCast() : null); } LG_SecurityDoor val = (LG_SecurityDoor)obj; AsyncItemSpawnWrapper asyncItemSpawnWrapper = new AsyncItemSpawnWrapper(); if ((Object)(object)val == (Object)null) { FeatureLogger.Error("Failed to identify sec door while spawning colored keycard!"); } else if (SNet.IsMaster) { pItemData val2 = default(pItemData); val2.itemID_gearCRC = val.m_keyItem.DataBlockID; ItemReplicationManager.SpawnItem(val2, delItemCallback.op_Implicit((Action)asyncItemSpawnWrapper.OnSpawn), (ItemMode)2, Vector3.zero, Quaternion.identity, (AIG_CourseNode)null, (PlayerAgent)null); } return asyncItemSpawnWrapper; } public void RetrieveKey() { switch (Config.RetrievalType) { case Settings.eRetrievalType.ToTerminal: StateTracker.Get().AddItemToTerminal(this); break; case Settings.eRetrievalType.ToHost: TrySpawnKey().AddSpawnCallback(delegate(ISyncedItem item) { //IL_001e: 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_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_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) KeyItemPickup_Core val2 = ((Il2CppObjectBase)item).TryCast(); if ((Object)(object)val2 != (Object)null) { val2.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, SNet.Master, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); } else if (SNet.IsMaster) { FeatureLogger.Error("Failed to give keycard directly to host. Adding to terminal!"); StateTracker.Get().AddItemToTerminal(this); } }); break; case Settings.eRetrievalType.ToRandom: TrySpawnKey().AddSpawnCallback(delegate(ISyncedItem item) { //IL_005f: 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_0068: 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_0071: 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) List list = SNet.LobbyPlayers.Where((SNet_Player p) => !p.IsBot).ToList(); KeyItemPickup_Core val3 = ((Il2CppObjectBase)item).TryCast(); if ((Object)(object)val3 != (Object)null) { val3.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, list[Random.Shared.Next(0, list.Count)], default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); } else if (SNet.IsMaster) { FeatureLogger.Error("Failed to give keycard directly to random human. Adding to terminal!"); StateTracker.Get().AddItemToTerminal(this); } }); break; case Settings.eRetrievalType.ToDoor: { LG_Zone lG_Zone = ZoneData.GetLG_Zone(); object obj; if (lG_Zone == null) { obj = null; } else { LG_Gate sourceGate = lG_Zone.m_sourceGate; obj = ((sourceGate != null) ? ((Il2CppObjectBase)sourceGate.SpawnedDoor).TryCast() : null); } LG_SecurityDoor val = (LG_SecurityDoor)obj; if ((Object)(object)val == (Object)null) { FeatureLogger.Error("Failed to retrieve zone door while unlocking colored keycard door!"); } else if (SNet.IsMaster) { val.AttemptOpenCloseInteraction(true); } break; } } } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ZoneData.IsCurrentlyInExpedition()) { RetrieveKey(); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ZoneData.IsSameExpedition(data)) { RetrieveKey(); } } [IteratorStateMachine(typeof(d__11))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__11(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_SecurityDoor__SetupKeyItemLock__Patch { public static void Postfix(LG_SecurityDoor __instance, GateKeyItem keyItem) { Zone.Data data = Zone.Data.FromZone(((LG_ZoneExpander)__instance.Gate).m_linksTo.m_zone); if (data.TryLookupLocation(ColoredKeyLocation.MakeTag(data), out var location)) { PickupHelper.AssociateItem((ItemInLevel)(object)__instance.m_keyItem.keyPickupCore, location.ID); } else { FeatureLogger.Error("Failed to create association for colored key for zone: " + data.ZoneName); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Colored Key Handler"; public override string Description => "Handles processing, despawning, and spawning colored keys as part of randomization"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } [FeatureConfig] public static Settings Config { get; set; } public static KeyedItem GetColoredKeyItem(Zone.Data data) { if (data.TryLookupItem(ColoredKeyItem.MakeTag(data), out var item)) { return item; } Item item2 = new ColoredKeyItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Zone.Callback] public void AddColoredKeys(Zone.Data data) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (data.Zone != null && (int)data.Zone.ProgressionPuzzleToEnter.PuzzleType == 1) { RegionList regions = (from i in data.PlacementsToZoneRegions(data.Zone.ProgressionPuzzleToEnter.ZonePlacementData) select i.Region).Distinct().ToArray(); data.AddLocation(ColoredKeyLocation.MakeTag(data), regions, ColoredKeyLocation.MakeRandData(), GetColoredKeyItem(data).ID); } } } public static class GenericItemInElevatorHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_GenericBigInElevatorLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_GenericBigInElevatorLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Generic Big In Elevator Locations", "Locations checked by picking up big items generically spawned in the elevator.", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class GenericItemInElevatorHandler : ArchipelagoFeature { private static class GenericItemInElevatorLocation { public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Generic Item-in-Elevator", "Item generically spawned in elevator", GenericItemInElevatorHandler_Tags.get_Tag_GenericBigInElevatorLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Factory__FactoryDone__Patch { public static void Postfix() { Objective.Data data = Layer.get_MainLayer(Expedition.Data.FromCurrentExpedition()).GetObjectiveDatas().First(); if (data.Objective.GenericItemFromStart == 0) { return; } if (!data.TryLookupLocation(GenericItemInElevatorLocation.MakeTag(data), out var location)) { FeatureLogger.Error("Failed to associate generic item in elevator!"); return; } CarryItemPickup_Core componentInChildren = ((Component)ElevatorCage.Current.m_cargoCage.m_itemsToMoveToCargo[0]).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { FeatureLogger.Error("Failed to find generic item in elevator during build!"); return; } if (((GameDataBlockBase)(object)((Item)componentInChildren).ItemDataBlock).persistentID != data.Objective.GenericItemFromStart) { FeatureLogger.Warning("Associated incorrect item type with generic item from start!"); } PickupHelper.AssociateItem((ItemInLevel)(object)componentInChildren, location.ID); } } private static IArchiveLogger? m_featureLogger; public override string Name => "Generic Item in Elevator"; public override string Description => "Handles items spawned via the Generic-Item-in-Elevator system.\nThis system allows prisoners to start with one non-objective-related Big Pickup in the elevator, which is often used to perform a required part of the mission. It is most commonly used to provide a Matter Wave Projecter at the start of an expedition."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Expedition.Callback] public void AddGenericItemInElevator(Expedition.Data data) { Objective.Data data2 = Layer.get_MainLayer(data).GetObjectiveDatas().First(); if (data2.Objective.GenericItemFromStart != 0) { KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, data2.Objective.GenericItemFromStart); data.AddLocation(GenericItemInElevatorLocation.MakeTag(data), Zone.get_StartingRegion(data), GenericItemInElevatorLocation.MakeRandData(), bigPickupItem.ID); } } } public static class PickupHelper_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_PickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_SmallPickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_BigPickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ResourcePickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ConsumablePickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ArtifactPickupLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_PickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_SmallPickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_BigPickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ResourcePickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ConsumablePickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ArtifactPickupItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_PickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Pickup Locations", "Locations checked when items are picked up (keys, cells, artifacts, etc)", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_SmallPickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Small Pickup Locations", "Location checked when small items are picked up (keys, IDs, GLPS, etc)", get_Tag_PickupLocations(gd))); } public static TagResolver get_Tag_BigPickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Big Pickup Locations", "Location checked when big items are picked up (cells, fog turbines, babies, etc)", get_Tag_PickupLocations(gd))); } public static TagResolver get_Tag_ResourcePickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Resource Pickup Locations", "Location checked when resources are picked up (ammo, med, tool, disinfect)", get_Tag_PickupLocations(gd))); } public static TagResolver get_Tag_ConsumablePickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Consumable Pickup Locations", "Location checked when consumables are picked up (glowsticks, flashlights, c-foam grenades, etc)", get_Tag_PickupLocations(gd))); } public static TagResolver get_Tag_ArtifactPickupLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Artifact Pickup Locations", "Location checked when artifacts are picked up (muted, bold, aggressive)", get_Tag_PickupLocations(gd))); } public static TagResolver get_Tag_PickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Pickup Items", "All items which are picked up (keys, cells, artifacts, etc)", RootRandomizationTags.get_Tag_AllItems(gd))); } public static TagResolver get_Tag_SmallPickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Small Pickup Items", "All small pickup items which end up in the left-side menu (keys, IDs, GLPS, etc)", get_Tag_PickupItems(gd))); } public static TagResolver get_Tag_BigPickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Big Pickup Items", "All big pickup items (cells, fog turbines, babies, etc)", get_Tag_PickupItems(gd))); } public static TagResolver get_Tag_ResourcePickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Resource Pickup Items", "All resource pickups (ammo, med, tool, disinfect)", get_Tag_PickupItems(gd))); } public static TagResolver get_Tag_ConsumablePickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Consumable Pickup Items", "All consumable pickups (glowsticks, flashlights, c-foam grenades, etc)", get_Tag_PickupItems(gd))); } public static TagResolver get_Tag_ArtifactPickupItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Artifact Pickup Items", "All artifact picksup (muted, bold, aggressive)", get_Tag_PickupItems(gd))); } } [InjectToIl2Cpp] [EnableFeatureByDefault] public class PickupHelper : ArchipelagoFeature { [InjectToIl2Cpp] private class ContainsLocationPickupComp : MonoBehaviour { public LocationID StoredLocation = new LocationID(); public ContainsLocationPickupComp(IntPtr ptr) : base(ptr) { } } [InjectToIl2Cpp] private class This_ConsumablesData : ConsumableDistributionDataBlock { public LocationID StoredLocation = new LocationID(); public This_ConsumablesData(IntPtr ptr) : base(ptr) { } public This_ConsumablesData(LocationID id, ConsumableDistributionDataBlock? original) : base(ClassInjector.DerivedConstructorPointer()) { ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this); if (original == null) { original = ((IEnumerable)GameDataBlockBase.GetAllBlocks()).First(); } StoredLocation = id; ((ConsumableDistributionDataBlock)this).ChanceToSpawnInResourceContainer = original.ChanceToSpawnInResourceContainer; ((ConsumableDistributionDataBlock)this).SpawnData = original.SpawnData; ((ConsumableDistributionDataBlock)this).SpawnsPerZone = original.SpawnsPerZone; ((GameDataBlockBase)this).Index = ((GameDataBlockBase)(object)original).Index; ((GameDataBlockBase)this).internalEnabled = ((GameDataBlockBase)(object)original).internalEnabled; ((GameDataBlockBase)this).name = ((GameDataBlockBase)(object)original).name; ((GameDataBlockBase)this).persistentID = 0u; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_DistributionJobUtils__TryGetExistingZoneFunctionDistribution__Patch { public static LG_DistributeItem? lastFetchedItem; public static void Postfix(ref LG_DistributeItem foundDist) { lastFetchedItem = foundDist; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_PickupItemsPerZone__Build__Patch { public static void Prefix(LG_Distribute_PickupItemsPerZone __instance) { LG_DistributionJobUtils__TryGetExistingZoneFunctionDistribution__Patch.lastFetchedItem = null; } public static void Postfix(LG_Distribute_PickupItemsPerZone __instance) { if (__instance.m_consumableDistributionData == null) { return; } LG_DistributeItem? lastFetchedItem = LG_DistributionJobUtils__TryGetExistingZoneFunctionDistribution__Patch.lastFetchedItem; LG_DistributeResourceContainer val = ((lastFetchedItem != null) ? ((Il2CppObjectBase)lastFetchedItem).TryCast() : null); if (val != null && val.m_packs.Count > 0) { ResourceContainerSpawnData val2 = val.m_packs[val.m_packs.Count - 1]; if (val2.m_consumableData != null && ((Il2CppObjectBase)val2.m_consumableData).Pointer != ((Il2CppObjectBase)__instance.m_consumableDistributionData).Pointer) { FeatureLogger.Warning("Overwriting consumable data during consumable forwarding!"); } val2.m_consumableData = __instance.m_consumableDistributionData; } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_PickupItemBuilder__SetupFunctionGO__Patch { public static void Postfix(LG_PickupItemBuilder __instance, LG_LayerType layer, GameObject GO) { ConsumableDistributionDataBlock consumableData = __instance.m_consumableData; This_ConsumablesData this_ConsumablesData = ((consumableData != null) ? ((Il2CppObjectBase)consumableData).TryCast() : null); if (this_ConsumablesData != null) { ItemInLevel componentInChildren = GO.GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { throw new NullReferenceException(); } AssociateItem(componentInChildren, this_ConsumablesData.StoredLocation); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ResourceContainer_Storage__PlaceSmallGenericPickup__Patch { public static void Postfix(LG_ResourceContainer_Storage __instance, ResourceContainerSpawnData pack, Transform align, int randomSeed) { ConsumableDistributionDataBlock consumableData = pack.m_consumableData; This_ConsumablesData this_ConsumablesData = ((consumableData != null) ? ((Il2CppObjectBase)consumableData).TryCast() : null); if (this_ConsumablesData != null) { ItemInLevel componentInChildren = ((Component)align).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { throw new NullReferenceException(); } AssociateItem(componentInChildren, this_ConsumablesData.StoredLocation); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_PickupItem_Sync__AttemptPickupInteraction__Patch { public static void Prefix(LG_PickupItem_Sync __instance, ref pPickupItemInteraction interaction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((int)interaction.type != 0) { return; } ContainsLocationPickupComp component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null) { return; } StateTracker stateTracker = StateTracker.Get(); SNet_Player val = default(SNet_Player); Location location = stateTracker.NotifyFoundLocation(player: (!((pPlayer)(ref interaction.pPlayer)).TryGetPlayer(ref val)) ? null : ((Il2CppObjectBase)val.PlayerAgent).TryCast(), id: component.StoredLocation); if (location.RandMode.IsTreatedAsRandom) { ((pPlayer)(ref interaction.pPlayer)).SetPlayer((SNet_Player)null); CarryItemPickup_Core val2 = ((Il2CppObjectBase)__instance.item).TryCast(); GenericSmallPickupItem_Core val3 = ((Il2CppObjectBase)__instance.item).TryCast(); if ((Object)(object)val2 != (Object)null) { val2.m_isWardenObjective = false; } else if ((Object)(object)val3 != (Object)null) { val3.m_isWardenObjective = false; } ((Component)__instance).gameObject.transform.position = new Vector3(0f, -10000f, 0f); ReplicatedItemWrapper replicationWrapper = __instance.item.ReplicationWrapper; if (replicationWrapper != null) { replicationWrapper.Replicator.Despawn(); } ((Il2CppObjectBase)__instance.GetReplicator()).Cast().Despawn(); } Object.Destroy((Object)(object)component); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_PickupItem_Sync__SetCurrentState_NoSync__Patch { public static void Postfix(LG_PickupItem_Sync __instance) { Item item = __instance.item; ContainsLocationPickupComp containsLocationPickupComp = ((item != null) ? ((Component)item).GetComponent() : null); if (!((Object)(object)containsLocationPickupComp != (Object)null)) { return; } Item item2 = __instance.item; Interact_Pickup_PickupItem val = ((item2 != null) ? ((Il2CppObjectBase)item2.PickupInteraction).TryCast() : null); if ((Object)(object)val != (Object)null) { Game.Data processedGameData = StateTracker.Get().MidManager.GetProcessedGameData(); Location loc = processedGameData.LookupLocation(containsLocationPickupComp.StoredLocation); string backupName = processedGameData.LookupTagDef(processedGameData.LookupItem(loc.ItemID).NameTag).Name; val.SetName((Func)new Il2CppFunc_string(() => loc.ScoutedItemName ?? backupName)); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Pickups Helper"; public override string Description => "Provides utilites used by other features to manage pickups (including big pickups)"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static void AssociateItem(ItemInLevel item, LocationID locationId, bool despawnIfFound = true) { ContainsLocationPickupComp containsLocationPickupComp = ((Component)item).GetComponent(); if ((Object)(object)containsLocationPickupComp == (Object)null) { containsLocationPickupComp = ((Component)item).gameObject.AddComponent(); } else if (!containsLocationPickupComp.StoredLocation.IsNull) { Game.Data processedGameData = Plugin.Get().MidManager.GetProcessedGameData(); int count = Math.Max(containsLocationPickupComp.StoredLocation.AsId.ToString().Length, locationId.AsId.ToString().Length); string text = new string('0', count); FeatureLogger.Error($"Overwriting location on pickup!\n Old Location: [{containsLocationPickupComp.StoredLocation.AsId.ToString(text)}] {processedGameData.LookupTagDef(processedGameData.LookupLocation(containsLocationPickupComp.StoredLocation).NameTag).Name} New Location: [{locationId.AsId.ToString(text)}] {processedGameData.LookupTagDef(processedGameData.LookupLocation(locationId).NameTag).Name}"); } containsLocationPickupComp.StoredLocation = locationId; StateTracker stateTracker = StateTracker.Get(); Location loc = stateTracker.MidManager.GetProcessedGameData().LookupLocation(locationId); if (despawnIfFound && stateTracker.HasLocation(locationId) && loc.RandMode.IsTreatedAsRandom) { if ((Object)(object)((Item)item).ReplicationWrapper != (Object)null) { ReplicatedItemWrapper replicationWrapper = ((Item)item).ReplicationWrapper; if (replicationWrapper != null) { replicationWrapper.Replicator.Despawn(); } } else { Object.Destroy((Object)(object)((Component)item).gameObject); } } else { if (!loc.RandMode.IsRandomized) { return; } Interact_Pickup_PickupItem val = ((Il2CppObjectBase)((Item)item).PickupInteraction).TryCast(); if ((Object)(object)val != (Object)null) { Game.Data processedGameData2 = stateTracker.MidManager.GetProcessedGameData(); string backupName = processedGameData2.LookupTagDef(processedGameData2.LookupItem(loc.ItemID).NameTag).Name; val.SetName((Func)new Il2CppFunc_string(() => loc.ScoutedItemName ?? backupName)); } } } public static void AssociateDistributionWithLocation(LG_Distribute_PickupItemsPerZone distribution, LocationID locationId) { if (((Feature)ArchipelagoFeatureHelper.GetFeature()).Enabled) { ConsumableDistributionDataBlock consumableDistributionData = distribution.m_consumableDistributionData; This_ConsumablesData this_ConsumablesData = ((consumableDistributionData != null) ? ((Il2CppObjectBase)consumableDistributionData).TryCast() : null); if (this_ConsumablesData != null) { FeatureLogger.Error($"Distribution already has location associated with it! Old ID: {this_ConsumablesData.StoredLocation}, New ID: {locationId}"); } else { distribution.m_consumableDistributionData = (ConsumableDistributionDataBlock)(object)new This_ConsumablesData(locationId, distribution.m_consumableDistributionData); } } } public static void AssociateDistributionWithLocation(LG_DistributePickUpItem distribution, LocationID locationId) { if (((Feature)ArchipelagoFeatureHelper.GetFeature()).Enabled) { ConsumableDistributionDataBlock consumableData = distribution.m_consumableData; This_ConsumablesData this_ConsumablesData = ((consumableData != null) ? ((Il2CppObjectBase)consumableData).TryCast() : null); if (this_ConsumablesData != null) { FeatureLogger.Error($"Distribution already has location associated with it! Old ID: {this_ConsumablesData.StoredLocation}, New ID: {locationId}"); } else { distribution.m_consumableData = (ConsumableDistributionDataBlock)(object)new This_ConsumablesData(locationId, distribution.m_consumableData); } } } } public static class ProgressionCellHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_ProgressionCellSpawnLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ProgressionCellSpawnLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Progression Cell Locations", "Locations checked by picking up cells specifically spawned by the game's progression puzzle system.", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ProgressionCellHandler : ArchipelagoFeature { private static class ProgressionCellLocation { public static TagResolver MakeTag(Zone.Data data, int count) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ZoneName} Progression Cell #{count} Spawn", "Progression cell spawn location", ProgressionCellHandler_Tags.get_Tag_ProgressionCellSpawnLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_ProgressionPuzzles__Build__Patch { public static void Postfix(LG_Distribute_ProgressionPuzzles __instance) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Invalid comparison between Unknown and I4 Queue jobs = ((Il2CppArrayBase)(object)LG_Factory.Current.m_batches)[16].Jobs; Layer.Data layerData = Layer.Data.FromLayer(__instance.m_layer); if (layerData.LayoutID == 0) { return; } IEnumerator> enumerator = (from z in __instance.m_layer.m_buildData.m_zoneBuildDatas where (int)z.ProgressionPuzzleToEnter.PuzzleType == 2 select layerData.FindZoneByIndex(z.LocalIndex)).SelectMany((Zone.Data z) => from i in Enumerable.Range(1, z.Zone.ProgressionPuzzleToEnter.PlacementCount) select Tuple.Create(z, i)).GetEnumerator(); Enumerator enumerator2 = jobs.GetEnumerator(); while (enumerator2.MoveNext()) { LG_FactoryJob current = enumerator2.Current; LG_Distribute_PickupItemsPerZone val = ((Il2CppObjectBase)current).TryCast(); if (val == null || ((Il2CppObjectBase)val.m_zone.m_layer).Pointer != ((Il2CppObjectBase)__instance.m_layer).Pointer || (int)val.m_pickupType != 3 || val.m_bigPickupDistributionData != null) { continue; } if (val.m_genericItemId != BigPickupHandler.CellItemID) { FeatureLogger.Error("Expected distribution to be a cell, but it wasn't!"); } else if (enumerator.MoveNext()) { if (!layerData.TryLookupLocation(ProgressionCellLocation.MakeTag(enumerator.Current.Item1, enumerator.Current.Item2), out var location)) { FeatureLogger.Error($"Failed to create association for progression cell #{enumerator.Current.Item2} in zone: {enumerator.Current.Item1.ZoneName}"); } else { PickupHelper.AssociateDistributionWithLocation(val, location.ID); } } else { FeatureLogger.Error("Had more cells than progression puzzle cells!"); } } if (enumerator.MoveNext()) { FeatureLogger.Error("Not all cell locations associated during layer build: " + layerData.LayerName); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Progression Cell Handler"; public override string Description => "Handles specifically cells spawned as part of progression puzzles\nProgression puzzles are blockers for entering a zone. In this case, any zone that requires a specific generator to be powered to enter"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_PickupHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Zone.Callback] public void AddProgressionCells(Zone.Data data) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ExpeditionZoneData? zone = data.Zone; if (((zone != null) ? ((int)zone.ProgressionPuzzleToEnter.PuzzleType) : 0) == 2) { KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, BigPickupHandler.CellItemID); RegionID[] array = (from i in data.PlacementsToZoneRegions(data.Zone.ProgressionPuzzleToEnter.ZonePlacementData) select i.Region).Distinct().ToArray(); for (int j = 1; j <= data.Zone.ProgressionPuzzleToEnter.PlacementCount; j++) { data.AddLocation(ProgressionCellLocation.MakeTag(data, j), array, ProgressionCellLocation.MakeRandData(), bigPickupItem.ID); } } } } } namespace ReTFO.Archipelago.Features.ObjectiveHandlers { public static class CollectHSUHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_HSUScanLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_HSUScanItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_HSUScanLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("HSU Scan Locations", "Locations checked by starting HSU scans", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_HSUScanItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("HSU Scan Items", "Items which start HSU scans", RootRandomizationTags.get_Tag_AllItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class CollectHSUHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 0; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return "Collect HSU"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 0; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)0)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string ScanStartedRegion(Objective.Data data) { return data.ObjectiveName() + " HSU Scan Started"; } public static string ScanCompletedRegion(Objective.Data data) { return data.ObjectiveName() + " HSU Scan Completed"; } } private static class CollectHSU_ScanLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " HSU Scan Location", "Location checked by starting a particular HSU scan", CollectHSUHandler_Tags.get_Tag_HSUScanLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private class CollectHSU_ScanItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass6_0 { public LG_ComputerTerminal terminal; public CollectHSU_ScanItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Initiating HSU Scan", 2f); terminal.AddLine("Scan will start in 3 seconds. Enjoy :)", true); } internal void b__1() { WO_HSUFindTakeSample val = ((Il2CppObjectBase)<>4__this.ObjectiveData.GetWardenObjective()).Cast(); val.m_hsu.m_puzzle.AttemptInteract((eChainedPuzzleInteraction)0); } } [CompilerGenerated] private sealed class d__6 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public CollectHSU_ScanItem <>4__this; private <>c__DisplayClass6_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass6_0(); <>8__1.terminal = terminal; <>8__1.<>4__this = <>4__this; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating HSU Scan", 2f); <>8__1.terminal.AddLine("Scan will start in 3 seconds. Enjoy :)", true); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { WO_HSUFindTakeSample val = ((Il2CppObjectBase)<>8__1.<>4__this.ObjectiveData.GetWardenObjective()).Cast(); val.m_hsu.m_puzzle.AttemptInteract((eChainedPuzzleInteraction)0); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__6 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__6(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Objective.Data ObjectiveData; public CollectHSU_ScanItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " HSU Scan", "Item which triggers a particular HSU scan", CollectHSUHandler_Tags.get_Tag_HSUScanItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ObjectiveData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ObjectiveData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__6))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(-2) { <>4__this = this, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class OnHSUSetup { public static void Postfix(LG_HSUScannerJob __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) LG_HSUScannerJob __instance2 = __instance; LocationID id; if (__instance2.m_hsu.m_isWardenObjective) { Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance2.m_hsu.OriginLayer).GetObjectiveDatas() .ElementAt(__instance2.m_hsu.WardenObjectiveChainIndex); if (!data.TryLookupLocation(CollectHSU_ScanLocation.MakeTag(data), out var location)) { FeatureLogger.Error("Failed to find HSU Scan Location while creating associations."); return; } id = location.ID; __instance2.m_hsu.m_pickupSampleInteraction.OnInteractionTriggered = DelegateSupport.ConvertDelegate>((Delegate)new Action(OnInteract)); } void OnInteract(PlayerAgent player) { if (!StateTracker.Get().NotifyFoundLocation(id, player).RandMode.IsTreatedAsRandom) { __instance2.m_hsu._Setup_b__14_2(player); } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Collect HSU Handler"; public override string Description => "Handles the Collect DNA Sample objective type.\nExample: R1A1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetHSUScanItem(Objective.Data data) { if (data.TryLookupItem(CollectHSU_ScanItem.MakeTag(data), out var item)) { return item; } Item item2 = new CollectHSU_ScanItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleCollectHSUSample(Objective.Data data) { if (This.IsCorrectObjective(data)) { RegionList regions = (from info in data.PlacementsToZoneRegions(data.ObjectiveData.ZonePlacementDatas[0]) select info.Region).ToList(); KeyedItem hSUScanItem = GetHSUScanItem(data); data.AddLocation(CollectHSU_ScanLocation.MakeTag(data), regions, CollectHSU_ScanLocation.MakeRandData(), hSUScanItem.ID); string text = ThisRegions.ScanStartedRegion(data); RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = hSUScanItem.PathReqs, ReqCount = 1u }); data.MakeOrWrapOnSolveEvents().Process(regionID, text); string regionName = ThisRegions.ScanCompletedRegion(data); RegionID regionID2 = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2 }); SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID2); } } } public static class ReactorStartupHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupReactorLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupCodeLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupSkipLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupReactorItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupCodeItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorStartupSkipItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupReactorLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupReactorItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupSkipLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupCodeLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupCodeItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_ReactorStartupSkipItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ReactorStartupReactorLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Reactor Locations", "Locations checked by entering zones with Reactor Startup reactors (as opposed to Reactor Shutdown reactors)", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ReactorStartupCodeLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Code Locations", "Locations checked by finding Reactor Startup codes. Includes \"free\" codes", TerminalLogHelper_Tags.get_Tag_TerminalLogLocations(gd))); } public static TagResolver get_Tag_ReactorStartupSkipLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Skip Locations", "Location checked when a reactor wave is survived used to grant wave skip items", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ReactorStartupReactorItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Reactor", "Reactor item indicating a reactor startup can be performed", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ReactorStartupCodeItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Code", "Reactor item indicating the player has found a reactor code", TerminalLogHelper_Tags.get_Tag_TerminalLogItems(gd))); } public static TagResolver get_Tag_ReactorStartupSkipItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Startup Skip", "Reactor items allowing players to skip to a particular wave", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ReactorStartupReactorLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Reactor Locations", "Locations checked by entering zones iwth Reactor Startup reactors for a particular objective", get_Tag_ReactorStartupReactorLocations(gd))); } public static TagResolver get_Tag_ReactorStartupReactorItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Reactors", "Reactor item indicating a reactor startup can be performed for a particular objective", get_Tag_ReactorStartupReactorItems(gd))); } public static TagResolver get_Tag_ReactorStartupSkipLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Skip Locations", "Location checked when a reactor wave is survived used to grant wave skip items for a particular objective", get_Tag_ReactorStartupSkipLocations(gd))); } public static TagResolver get_Tag_ReactorStartupCodeLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Codes", "Reactor code locations for a particular objective", get_Tag_ReactorStartupCodeLocations(gd))); } public static TagResolver get_Tag_ReactorStartupCodeItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Codes", "Reactor item indicating the player has found a reactor code for a particular objective", get_Tag_ReactorStartupCodeItems(gd))); } public static TagResolver get_Tag_ReactorStartupSkipItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor Startup Skip", "Reactor items allowing players to skip to a particular wave for a particular objective", get_Tag_ReactorStartupSkipItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ReactorStartupHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 1; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return "Reactor Startup"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 1; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)1)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string FoundReactor(Objective.Data data) { return data.ObjectiveName() + " Found Reactor"; } public static string SurvivedWave(Objective.Data data, int count) { return $"{data.ObjectiveName()} Survived Wave #{count}"; } public static string CompletedStartup(Objective.Data data, int count = 1) { return $"{data.ObjectiveName()} Completed Reactor Startup #{count}"; } } private static class ReactorStartup_ReactorLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor Location #{count}", "A reactor location for a particular reactor in an objective", ReactorStartupHandler_Tags.get_Tag_ReactorStartupReactorLocations_PerObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class ReactorStartup_ReactorItem : Item { public Objective.Data ObjectiveData { get; set; } public ReactorStartup_ReactorItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor", "A particular reactor item", ReactorStartupHandler_Tags.get_Tag_ReactorStartupReactorItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static class ReactorStartup_CodeLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor Code #{count} Location", "A reactor code location for a particular reactor code", ReactorStartupHandler_Tags.get_Tag_ReactorStartupCodeLocations_PerObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private class ReactorStartup_CodeItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass14_0 { public LG_ComputerTerminal terminal; public ReactorStartup_CodeItem <>4__this; public LG_WardenObjective_Reactor reactor; internal void b__0() { terminal.AddLine((TerminalLineType)2, $"Retrieving {<>4__this.NameTag}", 2f); if ((Object)(object)reactor != (Object)null) { terminal.AddLine(string.Format(((Feature)ArchipelagoFeatureHelper.GetFeature()).Localization.Get(182408469u), ((Il2CppArrayBase)(object)reactor.GetOverrideCodes())[<>4__this.Index]), true); } else { terminal.AddLine("<#F00>Failed to find any reactors to pull codes from!", true); } } } [CompilerGenerated] private sealed class d__14 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public ReactorStartup_CodeItem <>4__this; private StateTracker stateTracker; public StateTracker <>3__stateTracker; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__14(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ReactorStartup_CodeItem reactorStartup_CodeItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass14_0 CS$<>8__locals0 = new <>c__DisplayClass14_0 { terminal = terminal, <>4__this = <>4__this, reactor = reactorStartup_CodeItem.GetReactors().FirstOrDefault() }; stateTracker.AddItemToTerminal(reactorStartup_CodeItem); <>2__current = delegate { CS$<>8__locals0.terminal.AddLine((TerminalLineType)2, $"Retrieving {CS$<>8__locals0.<>4__this.NameTag}", 2f); if ((Object)(object)CS$<>8__locals0.reactor != (Object)null) { CS$<>8__locals0.terminal.AddLine(string.Format(((Feature)ArchipelagoFeatureHelper.GetFeature()).Localization.Get(182408469u), ((Il2CppArrayBase)(object)CS$<>8__locals0.reactor.GetOverrideCodes())[CS$<>8__locals0.<>4__this.Index]), true); } else { CS$<>8__locals0.terminal.AddLine("<#F00>Failed to find any reactors to pull codes from!", true); } }; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__14 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__14(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Objective.Data ObjectiveData { get; set; } public int Index { get; set; } public ReactorStartup_CodeItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; Index = count - 1; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor Code #{count}", "A particular reactor code", ReactorStartupHandler_Tags.get_Tag_ReactorStartupCodeItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } private List GetReactors() { List list = (from r in (IEnumerable)Object.FindObjectsOfType(Il2CppType.Of()) select ((Il2CppObjectBase)r).Cast() into r where r.m_isWardenObjective where r.OriginLayer == ObjectiveData.LayerType where r.WardenObjectiveChainIndex == ObjectiveData.ObjectiveIndex select r).ToList(); if (list.Count == 0) { FeatureLogger.Error("Failed to find valid reactor while granting reactor code item"); } return list; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ObjectiveData.IsCurrentlyInExpedition()) { OnStartExpeditionWithItem(stateTracker, ObjectiveData); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!ObjectiveData.IsSameExpedition(data)) { return; } List reactors = GetReactors(); foreach (LG_WardenObjective_Reactor item in reactors) { if (item.m_stateReplicator.State.stateCount == Index + 1) { item.CurrentStateOverrideCode = ((Il2CppArrayBase)(object)item.GetOverrideCodes())[Index]; ProgressionObjective_ReactorStartup.Update(ObjectiveData, item); } } stateTracker.AddItemToTerminal(this); } [IteratorStateMachine(typeof(d__14))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__14(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } private static class ReactorStartup_SkipLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor Wave #{count} Skip Location", "A reactor skip location for a particular skip", ReactorStartupHandler_Tags.get_Tag_ReactorStartupSkipLocations_PerObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private class ReactorStartup_SkipItem : Item { public Objective.Data ObjectiveData { get; set; } public ReactorStartup_SkipItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor Skip #{count}", "A particular reactor skip", ReactorStartupHandler_Tags.get_Tag_ReactorStartupSkipItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsUseful = true; result.IsRandomLike = true; return result; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_WardenObjective_Reactor__OnBuildDone__Patch { public static void Postfix(LG_WardenObjective_Reactor __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.OriginLayer).GetObjectiveDatas() .ElementAt(__instance.WardenObjectiveChainIndex); if (!This.IsCorrectObjective(data)) { return; } int num = 0; Enumerator enumerator = data.Objective.ReactorWaves.GetEnumerator(); while (enumerator.MoveNext()) { ReactorWaveData current = enumerator.Current; num++; if (!current.HasVerificationTerminal) { continue; } if (!data.TryLookupLocation(ReactorStartup_CodeLocation.MakeTag(data, num), out var location)) { FeatureLogger.Error($"Failed to create association for reactor code: {data.ObjectiveName()} Code #{num}"); continue; } int num2 = LG_LevelInteractionManager.Current.m_terminalItemsByKeyString.FindEntry(current.VerificationTerminalSerial); if (num2 == -1) { FeatureLogger.Error("Failed to identify reactor terminal log."); continue; } Entry val = ((Il2CppArrayBase>)(object)LG_LevelInteractionManager.Current.m_terminalItemsByKeyString.entries)[num2]; Component val2 = new Component(((Il2CppObjectBase)val.value).Pointer); LG_ComputerTerminal component = val2.GetComponent(); TerminalLogHelper.AssociateLog(component, current.VerificationTerminalFileName, location.ID); } ProgressionObjective_ReactorStartup objectiveItem = CustomObjectiveHandler.GetObjectiveItem(data.ObjectiveName()); ProgressionObjective_ReactorStartup.Setup(data, __instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_WardenObjective_Reactor__TryGetCurrentWaveData__Patch { public static void Postfix(LG_WardenObjective_Reactor __instance, ref string overrideCode) { //IL_0006: 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) Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.OriginLayer).GetObjectiveDatas() .ElementAt(__instance.WardenObjectiveChainIndex); if (!This.IsCorrectObjective(data)) { return; } int count = Math.Max(__instance.m_stateReplicator.State.stateCount, 1); if (!data.TryLookupLocation(ReactorStartup_CodeLocation.MakeTag(data, count), out var location)) { FeatureLogger.Error("Unknown error while checking if reactor code is obtained"); return; } StateTracker stateTracker = StateTracker.Get(); if (stateTracker.CollectedItemCounts.GetValueOrDefault(location.ItemID, 0) == 0 && location.Location.RandMode.IsTreatedAsRandom) { overrideCode = "––-–"; } ProgressionObjective_ReactorStartup.Update(data, __instance); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_WardenObjective_Reactor__AttemptInteract__Patch { public static void Postfix(LG_WardenObjective_Reactor __instance, pReactorInteraction interaction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_00e2: 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_00e9: Invalid comparison between Unknown and I4 //IL_0012: 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_00f1: Unknown result type (might be due to invalid IL or missing references) if ((int)interaction.type == 2) { Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.OriginLayer).GetObjectiveDatas() .ElementAt(__instance.WardenObjectiveChainIndex); StateTracker stateTracker = StateTracker.Get(); int stateCount = __instance.m_stateReplicator.State.stateCount; stateTracker.NotifyFoundRegion(ThisRegions.SurvivedWave(data, stateCount), null); if (data.TryLookupLocation(ReactorStartup_SkipLocation.MakeTag(data, stateCount), out var location)) { stateTracker.NotifyFoundLocation(location.ID, null); } else { FeatureLogger.Error("Failed to find skip location while grant location check"); } if (!data.Objective.ReactorWaves[stateCount - 1].VerifyInOtherZone) { if (data.TryLookupLocation(ReactorStartup_CodeLocation.MakeTag(data, stateCount), out var location2)) { stateTracker.NotifyFoundLocation(location2.ID, null); } else { FeatureLogger.Error("Failed to find code location while grant free code location check"); } } } else if ((int)interaction.type == 5) { Objective.Data data2 = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.OriginLayer).GetObjectiveDatas() .ElementAt(__instance.WardenObjectiveChainIndex); ProgressionObjective_ReactorStartup.Update(data2, __instance); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTerminal__OnPostRecall__Patch { public static void Postfix(LG_ComputerTerminal __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance.ConnectedReactor == (Object)null) && __instance.ConnectedReactor.m_isWardenObjective) { Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.ConnectedReactor.OriginLayer).GetObjectiveDatas() .ElementAt(__instance.ConnectedReactor.WardenObjectiveChainIndex); if (This.IsCorrectObjective(data)) { ProgressionObjective_ReactorStartup.Update(data, __instance.ConnectedReactor); } } } } private class SkipToWaveSubcommand : APCommandHandler.SubCommand { public override string HelpText => "Skips to a specific reactor wave. Must be used on a reactor terminal. Only skips forward.\nNote: Immediately executes all events related to completing the waves you skip. This may include enemy spawns.\nNote: You can unlock the ability to skip to a wave by surviving a wave.\n For example, surviving wave #1 will unlock the ability to skip to the start of wave #1.\n You do not need to enter the verification code, you only need to survive the wave."; public SkipToWaveSubcommand() { base.SubCommandName = "SKIPTOWAVE"; } public override void Execute(LG_ComputerTerminal terminal, string fullLine, string subCommand, string param2) { //IL_0038: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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_01fe: 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_020d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)terminal.ConnectedReactor == (Object)null) { terminal.AddLine("This sub-command must be used on a reactor terminal!", true); return; } StateTracker stateTracker = StateTracker.Get(); Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(terminal.ConnectedReactor.OriginLayer).GetObjectiveDatas() .ElementAt(terminal.ConnectedReactor.WardenObjectiveChainIndex); int stateCount = terminal.ConnectedReactor.m_stateReplicator.State.stateCount; if (param2 != null && param2.Length != 0 && int.TryParse(param2, out var result)) { if (result < 1) { terminal.AddLine("You cannot skip to a wave before wave #1", true); } else if (result <= stateCount && (int)terminal.ConnectedReactor.m_stateReplicator.State.status != 0) { terminal.AddLine($"You can only skip forward using this command. Current wave: {stateCount}", true); } else if (result > terminal.ConnectedReactor.m_waveCountMax) { terminal.AddLine($"This reactor only has {terminal.ConnectedReactor.m_waveCountMax} waves; cannot skip past that!", true); } else { if (hasWave(result)) { for (int i = Math.Max(stateCount, 1); i < result; i++) { WorldEventManager.ExecuteEvents(data.Objective.ReactorWaves[i - 1].Events, 0f); } pReactorState val = default(pReactorState); val.stateCount = result; val.stateProgress = 0f; val.status = (eReactorStatus)2; val.verifyFailed = false; pReactorState state = val; terminal.ConnectedReactor.m_stateReplicator.State = state; terminal.AddLine($"Jumping to reactor wave #{result}", true); return; } terminal.AddLine($"Skipping to reactor wave #{result} has not been unlocked!", true); } } IEnumerable enumerable = Enumerable.Range(stateCount + 1, terminal.ConnectedReactor.m_waveCountMax - stateCount).Where(hasWave); if (enumerable.Any()) { terminal.AddLine("Waves you may currently skip to: " + string.Join(", ", enumerable), true); } else { terminal.AddLine("Waves you may currently skip to: None", true); } bool hasWave(int count) { if (data.TryLookupItem(ReactorStartup_SkipItem.MakeTag(data, count), out var item)) { return stateTracker.CollectedItemCounts.GetValueOrDefault(item.ID, 0) > 0; } FeatureLogger.Error($"Failed to get reactor skip item for wave: {count}"); return false; } } } public class ProgressionObjective_ReactorStartup : CustomObjectiveHandler.ObjectiveItem { public static string MakeKey(Objective.Data data, LG_WardenObjective_Reactor reactor) { return data.ObjectiveName() + ((Il2CppObjectBase)reactor).Pointer; } public static void Setup(Objective.Data data, LG_WardenObjective_Reactor reactor) { CustomObjectiveHandler.GetObjectiveItem(MakeKey(data, reactor)).SetupWithData(data, reactor); } public static void Update(Objective.Data data, LG_WardenObjective_Reactor reactor) { CustomObjectiveHandler.GetObjectiveItem(MakeKey(data, reactor)).UpdateInternal(data, reactor); } public override void Setup() { base.IsActive = false; base.Scope = CustomObjectiveHandler.eObjectiveScope.Layer; base.ObjectiveTag = "CODES"; base.HeaderText = "REACTOR STARTUP OBJECTIVE"; base.SubText = "Retrieving data..."; base.Setup(); } public void SetupWithData(Objective.Data data, LG_WardenObjective_Reactor reactor) { //IL_0014: 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_0025: Unknown result type (might be due to invalid IL or missing references) base.HeaderText = data.ObjectiveName(); base.ScopeTarget = new GlobalZoneIndex((eDimensionIndex)data.LayerType, (LG_LayerType)data.LayerType, (eLocalZoneIndex)0); Refresh(); } public void UpdateInternal(Objective.Data data, LG_WardenObjective_Reactor reactor) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0024: Invalid comparison between Unknown and I4 base.IsActive = (int)reactor.m_stateReplicator.State.status != 0 && (int)reactor.m_stateReplicator.State.status != 5; base.SubText = MakeFormattedText(data, reactor); Refresh(); } private string MakeFormattedText(Objective.Data data, LG_WardenObjective_Reactor reactor) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) Objective.Data data2 = data; StateTracker stateTracker = StateTracker.Get(); int currentWave = Math.Max(reactor.m_stateReplicator.State.stateCount, 1); int waveCountMax = reactor.m_waveCountMax; List codes = ((IEnumerable)CustomExtensions.RangeSubset((Il2CppArrayBase)(object)reactor.GetOverrideCodes(), 0, waveCountMax)).Select(formatCode).ToList(); int num = currentWave; IEnumerable values = ((waveCountMax < 6) ? codes : ((num < 4) ? (from i in Enumerable.Range(0, 4) select codes[i]).Append(" ···") : ((waveCountMax - num >= 3) ? (from i in Enumerable.Range(num - 2, 3) select codes[i]).Prepend(" ···").Append(" ···") : (from i in Enumerable.Range(waveCountMax - 4, 4) select codes[i]).Prepend(" ···")))); return string.Join("\n> ", values); string formatCode(string code, int index) { bool flag = false; if (data2.TryLookupLocation(ReactorStartup_CodeLocation.MakeTag(data2, index + 1), out var location)) { flag = stateTracker.CollectedItemCounts.GetValueOrDefault(location.ItemID, 0) > 0 || !location.Location.RandMode.IsTreatedAsRandom; } else { FeatureLogger.Error($"Failed to lookup code location #{index + 1} during code UI formatting"); } string value = (flag ? code : "––-–"); return $"Wave #{index + 1} Code: {value}{((index + 1 == currentWave) ? " <" : "")}"; } } } private static IArchiveLogger? m_featureLogger; private SkipToWaveSubcommand? m_skipToWaveCommand; private const string NotACode = "––-–"; public override string Name => "Reactor Startup Handler"; public override string Description => "Handles the Reactor Startup objective type.\nExample: R1C1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public override void OnEnable() { base.OnEnable(); APCommandHandler.RegisterCommand(m_skipToWaveCommand ?? (m_skipToWaveCommand = new SkipToWaveSubcommand())); } public override void OnDisable() { base.OnDisable(); APCommandHandler.UnregisterCommand(m_skipToWaveCommand ?? (m_skipToWaveCommand = new SkipToWaveSubcommand())); } public static KeyedItem GetReactorItem(Objective.Data data) { if (data.TryLookupItem(ReactorStartup_ReactorItem.MakeTag(data), out var item)) { return item; } Item item2 = new ReactorStartup_ReactorItem(data); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetCodeItem(Objective.Data data, int count) { if (data.TryLookupItem(ReactorStartup_CodeItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new ReactorStartup_CodeItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetSkipItem(Objective.Data data, int count) { if (data.TryLookupItem(ReactorStartup_SkipItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new ReactorStartup_SkipItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleReactorStartupObjective(Objective.Data data) { //IL_02ef: Unknown result type (might be due to invalid IL or missing references) Objective.Data data2 = data; if (!This.IsCorrectObjective(data2)) { return; } int count = 0; KeyedItem reactorItem = GetReactorItem(data2); foreach (ZonePlacementData item in data2.ObjectiveData.ZonePlacementDatas.SelectMany((List ps) => ps.Iter())) { Zone.Data data3 = data2.FindZoneByPlacement(item); if (data3 == null) { FeatureLogger.Error("Failed to find reactor zone by placement: " + data2.ObjectiveName()); } else { addReactor(data3); } } if (count == 0) { foreach (Zone.Data item2 in Zone.get_AllZones(data2)) { if (item2.CustomGeo != null && !item2.CustomGeo.Contains("hall", StringComparison.OrdinalIgnoreCase) && item2.CustomGeo.Contains("reactor", StringComparison.OrdinalIgnoreCase)) { FeatureLogger.Debug("Using geomorph for reactor objective: " + data2.ObjectiveName()); addReactor(item2); break; } } if (count == 0) { FeatureLogger.Error("No reactor placements: " + data2.ObjectiveName()); } } RegionID startingRegion = data2.ObjectiveStartRegion; ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem pathReqs = reactorItem.PathReqs; count = 0; foreach (ReactorWaveData item3 in data2.Objective.ReactorWaves.Iter()) { int num = count + 1; count = num; string text = ThisRegions.SurvivedWave(data2, count); RegionID regionID = data2.LookupOrCreateRegion(text); data2.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID, ReqItem = pathReqs, ReqCount = 1u }); startingRegion = regionID; Objective.Data layerData = data2; ReactorWaveData val = item3; layerData.ProcessEvents(regionID, text, val.Events ?? (val.Events = new List(1))); KeyedItem skipItem = GetSkipItem(data2, count); data2.AddLocation(ReactorStartup_SkipLocation.MakeTag(data2, count), regionID, ReactorStartup_SkipLocation.MakeRandData(), skipItem.ID); KeyedItem codeItem = GetCodeItem(data2, count); pathReqs = codeItem.PathReqs; RegionList regions; if (item3.VerifyInOtherZone) { Zone.Data zoneData = data2.FindZoneByIndex(item3.ZoneForVerification) ?? throw new NullReferenceException("Failed to find zone for reactor code placement!"); regions = (from t in Terminal.get_TerminalDatas(zoneData) select data2.LookupOrCreateRegion(t.TerminalName)).ToList(); } else { regions = regionID; } data2.AddLocation(ReactorStartup_CodeLocation.MakeTag(data2, count), regions, ReactorStartup_CodeLocation.MakeRandData(), codeItem.ID); } Event.Wrapper wrapper = data2.MakeOrWrapOnSolveEvents(); count = 0; while (!wrapper.IsDone) { int num = count + 1; count = num; string text2 = ThisRegions.CompletedStartup(data2, count); RegionID regionID2 = data2.LookupOrCreateRegion(text2); data2.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID2, ReqItem = pathReqs, ReqCount = 1u }); pathReqs = reactorItem.PathReqs; startingRegion = regionID2; wrapper.Process(regionID2, text2); } if (!data2.Objective.DoNotSolveObjectiveOnReactorComplete) { SharedObjectiveHandler.AddObjectiveCompleteItem(data2, data2.LookupOrCreateRegion(ThisRegions.CompletedStartup(data2))); } void addReactor(Zone.Data zone) { int num2 = count + 1; count = num2; RegionList regions2 = data2.LookupOrCreateRegion(zone.ZoneName); data2.AddLocation(ReactorStartup_ReactorLocation.MakeTag(data2, count), regions2, ReactorStartup_ReactorLocation.MakeRandData(), reactorItem.ID); } } } public static class ReactorShutdownHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorShutdownReactorLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ReactorShutdownReactorItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ReactorShutdownReactorLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Shutdown Reactor Locations", "Locations checked by finding a reactor shutdown reactor", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ReactorShutdownReactorItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Reactor Shutdown Reactors", "Items representing a reactor used for a reactor shutdown objective", RootRandomizationTags.get_Tag_Never(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ReactorShutdownHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 2; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return "Reactor Shutdown"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 2; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)2)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string CompletedShutdown(Objective.Data data, int count) { return $"{data.ObjectiveName()} Completed {count} Reactor Startup"; } } private static class ReactorShutdownReactorLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Reactor #{count} Location", "A particular reactor location", ReactorShutdownHandler_Tags.get_Tag_ReactorShutdownReactorLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class ReactorShutdownReactorItem : Item { public Objective.Data ObjectiveData { get; set; } public ReactorShutdownReactorItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Reactor", "A particular reactor", ReactorShutdownHandler_Tags.get_Tag_ReactorShutdownReactorItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Reactor Shutdown Handler"; public override string Description => "Handles the Reactor Shutdown Startup objective type.\nExample: R1D1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetReactorItem(Objective.Data data) { if (data.TryLookupItem(ReactorShutdownReactorItem.MakeTag(data), out var item)) { return item; } Item item2 = new ReactorShutdownReactorItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleReactorShutdownObjective(Objective.Data data) { Objective.Data data2 = data; if (!This.IsCorrectObjective(data2)) { return; } int count = 0; KeyedItem reactorItem = GetReactorItem(data2); foreach (ZonePlacementData item in data2.ObjectiveData.ZonePlacementDatas.SelectMany((List ps) => ps.Iter())) { Zone.Data data3 = data2.FindZoneByPlacement(item); if (data3 == null) { FeatureLogger.Error("Failed to find reactor zone by placement: " + data2.ObjectiveName()); } else { addReactor(data3); } } if (count == 0) { foreach (Zone.Data item2 in Zone.get_AllZones(data2)) { string? customGeo = item2.CustomGeo; if (customGeo != null && customGeo.Contains("_reactor_", StringComparison.OrdinalIgnoreCase)) { FeatureLogger.Debug("Using geomorph for reactor objective: " + data2.ObjectiveName()); addReactor(item2); break; } } if (count == 0) { FeatureLogger.Error("No reactor placements: " + data2.ObjectiveName()); } } if (!data2.Objective.OnActivateOnSolveItem) { data2.Objective.OnActivateOnSolveItem = true; data2.Objective.EventsOnActivate?.Clear(); } Event.Wrapper wrapper = data2.MakeOrWrapOnSolveEvents(); count = 0; while (!wrapper.IsDone) { int num = count + 1; count = num; string text = ThisRegions.CompletedShutdown(data2, count); RegionID regionID = data2.LookupOrCreateRegion(text); data2.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data2.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = reactorItem.PathReqs, ReqCount = (uint)count }); wrapper.Process(regionID, text); } if (!data2.Objective.DoNotSolveObjectiveOnReactorComplete) { SharedObjectiveHandler.AddObjectiveCompleteItem(data2, data2.LookupOrCreateRegion(ThisRegions.CompletedShutdown(data2, 1))); } void addReactor(Zone.Data zone) { int num2 = count + 1; count = num2; data2.AddLocation(ReactorShutdownReactorLocation.MakeTag(data2, count), data2.LookupOrCreateRegion(zone.ZoneName), ReactorShutdownReactorLocation.MakeRandData(), reactorItem.ID); } } } public static class GatherSmallItemsHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GatherItemsLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GatherItemsItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_GatherItemsItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_GatherItemsLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Small Objective Items Spawn Locations", "Locations checked by picking up small objective items (for example, PIDs)", PickupHelper_Tags.get_Tag_SmallPickupLocations(gd))); } public static TagResolver get_Tag_GatherItemsItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Small Objective Items", "Items granting progress toward a \"Gather Small Items\" objective", PickupHelper_Tags.get_Tag_SmallPickupItems(gd))); } public static TagResolver get_Tag_GatherItemsItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Small Objective Items", "Items granting progress toward a particular objective", get_Tag_GatherItemsItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] [InjectToIl2Cpp] public class GatherSmallItemsHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 3; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); ItemDataBlock block = GameDataBlockBase.GetBlock(data.Objective.Gather_ItemId); if (block == null) { FeatureLogger.Error("Failed to find gather item datablock for objective: " + data.ObjectiveName()); } return $"Gather {data.Objective.Gather_RequiredCount}x \"{((block != null) ? block.publicName : null) ?? "null!"}\""; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 3; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)3)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string FoundItem(Objective.Data data, int count) { return $"{data.ObjectiveName()} Found {count} Items"; } } private static class GatherSmall_SpawnLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Spawn Spot #{count}", "A particular small objective pickup spawn location", GatherSmallItemsHandler_Tags.get_Tag_GatherItemsLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private class GatherSmall_Item : Item { [CompilerGenerated] private sealed class <>c__DisplayClass15_0 { public LG_ComputerTerminal terminal; public AsyncItemSpawnWrapper wrapper; public StateTracker stateTracker; public GatherSmall_Item <>4__this; public SNet_Player player; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving your small pickup...", 2f); } internal void b__1() { //IL_00a8: 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_00b1: 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_00ba: 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) ISyncedItem? item = wrapper.Item; GenericSmallPickupItem_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { if (SNet.IsMaster) { stateTracker.AddItemToTerminal(<>4__this); FeatureLogger.Error("Failed to spawn small pickup!"); terminal.AddLine("<#F00>Failed to retrieve small pickup! It has been re-added to terminal system.", true); wrapper.QueueDespawn(); } } else { val.SetupFromLevelgen(0, true); val._SpawnNode_k__BackingField = <>4__this.ObjectiveData.GetLG_Layer().m_zones[0].m_courseNodes[0]; val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); terminal.AddLine("Pickup \"" + ((Item)val).PublicName + "\" has been given to " + player.NickName, true); } } } [CompilerGenerated] private sealed class d__15 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public GatherSmall_Item <>4__this; private <>c__DisplayClass15_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0079: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; GatherSmall_Item gatherSmall_Item = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass15_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; <>8__1.wrapper = new AsyncItemSpawnWrapper(); pItemData val = default(pItemData); val.itemID_gearCRC = gatherSmall_Item.ObjectiveData.Objective.Gather_ItemId; val.originCourseNode = default(pCourseNode); val.originLayer = gatherSmall_Item.ObjectiveData.LayerType; pItemData val2 = val; ((pCourseNode)(ref val2.originCourseNode)).Set(gatherSmall_Item.ObjectiveData.GetLG_Layer().m_zones[0].m_courseNodes[0]); if (SNet.IsMaster) { ItemReplicationManager.SpawnItem(val2, delItemCallback.op_Implicit((Action)<>8__1.wrapper.OnSpawn), (ItemMode)2, Vector3.zero, Quaternion.identity, (AIG_CourseNode)null, (PlayerAgent)null); } <>8__1.player = <>8__1.terminal.m_syncedInteractionSource.Owner; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving your small pickup...", 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { //IL_00a8: 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_00b1: 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_00ba: 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) ISyncedItem? item = <>8__1.wrapper.Item; GenericSmallPickupItem_Core val3 = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val3 == (Object)null) { if (SNet.IsMaster) { <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); FeatureLogger.Error("Failed to spawn small pickup!"); <>8__1.terminal.AddLine("<#F00>Failed to retrieve small pickup! It has been re-added to terminal system.", true); <>8__1.wrapper.QueueDespawn(); } } else { val3.SetupFromLevelgen(0, true); val3._SpawnNode_k__BackingField = <>8__1.<>4__this.ObjectiveData.GetLG_Layer().m_zones[0].m_courseNodes[0]; val3.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)0, <>8__1.player, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false); <>8__1.terminal.AddLine("Pickup \"" + ((Item)val3).PublicName + "\" has been given to " + <>8__1.player.NickName, true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__15 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__15(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, GatherSmallItemsHandler_Tags.get_Tag_GatherItemsItems_PerObjective(ObjectiveData)); public Objective.Data ObjectiveData { get; set; } public bool IsEmpty { get; set; } public GatherSmall_Item(Objective.Data data, bool isEmpty) : base(MakeTag(data, isEmpty), MakeRandData()) { ObjectiveData = data; IsEmpty = isEmpty; } public static TagResolver MakeTag(Objective.Data data, bool isEmpty) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " " + (isEmpty ? "Empty " : "Pickup"), "A particular small objective pickup item", GatherSmallItemsHandler_Tags.get_Tag_GatherItemsItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (!IsEmpty && ObjectiveData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (!IsEmpty && ObjectiveData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__15))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } private class ZonePlacementEqualityComparer : IEqualityComparer { public bool Equals(ZonePlacementData? x, ZonePlacementData? y) { //IL_000f: 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_0036: 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_0067: 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) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (((x != null) ? new eLocalZoneIndex?(x.LocalIndex) : null) == ((y != null) ? new eLocalZoneIndex?(y.LocalIndex) : null)) { return ((x != null) ? new eDimensionIndex?(x.DimensionIndex) : null) == ((y != null) ? new eDimensionIndex?(y.DimensionIndex) : null); } return false; } public int GetHashCode(ZonePlacementData obj) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Tuple.Create(obj.LocalIndex, obj.DimensionIndex).GetHashCode(); } } [InjectToIl2Cpp] private class GatherSmall_FreeLcoationsComp : MonoBehaviour { public List LocationIDs = new List(0); public GatherSmall_FreeLcoationsComp(IntPtr ptr) : base(ptr) { } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_WardenObjective__BuildWardenObjective__Patch { public static void Postfix(LG_Distribute_WardenObjective __instance, int chainIndex) { //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown Objective.Data data = Layer.Data.FromLayer(__instance.m_layer).GetObjectiveDatas().ElementAt(chainIndex); if (!This.IsCorrectObjective(data)) { return; } Dictionary> dictionary = new Dictionary>(); int num = 0; List placements; int num2 = CalcEmptySpots(data, out placements); foreach (ZonePlacementData item in placements) { LG_Zone lG_Zone = data.FindZoneByPlacement(item).GetLG_Zone(); dictionary.Add(((Il2CppObjectBase)lG_Zone).Pointer, Tuple.Create(num++, 0)); } int gather_MaxPerZone = __instance.m_dataBlockData.Gather_MaxPerZone; int num3 = placements.Count * gather_MaxPerZone; int gather_SpawnCount = __instance.m_dataBlockData.Gather_SpawnCount; Queue jobQueue = LG_Factory.Current.m_currentBatch.Jobs; int start = jobQueue._head + jobQueue._size - gather_SpawnCount; IEnumerable enumerable = from i in Enumerable.Range(start, gather_SpawnCount) select jobQueue._array[i]; foreach (LG_FactoryJob item2 in enumerable) { LG_Distribute_PickupItemsPerZone val = ((Il2CppObjectBase)item2).Cast(); Tuple tuple = dictionary[((Il2CppObjectBase)val.m_zone).Pointer]; tuple = Tuple.Create(tuple.Item1, tuple.Item2 + 1); dictionary[((Il2CppObjectBase)val.m_zone).Pointer] = tuple; num = ((tuple.Item2 <= gather_MaxPerZone) ? (tuple.Item1 * gather_MaxPerZone + tuple.Item2) : (++num3)); if (!data.TryLookupLocation(GatherSmall_SpawnLocation.MakeTag(data, num), out var location)) { FeatureLogger.Error("Failed to lookup small gather item during association!"); } else { PickupHelper.AssociateDistributionWithLocation(val, location.ID); } } foreach (KeyValuePair> item3 in dictionary) { if (item3.Value.Item2 >= gather_MaxPerZone) { continue; } LG_Zone val2 = new LG_Zone(item3.Key); num = item3.Value.Item2; GatherSmall_FreeLcoationsComp gatherSmall_FreeLcoationsComp = ((Component)val2).gameObject.AddComponent(); gatherSmall_FreeLcoationsComp.LocationIDs = new List(gather_MaxPerZone - num); while (num++ < gather_MaxPerZone) { if (data.TryLookupLocation(GatherSmall_SpawnLocation.MakeTag(data, item3.Value.Item1 * gather_MaxPerZone + num), out var location2)) { gatherSmall_FreeLcoationsComp.LocationIDs.Add(location2.ID); } else { FeatureLogger.Error("Failed to find location(s) while generating free locations comp"); } } } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerAgent__SetCourseNode__Patch { public static void Prefix(PlayerAgent __instance, AIG_CourseNode courseNode) { IntPtr? obj; if (__instance == null) { obj = null; } else { AIG_CourseNode courseNode2 = ((Agent)__instance).CourseNode; if (courseNode2 == null) { obj = null; } else { LG_Zone zone = courseNode2.m_zone; obj = ((zone != null) ? new IntPtr?(((Il2CppObjectBase)zone).Pointer) : null); } } IntPtr intPtr = obj ?? IntPtr.Zero; IntPtr? obj2; if (courseNode == null) { obj2 = null; } else { LG_Zone zone2 = courseNode.m_zone; obj2 = ((zone2 != null) ? new IntPtr?(((Il2CppObjectBase)zone2).Pointer) : null); } if (intPtr != (obj2 ?? IntPtr.Zero)) { object obj3; if (courseNode == null) { obj3 = null; } else { LG_Zone zone3 = courseNode.m_zone; obj3 = ((zone3 != null) ? ((Component)zone3).GetComponent() : null); } GatherSmall_FreeLcoationsComp gatherSmall_FreeLcoationsComp = (GatherSmall_FreeLcoationsComp)obj3; if ((Object)(object)gatherSmall_FreeLcoationsComp != (Object)null) { StateTracker.Get().NotifyFoundLocations(gatherSmall_FreeLcoationsComp.LocationIDs, __instance); Object.Destroy((Object)(object)gatherSmall_FreeLcoationsComp); } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Gather Small Pickups Handler"; public override string Description => "Handles the GatherSmallItems objective type.\nExample: R1B1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetItem(Objective.Data data, bool isEmpty) { if (data.TryLookupItem(GatherSmall_Item.MakeTag(data, isEmpty), out var item)) { return item; } Item item2 = new GatherSmall_Item(data, isEmpty); return new KeyedItem(data.AddItem(item2), item2); } public static int CalcEmptySpots(Objective.Data data, out List placements) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (data.ObjectiveData.ZonePlacementDatas.Count == 0) { placements = new List(1) { new ZonePlacementData() }; } else { placements = data.ObjectiveData.ZonePlacementDatas.SelectMany((List ps) => ps.Iter()).Distinct(new ZonePlacementEqualityComparer()).ToList(); } if (data.Objective.Gather_MaxPerZone <= 0) { throw new ArgumentException($"{data.ObjectiveName()}: Expected positive MaxPerZone, got {data.Objective.Gather_MaxPerZone}"); } int num = placements.Count * data.Objective.Gather_MaxPerZone; int num2 = num - data.Objective.Gather_SpawnCount; if (num2 < 0) { num2 = 0; } return num2; } [Objective.Callback] public void HandleGatherSmallItemsObjective(Objective.Data data) { if (!This.IsCorrectObjective(data)) { return; } List placements; int num = CalcEmptySpots(data, out placements); KeyedItem item = GetItem(data, isEmpty: false); KeyedItem keyedItem = ((num > 0) ? GetItem(data, isEmpty: true) : default(KeyedItem)); int num2 = 0; foreach (ZonePlacementData item2 in placements) { RegionID regionID = data.LookupOrCreateRegion(data.FindZoneByPlacement(item2).ZoneName); for (int i = 0; i < data.Objective.Gather_MaxPerZone; i++) { RandomizationTag nameTag = GatherSmall_SpawnLocation.MakeTag(data, ++num2); RegionList regions = regionID; LocationData randData = GatherSmall_SpawnLocation.MakeRandData(); KeyedItem obj = ((num2 <= num) ? keyedItem : item); data.AddLocation(nameTag, regions, randData, obj.ID); } } if (num2 < data.Objective.Gather_SpawnCount) { RegionList regions2 = (from info in ((Layer.Data)data).PlacementsToZoneRegions((IEnumerable)placements) select info.Region).ToList(); while (num2 < data.Objective.Gather_SpawnCount) { RandomizationTag nameTag2 = GatherSmall_SpawnLocation.MakeTag(data, ++num2); LocationData randData2 = GatherSmall_SpawnLocation.MakeRandData(); KeyedItem obj2 = ((num2 <= num) ? keyedItem : item); data.AddLocation(nameTag2, regions2, randData2, obj2.ID); } } string regionName = ThisRegions.FoundItem(data, 0); RegionID regionID2 = data.LookupOrCreateRegion(regionName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.StartingRegion = data.ObjectiveStartRegion; path.EndingRegion = regionID2; ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; if (num > 0) { path2.ReqItem = item.PathReqs; path2.ReqCount = (uint)num; } data.AddPath(path2); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID startingRegion = regionID2; for (int j = 1; j <= data.Objective.Gather_SpawnCount; j++) { regionName = ThisRegions.FoundItem(data, j); regionID2 = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID2, ReqItem = item.PathReqs, ReqCount = 1u }); startingRegion = regionID2; if (j == data.Objective.Gather_RequiredCount) { SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID2); } wrapper.Process(regionID2, regionName, extendIfNecessary: true); } } } [EnableFeatureByDefault] [AutomatedFeature] public class ClearAPathHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 4; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return "Clear a Path"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 4; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)4)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string PathCleared(Objective.Data data) { return data.ObjectiveName() + " Path Cleared"; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Clear a Path Handler"; public override string Description => "Handles the ClearAPath objective type.\nExample: R2B1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } [Objective.Callback] public void HandleClearAPathObjective(Objective.Data data) { if (This.IsCorrectObjective(data)) { string regionName = ThisRegions.PathCleared(data); RegionID regionID = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = ExtractionHandler.GetExtractionReachableItem(data).PathReqs, ReqCount = 1u }); SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } } } public static class SpecialTerminalCommandHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SpecialCommandLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SpecialCommandItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_SpecialCommandLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Special Command Locations", "Locations checked by executing special command objectives' commands", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_SpecialCommandItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Special Command Items", "Items awared for executing special command objectives' commands", RootRandomizationTags.get_Tag_Never(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class SpecialTerminalCommandHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 5; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return "Execute Command " + data.Objective.SpecialTerminalCommand; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 5; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)5)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string CommandExecuted(Objective.Data data) { return data.ObjectiveName() + " Command Executed"; } } private static class STCLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Special Command Location", "A special command location for a particular objective", SpecialTerminalCommandHandler_Tags.get_Tag_SpecialCommandLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class STCItem : Item { public Objective.Data ObjectiveData { get; set; } public STCItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Special Command Item", "A special command item for a particular objective", SpecialTerminalCommandHandler_Tags.get_Tag_SpecialCommandItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Special Terminal Command Handler"; public override string Description => "Handles the SpecialTerminalCommand objective type.\nThis objective type refers only to when you need to enter a single special command.\nExamples: R5A1 Main, R8E1 secondary"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetItem(Objective.Data data) { if (data.TryLookupItem(STCItem.MakeTag(data), out var item)) { return item; } Item item2 = new STCItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleSpecialTerminalCommandObjective(Objective.Data data) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (This.IsCorrectObjective(data)) { IEnumerable placements = data.ObjectiveData.ZonePlacementDatas.FirstOrDefault>()?.Iter() ?? Enumerable.Repeat(new ZonePlacementData(), 1); IEnumerable source = from info in data.PlacementsToTerminalRegions(placements) select info.Region; KeyedItem item = GetItem(data); data.AddLocation(STCLocation.MakeTag(data), source.ToArray(), STCLocation.MakeRandData(), item.ID); string text = ThisRegions.CommandExecuted(data); RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = item.PathReqs, ReqCount = 1u }); Event.Wrapper wrapper = data.WrapOnActivateEvents(); wrapper.Process(regionID, text); SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } } } public static class RetrieveBigItemsHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_BigRetrievalLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_BigRetrievalItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_BigRetrievalLocations_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_BigRetrievalItems_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_BigRetrievalLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Big Retrieval Locations", "Locations checked by picking up big retrieval objective items, IE in R2A1", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } public static TagResolver get_Tag_BigRetrievalItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Big Retrieval Items", "Big pickup items marked as retrieval objective items, IE the cargos in R2A1", PickupHelper_Tags.get_Tag_BigPickupItems(gd))); } public static TagResolver get_Tag_BigRetrievalLocations_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Big Retrieval Locations", "Locations checked by picking up big retrieval items for a particular objective", get_Tag_BigRetrievalLocations(gd))); } public static TagResolver get_Tag_BigRetrievalItems_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Big Retrieval Items", "Big pickup items marked as big retrieval items for a particular objective", get_Tag_BigRetrievalItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class RetrieveBigItemsHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 6; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Retrieve {data.Objective.Retrieve_Items.Count}x Big Items"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 6; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)6)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string RetrievedItem(Objective.Data data, int count) { return $"{data.ObjectiveName()} {count} Big Items Retrieved"; } } private static class BigRetrieval_Location { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Retrieval Location #{count}", "A location containing a particular retrieval target", RetrieveBigItemsHandler_Tags.get_Tag_BigRetrievalLocations_ByObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private class BigRetrieval_Item : Item { [CompilerGenerated] private sealed class <>c__DisplayClass16_0 { public LG_ComputerTerminal terminal; public string itemName; public AsyncItemSpawnWrapper wrapper; public StateTracker stateTracker; public BigRetrieval_Item <>4__this; public PlayerAgent player; public Vector3 position; public Quaternion rotation; public AIG_CourseNode node; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving " + itemName, 2f); } internal void b__1() { //IL_00ba: 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) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass16_1 CS$<>8__locals0 = new <>c__DisplayClass16_1 { CS$<>8__locals1 = this }; ISyncedItem? item = wrapper.Item; CarryItemPickup_Core val = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val == (Object)null) { wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn " + itemName + "!"); stateTracker.AddItemToTerminal(<>4__this); terminal.AddLine("<#F00>Failed to retrieve " + itemName + "! It has been re-added to terminal system.", true); return; } val.SpawnNode = <>4__this.Data.GetLG_Layer().m_zones[0].m_courseNodes[0]; ((Item)val).Set_pItemData(new pItemData { itemID_gearCRC = ((Item)val).pItemData.itemID_gearCRC, originLayer = <>4__this.Data.LayerType }); val.m_isWardenObjective = true; CS$<>8__locals0.items = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)<>4__this.Data.LayerType, <>4__this.Data.ObjectiveIndex); CP_Bioscan_Core val2 = ((WardenObjectiveManager.m_customGeoExitWinConditionItem == null) ? ((Il2CppObjectBase)((Il2CppArrayBase)(object)((Il2CppObjectBase)WardenObjectiveManager.m_elevatorExitWinConditionItem).Cast().m_puzzle.m_chainedPuzzleCores)[0]).TryCast() : ((Il2CppObjectBase)((Il2CppArrayBase)(object)((Il2CppObjectBase)WardenObjectiveManager.m_customGeoExitWinConditionItem).Cast().m_puzzle.m_chainedPuzzleCores)[0]).TryCast()); if ((Object)(object)val2 == (Object)null || val2.m_reqItems.Any((iWardenObjectiveItem i) => ((Il2CppObjectBase)i).Pointer == ((Il2CppObjectBase)CS$<>8__locals0.items[CS$<>8__locals0.CS$<>8__locals1.<>4__this.ItemIndex]).Pointer)) { Il2CppReferenceArray val3 = new Il2CppReferenceArray(1L) { [0] = CS$<>8__locals0.items[<>4__this.ItemIndex] }; Il2CppReferenceArray val4 = new Il2CppReferenceArray(1L) { [0] = ((Il2CppObjectBase)val).Cast() }; WardenObjectiveManager.RemoveObjectiveItemAsRequiredForExitScan(val3); WardenObjectiveManager.AddObjectiveItemAsRequiredForExitScan(true, val4); } CS$<>8__locals0.items[<>4__this.ItemIndex] = ((Il2CppObjectBase)val).Cast(); val.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)1, player.Owner, default(pItemData_Custom), position, rotation, node, true, true); val.m_navMarkerPlacer.SetMarkerVisible(true); val.m_terminalItem.PlayPing(); terminal.AddLine(itemName + " has been placed somewhere nearby", true); } } [CompilerGenerated] private sealed class <>c__DisplayClass16_1 { public List items; public <>c__DisplayClass16_0 CS$<>8__locals1; internal bool b__2(iWardenObjectiveItem i) { return ((Il2CppObjectBase)i).Pointer == ((Il2CppObjectBase)items[CS$<>8__locals1.<>4__this.ItemIndex]).Pointer; } } [CompilerGenerated] private sealed class d__16 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public BigRetrieval_Item <>4__this; private <>c__DisplayClass16_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0188: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; BigRetrieval_Item bigRetrieval_Item = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass16_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; ItemDataBlock block = GameDataBlockBase.GetBlock(bigRetrieval_Item.Data.Objective.Retrieve_Items[bigRetrieval_Item.ItemIndex]); <>8__1.itemName = $"Big Pickup #{((GameDataBlockBase)(object)block)?.persistentID ?? 0} \"{((block != null) ? block.publicName : null) ?? "null"}\""; <>8__1.wrapper = bigRetrieval_Item.TrySpawnAsync(); <>8__1.node = <>8__1.terminal.SpawnNode; Random random = new Random(Guid.NewGuid().GetHashCode()); <>8__1.player = <>8__1.terminal.m_syncedInteractionSource; <>8__1.position = <>8__1.player.FPSCamera.Position; Vector3 flatRight = ((LookCameraController)<>8__1.player.FPSCamera).FlatRight; Vector3 val = Quaternion.AngleAxis(30f + random.NextSingle() * 120f, Vector3.up) * flatRight; Quaternion val2 = Quaternion.FromToRotation(val, Vector3.down); Quaternion val3 = Quaternion.Lerp(Quaternion.identity, val2, 0.4f + random.NextSingle() * 0.4f); Vector3 val4 = val3 * val; RaycastHit val5 = default(RaycastHit); if (Physics.Raycast(<>8__1.position, val4, ref val5, 10f, 1)) { <>8__1.position = ((RaycastHit)(ref val5)).point; } <>8__1.rotation = Quaternion.AngleAxis(360f * random.NextSingle(), Vector3.up); <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving " + <>8__1.itemName, 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { //IL_00ba: 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) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass16_1 CS$<>8__locals0 = new <>c__DisplayClass16_1 { CS$<>8__locals1 = <>8__1 }; ISyncedItem? item = <>8__1.wrapper.Item; CarryItemPickup_Core val6 = ((item != null) ? ((Il2CppObjectBase)item).TryCast() : null); if ((Object)(object)val6 == (Object)null) { <>8__1.wrapper.QueueDespawn(); FeatureLogger.Error("Failed to spawn " + <>8__1.itemName + "!"); <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); <>8__1.terminal.AddLine("<#F00>Failed to retrieve " + <>8__1.itemName + "! It has been re-added to terminal system.", true); } else { val6.SpawnNode = <>8__1.<>4__this.Data.GetLG_Layer().m_zones[0].m_courseNodes[0]; ((Item)val6).Set_pItemData(new pItemData { itemID_gearCRC = ((Item)val6).pItemData.itemID_gearCRC, originLayer = <>8__1.<>4__this.Data.LayerType }); val6.m_isWardenObjective = true; CS$<>8__locals0.items = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)<>8__1.<>4__this.Data.LayerType, <>8__1.<>4__this.Data.ObjectiveIndex); CP_Bioscan_Core val7 = ((WardenObjectiveManager.m_customGeoExitWinConditionItem == null) ? ((Il2CppObjectBase)((Il2CppArrayBase)(object)((Il2CppObjectBase)WardenObjectiveManager.m_elevatorExitWinConditionItem).Cast().m_puzzle.m_chainedPuzzleCores)[0]).TryCast() : ((Il2CppObjectBase)((Il2CppArrayBase)(object)((Il2CppObjectBase)WardenObjectiveManager.m_customGeoExitWinConditionItem).Cast().m_puzzle.m_chainedPuzzleCores)[0]).TryCast()); if ((Object)(object)val7 == (Object)null || val7.m_reqItems.Any((iWardenObjectiveItem i) => ((Il2CppObjectBase)i).Pointer == ((Il2CppObjectBase)CS$<>8__locals0.items[CS$<>8__locals0.CS$<>8__locals1.<>4__this.ItemIndex]).Pointer)) { Il2CppReferenceArray val8 = new Il2CppReferenceArray(1L) { [0] = CS$<>8__locals0.items[<>8__1.<>4__this.ItemIndex] }; Il2CppReferenceArray val9 = new Il2CppReferenceArray(1L) { [0] = ((Il2CppObjectBase)val6).Cast() }; WardenObjectiveManager.RemoveObjectiveItemAsRequiredForExitScan(val8); WardenObjectiveManager.AddObjectiveItemAsRequiredForExitScan(true, val9); } CS$<>8__locals0.items[<>8__1.<>4__this.ItemIndex] = ((Il2CppObjectBase)val6).Cast(); val6.m_sync.AttemptPickupInteraction((ePickupItemInteractionType)1, <>8__1.player.Owner, default(pItemData_Custom), <>8__1.position, <>8__1.rotation, <>8__1.node, true, true); val6.m_navMarkerPlacer.SetMarkerVisible(true); val6.m_terminalItem.PlayPing(); <>8__1.terminal.AddLine(<>8__1.itemName + " has been placed somewhere nearby", true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__16 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__16(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Objective.Data Data { get; set; } public int ItemIndex { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, RetrieveBigItemsHandler_Tags.get_Tag_BigRetrievalItems_ByObjective(Data)); public BigRetrieval_Item(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { Data = data; ItemIndex = count - 1; } public static RandomizationTag MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Retrieval Item #{count}", "A particular big retrieval item", RetrieveBigItemsHandler_Tags.get_Tag_BigRetrievalItems_ByObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } private AsyncItemSpawnWrapper TrySpawnAsync() { //IL_002c: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) AsyncItemSpawnWrapper asyncItemSpawnWrapper = new AsyncItemSpawnWrapper(); ItemDataBlock block = GameDataBlockBase.GetBlock(Data.Objective.Retrieve_Items[ItemIndex]); if (block != null) { pItemData val = default(pItemData); val.itemID_gearCRC = ((GameDataBlockBase)(object)block).persistentID; ItemReplicationManager.SpawnItem(val, delItemCallback.op_Implicit((Action)asyncItemSpawnWrapper.OnSpawn), (ItemMode)2, Vector3.zero, Quaternion.identity, (AIG_CourseNode)null, (PlayerAgent)null); } return asyncItemSpawnWrapper; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (Data.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (Data.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__16))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_WardenObjective____c__DisplayClass8_1___DistributePickupItems_b__0__Patch { public static void Postfix(__c__DisplayClass8_1 __instance, LG_Zone zone) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 Objective.Data data = Layer.Data.FromLayerFlattened(zone.Layer).GetObjectiveDatas().ElementAt(__instance.field_Public___c__DisplayClass8_0_0.chainIndex); if ((int)data.Objective.Type == 6) { if (data.TryLookupLocation(BigRetrieval_Location.MakeTag(data, __instance.i + 1), out var location)) { PickupHelper.AssociateDistributionWithLocation(((Il2CppObjectBase)LG_Factory.Current.m_currentBatch.Jobs.FromEnd()).Cast(), location.ID); } else { FeatureLogger.Error("Failed to lookup big retrieval target location during association"); } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Retrieve Big Items Handler"; public override string Description => "Handles the RetrieveBigItems objective type.\nExample: R2A1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetItem(Objective.Data data, int count) { if (data.TryLookupItem(BigRetrieval_Item.MakeTag(data, count), out var item)) { return item; } Item item2 = new BigRetrieval_Item(data, count); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleRetrieveBigItemsObjective(Objective.Data data) { if (This.IsCorrectObjective(data)) { List> list = data.ObjectiveToZoneRegionSets(data.Objective.Retrieve_Items.Count).ToList(); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID regionID = data.ObjectiveStartRegion; for (int i = 1; i <= data.Objective.Retrieve_Items.Count; i++) { KeyedItem item = GetItem(data, i); data.AddLocation(BigRetrieval_Location.MakeTag(data, i), list[i - 1], BigRetrieval_Location.MakeRandData(), item.ID); string text = ThisRegions.RetrievedItem(data, i); RegionID regionID2 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2, ReqItem = item.PathReqs, ReqCount = 1u }); regionID = regionID2; wrapper.Process(regionID2, text); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } } } public static class PowerCellDistributionHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PowerCellDistributionCellLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PowerCellDistributionGenLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PowerCellDistributionGenItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_PowerCellDistributionCellLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_PowerCellDistributionGenLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_PowerCellDistributionGenItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_PowerCellDistributionCellLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("PowerCell Distribution Cell Locations", "Locations checked by picking up cells spawned for the PowerCell Distribution objective (always in the starting lift, if spawned)", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } public static TagResolver get_Tag_PowerCellDistributionGenLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("PowerCell Distribution Gen Locations", "Locations checked by finding generators for the PowerCell Distribution objective", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_PowerCellDistributionGenItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("PowerCell Distribution Gen Items", "Items indicating access to a PowerCell Distribution generator", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_PowerCellDistributionCellLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " PowerCell Distribution Cell Locations", "Locations checked by picking up cells spawned for a particular objective", get_Tag_PowerCellDistributionCellLocations(gd))); } public static TagResolver get_Tag_PowerCellDistributionGenLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " PowerCell Distribution Gen Locations", "Locations checked by finding generators for a particular objective", get_Tag_PowerCellDistributionGenLocations(gd))); } public static TagResolver get_Tag_PowerCellDistributionGenItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " PowerCell Distribution Gen Items", "Items indicating access to a PowerCell Distribution generator for a particular objective", get_Tag_PowerCellDistributionGenItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class PowerCellDistributionHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 7; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Distribute {data.Objective.PowerCellsToDistribute} Power Cells"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 7; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)7)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string CellFound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Obtained {count} Cells"; } public static string GeneratorPowered(Objective.Data data, int count) { return $"{data.ObjectiveName()} Powered {count} Generators"; } } private static class PowerCellDistribution_CellLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Cell Location #{count}", "A particular cell spawned for a particular objective", PowerCellDistributionHandler_Tags.get_Tag_PowerCellDistributionCellLocations_PerObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private static class PowerCellDistribution_GenLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Gen Location #{count}", "A particular generator spawn for a particular objective", PowerCellDistributionHandler_Tags.get_Tag_PowerCellDistributionGenLocations_PerObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class PowerCellDistribution_GenItem : Item { public Objective.Data ObjectiveData { get; set; } public int Count { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, PowerCellDistributionHandler_Tags.get_Tag_PowerCellDistributionGenItems_PerObjective(ObjectiveData)); public PowerCellDistribution_GenItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; Count = count; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Gen Item #{count}", "A particular generator for a particular objective", PowerCellDistributionHandler_Tags.get_Tag_PowerCellDistributionGenItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Factory__FactoryDone__Patch { public static void Postfix() { Objective.Data data = Layer.get_MainLayer(Expedition.Data.FromCurrentExpedition()).GetObjectiveDatas().First(); if (!This.IsCorrectObjective(data)) { return; } IEnumerable enumerable = ElevatorCage.Current.m_cargoCage.m_itemsToMoveToCargo.Iter(); if (data.Objective.GenericItemFromStart != 0) { enumerable = enumerable.Skip(1); } int num = 0; foreach (Transform item in enumerable) { if (!data.TryLookupLocation(PowerCellDistribution_CellLocation.MakeTag(data, ++num), out var location)) { FeatureLogger.Error("Failed to identify powercell distribution cell location during association!"); continue; } CarryItemPickup_Core componentInChildren = ((Component)item).GetComponentInChildren(); if (((GameDataBlockBase)(object)((Item)componentInChildren).ItemDataBlock).persistentID != BigPickupHandler.CellItemID) { FeatureLogger.Warning("Associated a non-cell item with distribution objective starting cell location!"); } PickupHelper.AssociateItem((ItemInLevel)(object)componentInChildren, location.ID); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Powercell Distribution Handler"; public override string Description => "Handles the PowerCellDistribution objective type.\nExample: R2B2"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetGenItem(Objective.Data data, int count) { if (data.TryLookupItem(PowerCellDistribution_GenItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new PowerCellDistribution_GenItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandlePowerCellDistributionObjective(Objective.Data data) { if (!This.IsCorrectObjective(data)) { return; } KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, BigPickupHandler.CellItemID); if (data.LayerType.IsMainLayer) { RegionID regionID = data.LookupOrCreateRegion(Zone.get_FirstZone(data).ZoneName); for (int i = 1; i <= data.Objective.PowerCellsToDistribute; i++) { data.AddLocation(PowerCellDistribution_CellLocation.MakeTag(data, i), regionID, PowerCellDistribution_CellLocation.MakeRandData(), bigPickupItem.ID); } } List> list = data.ObjectiveToZoneRegionSets(data.Objective.PowerCellsToDistribute).ToList(); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID regionID2 = data.ObjectiveStartRegion; for (int j = 1; j <= data.Objective.PowerCellsToDistribute; j++) { KeyedItem genItem = GetGenItem(data, j); data.AddLocation(PowerCellDistribution_GenLocation.MakeTag(data, j), list[j - 1], PowerCellDistribution_GenLocation.MakeRandData(), genItem.ID); RegionID regionID3 = data.LookupOrCreateRegion(ThisRegions.CellFound(data, j)); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = regionID3, ReqItem = bigPickupItem.PathReqs, ReqCount = 1u }); string text = ThisRegions.GeneratorPowered(data, j); RegionID regionID4 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID3, EndingRegion = regionID4, ReqItem = genItem.PathReqs, ReqCount = 1u }); regionID2 = regionID4; wrapper.Process(regionID4, text); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID2); } } public static class TerminalUplinkHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TerminalUplinkTerminalLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TerminalUplinkCompletionLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TerminalUplinkTerminalItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TerminalUplinkCompletionItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TerminalUplinkTerminalLocations_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TerminalUplinkCompletionLocations_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TerminalUplinkTerminalItems_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TerminalUplinkCompletionItems_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_TerminalUplinkTerminalLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Standard Uplink Terminal Locations", "Locations checked by finding an uplink terminal", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TerminalUplinkCompletionLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Standard Uplink Locations", "Locations checked by completing a standard uplink", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TerminalUplinkTerminalItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Standard Uplink Terminal Items", "Items indicating an uplink terminal is reachable", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TerminalUplinkCompletionItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Standard Uplink Completion Items", "Items indicating an uplink is completed", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TerminalUplinkTerminalLocations_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Standard Uplink Terminal Locations", "Locations checked by finding an uplink terminal for a particular objective", get_Tag_TerminalUplinkTerminalLocations(gd))); } public static TagResolver get_Tag_TerminalUplinkCompletionLocations_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Standard Uplink Locations", "Locations checked by completing a standard uplink for a particular objective", get_Tag_TerminalUplinkCompletionLocations(gd))); } public static TagResolver get_Tag_TerminalUplinkTerminalItems_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Standard Uplink Terminal Items", "Items indicating an uplink terminal is reachable for a particular objective", get_Tag_TerminalUplinkTerminalItems(gd))); } public static TagResolver get_Tag_TerminalUplinkCompletionItems_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Standard Uplink Completion Items", "Items indicating an uplink is completed for a particular objective", get_Tag_TerminalUplinkCompletionItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class TerminalUplinkHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 8; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Complete {data.Objective.Uplink_NumberOfTerminals} Uplinks"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 8; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)8)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string TerminalFound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Found {count} Terminal{((count == 1) ? "" : "s")}"; } public static string UplinkCompleted(Objective.Data data, int count) { return $"{data.ObjectiveName()} Completed {count} Uplink{((count == 1) ? "" : "s")}"; } } private static class TerminalUplink_TerminalLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Uplink Terminal Location {count}", "A particular standard uplink terminal location", TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkTerminalLocations_ByObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private static class TerminalUplink_CompletionLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Uplink Completion Location {count}", "A particular standard uplink completion location", TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkCompletionLocations_ByObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class TerminalUplink_TerminalItem : Item { public Objective.Data ObjectiveData { get; set; } public int Count { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkTerminalItems_ByObjective(ObjectiveData)); public TerminalUplink_TerminalItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; Count = count; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Uplink Terminal Item {count}", "A particular standard uplink terminal", TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkTerminalItems_ByObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private class TerminalUplink_CompletionItem : Item { public Objective.Data ObjectiveData { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkCompletionItems_ByObjective(ObjectiveData)); public TerminalUplink_CompletionItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Uplink Completion Item", "A particular standard uplink completion", TerminalUplinkHandler_Tags.get_Tag_TerminalUplinkCompletionItems_ByObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Standard Uplink Handler"; public override string Description => "Handles the TerminalUplink objective type.\nThis handles specifically only the standard uplink and not the corrupted or \"dual\" uplinkExample: R2B3"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetTerminalItem(Objective.Data data, int count) { if (data.TryLookupItem(TerminalUplink_TerminalItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new TerminalUplink_TerminalItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetCompletionItem(Objective.Data data) { if (data.TryLookupItem(TerminalUplink_CompletionItem.MakeTag(data), out var item)) { return item; } Item item2 = new TerminalUplink_CompletionItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleTerminalUplinkObjective(Objective.Data data) { if (This.IsCorrectObjective(data)) { List> list = data.ObjectiveToTerminalRegionSets(data.Objective.Uplink_NumberOfTerminals).ToList(); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); KeyedItem completionItem = GetCompletionItem(data); RegionID regionID = data.ObjectiveStartRegion; for (int i = 1; i <= data.Objective.Uplink_NumberOfTerminals; i++) { KeyedItem terminalItem = GetTerminalItem(data, i); data.AddLocation(TerminalUplink_TerminalLocation.MakeTag(data, i), list[i - 1], TerminalUplink_TerminalLocation.MakeRandData(), terminalItem.ID); string regionName = ThisRegions.TerminalFound(data, i); RegionID regionID2 = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2, ReqItem = terminalItem.PathReqs, ReqCount = 1u }); data.AddLocation(TerminalUplink_CompletionLocation.MakeTag(data, i), regionID2, TerminalUplink_CompletionLocation.MakeRandData(), completionItem.ID); string text = ThisRegions.UplinkCompleted(data, i); RegionID regionID3 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = regionID3, ReqItem = completionItem.PathReqs, ReqCount = 1u }); regionID = regionID3; wrapper.Process(regionID3, text); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } } } public static class CentralGenClusterHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CentralGenCellLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CentralGenClusterLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CentralGenClusterItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CentralGenScanLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CentralGenScanItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_CentralGenCellLocations_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_CentralGenCellLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Central Gen Cell Locations", "Locations checked by picking up cells spawned for central gen cluster objectives", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } public static TagResolver get_Tag_CentralGenClusterLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Central Gen Cluster Locations", "Locations checked by finding central gen clusters", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CentralGenClusterItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Central Gen Cluster Items", "Items representing central gen clusters", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CentralGenScanLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Central Gen Scan Locations", "Locations checked by fully powering a central gen cluster", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_CentralGenScanItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Central Gen Scan Items", "Items which start the final gen cluster scan (which normally occurs when it's fully powered)", RootRandomizationTags.get_Tag_ScanItems(gd))); } public static TagResolver get_Tag_CentralGenCellLocations_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Central Gen Cell Locations", "Locations for cells for a particular objective", get_Tag_CentralGenCellLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class CentralGenClusterHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 9; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"{data.Objective.CentralPowerGenClustser_NumberOfGenerators}x Central Gen Cluster"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 9; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)9)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string FoundGenCluster(Objective.Data data) { return data.ObjectiveName() + " Found Gen Cluster"; } public static string PoweredGenerator(Objective.Data data, int count) { return $"{data.ObjectiveName()} Powered Generator #{count}"; } public static string CompletedScan(Objective.Data data) { return data.ObjectiveName() + " Completed Scan"; } } private static class GenCluster_CellLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Central Gen Cell Location #{count}", "A particular cell spawn location", CentralGenClusterHandler_Tags.get_Tag_CentralGenCellLocations_ByObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private static class GenCluster_ClusterLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Central Gen Cluster Location", "A particular gen cluster spawn location", CentralGenClusterHandler_Tags.get_Tag_CentralGenClusterLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class GenCluster_ClusterItem : Item { public Objective.Data ObjectiveData { get; set; } public GenCluster_ClusterItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Central Gen Cluster Item", "A particular gen cluster", CentralGenClusterHandler_Tags.get_Tag_CentralGenClusterItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static class GenCluster_ScanLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Gen Cluster Scan Location", "A particular scan location", CentralGenClusterHandler_Tags.get_Tag_CentralGenScanLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private class GenCluster_ScanItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass6_0 { public LG_ComputerTerminal terminal; public LG_PowerGeneratorCluster cluster; public StateTracker stateTracker; public GenCluster_ScanItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Initiating Gen Cluster Scan", 2f); } internal void b__1() { if ((Object)(object)cluster != (Object)null) { terminal.AddLine("Scan will start in 3 seconds. Enjoy :)", true); ((MonoBehaviour)cluster).StartCoroutine(cluster.ObjectiveEndSequence()); cluster.SetFogIndex(cluster.m_currentFogStepIndex + 1); } else { terminal.AddLine("<#F00>Failed to find generator cluster! Item returned to terminal.", true); stateTracker.AddItemToTerminal(<>4__this); } } } [CompilerGenerated] private sealed class d__6 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private StateTracker stateTracker; public StateTracker <>3__stateTracker; public GenCluster_ScanItem <>4__this; private <>c__DisplayClass6_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; GenCluster_ScanItem genCluster_ScanItem = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass6_0(); <>8__1.terminal = terminal; <>8__1.stateTracker = stateTracker; <>8__1.<>4__this = <>4__this; List objectiveItemCollection = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)genCluster_ScanItem.ObjectiveData.LayerType, genCluster_ScanItem.ObjectiveData.ObjectiveIndex); <>8__1.cluster = ((Il2CppObjectBase)objectiveItemCollection[0]).TryCast(); <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating Gen Cluster Scan", 2f); }; <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = delegate { if ((Object)(object)<>8__1.cluster != (Object)null) { <>8__1.terminal.AddLine("Scan will start in 3 seconds. Enjoy :)", true); ((MonoBehaviour)<>8__1.cluster).StartCoroutine(<>8__1.cluster.ObjectiveEndSequence()); <>8__1.cluster.SetFogIndex(<>8__1.cluster.m_currentFogStepIndex + 1); } else { <>8__1.terminal.AddLine("<#F00>Failed to find generator cluster! Item returned to terminal.", true); <>8__1.stateTracker.AddItemToTerminal(<>8__1.<>4__this); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__6 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__6(0) { <>4__this = <>4__this }; } d__.stateTracker = <>3__stateTracker; d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Objective.Data ObjectiveData; public GenCluster_ScanItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Gen Cluster Scan Item", "A particular scan item", CentralGenClusterHandler_Tags.get_Tag_CentralGenScanItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ObjectiveData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ObjectiveData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__6))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(-2) { <>4__this = this, <>3__stateTracker = stateTracker, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_PowerGeneratorCluster___Setup_b__15_1__Patch { public static bool Prefix(LG_PowerGeneratorCluster __instance) { if (__instance.m_currentFogStepIndex == ((Il2CppArrayBase)(object)__instance.m_fogDataSteps).Count - 2) { Objective.Data data = Layer.Data.FromLayer(__instance.SpawnNode.m_zone.Layer).GetObjectiveDatas().ElementAt(__instance.WardenObjectiveChainIndex); if (data.TryLookupLocation(GenCluster_ScanLocation.MakeTag(data), out var location)) { if (StateTracker.Get().NotifyFoundLocation(location.ID, null).RandMode.IsTreatedAsRandom) { return false; } } else { FeatureLogger.Error("Failed to notify finding of gen cluster scan location!"); } } return true; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Distribute_WardenObjective____c__DisplayClass8_1___DistributePickupItems_b__0__Patch { public static void Postfix(__c__DisplayClass8_1 __instance, LG_Zone zone) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 Objective.Data data = Layer.Data.FromLayerFlattened(zone.Layer).GetObjectiveDatas().ElementAt(__instance.field_Public___c__DisplayClass8_0_0.chainIndex); if ((int)data.Objective.Type == 9) { if (data.TryLookupLocation(GenCluster_CellLocation.MakeTag(data, __instance.i + 1), out var location)) { PickupHelper.AssociateDistributionWithLocation(((Il2CppObjectBase)LG_Factory.Current.m_currentBatch.Jobs.FromEnd()).Cast(), location.ID); } else { FeatureLogger.Error("Failed to create association for Central Gen Cluster spawned cell!"); } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Central Generator Cluster Handler"; public override string Description => "Handles the CentralGenCluster objective type.\nExample: R2D1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetClusterItem(Objective.Data data) { if (data.TryLookupItem(GenCluster_ClusterItem.MakeTag(data), out var item)) { return item; } Item item2 = new GenCluster_ClusterItem(data); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetScanItem(Objective.Data data) { if (data.TryLookupItem(GenCluster_ScanItem.MakeTag(data), out var item)) { return item; } Item item2 = new GenCluster_ScanItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleCentralGenGlusterObjective(Objective.Data data) { if (!This.IsCorrectObjective(data)) { return; } KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, BigPickupHandler.CellItemID); List> list = (from ps in data.PlacementsToZoneRegions(data.ObjectiveData.ZonePlacementDatas) select ps.Select((Game.Data.RegionInfo i) => i.Region).ToList()).TakeLooped(data.Objective.CentralPowerGenClustser_NumberOfPowerCells).ToList(); for (int j = 1; j <= data.Objective.CentralPowerGenClustser_NumberOfPowerCells; j++) { data.AddLocation(GenCluster_CellLocation.MakeTag(data, j), list[j - 1], GenCluster_CellLocation.MakeRandData(), bigPickupItem.ID); } Zone.Data data2 = null; foreach (Zone.Data item in Zone.get_AllZones(data)) { ExpeditionZoneData? zone = item.Zone; if (((zone != null && zone.GeneratorClustersInZone != 0) ? 1 : 0) > (false ? 1 : 0)) { data2 = item; break; } } if (data2 == null) { FeatureLogger.Warning("Failed to find gen cluster for objective: " + data.ObjectiveName()); data2 = Zone.get_FirstZone(data); } KeyedItem clusterItem = GetClusterItem(data); data.AddLocation(GenCluster_ClusterLocation.MakeTag(data), data.LookupOrCreateRegion(data2.ZoneName), GenCluster_ClusterLocation.MakeRandData(), clusterItem.ID); RegionID regionID = data.LookupOrCreateRegion(ThisRegions.FoundGenCluster(data)); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = clusterItem.PathReqs, ReqCount = 1u }); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID regionID2 = regionID; for (int k = 1; k <= data.Objective.CentralPowerGenClustser_NumberOfGenerators; k++) { string text = ThisRegions.PoweredGenerator(data, k); RegionID regionID3 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = regionID3, ReqItem = bigPickupItem.PathReqs, ReqCount = 1u }); regionID2 = regionID3; wrapper.Process(regionID3, text, extendIfNecessary: true); } KeyedItem scanItem = GetScanItem(data); data.AddLocation(GenCluster_ScanLocation.MakeTag(data), regionID2, GenCluster_ScanLocation.MakeRandData(), scanItem.ID); string regionName = ThisRegions.CompletedScan(data); RegionID regionID4 = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = regionID4, ReqItem = scanItem.PathReqs, ReqCount = 1u }); SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID4); } } public static class ProcessItemHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ProcessItemStartLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ProcessItemProcessorLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ProcessItemProcessorItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ProcessItemStartLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Process Item Start Locations", "Locations checked by starting picking up the start item for Process Item objectives (if it spawned in the elevator)", PickupHelper_Tags.get_Tag_BigPickupLocations(gd))); } public static TagResolver get_Tag_ProcessItemProcessorLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Process Item Processor Locations", "Locations containing the processor for a Process Item objective", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ProcessItemProcessorItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Process Item Processor Items", "Items indicating a Process Items processor is reachable", RootRandomizationTags.get_Tag_Never(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ProcessItemHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 10; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); ItemDataBlock block = GameDataBlockBase.GetBlock(data.Objective.ActivateHSU_ItemFromStart); if (block == null) { FeatureLogger.Error("Failed to find start item for objective: " + data.ObjectiveName()); } ItemDataBlock block2 = GameDataBlockBase.GetBlock(data.Objective.ActivateHSU_ItemAfterActivation); if (block2 == null) { return "Process \"" + (((block != null) ? block.publicName : null) ?? "null!") + "\""; } return $"Process \"{((block != null) ? block.publicName : null) ?? "null!"}\" into \"{((block2 != null) ? block2.publicName : null) ?? "null!"}\""; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 10; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)10)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string ItemObtained(Objective.Data data) { return data.ObjectiveName() + " Item Obtained"; } public static string ItemProcessed(Objective.Data data) { return data.ObjectiveName() + " Item Processed"; } } private static class ProcessItem_StartLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Start Location", "Location checked by grabbing a particular big pickup", ProcessItemHandler_Tags.get_Tag_ProcessItemStartLocations(gd))); } public static LocationData MakeRandData() { return new LocationData(); } } private static class ProcessItem_ProcessorLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Processor Location", "Location checked by finding a particular processor", ProcessItemHandler_Tags.get_Tag_ProcessItemProcessorLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class ProcessItem_ProcessorItem : Item { public Objective.Data ObjectiveData { get; set; } public ProcessItem_ProcessorItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Processor Item", "Item indicating a particular processor is reachable", ProcessItemHandler_Tags.get_Tag_ProcessItemProcessorItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_Factory__FactoryDone__Patch { public static void Postfix() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 Expedition.Data expeditionData = Expedition.Data.FromCurrentExpedition(); Objective.Data data = Layer.get_MainLayer(expeditionData).GetObjectiveDatas().First(); int num = 0; if (data.Objective.GenericItemFromStart != 0) { num++; } if ((int)data.Objective.Type == 7) { num += data.Objective.PowerCellsToDistribute; } foreach (Objective.Data item in Layer.get_RealLayers(expeditionData).SelectMany((Layer.Data l) => l.GetObjectiveDatas())) { if (This.IsCorrectObjective(item) && item.Objective.ActivateHSU_BringItemInElevator) { CarryItemPickup_Core componentInChildren = ((Component)ElevatorCage.Current.m_cargoCage.m_itemsToMoveToCargo[num]).GetComponentInChildren(); if (((GameDataBlockBase)(object)((Item)componentInChildren).ItemDataBlock).persistentID != item.Objective.ActivateHSU_ItemFromStart) { FeatureLogger.Warning("Associating wrong item with processor objective starting item!"); } if (item.TryLookupLocation(ProcessItem_StartLocation.MakeTag(item), out var location)) { PickupHelper.AssociateItem((ItemInLevel)(object)componentInChildren, location.ID); } else { FeatureLogger.Error("Failed to create association for process item objective's starting item!"); } } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Process Item Handler"; public override string Description => "Handles the ActiveSmallHSU objective type.\nExample: R3A1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetProcessorItem(Objective.Data data) { if (data.TryLookupItem(ProcessItem_ProcessorItem.MakeTag(data), out var item)) { return item; } Item item2 = new ProcessItem_ProcessorItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleActivateSmallHSUObjective(Objective.Data data) { if (This.IsCorrectObjective(data)) { KeyedItem bigPickupItem = BigPickupHandler.GetBigPickupItem(data, data.Objective.ActivateHSU_ItemFromStart); if (data.Objective.ActivateHSU_BringItemInElevator) { RegionList regions = data.LookupOrCreateRegion(Zone.get_FirstZone(data.GetLayer(LayerType.Main)).ZoneName); data.AddLocation(ProcessItem_StartLocation.MakeTag(data), regions, ProcessItem_StartLocation.MakeRandData(), bigPickupItem.ID); } RegionID regionID = data.LookupOrCreateRegion(ThisRegions.ItemObtained(data)); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = bigPickupItem.PathReqs, ReqCount = 1u }); KeyedItem processorItem = GetProcessorItem(data); data.AddLocation(ProcessItem_ProcessorLocation.MakeTag(data), (from info in data.ObjectiveData.ZonePlacementDatas.SelectMany, Game.Data.RegionInfo>(((Layer.Data)data).PlacementsToZoneRegions) select info.Region).ToList(), ProcessItem_ProcessorLocation.MakeRandData(), processorItem.ID); string text = ThisRegions.ItemProcessed(data); RegionID regionID2 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2, ReqItem = processorItem.PathReqs, ReqCount = 1u }); if (data.Objective.EventsOnActivate.Any()) { data.ProcessEvents(regionID2, text, data.Objective.EventsOnActivate); } WardenObjectiveDataBlock objective = data.Objective; data.ProcessEvents(regionID2, text, objective.ActivateHSU_Events ?? (objective.ActivateHSU_Events = new List(1))); if (data.Objective.ActivateHSU_ObjectiveCompleteAfterInsertion) { SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID2); } } } } [EnableFeatureByDefault] [AutomatedFeature] public class SurvivalHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 11; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Survive {TimeSpan.FromSeconds(data.Objective.Survival_TimeToSurvive):c}"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 11; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)11)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string Started(Objective.Data data) { return data.ObjectiveName() + " Started"; } public static string Survived(Objective.Data data, float duration) { return $"{data.ObjectiveName()} Survived {TimeSpan.FromSeconds(duration):c}"; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Survival Handler"; public override string Description => "Handles the Survival objective type.\nThe survival objective is any objective that puts a timer at the top of the screen.\nExamples: R5B4, R8E1"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } [Objective.Callback] public void HandleSurvivalObjective(Objective.Data data) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Invalid comparison between Unknown and I4 if (!This.IsCorrectObjective(data)) { return; } string regionName = ThisRegions.Started(data); RegionID regionID = data.LookupOrCreateRegion(regionName); ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.StartingRegion = data.ObjectiveStartRegion; path.EndingRegion = regionID; ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; if (data.ObjectiveIndex > 0) { path2.ReqItem = SharedObjectiveHandler.GetCompleteObjectiveItem(data).PathReqs; path2.ReqCount = (uint)data.ObjectiveIndex; } data.AddPath(path2); SortedList> sortedList = new SortedList>(); WardenObjectiveDataBlock objective = data.Objective; Enumerator enumerator = (objective.EventsOnActivate ?? (objective.EventsOnActivate = new List())).GetEnumerator(); while (enumerator.MoveNext()) { WardenObjectiveEventData current = enumerator.Current; if ((int)current.Type == 999) { break; } if (!sortedList.TryGetValue(current.Delay, out var value)) { value = new List(2); sortedList.Add(current.Delay, value); } value.Add(current); } RegionID startingRegion = regionID; foreach (KeyValuePair> item in sortedList) { string text = ThisRegions.Survived(data, item.Key); RegionID regionID2 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID2 }); startingRegion = regionID2; data.ProcessEvents(regionID2, text, item.Value); Enumerator enumerator3 = item.Value.GetEnumerator(); while (enumerator3.MoveNext()) { WardenObjectiveEventData current3 = enumerator3.Current; current3.Delay = item.Key; } } data.Objective.EventsOnActivate = new List(sortedList.Sum((KeyValuePair> pair) => pair.Value.Count)); foreach (WardenObjectiveEventData item2 in sortedList.SelectMany((KeyValuePair> pair) => pair.Value.Iter())) { data.Objective.EventsOnActivate.Add(item2); } RegionID regionID3 = data.LookupOrCreateRegion(ThisRegions.Survived(data, data.Objective.Survival_TimeToSurvive)); if (!sortedList.ContainsKey(data.Objective.Survival_TimeToSurvive)) { startingRegion = regionID; foreach (KeyValuePair> item3 in sortedList.Reverse()) { if (item3.Key < data.Objective.Survival_TimeToSurvive) { startingRegion = data.LookupOrCreateRegion(ThisRegions.Survived(data, item3.Key)); break; } } data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID3 }); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID3); } } public static class GatherTerminalHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GatherTerminalsCommandLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GatherTerminalsCommandItem { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_GatherTerminalsCommandLocations_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_GatherTerminalsCommandItem_ByObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_GatherTerminalsCommandLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Gather Terminals Command Locations", "Locations checked executing gather terminals commands", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver get_Tag_GatherTerminalsCommandItem(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Gather Terminals Command Items", "Items representing a gather terminals command having been executed", RootRandomizationTags.get_Tag_AllItems(gd))); } public static TagResolver get_Tag_GatherTerminalsCommandLocations_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Gather Terminals Command Locations", "Locations checked executing gather terminals commands for a particular objective", get_Tag_GatherTerminalsCommandLocations(gd))); } public static TagResolver get_Tag_GatherTerminalsCommandItem_ByObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Gather Terminals Command Items", "Items representing a gather terminals command having been executed for a particular objective", get_Tag_GatherTerminalsCommandItem(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class GatherTerminalHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 12; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Execute {data.Objective.GatherTerminal_Command} on {data.Objective.GatherTerminal_RequiredCount} Terminals"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 12; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)12)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string CommandExecuted(Objective.Data data, int count) { return $"{data.ObjectiveName()} {count} command{((count == 1) ? "" : "s")} executed"; } } private static class GatherTerminals_CommandLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Command Location #{count}", "Location containing a gather terminals command", GatherTerminalHandler_Tags.get_Tag_GatherTerminalsCommandLocations_ByObjective(data2))); } public static LocationData MakeRandData() { return new LocationData(); } } private class GatherTerminals_CommandItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass15_0 { public GatherTerminals_CommandItem <>4__this; public LG_ComputerTerminal terminal; internal void b__0() { LocalizedText gatherTerminal_DownloadingText = <>4__this.ObjectiveData.Objective.GatherTerminal_DownloadingText; if (gatherTerminal_DownloadingText.Id == 0) { string untranslatedText = gatherTerminal_DownloadingText.UntranslatedText; if (untranslatedText == null || untranslatedText.Length == 0) { terminal.m_command.AddOutput((TerminalLineType)4, 436196897u, 1f, (TerminalSoundType)0, (TerminalSoundType)0); return; } } terminal.m_command.AddOutput((TerminalLineType)4, LocalizedText.op_Implicit(<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadingText), MathF.Min(1f, <>4__this.ObjectiveData.Objective.GatherTerminal_DownloadTime), (TerminalSoundType)0, (TerminalSoundType)0); } internal void b__1() { //IL_0010: 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) List objectiveItemCollection = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)<>4__this.ObjectiveData.LayerType, <>4__this.ObjectiveData.ObjectiveIndex); objectiveItemCollection[<>4__this.Count - 1].ObjectiveItemSolved = true; WardenObjectiveManager.OnLocalPlayerSolvedObjectiveItem((LG_LayerType)<>4__this.ObjectiveData.LayerType, objectiveItemCollection[<>4__this.Count - 1], true); LocalizedText gatherTerminal_DownloadCompleteText = <>4__this.ObjectiveData.Objective.GatherTerminal_DownloadCompleteText; if (gatherTerminal_DownloadCompleteText.Id == 0) { string untranslatedText = gatherTerminal_DownloadCompleteText.UntranslatedText; if (untranslatedText == null || untranslatedText.Length == 0) { terminal.m_command.AddOutput(2410856699u, true); return; } } terminal.m_command.AddOutput(LocalizedText.op_Implicit(<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadCompleteText), true); } } [CompilerGenerated] private sealed class d__15 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; public GatherTerminals_CommandItem <>4__this; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private <>c__DisplayClass15_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass15_0(); <>8__1.<>4__this = <>4__this; <>8__1.terminal = terminal; <>2__current = delegate { LocalizedText gatherTerminal_DownloadingText = <>8__1.<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadingText; if (gatherTerminal_DownloadingText.Id == 0) { string untranslatedText = gatherTerminal_DownloadingText.UntranslatedText; if (untranslatedText == null || untranslatedText.Length == 0) { <>8__1.terminal.m_command.AddOutput((TerminalLineType)4, 436196897u, 1f, (TerminalSoundType)0, (TerminalSoundType)0); return; } } <>8__1.terminal.m_command.AddOutput((TerminalLineType)4, LocalizedText.op_Implicit(<>8__1.<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadingText), MathF.Min(1f, <>8__1.<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadTime), (TerminalSoundType)0, (TerminalSoundType)0); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0010: 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) List objectiveItemCollection = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)<>8__1.<>4__this.ObjectiveData.LayerType, <>8__1.<>4__this.ObjectiveData.ObjectiveIndex); objectiveItemCollection[<>8__1.<>4__this.Count - 1].ObjectiveItemSolved = true; WardenObjectiveManager.OnLocalPlayerSolvedObjectiveItem((LG_LayerType)<>8__1.<>4__this.ObjectiveData.LayerType, objectiveItemCollection[<>8__1.<>4__this.Count - 1], true); LocalizedText gatherTerminal_DownloadCompleteText = <>8__1.<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadCompleteText; if (gatherTerminal_DownloadCompleteText.Id == 0) { string untranslatedText2 = gatherTerminal_DownloadCompleteText.UntranslatedText; if (untranslatedText2 == null || untranslatedText2.Length == 0) { <>8__1.terminal.m_command.AddOutput(2410856699u, true); return; } } <>8__1.terminal.m_command.AddOutput(LocalizedText.op_Implicit(<>8__1.<>4__this.ObjectiveData.Objective.GatherTerminal_DownloadCompleteText), true); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__15 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__15(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, GatherTerminalHandler_Tags.get_Tag_GatherTerminalsCommandItem_ByObjective(ObjectiveData)); public Objective.Data ObjectiveData { get; set; } public int Count { get; set; } public GatherTerminals_CommandItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; Count = count; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Command Item #{count}", "Item obtained for completing a gather terminals command", GatherTerminalHandler_Tags.get_Tag_GatherTerminalsCommandItem_ByObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ObjectiveData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ObjectiveData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__15))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(-2) { <>4__this = this, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class LG_ComputerTermina__OnWardenObjectiveGatherCommandDone__Patch { public static bool Prefix(LG_ComputerTerminal __instance) { //IL_000b: 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) Objective.Data data = Expedition.Data.FromCurrentExpedition().GetLayer(__instance.SpawnNode.LayerType).GetObjectiveDatas() .ElementAt(__instance.WardenObjectiveChainIndex); if (!This.IsCorrectObjective(data)) { FeatureLogger.Error("Failed to find objective data while intercepting gather command!"); return true; } List objectiveItemCollection = WardenObjectiveManager.GetObjectiveItemCollection((LG_LayerType)data.LayerType, data.ObjectiveIndex); int i; for (i = 0; i < objectiveItemCollection.Count && !(((Il2CppObjectBase)objectiveItemCollection[i]).Pointer == ((Il2CppObjectBase)__instance).Pointer); i++) { } if (i == objectiveItemCollection.Count) { FeatureLogger.Error("Failed to find terminal index while intercepting gather command!"); return true; } RandomizationTag randomizationTag = GatherTerminals_CommandLocation.MakeTag(data, i + 1); if (!data.TryLookupLocation(randomizationTag, out var location)) { FeatureLogger.Error("Failed to find location index while intercepting gather command: " + data.LookupTagDef(randomizationTag).Name); return true; } if (StateTracker.Get().NotifyFoundLocation(location.ID, __instance.m_syncedInteractionSource).RandMode.IsTreatedAsRandom) { __instance.m_command.AddOutput("Discovered item(s):", false); __instance.m_command.AddOutput(" " + (location.ItemID.IsNull ? "None" : data.LookupTagDef(data.LookupItem(location.ItemID).NameTag).Name), true); return false; } return true; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Gather Terminals Handler"; public override string Description => "Handles the GatherTerminals objective type.\nThis objective type refers only to when you need to enter multiple special command.\nExample: R5A3 Main"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetCommandItem(Objective.Data data, int count) { if (data.TryLookupItem(GatherTerminals_CommandItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new GatherTerminals_CommandItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleGatherTerminalObjective(Objective.Data data) { if (!This.IsCorrectObjective(data)) { return; } if (data.Objective.GatherTerminal_RequiredCount > data.Objective.GatherTerminal_SpawnCount) { FeatureLogger.Error(data.ObjectiveName() + ": Expected at least as many terminal spawns as required terminals"); return; } List> list = data.ObjectiveToTerminalRegionSets(data.Objective.GatherTerminal_SpawnCount).ToList(); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID startingRegion = data.ObjectiveStartRegion; for (int i = 1; i <= data.Objective.GatherTerminal_SpawnCount; i++) { KeyedItem commandItem = GetCommandItem(data, i); data.AddLocation(GatherTerminals_CommandLocation.MakeTag(data, i), list[i - 1], GatherTerminals_CommandLocation.MakeRandData(), commandItem.ID); string text = ThisRegions.CommandExecuted(data, i); RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = startingRegion, EndingRegion = regionID, ReqItem = commandItem.PathReqs, ReqCount = 1u }); startingRegion = regionID; if (i == data.Objective.GatherTerminal_RequiredCount) { SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } wrapper.Process(regionID, text, extendIfNecessary: true); } } } public static class CorruptedUplinkHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CorruptedUplinkTerminalLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CorruptedUplinkTerminalItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CorruptedUplinkCompletionLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CorruptedUplinkCompletionItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_CorruptedUplinkTerminalLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_CorruptedUplinkTerminalItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_CorruptedUplinkCompletionLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_CorruptedUplinkCompletionItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_CorruptedUplinkTerminalLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Corrupted Uplink Terminal Locations", "Locations checked by finding Corrupted Uplink terminals", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CorruptedUplinkTerminalItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Corrupted Uplink Terminal Items", "Terminal items used for Corrupted Uplinks", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CorruptedUplinkCompletionLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Corrupted Uplink Completion Locations", "Locations checked by completing Corrupted Uplinks", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CorruptedUplinkCompletionItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Corrupted Uplink Completion Items", "Represents a corrupted uplink having been completed", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CorruptedUplinkTerminalLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Corrupted Uplink Terminal Locations", "Locations checked by finding Corrupted Uplink terminals for a particular objective", get_Tag_CorruptedUplinkTerminalLocations(gd))); } public static TagResolver get_Tag_CorruptedUplinkTerminalItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Corrupted Uplink Terminal Items", "Terminal items used for Corrupted Uplinks for a particular objective", get_Tag_CorruptedUplinkTerminalItems(gd))); } public static TagResolver get_Tag_CorruptedUplinkCompletionLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Corrupted Uplink Completion Locations", "Locations checked by completing Corrupted Uplinks for a particular objective", get_Tag_CorruptedUplinkCompletionLocations(gd))); } public static TagResolver get_Tag_CorruptedUplinkCompletionItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Corrupted Uplink Completion Items", "Represents a corrupted uplink having been completed for a particular objective", get_Tag_CorruptedUplinkCompletionItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class CorruptedUplinkHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 13; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Perform {data.Objective.Uplink_NumberOfTerminals} Corrupted Uplinks"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 13; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)13)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string TerminalFound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Found {count} Terminal Pair{((count == 1) ? "" : "s")}"; } public static string UplinkComplete(Objective.Data data, int count) { return $"{data.ObjectiveName()} Uplink #{count} Completed"; } } private static class CorruptedUplink_TerminalLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Terminal Location #{count}", "A spawn location for a particular terminal", CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkTerminalLocations_PerObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class CorruptedUplink_TerminalItem : Item { public Objective.Data ObjectiveData { get; set; } public int Count { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkTerminalItems_PerObjective(ObjectiveData)); public CorruptedUplink_TerminalItem(Objective.Data data, int count) : base(MakeTag(data, count), MakeRandData()) { ObjectiveData = data; Count = count; } public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Terminal #{count}", "A particular terminal", CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkTerminalItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static class CorruptedUplink_CompletionLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Completion Location #{count}", "A particular completion location", CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkCompletionLocations_PerObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class CorruptedUplink_CompletionItem : Item { public Objective.Data ObjectiveData { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkCompletionItems_PerObjective(ObjectiveData)); public CorruptedUplink_CompletionItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Terminal", "A particular uplink completion item", CorruptedUplinkHandler_Tags.get_Tag_CorruptedUplinkCompletionItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Corrupted Uplink Handler"; public override string Description => "Handles the CorruptedTerminalUplink objective type.\nThis handles specifically only the corrupted or \"dual\" uplink typeExample: R5C3"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetTerminalItem(Objective.Data data, int count) { if (data.TryLookupItem(CorruptedUplink_TerminalItem.MakeTag(data, count), out var item)) { return item; } Item item2 = new CorruptedUplink_TerminalItem(data, count); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetCompletionItem(Objective.Data data) { if (data.TryLookupItem(CorruptedUplink_CompletionItem.MakeTag(data), out var item)) { return item; } Item item2 = new CorruptedUplink_CompletionItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleCorruptedUplinkObjective(Objective.Data data) { if (This.IsCorrectObjective(data)) { List> list = data.UnstuffPlacements(data.PlacementsToTerminalRegions(data.ObjectiveData.ZonePlacementDatas), data.Objective.Uplink_NumberOfTerminals).ToList(); KeyedItem completionItem = GetCompletionItem(data); Event.Wrapper wrapper = data.MakeOrWrapOnSolveEvents(); RegionID regionID = data.ObjectiveStartRegion; for (int i = 1; i <= data.Objective.Uplink_NumberOfTerminals; i++) { KeyedItem terminalItem = GetTerminalItem(data, 2 * i - 1); data.AddLocation(CorruptedUplink_TerminalLocation.MakeTag(data, 2 * i - 1), list[i - 1], CorruptedUplink_TerminalLocation.MakeRandData(), terminalItem.ID); KeyedItem terminalItem2 = GetTerminalItem(data, 2 * i); data.AddLocation(CorruptedUplink_TerminalLocation.MakeTag(data, 2 * i), list[i - 1], CorruptedUplink_TerminalLocation.MakeRandData(), terminalItem2.ID); string regionName = ThisRegions.TerminalFound(data, i); RegionID regionID2 = data.LookupOrCreateRegion(regionName); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2, ReqItem = terminalItem.PathReqs, ReqCount = 2u }); data.AddLocation(CorruptedUplink_CompletionLocation.MakeTag(data, i), regionID2, CorruptedUplink_CompletionLocation.MakeRandData(), completionItem.ID); string text = ThisRegions.UplinkComplete(data, i); RegionID regionID3 = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID2, EndingRegion = regionID3, ReqItem = completionItem.PathReqs, ReqCount = 1u }); regionID = regionID3; wrapper.Process(regionID3, text); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID); } } } [EnableFeatureByDefault] [AutomatedFeature] public class EmptyHandler : ArchipelagoFeature { private static IArchiveLogger? m_featureLogger; public override string Name => "Empty Handler"; public override string Description => "Handles the Empty objective type.\nThis is a special objective type which cannot be beaten, and requires a ForceCompelteObjective event (or Win event).\nExample: R8E2 (Main) Objective #2\n -> This level has two chained objectives; the first is survival, and winning it triggers the nightmare surge. The second is empty, so you can't extract after \"surviving\" the objective."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } } public static class TimedSequenceHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TimedSequenceMainLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TimedSequenceMainItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TimedSequenceVerifyLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_TimedSequenceVerifyItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $E93D81478905A37B27DF6F640623743D { [SpecialName] public static class $66441969E171E5CA8C86F896EE40E940 { } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TimedSequenceVerifyLocations_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] public TagResolver Tag_TimedSequenceVerifyItems_PerObjective { [ExtensionMarker("$66441969E171E5CA8C86F896EE40E940")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_TimedSequenceMainLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Timed Sequence Main Locations", "Locations containing the main terminal for a timed sequence", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TimedSequenceMainItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Timed Sequence Main Items", "Timed Sequence main terminal items", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TimedSequenceVerifyLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Timed Sequence Verify Locations", "Locations containing a verify terminal for a timed sequence", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TimedSequenceVerifyItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Timed Sequence Verify Items", "Timed Sequence verify terminal items", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_TimedSequenceVerifyLocations_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Timed Sequence Verify Locations", "Locations containing a verify terminal for a particular timed sequence", get_Tag_TimedSequenceVerifyLocations(gd))); } public static TagResolver get_Tag_TimedSequenceVerifyItems_PerObjective(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Timed Sequence Verify Items", "Timed Sequence verify terminal items for a particular objective", get_Tag_TimedSequenceVerifyItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class TimedSequenceHandler : ArchipelagoFeature { private static class This { public const eWardenObjectiveType ObjectiveType = 15; public static string ObjectiveSummary(Objective.Data data) { CheckIsCorrectObjective(data); return $"Perform {data.Objective.TimedTerminalSequence_NumberOfRounds}-Round Timed Sequence"; } public static bool IsCorrectObjective(Objective.Data data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)data.Objective.Type == 15; } public static void CheckIsCorrectObjective(Objective.Data data) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!IsCorrectObjective(data)) { FeatureLogger.Error($"Wrong objective type! Expected {Enum.GetName((eWardenObjectiveType)15)}, got {data.Objective.Type}"); } } } private static class ThisRegions { public static string StartRound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Start Round {count}"; } public static string FailRound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Fail Round {count}"; } public static string CompleteRound(Objective.Data data, int count) { return $"{data.ObjectiveName()} Complete Round {count}"; } } private static class TimedSequence_MainLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Main Terminal Location", "Location of a particular terminal", TimedSequenceHandler_Tags.get_Tag_TimedSequenceMainLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private static class TimedSequence_VerifyLocation { public static TagResolver MakeTag(Objective.Data data, int count) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.ObjectiveName()} Verify Terminal Location ${count}", "Location of a particular terminal", TimedSequenceHandler_Tags.get_Tag_TimedSequenceVerifyLocations_PerObjective(data2))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class TimedSequence_MainItem : Item { public Objective.Data ObjectiveData { get; set; } public TimedSequence_MainItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Main Terminal Item", "A particular terminal", TimedSequenceHandler_Tags.get_Tag_TimedSequenceMainItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private class TimedSequence_VerifyItem : Item { public Objective.Data ObjectiveData { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, TimedSequenceHandler_Tags.get_Tag_TimedSequenceVerifyItems_PerObjective(ObjectiveData)); public TimedSequence_VerifyItem(Objective.Data data) : base(MakeTag(data), MakeRandData()) { ObjectiveData = data; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Verify Terminal Item", "A particular terminal", TimedSequenceHandler_Tags.get_Tag_TimedSequenceVerifyItems_PerObjective(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Timed Sequence Handler"; public override string Description => "Handles the TimedSequence objective type.\nThis handles specifically only the corrupted or \"dual\" uplink typeExample: R5C3"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetMainTerminal(Objective.Data data) { if (data.TryLookupItem(TimedSequence_MainItem.MakeTag(data), out var item)) { return item; } Item item2 = new TimedSequence_MainItem(data); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetVerifyTerminal(Objective.Data data) { if (data.TryLookupItem(TimedSequence_VerifyItem.MakeTag(data), out var item)) { return item; } Item item2 = new TimedSequence_VerifyItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Objective.Callback] public void HandleTimedSequenceObjective(Objective.Data data) { if (!This.IsCorrectObjective(data)) { return; } if (data.Objective.TimedTerminalSequence_NumberOfRounds < 1) { FeatureLogger.Error(data.ObjectiveName() + ": Cannot have fewer than 1 TimedSequence round!"); return; } IEnumerable> source = data.PlacementsToTerminalRegions(data.ObjectiveData.ZonePlacementDatas); KeyedItem mainTerminal = GetMainTerminal(data); data.AddLocation(TimedSequence_MainLocation.MakeTag(data), (from info in source.First() select info.Region).ToList(), TimedSequence_MainLocation.MakeRandData(), mainTerminal.ID); KeyedItem verifyTerminal = GetVerifyTerminal(data); int num = 0; foreach (IEnumerable item in source.Skip(1)) { num++; data.AddLocation(TimedSequence_VerifyLocation.MakeTag(data, num), item.Select((Game.Data.RegionInfo i) => i.Region).ToList(), TimedSequence_VerifyLocation.MakeRandData(), verifyTerminal.ID); } int num2 = 1; string text = ThisRegions.StartRound(data, num2); RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID, ReqItem = mainTerminal.PathReqs, ReqCount = 1u }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceStart.Count >= num2) { data.ProcessEvents(regionID, text, data.Objective.TimedTerminalSequence_EventsOnSequenceStart[num2 - 1]); } string text2 = ThisRegions.FailRound(data, num2); RegionID regionID2 = data.LookupOrCreateRegion(text2); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2 }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceFail.Count >= num2) { data.ProcessEvents(regionID2, text2, data.Objective.TimedTerminalSequence_EventsOnSequenceFail[num2 - 1]); } string text3 = ThisRegions.CompleteRound(data, num2); RegionID regionID3 = data.LookupOrCreateRegion(text3); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID3, ReqItem = verifyTerminal.PathReqs, ReqCount = (uint)num }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceDone.Count >= num2) { data.ProcessEvents(regionID3, text3, data.Objective.TimedTerminalSequence_EventsOnSequenceDone[num2 - 1]); } for (num2 = 2; num2 <= data.Objective.TimedTerminalSequence_NumberOfRounds; num2++) { text = ThisRegions.StartRound(data, num2); regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.ObjectiveStartRegion, EndingRegion = regionID }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceStart.Count >= num2) { data.ProcessEvents(regionID, text, data.Objective.TimedTerminalSequence_EventsOnSequenceStart[num2 - 1]); } text2 = ThisRegions.FailRound(data, num2); regionID2 = data.LookupOrCreateRegion(text2); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID2 }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceFail.Count >= num2) { data.ProcessEvents(regionID2, text2, data.Objective.TimedTerminalSequence_EventsOnSequenceFail[num2 - 1]); } text3 = ThisRegions.CompleteRound(data, num2); regionID3 = data.LookupOrCreateRegion(text3); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = regionID, EndingRegion = regionID3 }); if (data.Objective.TimedTerminalSequence_EventsOnSequenceDone.Count >= num2) { data.ProcessEvents(regionID3, text3, data.Objective.TimedTerminalSequence_EventsOnSequenceDone[num2 - 1]); } } if (data.Objective.OnActivateOnSolveItem && data.Objective.EventsOnActivate.Any()) { data.ProcessEvents(regionID3, text3, data.Objective.EventsOnActivate); } SharedObjectiveHandler.AddObjectiveCompleteItem(data, regionID3); } } public static class ExtractionHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ExtractionLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ExtractionItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ExtractionLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Extraction Locations", "Locations checked by reaching extraction on an expedition", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_ExtractionItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Extraction Items", "Items indicating extraction is reachable on a particular level", RootRandomizationTags.get_Tag_Never(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class ExtractionHandler : ArchipelagoFeature { private static class ExtractionReachableLocation { public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Extraction Location", "The locaiton of extraction for a particular expedition", ExtractionHandler_Tags.get_Tag_ExtractionLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } private class ExtractionReachableItem : Item { private Expedition.Data ExpeditionData { get; set; } public ExtractionReachableItem(Expedition.Data data) : base(MakeTag(data), MakeRandData()) { ExpeditionData = data; } public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Extraction Reachable", "Indiciates extraction is reachable for a particular expedition", ExtractionHandler_Tags.get_Tag_ExtractionItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Extraction Handler"; public override string Description => "Adds an \"Extraction Reachable\" item used to help identify when an expedition is clearable.\nThis item has no impact on play and is purely an internal item."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetExtractionReachableItem(Expedition.Data data) { if (data.TryLookupItem(ExtractionReachableItem.MakeTag(data), out var item)) { return item; } Item item2 = new ExtractionReachableItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Expedition.Callback] public void AddExtraction(Expedition.Data data) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 ComplexResourceSetDataBlock block = GameDataBlockBase.GetBlock(data.Expedition.Expedition.ComplexResourceData); Layer.Data layerData = Layer.get_MainLayer(data); Zone.Data data2 = null; foreach (Zone.Data z in Zone.get_AllZones(layerData).Reverse()) { if (z.CustomGeo != null && !(z.CustomGeo == "") && block.CustomGeomorphs_Exit_1x1.Any((ResourceData c) => c.Prefab == z.CustomGeo)) { data2 = z; break; } } if (data2 == null && (int)data.Expedition.MainLayerData.ObjectiveData.WinCondition != 1) { data2 = Zone.get_FirstZone(layerData); } else if (data2 == null) { FeatureLogger.Warning("Failed to place extraction for " + data.ExpeditionName); return; } KeyedItem extractionReachableItem = GetExtractionReachableItem(data); data.AddLocation(ExtractionReachableLocation.MakeTag(data), data.LookupOrCreateRegion(data2.ZoneName), ExtractionReachableLocation.MakeRandData(), extractionReachableItem.ID); } } public static class SharedObjectiveHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CompleteObjectiveLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CompleteObjectiveItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SectorClearLocations { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $2833969430CAB23CD70890D67B9ADDD5 { [SpecialName] public static class $5667123F7013DAD37BB214B248F3E5D2 { } [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] public TagResolver Tag_SectorClearItems_ByExpedition { [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $9DAFA10623A49E693D4D9BEA615A7202 { [SpecialName] public static class $70E40AF8BA672009D4689E0A70FAB84A { } [ExtensionMarker("$70E40AF8BA672009D4689E0A70FAB84A")] public TagResolver Tag_CompleteObjectiveItems_PerLayer { [ExtensionMarker("$70E40AF8BA672009D4689E0A70FAB84A")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_CompleteObjectiveLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Complete Objective Locations", "Locations checked by completing objectives", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_CompleteObjectiveItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Complete Objective Items", "Items representing objective completions", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_SectorClearLocations(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Sector Clear Locations", "Locations checked by clearing a sector and successfully extracting (or equivalent)", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_SectorClearItems_ByExpedition(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Sector Clear Items", "Items awarded by successfully clearing a sector in a particular expedition", RootRandomizationTags.get_Tag_GoalItems_ByExpedition(data2))); } public static TagResolver get_Tag_CompleteObjectiveItems_PerLayer(Layer.Data data) { Layer.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.LayerName + " Complete Objective Items", "Items representing objective completions for a particular layer in an expedition", RootRandomizationTags.get_Tag_Never(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class SharedObjectiveHandler : ArchipelagoFeature { public static class CompleteObjectiveLocation { public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Completion Location", "Location checked by completing a particular objective", SharedObjectiveHandler_Tags.get_Tag_CompleteObjectiveLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } public class CompleteObjectiveItem : Item { public Objective.Data Layer { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, SharedObjectiveHandler_Tags.get_Tag_CompleteObjectiveItems_PerLayer(Layer)); public CompleteObjectiveItem(Objective.Data layer) : base(MakeTag(layer), MakeRandData()) { Layer = layer; } public static TagResolver MakeTag(Objective.Data data) { Objective.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ObjectiveName() + " Completion", "Item representing a particular objective being cleared", SharedObjectiveHandler_Tags.get_Tag_CompleteObjectiveItems_PerLayer(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } private static class SectorClearedLocation { public static TagResolver MakeTag(Layer.Data data) { Layer.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.LayerName + " Sector Clear Location", "Location checked by clearing a particular layer and successfull extracting (or equivalent)", SharedObjectiveHandler_Tags.get_Tag_SectorClearLocations(gd))); } public static LocationData MakeRandData() { LocationData result = new LocationData(); result.IsAutoDiscovered = true; return result; } } public class SectorClearedItem : Item { public Layer.Data Layer { get; set; } public SectorClearedItem(Layer.Data layer) : base(MakeTag(layer), MakeRandData()) { Layer = layer; } public static TagResolver MakeTag(Layer.Data data) { Layer.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.LayerName + " Sector Clear", "Item representing a particular sector layer was successfull cleared", SharedObjectiveHandler_Tags.get_Tag_SectorClearItems_ByExpedition(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class RundownManager__OnExpeditionEnded__Patch { public static void Postfix(ExpeditionEndState endState) { //IL_0000: 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_0060: Invalid comparison between Unknown and I4 //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 if ((int)endState != 0) { return; } StateTracker stateTracker = StateTracker.Get(); Expedition.Data data = Expedition.Data.FromCurrentExpedition(); if (data.TryLookupLocation(SectorClearedLocation.MakeTag(Layer.get_MainLayer(data)), out var location)) { stateTracker.NotifyFoundLocation(location.ID, null); } else { FeatureLogger.Error("Failed to award main sector clear!"); } if (Layer.get_HasSecondary(data)) { if ((int)WardenObjectiveManager.CurrentState.second_status == 40) { if (data.TryLookupLocation(SectorClearedLocation.MakeTag(data.GetLayer(LayerType.Secondary)), out var location2)) { stateTracker.NotifyFoundLocation(location2.ID, null); } else { FeatureLogger.Error("Failed to award secondary sector clear!"); } } else { FeatureLogger.Debug("Secondary clear not awared due to it not being cleared"); } } if (!Layer.get_HasOverload(data)) { return; } if ((int)WardenObjectiveManager.CurrentState.third_status == 40) { if (data.TryLookupLocation(SectorClearedLocation.MakeTag(data.GetLayer(LayerType.Overload)), out var location3)) { stateTracker.NotifyFoundLocation(location3.ID, null); } else { FeatureLogger.Error("Failed to award overload sector clear!"); } } else { FeatureLogger.Debug("Overload clear not awared due to it not being cleared"); } } } private static IArchiveLogger? m_featureLogger; public const string SectorClearsCat = "Sector Clears"; public override string Name => "Shared Objective Handler"; public override string Description => "Handles several items shared by all objectives."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_ObjectiveHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public static KeyedItem GetCompleteObjectiveItem(Objective.Data data) { if (data.TryLookupItem(CompleteObjectiveItem.MakeTag(data), out var item)) { return item; } Item item2 = new CompleteObjectiveItem(data); return new KeyedItem(data.AddItem(item2), item2); } public static KeyedItem GetSectorClearedItem(Layer.Data data) { if (data.TryLookupItem(SectorClearedItem.MakeTag(data), out var item)) { return item; } Item item2 = new SectorClearedItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Layer.Callback] public void AddCommonObjectiveElements(Layer.Data data) { //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Invalid comparison between Unknown and I4 List source = data.GetObjectiveDatas().ToList(); if (!source.Any()) { return; } Objective.Data data2 = source.First(); Objective.Data data3 = source.Last(); RegionID objectiveStartRegion = data.ObjectiveStartRegion; if (data.LayerType.IsMainLayer) { data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = Zone.get_StartingRegion(data), EndingRegion = objectiveStartRegion }); } string text = data.LayerName + " Goto Win"; RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = objectiveStartRegion, EndingRegion = regionID, ReqItem = GetCompleteObjectiveItem(data.GetObjectiveDatas().First()).PathReqs, ReqCount = (uint)data.GetObjectiveDatas().Count(), AlternateItem = ((data.LayerType == LayerType.Main) ? WinEventHandler.GetInstantWinPathReqs(data) : new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem()) }); string text2 = data.LayerName + " Sector Cleared"; RegionID regionID2 = data.LookupOrCreateRegion(text2); ReTFO.Archipelago.ModdedInstanceData.Model.Path path = new ReTFO.Archipelago.ModdedInstanceData.Model.Path(); path.StartingRegion = regionID; path.EndingRegion = regionID2; ReTFO.Archipelago.ModdedInstanceData.Model.Path path2 = path; if (data.LayerType.IsMainLayer) { path2.ReqItem = ExtractionHandler.GetExtractionReachableItem(data).PathReqs; path2.ReqCount = 1u; path2.AlternateItem = WinEventHandler.GetInstantWinPathReqs(data); } else { path2.ReqItem = GetSectorClearedItem(Layer.get_MainLayer(data)).PathReqs; path2.ReqCount = 1u; } data.AddPath(path2); if ((int)data3.Objective.EventsOnGotoWinTrigger == 0) { WardenObjectiveDataBlock objective = data3.Objective; data.ProcessEvents(regionID, text, objective.EventsOnGotoWin ?? (objective.EventsOnGotoWin = new List(1))); } else { if ((int)data3.Objective.EventsOnGotoWinTrigger != 1) { throw new ArgumentException("Objective.EventsOnGotoWinTrigger has an unexpected value for expedition: " + data3.ExpeditionName); } WardenObjectiveDataBlock objective = data3.Objective; data.ProcessEvents(regionID2, text2, objective.EventsOnGotoWin ?? (objective.EventsOnGotoWin = new List(1))); } KeyedItem sectorClearedItem = GetSectorClearedItem(data); data.AddLocation(SectorClearedLocation.MakeTag(data), regionID2, SectorClearedLocation.MakeRandData(), sectorClearedItem.ID); } public static LocationID AddObjectiveCompleteItem(Objective.Data data, RegionList regions) { KeyedItem completeObjectiveItem = GetCompleteObjectiveItem(data); return data.AddLocation(CompleteObjectiveLocation.MakeTag(data), regions, CompleteObjectiveLocation.MakeRandData(), completeObjectiveItem.ID); } } } namespace ReTFO.Archipelago.Features.FloatingItems { [EnableFeatureByDefault] public class ArtifactsAndBoostersHandler : ArchipelagoFeature { [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class ArtifactPickup_Core__OnInteractionPickUp__Patch { public static void Postfix(ArtifactPickup_Core __instance, PlayerAgent player) { //IL_001e: 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) if (((Il2CppObjectBase)SNet.Master).Pointer != ((Il2CppObjectBase)player.Owner).Pointer) { return; } int num = BoosterUtils.BoosterCurrencyFromHeatAndArtifactCount((BoosterImplantCategory)__instance.m_artifactCategory, 1f, 1); float num2 = BoosterUtils.BoosterPartsFromCurrency(num); long num3 = (long)((float)GetArtifactValue(__instance.m_artifactCategory) * num2); EnergyLinkHandler.AddEnergy(num3).ContinueWith(delegate(Task t) { if (!t.IsCompletedSuccessfully) { FeatureLogger.Error("Failed to add energy when grabbing artifact!"); } }); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PersistentInventoryManager__Setup__Patch { public static void Postfix(PersistentInventoryManager __instance) { ArtifactsAndBoostersHandler feature = ArchipelagoFeatureHelper.GetFeature(); if (feature.m_overwriteCallback == null) { feature.m_overwriteCallback = new Il2CppAction(feature.OverwriteInventory); __instance.OnBoosterImplantInventoryChanged += (Action)feature.m_overwriteCallback; } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_ScrollWindow__SetContentItems__Patch { public static void Prefix(CM_ScrollWindow __instance, List contentItems) { //IL_003f: 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_0055: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) iScrollWindowContent? obj = contentItems.FirstOrDefault(); CM_BoosterImplantSlotItem val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val != (Object)null)) { return; } CM_BoosterImplantSlotItem selectedBoosterImplantItem = ((CM_LobbyScrollItem)val).m_parentBar.selectedBoosterImplantItem; if (((selectedBoosterImplantItem != null) ? new BoosterImplantCategory?(selectedBoosterImplantItem.BoosterImplant.Category) : null) != (BoosterImplantCategory?)val.BoosterImplant.Category) { ((CM_LobbyScrollItem)val).m_parentBar.selectedBoosterImplantItem = null; } List boosterImplantInventory = PersistentInventoryManager.GetBoosterImplantInventory(val.BoosterImplant.Category); while (contentItems.Count < boosterImplantInventory.Count) { GameObject val2 = Object.Instantiate(((Component)val).gameObject); CM_BoosterImplantSlotItem component = val2.GetComponent(); ((RectTransformComp)component).Setup(); ((CM_LobbyScrollItem)component).SetupFromLobby(((CM_LobbyScrollItem)val).m_guiAlign, ((CM_LobbyScrollItem)val).m_parentBar, false); component.LoadData(boosterImplantInventory[contentItems.Count]); ((CM_Item)component).ID = (int)component.BoosterInstanceID; ((CM_LobbyScrollItem)component).PlayIntro((float)contentItems.Count, -1); component.SetBackgroundEnabled(true); component.SetIconFromCategory(); ((RectTransformComp)component).SetVisible(true); if (component.IsPreparedSlot) { ((CM_LobbyScrollItem)component).m_parentBar.selectedBoosterImplantItem = component; } contentItems.Add(((Il2CppObjectBase)component).Cast()); } } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PersistentInventoryManager__ApplyPendingBoosterImplantTransactionsToModel__Patch { public static bool Prefix() { PersistentInventoryManager.Current.ClearPendingBoosterImplantTransactions(); return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class DropServerManager__NewGameSession__Patch { public static void Prefix(ref uint[] boosterIds) { boosterIds = null; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class DropServerGameSession__ConsumeBoosters__Patch { public static bool Prefix() { return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_BoosterImplantSlotItem__PrepareBoosterImplant__Patch { public static bool Prefix(CM_BoosterImplantSlotItem __instance) { //IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown //IL_0021: 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_0029: 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) BoosterImplantCategory category = __instance.BoosterImplant.Category; Task task = EnergyLinkHandler.RequestEnergy(GetArtifactValue((ArtifactCategory)((int)category switch { 0 => 0, 1 => 1, 2 => 2, _ => throw new ArgumentException("Expected booster type to be one of Muted, Bold, or Aggressive"), })), allowCancel: true); task.Wait(); return task.IsCompletedSuccessfully; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_BoosterImplantSlotItem__UnprepareBoosterImplant__Patch { public static void Postfix(CM_BoosterImplantSlotItem __instance) { //IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown //IL_0021: 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_0029: 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) BoosterImplantCategory category = __instance.BoosterImplant.Category; Task task = EnergyLinkHandler.AddEnergy(GetArtifactValue((ArtifactCategory)((int)category switch { 0 => 0, 1 => 1, 2 => 2, _ => throw new ArgumentException("Expected booster type to be one of Muted, Bold, or Aggressive"), }))); } } [CompilerGenerated] private sealed class <>c__DisplayClass21_0 { public BoosterImplantTemplateDataBlock template; public BoosterImplantInventoryItem baseItem; public ArtifactsAndBoostersHandler <>4__this; } [CompilerGenerated] private sealed class d__21 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private BoosterImplantInventoryItem <>2__current; private int <>l__initialThreadId; private BoosterImplantTemplateDataBlock template; public BoosterImplantTemplateDataBlock <>3__template; public ArtifactsAndBoostersHandler <>4__this; private <>c__DisplayClass21_0 <>8__1; private IEnumerator <>7__wrap1; private Enumerator <>7__wrap2; BoosterImplantInventoryItem IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__21(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; } <>8__1 = null; <>7__wrap1 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_00d7: 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_00f9: 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_0115: Expected O, but got Unknown //IL_0178: 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) try { uint current2; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass21_0(); <>8__1.template = template; <>8__1.<>4__this = <>4__this; <>8__1.baseItem = new BoosterImplantInventoryItem { Flags = 1u, Effects = new Il2CppStructArray((long)(<>8__1.template.Effects.Count + <>8__1.template.RandomEffects.Count)), Conditions = new Il2CppStructArray((long)(<>8__1.template.Conditions.Count + ((<>8__1.template.RandomConditions.Count > 0) ? 1 : 0))), TemplateId = ((GameDataBlockBase)(object)<>8__1.template).persistentID, UsesRemaining = (int)<>8__1.template.DurationRange.y, Id = 1u }; for (int i = 0; i < <>8__1.template.Conditions.Count; i++) { ((Il2CppArrayBase)(object)((BoosterImplantBase)<>8__1.baseItem).Conditions)[i] = <>8__1.template.Conditions[i]; } for (int j = 0; j < <>8__1.template.Effects.Count; j++) { ((Il2CppArrayBase)(object)((BoosterImplantBase)<>8__1.baseItem).Effects)[j] = new BoosterImplantEffect { Id = <>8__1.template.Effects[j].BoosterImplantEffect, Param = <>8__1.template.Effects[j].MaxValue }; } if (<>8__1.template.RandomConditions.Count == 0) { <>7__wrap1 = GenerateRecursive(0).GetEnumerator(); <>1__state = -3; goto IL_0248; } <>7__wrap2 = <>8__1.template.RandomConditions.GetEnumerator(); goto IL_0344; } case 1: <>1__state = -3; goto IL_0248; case 2: { <>1__state = -4; goto IL_032a; } IL_0248: if (<>7__wrap1.MoveNext()) { BoosterImplantInventoryItem current = <>7__wrap1.Current; <>2__current = current; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = null; break; IL_02b5: ((Il2CppArrayBase)(object)((BoosterImplantBase)<>8__1.baseItem).Conditions)[<>8__1.template.Conditions.Count] = current2; <>7__wrap1 = GenerateRecursive(0).GetEnumerator(); <>1__state = -4; goto IL_032a; IL_032a: if (<>7__wrap1.MoveNext()) { BoosterImplantInventoryItem current3 = <>7__wrap1.Current; <>2__current = current3; <>1__state = 2; return true; } <>m__Finally2(); <>7__wrap1 = null; goto IL_0344; IL_0344: while (<>7__wrap2.MoveNext()) { current2 = <>7__wrap2.Current; if (current2 == 11 && <>8__1.template.RandomConditions.Count > 1) { continue; } goto IL_02b5; } <>7__wrap2 = null; break; } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } [IteratorStateMachine(typeof(<>c__DisplayClass21_0.<g__GenerateRecursive|0>d))] IEnumerable GenerateRecursive(int depth) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass21_0.<g__GenerateRecursive|0>d(-2) { <>4__this = this, <>3__depth = depth }; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__21 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__21(0) { <>4__this = <>4__this }; } d__.template = <>3__template; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static IArchiveLogger? m_featureLogger; private SortedList>? m_cachedImplants; private Il2CppAction? m_overwriteCallback; public override string Name => "Artifacts and Boosters Handler"; public override string Description => "Converts all collected artifacts to shared energy, and allows players to used energy to equip boosters."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_FloatingHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public IReadOnlyDictionary> CachedImplants { get { RegenerateLists(); return m_cachedImplants; } } public uint NextID { get; protected set; } public override void OnEnable() { base.OnEnable(); if ((Object)(object)PersistentInventoryManager.Current != (Object)null && m_overwriteCallback == null) { m_overwriteCallback = new Il2CppAction(OverwriteInventory); OverwriteInventory(); PersistentInventoryManager.Current.OnBoosterImplantInventoryChanged.Invoke(); PersistentInventoryManager current = PersistentInventoryManager.Current; current.OnBoosterImplantInventoryChanged += (Action)m_overwriteCallback; } } public override void OnDisable() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown base.OnDisable(); if (!((Object)(object)PersistentInventoryManager.Current != (Object)null)) { return; } if (m_overwriteCallback != null) { PersistentInventoryManager current = PersistentInventoryManager.Current; current.OnBoosterImplantInventoryChanged -= (Action)m_overwriteCallback; m_overwriteCallback = null; } PersistentInventoryManager.Current.m_boosterImplantInventory = new BoosterImplantInventoryModel(); CancellationTokenSource val = new CancellationTokenSource(); Task boosterImplantPlayerDataAsync = DropServerManager.Current.GetBoosterImplantPlayerDataAsync(val.Token); ((Task)boosterImplantPlayerDataAsync).Wait(); if (((Task)boosterImplantPlayerDataAsync).IsCanceled || ((Task)boosterImplantPlayerDataAsync).IsFaulted || !boosterImplantPlayerDataAsync.Result.BoosterData.HasValue) { FeatureLogger.Warning("Failed to retrieve actual booster data. Clearing out booster inventory!"); return; } BoosterImplantPlayerData valueOrDefault = boosterImplantPlayerDataAsync.Result.BoosterData.GetValueOrDefault(); BoosterImplantInventoryModel boosterImplantInventory = PersistentInventoryManager.Current.m_boosterImplantInventory; boosterImplantInventory.New = new List(((Il2CppArrayBase)(object)valueOrDefault.New).Count); foreach (uint item in (Il2CppArrayBase)(object)valueOrDefault.New) { boosterImplantInventory.New.Add(item); } ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[0].Currency = valueOrDefault.Basic.Currency; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[0].Missed = valueOrDefault.Basic.Missed; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[0].MissedAcknowledged = valueOrDefault.Basic.MissedAck; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[0].Inventory = new List(((Il2CppArrayBase)(object)valueOrDefault.Basic.Inventory).Count); foreach (BoosterImplantInventoryItem item2 in (Il2CppArrayBase)(object)valueOrDefault.Basic.Inventory) { ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[0].Inventory.Add(new BoosterImplantInventoryItem(item2)); } ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[1].Currency = valueOrDefault.Advanced.Currency; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[1].Missed = valueOrDefault.Advanced.Missed; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[1].MissedAcknowledged = valueOrDefault.Advanced.MissedAck; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[1].Inventory = new List(((Il2CppArrayBase)(object)valueOrDefault.Advanced.Inventory).Count); foreach (BoosterImplantInventoryItem item3 in (Il2CppArrayBase)(object)valueOrDefault.Advanced.Inventory) { ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[1].Inventory.Add(new BoosterImplantInventoryItem(item3)); } ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[2].Currency = valueOrDefault.Specialized.Currency; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[2].Missed = valueOrDefault.Specialized.Missed; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[2].MissedAcknowledged = valueOrDefault.Specialized.MissedAck; ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[2].Inventory = new List(((Il2CppArrayBase)(object)valueOrDefault.Specialized.Inventory).Count); foreach (BoosterImplantInventoryItem item4 in (Il2CppArrayBase)(object)valueOrDefault.Specialized.Inventory) { ((Il2CppArrayBase)(object)boosterImplantInventory.Categories)[2].Inventory.Add(new BoosterImplantInventoryItem(item4)); } } public void RegenerateLists(bool force = false) { //IL_0054: 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_00dc: Unknown result type (might be due to invalid IL or missing references) if (m_cachedImplants != null && !force) { return; } m_cachedImplants?.Clear(); if (m_cachedImplants == null) { m_cachedImplants = new SortedList>(); } NextID = 1u; SortedList> sortedList = new SortedList>(4); foreach (BoosterImplantTemplateDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { if (!sortedList.TryGetValue(allBlock.ImplantCategory, out var value)) { value = new List(); sortedList[allBlock.ImplantCategory] = value; } foreach (BoosterImplantInventoryItem item in GenerateIdealBoosters(allBlock)) { value.Add(item); } } foreach (KeyValuePair> item2 in sortedList) { m_cachedImplants[item2.Key] = Il2CppReferenceArray.op_Implicit(item2.Value.ToArray()); } } [IteratorStateMachine(typeof(d__21))] public IEnumerable GenerateIdealBoosters(BoosterImplantTemplateDataBlock template) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__21(-2) { <>4__this = this, <>3__template = template }; } public static long GetArtifactValue(ArtifactCategory cat) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected I4, but got Unknown return (int)cat switch { 0 => 40000000000L, 1 => 126000000000L, 2 => 400000000000L, _ => throw new ArgumentException($"Unexpected artifact category: {(int)cat}"), }; } public void OverwriteInventory() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected O, but got Unknown PersistentInventoryManager current = PersistentInventoryManager.Current; if (((IEnumerable)current.m_boosterImplantInventory.Categories).Sum((Category c) => c.Inventory.Count) == CachedImplants.Sum>>((KeyValuePair> pair) => ((Il2CppArrayBase)(object)pair.Value).Count)) { return; } FeatureLogger.Debug("Overwriting booster inventory"); Il2CppReferenceArray val = CachedImplants[(BoosterImplantCategory)0]; Category val2 = ((Il2CppArrayBase)(object)current.m_boosterImplantInventory.Categories)[0]; val2.Inventory.Clear(); val2.Inventory.EnsureCapacity(((Il2CppArrayBase)(object)val).Length); foreach (BoosterImplantInventoryItem item in (Il2CppArrayBase)(object)val) { val2.Inventory.Add(new BoosterImplantInventoryItem(item)); } val = CachedImplants[(BoosterImplantCategory)1]; val2 = ((Il2CppArrayBase)(object)current.m_boosterImplantInventory.Categories)[1]; val2.Inventory.Clear(); val2.Inventory.EnsureCapacity(((Il2CppArrayBase)(object)val).Length); foreach (BoosterImplantInventoryItem item2 in (Il2CppArrayBase)(object)val) { val2.Inventory.Add(new BoosterImplantInventoryItem(item2)); } val = CachedImplants[(BoosterImplantCategory)2]; val2 = ((Il2CppArrayBase)(object)current.m_boosterImplantInventory.Categories)[2]; val2.Inventory.Clear(); val2.Inventory.EnsureCapacity(((Il2CppArrayBase)(object)val).Length); foreach (BoosterImplantInventoryItem item3 in (Il2CppArrayBase)(object)val) { val2.Inventory.Add(new BoosterImplantInventoryItem(item3)); } current.OnBoosterImplantInventoryChanged.Invoke(); } } public static class FreeCheckpointsHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_FreeCheckpoints { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_FreeCheckpoints(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Free Checkpoint Items", "Items which trigger an immediate checkpoint when used", RootRandomizationTags.get_Tag_OptionalItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class FreeCheckpointsHandler : ArchipelagoFeature { private class FreeCheckpointItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass11_0 { public LG_ComputerTerminal terminal; internal void b__0() { terminal.AddLine((TerminalLineType)4, "Activating <#0F0>CHECKPOINT", 2.5f); } internal void b__1() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) SNet.Capture.CaptureGameState((eBufferType)3); CheckpointManager.StoreCheckpoint(terminal.m_position); terminal.AddLine("<#0F0>CHECKPOINT reached!", true); } } [CompilerGenerated] private sealed class d__11 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; private <>c__DisplayClass11_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__11(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass11_0(); <>8__1.terminal = terminal; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)4, "Activating <#0F0>CHECKPOINT", 2.5f); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) SNet.Capture.CaptureGameState((eBufferType)3); CheckpointManager.StoreCheckpoint(<>8__1.terminal.m_position); <>8__1.terminal.AddLine("<#0F0>CHECKPOINT reached!", true); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__11 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__11(0); } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Expedition.Data ExpeditionData { get; set; } public override Expedition.Data? RequiredExpedition => ExpeditionData; public FreeCheckpointItem(Expedition.Data expedition) : base(MakeTag(expedition), MakeRandData()) { ExpeditionData = expedition; } public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Free Checkpoint", "Item which triggers a checkpoint when used", FreeCheckpointsHandler_Tags.get_Tag_FreeCheckpoints(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsUseful = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player = null) { if (ExpeditionData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ExpeditionData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__11))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__11(-2) { <>3__terminal = terminal }; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Unlock Expedition Handler"; public override string Description => "Locks expeditions and adds floating expedition unlock items which unlock them"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_FloatingHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetCheckpointItem(Expedition.Data data) { if (data.TryLookupItem(FreeCheckpointItem.MakeTag(data), out var item)) { return item; } Item item2 = new FreeCheckpointItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Expedition.Callback] public void AddExpeditionUnlock(Expedition.Data data) { data.AddFloatingItem(GetCheckpointItem(data).ID); } } public static class LockGearHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GearItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_HackingTool { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MeleeItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MeleeSledgehammerItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MeleeKnifeItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MeleeSpearItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MeleeBatItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PrimaryItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PrimaryGuns { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_PrimaryShotgun { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SpecialItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SpecialGuns { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SpecialShotgun { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ToolItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_BiotrackerItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_MineDeployerItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_CFoamItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_SentryItems { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_GearItems_ByType(uint itemBaseID) { throw new NotSupportedException(); } } public static TagResolver get_Tag_GearItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Gear Items", "All equippable gear items, including weapons, primaries, specials, tools, and the hacking tool.", RootRandomizationTags.get_Tag_OptionalItems(gd))); } public static TagResolver Tag_GearItems_ByType(this Game.Data data, uint itemBaseID) { switch (itemBaseID) { case 53u: return get_Tag_HackingTool(data); case 100u: return get_Tag_MeleeSledgehammerItems(data); case 161u: return get_Tag_MeleeKnifeItems(data); case 162u: return get_Tag_MeleeSpearItems(data); case 163u: return get_Tag_MeleeBatItems(data); case 108u: return get_Tag_PrimaryGuns(data); case 156u: return get_Tag_PrimaryShotgun(data); case 109u: return get_Tag_SpecialGuns(data); case 110u: return get_Tag_SpecialShotgun(data); case 28u: return get_Tag_BiotrackerItems(data); case 37u: return get_Tag_MineDeployerItems(data); case 73u: return get_Tag_CFoamItems(data); case 97u: return get_Tag_SentryItems(data); default: { ItemDataBlock block = GameDataBlockBase.GetBlock(itemBaseID); throw new ArgumentException("Item " + (((block != null) ? block.publicName : null) ?? "NULL") + " is not a gear item type!"); } } } public static TagResolver get_Tag_HackingTool(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Hacking Tool", "Special gear category for the sentry gun", RootRandomizationTags.get_Tag_Never(gd))); } public static TagResolver get_Tag_MeleeItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Melee Gear Items", "All equippable gear items in the melee slot", get_Tag_GearItems(gd))); } public static TagResolver get_Tag_MeleeSledgehammerItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Melee Sledgehammer Items", "All melee gear considered to be a sledgehammer", get_Tag_MeleeItems(gd))); } public static TagResolver get_Tag_MeleeKnifeItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Melee Knife Items", "All melee gear considered to be a knife", get_Tag_MeleeItems(gd))); } public static TagResolver get_Tag_MeleeSpearItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Melee Spear Items", "All melee gear considered to be a spear", get_Tag_MeleeItems(gd))); } public static TagResolver get_Tag_MeleeBatItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Melee Bat Items", "All melee gear considered to be a bat", get_Tag_MeleeItems(gd))); } public static TagResolver get_Tag_PrimaryItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Primary Gear Items", "All equippable gear items in the primary slot", get_Tag_GearItems(gd))); } public static TagResolver get_Tag_PrimaryGuns(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Primary Gun Items", "Equippable items in the primary slot which are considered guns", get_Tag_PrimaryItems(gd))); } public static TagResolver get_Tag_PrimaryShotgun(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Primary Shotgun Items", "Equippable items in the primary slot which are considered shotguns", get_Tag_PrimaryItems(gd))); } public static TagResolver get_Tag_SpecialItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Special Gear Items", "All equippable gear items in the special slot", get_Tag_GearItems(gd))); } public static TagResolver get_Tag_SpecialGuns(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Special Gun Items", "Equippable items in the special slot which are considered guns", get_Tag_SpecialItems(gd))); } public static TagResolver get_Tag_SpecialShotgun(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Special Shotgun Items", "Equippable items in the special slot which are considered shotguns", get_Tag_SpecialItems(gd))); } public static TagResolver get_Tag_ToolItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Tool Gear Items", "All equippable gear items in the tool slot (also known as the class slot)", get_Tag_GearItems(gd))); } public static TagResolver get_Tag_BiotrackerItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Biotracker Items", "All equippable gear items in the tool slot considered to be a biotracker", get_Tag_ToolItems(gd))); } public static TagResolver get_Tag_MineDeployerItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Mine Deployer Items", "All equippable gear items in the tool slot considered to be a mine deployer", get_Tag_ToolItems(gd))); } public static TagResolver get_Tag_CFoamItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("C-foam Items Items", "All equippable gear items in the tool slot considered to be a CFoam launcher", get_Tag_ToolItems(gd))); } public static TagResolver get_Tag_SentryItems(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Sentry Items", "All equippable gear items in the tool slot considered to be a deployable sentry", get_Tag_ToolItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class LockGearHandler : ArchipelagoFeature { private class GearItemUnlock : Item { [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public LG_ComputerTerminal terminal; public SNet_Player player; public GearItemUnlock <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving your gear...", 2f); } internal void b__1() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown PlayerBackpack val = default(PlayerBackpack); if (!PlayerBackpackManager.TryGetBackpack(player, ref val)) { FeatureLogger.Error("Failed to get player backpack while giving gear!"); terminal.AddLine("<#F00>Failed to retrieve your gear! It has been re-added to terminal system.", true); } GearIDRange desiredGear = new GearIDRange(<>4__this.Block.GearJSON); SetPlayerGear(player, desiredGear); terminal.AddLine("Gear item \"" + ((GameDataBlockBase)(object)<>4__this.Block).name + "\" has been given to " + player.NickName, true); } } [CompilerGenerated] private sealed class d__9 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public GearItemUnlock <>4__this; private <>c__DisplayClass9_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass9_0(); <>8__1.terminal = terminal; <>8__1.<>4__this = <>4__this; <>8__1.player = <>8__1.terminal.m_syncedInteractionSource.Owner; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving your gear...", 2f); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown PlayerBackpack val = default(PlayerBackpack); if (!PlayerBackpackManager.TryGetBackpack(<>8__1.player, ref val)) { FeatureLogger.Error("Failed to get player backpack while giving gear!"); <>8__1.terminal.AddLine("<#F00>Failed to retrieve your gear! It has been re-added to terminal system.", true); } GearIDRange desiredGear = new GearIDRange(<>8__1.<>4__this.Block.GearJSON); SetPlayerGear(<>8__1.player, desiredGear); <>8__1.terminal.AddLine("Gear item \"" + ((GameDataBlockBase)(object)<>8__1.<>4__this.Block).name + "\" has been given to " + <>8__1.player.NickName, true); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__9 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__9(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public PlayerOfflineGearDataBlock Block { get; set; } public GearItemUnlock(Game.Data data, PlayerOfflineGearDataBlock block) : base(MakeTag(data, block), MakeRandData()) { Block = block; } public static TagResolver MakeTag(Game.Data data, PlayerOfflineGearDataBlock block) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown GearIDRange idRange = new GearIDRange(block.GearJSON); string name = idRange.PublicGearName.ToString(); GearCategoryDataBlock block2 = GameDataBlockBase.GetBlock(idRange.GetCompID((eGearComponent)2)); if (block2 != null) { name = ((Object)block2.PublicName).ToString(); ArchetypeDataBlock block3 = GameDataBlockBase.GetBlock(idRange.GetCompID((eGearComponent)1) switch { 2u => block2.AutoArchetype, 1u => block2.BurstArchetype, 0u => block2.SemiArchetype, 3u => block2.SemiBurstArchetype, 11u => 57u, 12u => 55u, 10u => 54u, 13u => 58u, _ => 0u, }); if (block3 != null) { name = ((Object)block3.PublicName).ToString(); } } name = name + " (" + idRange.PublicGearName + ")"; return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag(name, "A specific gear item", gd.Tag_GearItems_ByType(idRange.GetCompID((eGearComponent)3)))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsUseful = true; result.CollectedByDefault = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { AddGear(stateTracker, Block); stateTracker.AddItemToTerminal(this); } public override void OnItemLost(StateTracker stateTracker) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GearIDRange val = new GearIDRange(Block.GearJSON); RemoveGear(val); val.SetCompID((eGearComponent)0, ((GameDataBlockBase)(object)Block).persistentID, false); } [IteratorStateMachine(typeof(d__9))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(-2) { <>4__this = this, <>3__terminal = terminal }; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class PlayerBackpackManager__EquipBotGear__Patch { private static List> m_lastEquippedGear = new List>(); public static void Prefix(SNet_Player bot, ref GearIDRange gearSetup) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected I4, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected I4, but got Unknown GearIDRange localGear = gearSetup; ItemDataBlock block = GameDataBlockBase.GetBlock(gearSetup.GetCompID((eGearComponent)3)); int index = bot.CharacterSlot.index; int num = (int)block.inventorySlot; while (m_lastEquippedGear.Count <= index) { m_lastEquippedGear.Add(new List()); } List list = m_lastEquippedGear[index]; while (list.Count <= num) { list.Add(null); } if (!((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[(int)block.inventorySlot].Any((GearIDRange g) => g.IsEqual(localGear))) { gearSetup = list[num] ?? ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[(int)block.inventorySlot].First(); } list[num] = gearSetup; } } private static IArchiveLogger? m_featureLogger; private const eGearComponent INJECTED_COMP_VALUE = 0; public override string Name => "Lock Gear Handler"; public override string Description => "Disables player gear items and adds floating items which re-enables them"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_FloatingHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetGearItem(Game.Data data, PlayerOfflineGearDataBlock block) { if (data.TryLookupItem(GearItemUnlock.MakeTag(data, block), out var item)) { return item; } Item item2 = new GearItemUnlock(data, block); return new KeyedItem(data.AddItem(item2), item2); } [Game.Callback] public void AddGearItems(Game.Data data) { //IL_0015: 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_0023: Invalid comparison between Unknown and I4 foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { if ((int)allBlock.Type != 0 && (int)allBlock.Type != 3 && ((GameDataBlockBase)(object)allBlock).internalEnabled) { data.AddFloatingItem(GetGearItem(data, allBlock).ID); } } } private static void AddGear(StateTracker stateTracker, PlayerOfflineGearDataBlock block) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown GearIDRange val = new GearIDRange(block.GearJSON); val.SetCompID((eGearComponent)0, ((GameDataBlockBase)(object)block).persistentID, false); int num = (int)GameDataBlockBase.GetBlock(val.GetCompID((eGearComponent)3)).inventorySlot; GearIDRange val2 = null; if (((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num].Count == 1) { uint compID = ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num][0].GetCompID((eGearComponent)0); if (compID != 0) { KeyedItem gearItem = GetGearItem(stateTracker.MidManager.GetProcessedGameData(), GameDataBlockBase.GetBlock(compID)); int valueOrDefault = stateTracker.CollectedItemCounts.GetValueOrDefault(gearItem.ID, 0); if (valueOrDefault == 0) { val2 = ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num][0]; } else if (compID == ((GameDataBlockBase)(object)block).persistentID && valueOrDefault == 1) { return; } } } int num2 = findIndex(((GameDataBlockBase)(object)block).persistentID); bool flag = false; for (int i = 0; i < ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num].Count; i++) { if (num2 < findIndex(((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num][i].GetCompID((eGearComponent)0))) { ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num].Insert(i, val); flag = true; break; } } if (!flag) { ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[num].Add(val); } if (val2 != null) { RemoveGear(val2); } static int findIndex(uint datablockId) { int num3 = 0; foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { if (((GameDataBlockBase)(object)allBlock).persistentID == datablockId) { return num3; } num3++; } return num3; } } private static void RemoveGear(GearIDRange ids) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected I4, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected I4, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Invalid comparison between Unknown and I4 //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //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) InventorySlot inventorySlot = GameDataBlockBase.GetBlock(ids.GetCompID((eGearComponent)3)).inventorySlot; List val = ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[(int)inventorySlot]; uint compID = ids.GetCompID((eGearComponent)0); ids.SetCompID((eGearComponent)0, 0u, false); uint num = 0u; int i; for (i = 0; i < val.Count; i++) { num = val[i].GetCompID((eGearComponent)0); val[i].SetCompID((eGearComponent)0, 0u, false); if (val[i].IsEqual(ids)) { break; } val[i].SetCompID((eGearComponent)0, num, false); } ids.SetCompID((eGearComponent)0, compID, false); if (i != val.Count) { val[i].SetCompID((eGearComponent)0, num, false); val.RemoveAt(i); } else { FeatureLogger.Warning("Failed to remove gear item during OnItemLost"); } if (val.Count == 0) { FeatureLogger.Warning("Removed all player gear from slot " + Enum.GetName(inventorySlot) + "; restoring first entry to prevent bugs..."); GearIDRange val2 = null; foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase.GetAllBlocks()) { if ((int)allBlock.Type != 0 && (int)allBlock.Type != 3) { val2 = new GearIDRange(allBlock.GearJSON); if (GameDataBlockBase.GetBlock(val2.GetCompID((eGearComponent)3)).inventorySlot == inventorySlot) { val2.SetCompID((eGearComponent)0, ((GameDataBlockBase)(object)allBlock).persistentID, false); break; } val2 = null; } } if (val2 == null) { FeatureLogger.Error("Somehow did not find a replacment gear item!"); val2 = ids; } val.Add(val2); } if (SNet.LobbyPlayers.Count == 0) { if (((Il2CppArrayBase)(object)PlayerBackpackManager.LocalBackpack.Slots)[(int)inventorySlot].GearIDRange.IsEqual(ids)) { SetPlayerGear(SNet.LocalPlayer, val[0]); } return; } Enumerator enumerator2 = SNet.Slots.SlottedPlayers.GetEnumerator(); while (enumerator2.MoveNext()) { SNet_Player current2 = enumerator2.Current; if (current2.IsLocal || (SNet.IsMaster && current2.IsBot)) { PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(current2); if (((Il2CppArrayBase)(object)backpack.Slots)[(int)inventorySlot].GearIDRange.IsEqual(ids)) { SetPlayerGear(current2, val[0]); } } } } private static void SetPlayerGear(SNet_Player player, GearIDRange desiredGear) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected I4, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected I4, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected I4, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Invalid comparison between Unknown and I4 //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Invalid comparison between Unknown and I4 //IL_01db: 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) FeatureLogger.Debug($"Attempting to give \"{player.NickName}\" gear item \"{desiredGear.PublicGearName}\""); if (!player.IsLocal && (!player.IsBot || !SNet.IsMaster)) { FeatureLogger.Debug("Cancelled -> That player is not locally owned!"); return; } ItemDataBlock block = GameDataBlockBase.GetBlock(desiredGear.GetCompID((eGearComponent)3)); InventorySlot inventorySlot = block.inventorySlot; PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(player); SNet_IPlayerAgent playerAgent = player.PlayerAgent; PlayerAgent val = ((playerAgent != null) ? ((Il2CppObjectBase)playerAgent).Cast() : null); Item val2 = default(Item); if ((int)((Il2CppArrayBase)(object)backpack.Slots)[(int)inventorySlot].Status == 1 && backpack.TryGetDeployedItem(inventorySlot, ref val2)) { FeatureLogger.Debug("Detected that gear being replaced is deployed. Attempting to pick up as a sentry gun..."); SentryGunInstance val3 = ((Il2CppObjectBase)val2).TryCast(); if ((Object)(object)val3 == (Object)null) { FeatureLogger.Debug("Failed to pick up sentry gun while changing gear!"); } else { ((ItemEquippable)val3).PickUp(val); } } if (player.IsBot) { PlayerBackpackManager.EquipBotGear(player, desiredGear); } else if (player.IsLocal) { PlayerBackpackManager.EquipLocalGear(desiredGear); } else { PlayerBackpackManager.Current.EquipSyncGear(inventorySlot, desiredGear, player); } Item instance = ((Il2CppArrayBase)(object)backpack.Slots)[(int)inventorySlot].Instance; ItemEquippable val4 = ((Il2CppObjectBase)instance).TryCast(); if ((Object)(object)val4 == (Object)null) { FeatureLogger.Warning("Failed to identify newly spawned gear as equippable. Skipping relevant calls."); } else if ((int)val4.AmmoType == 0 || (int)val4.AmmoType == 1 || (int)val4.AmmoType == 2) { AmmoType ammoType = val4.AmmoType; float num = 0.5f * (int)ammoType switch { 0 => 460f, 1 => 230f, 2 => 150f, _ => throw new ArgumentException(), }; if (backpack.AmmoStorage.GetAmmoInPack(val4.AmmoType) < num) { backpack.AmmoStorage.SetAmmo(val4.AmmoType, num); } BulletWeapon val5 = ((Il2CppObjectBase)val4).TryCast(); if ((Object)(object)val5 != (Object)null) { ((ItemEquippable)val5).SetCurrentClipRel(1f); } } } } public static class LockLobbySlotsHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_LobbySlotUnlocks { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_LobbySlotUnlocks(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Unlock Lobby Slot Items", "Items which unlock more lobby slots", RootRandomizationTags.get_Tag_OptionalItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class LockLobbySlotsHandler : ArchipelagoFeature { private class LobbySlotUnlockItem : Item { public int Index { get; set; } public LobbySlotUnlockItem(Game.Data data, int index) : base(MakeTag(data, index), MakeRandData()) { Index = index; } public static TagResolver MakeTag(Game.Data data, int index) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag($"Lobby Slot #{index} Unlock", "Item which unlocks a particular lobby slot", LockLobbySlotsHandler_Tags.get_Tag_LobbySlotUnlocks(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsUseful = true; result.CollectedByDefault = true; return result; } public void LockButtonNow() { //IL_0027: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_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_0084: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_0116: 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) //IL_0122: 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_013e: 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) CM_PlayerLobbyBar val = ((Il2CppArrayBase)(object)MainMenuGuiLayer.Current.PageLoadout.m_playerLobbyBars)[Index]; TextMeshPro component = ((Component)val.m_permissionButton).GetComponent(); Color grey = Color.grey; grey.a = 0.4f; ((Graphic)component).color = grey; if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)[0] = new Color(grey.r, grey.g, grey.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)[0].a); } if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)[0] = new Color(grey.r, grey.g, grey.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)[0].a); } if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)[0] = new Color(grey.r, grey.g, grey.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)[0].a); } foreach (SpriteRenderer componentsInChild in ((Component)val.m_permissionButton).GetComponentsInChildren()) { componentsInChild.color = grey; } val.OnPermissionButtonPressed = null; } public void UnlockButtonNow() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_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_0084: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_0116: 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) //IL_0122: 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_013e: 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) //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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown CM_PlayerLobbyBar val = ((Il2CppArrayBase)(object)MainMenuGuiLayer.Current.PageLoadout.m_playerLobbyBars)[Index]; Color red = Color.red; red.a = 0.4f; TextMeshPro component = ((Component)val.m_permissionButton).GetComponent(); ((Graphic)component).color = red; if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)[0] = new Color(red.r, red.g, red.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOrg)[0].a); } if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)[0] = new Color(red.r, red.g, red.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOut)[0].a); } if ((((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)?.Count ?? 0) > 0) { ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)[0] = new Color(red.r, red.g, red.b, ((Il2CppArrayBase)(object)val.m_permissionButton.m_textColorOver)[0].a); } foreach (SpriteRenderer componentsInChild in ((Component)val.m_permissionButton).GetComponentsInChildren()) { componentsInChild.color = red; } __c__DisplayClass29_0 val2 = new __c__DisplayClass29_0 { __4__this = MainMenuGuiLayer.Current.PageLoadout, bar = val }; IntPtr il2CppMethod = IL2CPP.GetIl2CppMethod(((Il2CppObjectBase)val2).ObjectClass, false, "b__7", typeof(void).FullName, new string[1] { typeof(int).FullName }); val.OnPermissionButtonPressed = new Action((Object)(object)val2, il2CppMethod); } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player = null) { UnlockButtonNow(); } public override void OnItemLost(StateTracker stateTracker) { SNet.Slots.SetSlotPermission(Index, (SlotPermission)1); SNet_Player player = ((Il2CppArrayBase)(object)SNet.Slots.CharacterSlots)[Index].player; if ((Object)(object)player != (Object)null) { SNet.Slots.RemoveFromPlayersInGame(player); } LockButtonNow(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class SNet_PlayerSlotManager__GetSlotPermission__Patch { public static bool Prefix(SNet_PlayerSlotManager __instance, int playerIndex) { if (playerIndex == 0) { return true; } StateTracker stateTracker = StateTracker.Get(); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); if (!processedGameData.TryLookupItem(LobbySlotUnlockItem.MakeTag(processedGameData, playerIndex), out var item)) { FeatureLogger.Error("Failed to lookup slot unlock item; allowing slot modifications!"); return true; } if (stateTracker.CollectedItemCounts.GetValueOrDefault(item.ID, 0) > 0) { return true; } if (!item.Item.RandMode.IsTreatedAsRandom) { return true; } ((Il2CppArrayBase)(object)__instance.m_playerSlotPermissions)[playerIndex] = (SlotPermission)1; return false; } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class CM_PlayerLobbyBar__SetupSlot__Patch { public static void Postfix(CM_PlayerLobbyBar __instance, int pillarIndex) { if (pillarIndex != 0) { StateTracker stateTracker = StateTracker.Get(); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); if (!processedGameData.TryLookupItem(LobbySlotUnlockItem.MakeTag(processedGameData, pillarIndex), out var item)) { FeatureLogger.Error("Failed to lookup slot unlock item; not locking slot button!"); } else if (stateTracker.CollectedItemCounts.GetValueOrDefault(item.ID, 0) <= 0 && item.Item.RandMode.IsTreatedAsRandom) { item.OnItemLost(stateTracker); } } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Lock Lobby Spots Handler"; public override string Description => "Locks lobby slots and forces players to find specific items to unlock them"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_FloatingHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetSlotUnlockItem(Game.Data data, int index) { if (data.TryLookupItem(LobbySlotUnlockItem.MakeTag(data, index), out var item)) { return item; } Item item2 = new LobbySlotUnlockItem(data, index); return new KeyedItem(data.AddItem(item2), item2); } [Game.Callback] public void AddSlotUnlockItems(Game.Data data) { for (int i = 1; i < ((Il2CppArrayBase)(object)SNet.Slots.CharacterSlots).Count; i++) { data.AddFloatingItem(GetSlotUnlockItem(data, i).ID); } } } public static class UnlockExpeditionHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $55FD246F9BFF39DD56FCB5C25D4DF852 { } [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] public TagResolver Tag_ExpeditionUnlocks { [ExtensionMarker("$55FD246F9BFF39DD56FCB5C25D4DF852")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_ExpeditionUnlocks(Game.Data data) { return new TagResolver(data, (Game.Data gd) => gd.LookupOrCreateTag("Expedition Unlock Items", "Items which trigger expeditions to be unlocked", RootRandomizationTags.get_Tag_OptionalItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class UnlockExpeditionHandler : ArchipelagoFeature { public class Settings { [FSDisplayName("Unlock All Expeditions")] [FSDescription("Immediately unlocks all expeditions")] public FButton UnlockAllButton { get; set; } = new FButton("Unlock All", (string)null, (Action)UnlockAll, false); [FSDisplayName("Re-Lock All Expeditions")] [FSDescription("Undoes the Unlock All button, applying locks to any expeditions which were previously locked")] public FButton ResetAllButton { get; set; } = new FButton("Reset Locks", (string)null, (Action)ResetLocks, false); } private class ExpeditionUnlockItem : Item { public Expedition.Data ExpeditionData { get; set; } public override Expedition.Data? RequiredExpedition => ExpeditionData; public ExpeditionUnlockItem(Expedition.Data expedition) : base(MakeTag(expedition), MakeRandData()) { ExpeditionData = expedition; base.Tag2 = RootRandomizationTags.get_Tag_UnlockItems_ByExpedition(expedition); } public static TagResolver MakeTag(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Expedition Unlock", "Item which unlocks a particular expedition", UnlockExpeditionHandler_Tags.get_Tag_ExpeditionUnlocks(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; result.CollectedByDefault = true; return result; } private List FindExpeditions() { List list = (from e in GetExpeditions() where Expedition.Data.TryFromExpedition(e)?.IsSameExpedition(ExpeditionData) ?? false select e).ToList(); if (list.Count == 0) { FeatureLogger.Error("Failed to find expedition during lock/unlock event: " + ExpeditionData.ExpeditionName); } return list; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player = null) { if (!((Feature)ArchipelagoFeatureHelper.GetFeature()).Enabled) { return; } foreach (ExpeditionInTierData item in FindExpeditions()) { item.Accessibility = (eExpeditionAccessibility)2; } StateTracker.UpdateLocationCounts(); } public override void OnItemLost(StateTracker stateTracker) { if (!((Feature)ArchipelagoFeatureHelper.GetFeature()).Enabled) { return; } foreach (ExpeditionInTierData item in FindExpeditions()) { item.Accessibility = (eExpeditionAccessibility)1; } StateTracker.UpdateLocationCounts(); } } [CompilerGenerated] private sealed class d__15 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private ExpeditionInTierData <>2__current; private int <>l__initialThreadId; private RundownDataBlock rundown; public RundownDataBlock <>3__rundown; private Enumerator <>7__wrap1; ExpeditionInTierData IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = rundown.TierA.GetEnumerator(); goto IL_0069; case 1: <>1__state = -1; goto IL_0069; case 2: <>1__state = -1; goto IL_00b8; case 3: <>1__state = -1; goto IL_0107; case 4: <>1__state = -1; goto IL_0158; case 5: { <>1__state = -1; break; } IL_0069: if (<>7__wrap1.MoveNext()) { ExpeditionInTierData current = <>7__wrap1.Current; <>2__current = current; <>1__state = 1; return true; } <>7__wrap1 = null; <>7__wrap1 = rundown.TierB.GetEnumerator(); goto IL_00b8; IL_00b8: if (<>7__wrap1.MoveNext()) { ExpeditionInTierData current2 = <>7__wrap1.Current; <>2__current = current2; <>1__state = 2; return true; } <>7__wrap1 = null; <>7__wrap1 = rundown.TierC.GetEnumerator(); goto IL_0107; IL_0158: if (<>7__wrap1.MoveNext()) { ExpeditionInTierData current3 = <>7__wrap1.Current; <>2__current = current3; <>1__state = 4; return true; } <>7__wrap1 = null; <>7__wrap1 = rundown.TierE.GetEnumerator(); break; IL_0107: if (<>7__wrap1.MoveNext()) { ExpeditionInTierData current4 = <>7__wrap1.Current; <>2__current = current4; <>1__state = 3; return true; } <>7__wrap1 = null; <>7__wrap1 = rundown.TierD.GetEnumerator(); goto IL_0158; } if (<>7__wrap1.MoveNext()) { ExpeditionInTierData current5 = <>7__wrap1.Current; <>2__current = current5; <>1__state = 5; return true; } <>7__wrap1 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__15 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__15(0); } d__.rundown = <>3__rundown; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static IArchiveLogger? m_featureLogger; public override string Name => "Unlock Expedition Handler"; public override string Description => "Locks expeditions and adds floating expedition unlock items which unlock them"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_FloatingHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [FeatureConfig] public static int Config { get; set; } [IteratorStateMachine(typeof(d__15))] private static IEnumerable UnpackRundown(RundownDataBlock rundown) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(-2) { <>3__rundown = rundown }; } private static IEnumerable GetExpeditions() { return ((IEnumerable)GameDataBlockBase.GetAllBlocks()).SelectMany(UnpackRundown) ?? Enumerable.Empty(); } public static KeyedItem GetExpeditionUnlockItem(Expedition.Data data) { if (data.TryLookupItem(ExpeditionUnlockItem.MakeTag(data), out var item)) { return item; } Item item2 = new ExpeditionUnlockItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Expedition.Callback] public void AddExpeditionUnlock(Expedition.Data data) { KeyedItem expeditionUnlockItem = GetExpeditionUnlockItem(data); data.AddFloatingItem(expeditionUnlockItem.ID); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { Name = data.ExpeditionName + " Expdition Unlock", StartingRegion = data.MenuRegion, EndingRegion = Zone.get_StartingRegion(data), ReqItem = expeditionUnlockItem.PathReqs, ReqCount = 1u }); } public static void UnlockAll() { foreach (ExpeditionInTierData expedition in GetExpeditions()) { expedition.Accessibility = (eExpeditionAccessibility)2; } } public static void ResetLocks() { StateTracker stateTracker = StateTracker.Get(); Game.Data processedGameData = stateTracker.MidManager.GetProcessedGameData(); foreach (ExpeditionInTierData expedition in GetExpeditions()) { if (!processedGameData.TryLookupExpedition(expedition.Descriptive.Prefix, out Expedition.Data data)) { FeatureLogger.Warning("Failed to find data for expedition: " + expedition.Descriptive.Prefix + "; not applying lock!"); continue; } KeyedItem expeditionUnlockItem = GetExpeditionUnlockItem(data); if (expeditionUnlockItem.Item.RandMode.IsTreatedAsRandom && stateTracker.CollectedItemCounts.GetValueOrDefault(expeditionUnlockItem.ID, 0) <= 0) { expedition.Accessibility = (eExpeditionAccessibility)1; } } } } } namespace ReTFO.Archipelago.Features.EventHandlers { [EnableFeatureByDefault] [AutomatedFeature] public class CheckEventRegionsHandler : ArchipelagoFeature { private static IArchiveLogger? m_featureLogger; public override string Name => "Check Event Regions Handler"; public override string Description => "Adds check region events to event data to automatically identify when event regions are entered"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Event.Callback] public void InsertCheckRegionEvent(Event.Data data) { data.Insert(0, EventHelper.CreateCheckRegionEvent(data.EventRegion)); } } public static class CustomScanHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_EventScanItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_EventScanItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Event Scan Items", "Scans triggered by starting a custom event", RootRandomizationTags.get_Tag_ScanItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class CustomScanHandler : ArchipelagoFeature { public class StartCustomScanItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass13_0 { public LG_ComputerTerminal terminal; public StartCustomScanItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Initiating Scan " + <>4__this.WorldEventObjectFilter, 2f); terminal.AddLine("Scan will start in 10 seconds. Good luck :)", true); } internal void b__1() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0033: Expected O, but got Unknown WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)22, WorldEventObjectFilter = <>4__this.WorldEventObjectFilter, Delay = 10f }, 0f); } } [CompilerGenerated] private sealed class d__13 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public StartCustomScanItem <>4__this; private <>c__DisplayClass13_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__13(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass13_0(); <>8__1.terminal = terminal; <>8__1.<>4__this = <>4__this; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating Scan " + <>8__1.<>4__this.WorldEventObjectFilter, 2f); <>8__1.terminal.AddLine("Scan will start in 10 seconds. Good luck :)", true); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0033: Expected O, but got Unknown WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)22, WorldEventObjectFilter = <>8__1.<>4__this.WorldEventObjectFilter, Delay = 10f }, 0f); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__13 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__13(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Expedition.Data Data { get; set; } public string WorldEventObjectFilter { get; set; } public StartCustomScanItem(Expedition.Data data, string worldEventObjectFilter) : base(MakeTag(data, worldEventObjectFilter), MakeRandData()) { Data = data; WorldEventObjectFilter = worldEventObjectFilter; } public static TagResolver MakeTag(Expedition.Data data, string worldEventObjectFilter) { Expedition.Data data2 = data; string worldEventObjectFilter2 = worldEventObjectFilter; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Event Scan \"" + worldEventObjectFilter2 + "\"", "A particular event-triggered scan", CustomScanHandler_Tags.get_Tag_EventScanItems(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (Data.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (Data.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__13))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__13(-2) { <>4__this = this, <>3__terminal = terminal }; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Custom Scans Handler"; public override string Description => "Handles certain custom scans which are triggered by events\nThese are typically zone scans, and are often started by a terminal command"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetCustomScanStartItem(Expedition.Data data, string worldEventObjectFilter) { if (data.TryLookupItem(StartCustomScanItem.MakeTag(data, worldEventObjectFilter), out var item)) { return item; } Item item2 = new StartCustomScanItem(data, worldEventObjectFilter); return new KeyedItem(data.AddItem(item2), item2); } [Event.Callback] public void ProcessCustomScanStartEvents(Event.Data data) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 int num = 0; foreach (WardenObjectiveEventData datum in data) { if ((int)datum.Type == 22) { num++; string worldEventObjectFilter = datum.WorldEventObjectFilter; if (worldEventObjectFilter != null && worldEventObjectFilter.Length != 0) { EventHelper.ConvertToCheckLocationEvent(data, datum, num, GetCustomScanStartItem(data, datum.WorldEventObjectFilter).ID); } } } } [Zone.Callback] public void AddCustomScans(Zone.Data data) { if (data.Zone == null) { return; } foreach (SpecificChainPuzzleSpawnData item in data.Zone.WorldEventChainedPuzzleDatas.Iter()) { SpecificChainPuzzleSpawnData val = item; Event.Wrapper wrapper = data.WrapEvents(val.EventsOnScanDone ?? (val.EventsOnScanDone = new List(1))); KeyedItem customScanStartItem = GetCustomScanStartItem(data, item.WorldEventObjectFilter); uint num = 0u; while (!wrapper.IsDone) { num++; string text = $"{data.ZoneName} Custom Scan ({item.WorldEventObjectFilter}) (Completion #{num})"; RegionID regionID = data.LookupOrCreateRegion(text); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.LookupOrCreateRegion(data.ZoneName), EndingRegion = regionID, ReqItem = customScanStartItem.PathReqs, ReqCount = num, AlternateItem = new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem() }); wrapper.Process(regionID, text); } } } } public static class EventHelper_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_EventItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_EventLocations { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_EventLocation_ByType(eWardenObjectiveEventType type) { throw new NotSupportedException(); } } public static TagResolver get_Tag_EventItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Event Items", "Items corresponding to in-game events", RootRandomizationTags.get_Tag_AllItems(gd))); } public static TagResolver get_Tag_EventLocations(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Event Locations", "Locations found by triggering particular events", RootRandomizationTags.get_Tag_AllLocations(gd))); } public static TagResolver Tag_EventLocation_ByType(this Game.Data gameData, eWardenObjectiveEventType type) { //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 new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Event Locations for " + Enum.GetName(type) + " Event", "Locations found by triggering a particular event type", get_Tag_EventLocations(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] [InjectToIl2Cpp] public class EventHelper : ArchipelagoFeature { private class EventLocation : Location { public WardenObjectiveEventData SourceEvent { get; init; } public EventLocation(Event.Data data, WardenObjectiveEventData sourceEvent, int count) : base(MakeTag(data, sourceEvent, count), data.EventRegion, MakeRandData()) { SourceEvent = sourceEvent; } public static TagResolver MakeTag(Event.Data data, WardenObjectiveEventData sourceEvent, int count) { Event.Data data2 = data; WardenObjectiveEventData sourceEvent2 = sourceEvent; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag($"{data2.EventName} {Enum.GetName(sourceEvent2.Type)} #{count}", "A particular event instance", gd.Tag_EventLocation_ByType(sourceEvent2.Type))); } public static LocationData MakeRandData() { return new LocationData(); } } [ArchivePatch(/*Could not decode attribute arguments.*/)] public static class WorldEventManager__ExecuteEvent_Internal__Patch { [MethodImpl(MethodImplOptions.NoInlining)] public static bool Prefix(ref WardenObjectiveEventData eData, float currentDuration) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 WardenObjectiveEventData inputEvent = eData; RegionID id2; if ((int)eData.Type == 1512758915) { if (!checkCondition()) { return false; } byte[] array = new byte[8]; BitConverter.GetBytes(inputEvent.EnemyID).CopyTo(array, 0); BitConverter.GetBytes(inputEvent.FogSetting).CopyTo(array, 4); id2 = new RegionID { AsId = BitConverter.ToInt64(array) }; if (currentDuration >= inputEvent.Delay) { regionCallback(); } else { TriggerDelayedWorldEvent(regionCallback, inputEvent.Delay - currentDuration); } return false; } LocationID id; if ((int)eData.Type == 1512758916) { if (checkCondition()) { return false; } byte[] array2 = new byte[8]; BitConverter.GetBytes(inputEvent.EnemyID).CopyTo(array2, 0); BitConverter.GetBytes(inputEvent.FogSetting).CopyTo(array2, 4); id = new LocationID { AsId = BitConverter.ToInt64(array2) }; if (currentDuration >= inputEvent.Delay) { locationCallback(); } else { TriggerDelayedWorldEvent(locationCallback, inputEvent.Delay - currentDuration); } StateTracker stateTracker = StateTracker.Get(); Location location = stateTracker.MidManager.GetProcessedGameData().LookupLocation(id); if (!location.RandMode.IsTreatedAsRandom) { if (location is EventLocation eventLocation) { eData = eventLocation.SourceEvent; } else { FeatureLogger.Error($"Failed to retrieve original event data from event for location: [{id.AsId}] {stateTracker.MidManager.GetProcessedGameData().LookupTagDef(location.NameTag).Name}"); } return true; } return false; } return true; bool checkCondition() { if (inputEvent.Condition != null && inputEvent.Condition.ConditionIndex >= 0) { return WorldEventManager.GetCondition(inputEvent.Condition.ConditionIndex) != inputEvent.Condition.IsTrue; } return false; } void locationCallback() { StateTracker.Get().NotifyFoundLocation(id, null); } void regionCallback() { StateTracker.Get().NotifyFoundRegion(Expedition.Data.FromCurrentExpedition().LookupRegion(id2).Name, null); } } } [CompilerGenerated] private sealed class <g__ActionAfterDelayCoroutine|16_0>d : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float delay; public Action action; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <g__ActionAfterDelayCoroutine|16_0>d(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; action(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IArchiveLogger? m_featureLogger; private const eWardenObjectiveEventType CheckRegionEventType = 1512758915; private const eWardenObjectiveEventType CheckLocationEventType = 1512758916; public override string Name => "Events Helper"; public override string Description => "Provides utilites used by other features to manage events"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } private static WardenObjectiveEventData MakeBlankEvent() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0012: 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_0025: Expected O, but got Unknown //IL_0025: 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_0033: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown return new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)0, Condition = new WorldEventConditionPair { ConditionIndex = -1, IsTrue = false }, ChainPuzzle = 0u, DialogueID = 0u, SoundID = 0u, WardenIntel = LocalizedText.op_Implicit(0u), CustomSubObjective = LocalizedText.op_Implicit(0u), CustomSubObjectiveHeader = LocalizedText.op_Implicit(0u) }; } public static WardenObjectiveEventData CreateCheckRegionEvent(RegionID regionId) { WardenObjectiveEventData val = MakeBlankEvent(); val.Type = (eWardenObjectiveEventType)1512758915; byte[] bytes = BitConverter.GetBytes(regionId.AsId); val.Type = (eWardenObjectiveEventType)1512758915; val.EnemyID = BitConverter.ToUInt32(bytes, 0); val.FogSetting = BitConverter.ToUInt32(bytes, 4); return val; } public static void ConvertToCheckLocationEvent(Event.Data data, WardenObjectiveEventData e, int count, ItemID item) { Location location = new EventLocation(data, ((Il2CppObjectBase)((Object)e).MemberwiseClone()).Cast(), count); location.ItemID = item; LocationID locationID = data.AddLocation(location); if (locationID.IsNull) { FeatureLogger.Warning("Failed to add event location!"); return; } byte[] bytes = BitConverter.GetBytes(locationID.AsId); e.Type = (eWardenObjectiveEventType)1512758916; e.EnemyID = BitConverter.ToUInt32(bytes, 0); e.FogSetting = BitConverter.ToUInt32(bytes, 4); } public static void TriggerDelayedWorldEvent(Action action, float delay) { Coroutine val = ((MonoBehaviour)WorldEventManager.Current).StartCoroutine((IEnumerator)new Il2CppEnumerator(ActionAfterDelayCoroutine(action, delay))); WorldEventManager.m_worldEventEventCoroutines.Add(val); [IteratorStateMachine(typeof(<g__ActionAfterDelayCoroutine|16_0>d))] static IEnumerator ActionAfterDelayCoroutine(Action action, float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <g__ActionAfterDelayCoroutine|16_0>d(0) { action = action, delay = delay }; } } } [EnableFeatureByDefault] [AutomatedFeature] public class ForceCompleteObjectiveEventHandler : ArchipelagoFeature { private static IArchiveLogger? m_featureLogger; public override string Name => "Force Complete Objective Event Handler"; public override string Description => "Handles the ForceCompleteObjective event type, which immediately completes an objective."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } [Event.Callback] public void ProcessForceCompleteEvents(Event.Data data) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (WardenObjectiveEventData datum in data) { if ((int)datum.Type == 12) { num++; Layer.Data layer = data.GetLayer(datum.Layer); EventHelper.ConvertToCheckLocationEvent(data, datum, num, SharedObjectiveHandler.GetCompleteObjectiveItem(layer.GetObjectiveDatas().First()).ID); } } } } public static class UnlockEventHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_UnlockEventItem { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_UnlockEventItem(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Unlock Event Items", "Event items which trigger sec doors to unlock", EventHelper_Tags.get_Tag_EventItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class UnlockEventHandler : ArchipelagoFeature { private class UnlockZoneItem : Item { public Zone.Data ZoneData { get; set; } public UnlockZoneItem(Zone.Data data) : base(MakeTag(data), MakeRandData()) { ZoneData = data; } public static TagResolver MakeTag(Zone.Data data) { Zone.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ZoneName + " Unlock Event", "Event item which unlocks a particular door", UnlockEventHandler_Tags.get_Tag_UnlockEventItem(gd))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } private void UnlockZoneNow() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0022: 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_0038: 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_0058: Expected O, but got Unknown WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)2, DimensionIndex = ZoneData.LayerType, Layer = ZoneData.LayerType, LocalIndex = ZoneData.Zone.LocalIndex }, 0f); } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ZoneData.IsCurrentlyInExpedition()) { UnlockZoneNow(); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ZoneData.IsSameExpedition(data)) { UnlockZoneNow(); } } } private static IArchiveLogger? m_featureLogger; public override string Name => "Unlock Event Handler"; public override string Description => "Handles events which unlock or open doors"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetUnlockEventItem(Zone.Data data) { if (data.TryLookupItem(UnlockZoneItem.MakeTag(data), out var item)) { return item; } Item item2 = new UnlockZoneItem(data); return new KeyedItem(data.AddItem(item2), item2); } [Event.Callback] public void ProcessUnlockEvents(Event.Data data) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 int num = 0; foreach (WardenObjectiveEventData datum in data) { if ((int)datum.Type == 2 || (int)datum.Type == 1) { num++; Zone.Data data2 = data.FindZoneByEvent(datum); if (data2 != null) { EventHelper.ConvertToCheckLocationEvent(data, datum, num, GetUnlockEventItem(data2).ID); continue; } FeatureLogger.Debug($"Failed to find zone for unlock event: {data.EventName} #{num}"); } } } } public static class WarpEvent_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_WarpEventItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_WarpEventItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Warp Event Items", "Event items which trigger the team to teleport, typically between dimensions", RootRandomizationTags.get_Tag_WarpItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class WarpEventsHandler : ArchipelagoFeature { private class DimensionWarpItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass18_0 { public LG_ComputerTerminal terminal; public DimensionWarpItem <>4__this; internal void b__0() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) terminal.AddLine((TerminalLineType)2, "Initiating Dimension Warp to " + Enum.GetName((eDimensionIndex)<>4__this.TargetZone.LayerType), 2f); terminal.AddLine("Warp will occur in 3 seconds. Enjoy the scenery :)", true); } internal void b__1() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0027: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got I4 ? val = new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)8, DimensionIndex = <>4__this.TargetZone.LayerType, Layer = <>4__this.TargetZone.LayerType }; ? val2 = val; ExpeditionZoneData? zone = <>4__this.TargetZone.Zone; int num; if (zone == null) { num = 0; val = num; num = (int)val; } else { val = zone.LocalIndex; num = (int)val; } ((WardenObjectiveEventData)val2).LocalIndex = (eLocalZoneIndex)val; ((WardenObjectiveEventData)num).Delay = 3f; ((WardenObjectiveEventData)num).ClearDimension = <>4__this.ClearDimension; ((WardenObjectiveEventData)num).WorldEventObjectFilter = <>4__this.WarpAlign; WorldEventManager.ExecuteEvent((WardenObjectiveEventData)(object)num, 0f); } } [CompilerGenerated] private sealed class d__18 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public DimensionWarpItem <>4__this; private <>c__DisplayClass18_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass18_0(); <>8__1.terminal = terminal; <>8__1.<>4__this = <>4__this; <>2__current = delegate { //IL_001c: Unknown result type (might be due to invalid IL or missing references) <>8__1.terminal.AddLine((TerminalLineType)2, "Initiating Dimension Warp to " + Enum.GetName((eDimensionIndex)<>8__1.<>4__this.TargetZone.LayerType), 2f); <>8__1.terminal.AddLine("Warp will occur in 3 seconds. Enjoy the scenery :)", true); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0027: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got I4 ? val = new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)8, DimensionIndex = <>8__1.<>4__this.TargetZone.LayerType, Layer = <>8__1.<>4__this.TargetZone.LayerType }; ? val2 = val; ExpeditionZoneData? zone = <>8__1.<>4__this.TargetZone.Zone; int num; if (zone == null) { num = 0; val = num; num = (int)val; } else { val = zone.LocalIndex; num = (int)val; } ((WardenObjectiveEventData)val2).LocalIndex = (eLocalZoneIndex)val; ((WardenObjectiveEventData)num).Delay = 3f; ((WardenObjectiveEventData)num).ClearDimension = <>8__1.<>4__this.ClearDimension; ((WardenObjectiveEventData)num).WorldEventObjectFilter = <>8__1.<>4__this.WarpAlign; WorldEventManager.ExecuteEvent((WardenObjectiveEventData)(object)num, 0f); }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__18 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__18(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Zone.Data TargetZone { get; set; } public bool ClearDimension { get; set; } public string? WarpAlign { get; set; } public DimensionWarpItem(Zone.Data targetZone, string? align, bool clearDimension) : base(MakeTag(targetZone, align, clearDimension), MakeRandData()) { TargetZone = targetZone; ClearDimension = clearDimension; WarpAlign = align; } public static TagResolver MakeTag(Zone.Data targetZone, string? align, bool clearDimension) { Zone.Data targetZone2 = targetZone; string align2 = align; return new TagResolver(targetZone2, (Game.Data gd) => gd.LookupOrCreateTag(MakeName(targetZone2, align2, clearDimension), "A particular warp event item", WarpEvent_Tags.get_Tag_WarpEventItems(gd))); } public static string MakeName(Zone.Data targetZone, string? align, bool clearDimension) { if (align != null) { return $"Warp to {targetZone.LayerName} (Align: {align}) {(clearDimension ? " (with DimensionClearing)" : "")}"; } return "Warp to " + targetZone.ZoneName + " " + (clearDimension ? " (with DimensionClearing)" : ""); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (TargetZone.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (TargetZone.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__18))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(-2) { <>4__this = this, <>3__terminal = terminal }; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Warp Events Helper"; public override string Description => "Handles dimension warp events as paths"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetDimensionWarpEventItem(Zone.Data targetZone, string? align, bool cleanDimension) { if (targetZone.TryLookupItem(DimensionWarpItem.MakeTag(targetZone, align, cleanDimension), out var item)) { return item; } Item item2 = new DimensionWarpItem(targetZone, align, cleanDimension); return new KeyedItem(targetZone.AddItem(item2), item2); } private static string GetDimensionWarpEventLocationName(Event.Data data, int count) { return $"{data.EventName} - Dimension Warp #{count}"; } [Event.Callback] public void AddEventWarps(Event.Data data) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 int num = 0; foreach (WardenObjectiveEventData datum in data) { if ((int)datum.Type == 8) { num++; Zone.Data data2 = data.FindZoneByEvent(datum); if (data2 == null) { FeatureLogger.Warning("Failed to identify warp target for event: " + data.EventName); continue; } KeyedItem dimensionWarpEventItem = GetDimensionWarpEventItem(data2, datum.WorldEventObjectFilter, datum.ClearDimension); EventHelper.ConvertToCheckLocationEvent(data, datum, num, dimensionWarpEventItem.ID); data.AddPath(new ReTFO.Archipelago.ModdedInstanceData.Model.Path { StartingRegion = data.EventRegion, EndingRegion = data.LookupOrCreateRegion(data2.ZoneName), ReqItem = dimensionWarpEventItem.PathReqs, ReqCount = 1u }); } } } } public static class WinEventHandler_Tags { [SpecialName] public sealed class $2B8804A94F2EF68DF77A343A46EE5A78 { [SpecialName] public static class $F943E16B16B76A20C49A59C8DF7C8955 { } [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] public TagResolver Tag_WinEventItems { [ExtensionMarker("$F943E16B16B76A20C49A59C8DF7C8955")] get { throw new NotSupportedException(); } } } [SpecialName] public sealed class $2833969430CAB23CD70890D67B9ADDD5 { [SpecialName] public static class $5667123F7013DAD37BB214B248F3E5D2 { } [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] public TagResolver Tag_WinEventItemForExpedition { [ExtensionMarker("$5667123F7013DAD37BB214B248F3E5D2")] get { throw new NotSupportedException(); } } } public static TagResolver get_Tag_WinEventItems(Game.Data gameData) { return new TagResolver(gameData, (Game.Data gd) => gd.LookupOrCreateTag("Win Event Items", "Event items which cause the player to immediately clear the main sector and extract (optionally triggered on death)", EventHelper_Tags.get_Tag_EventItems(gd))); } public static TagResolver get_Tag_WinEventItemForExpedition(Expedition.Data data) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(data2.ExpeditionName + " Win Event Item", "A win event item category for a particular expedition", get_Tag_WinEventItems(gd))); } } [EnableFeatureByDefault] [AutomatedFeature] public class WinEventHandler : ArchipelagoFeature { private class InstantWinItem : Item { [CompilerGenerated] private sealed class <>c__DisplayClass15_0 { public LG_ComputerTerminal terminal; public InstantWinItem <>4__this; internal void b__0() { terminal.AddLine((TerminalLineType)2, "Retrieving your win event", 2f); } internal void b__1() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0071: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (<>4__this.OnDeath) { WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)26, Layer = (LG_LayerType)0, Delay = 0f }, 0f); terminal.AddLine("<#F00>ERROR: Prisoner death required. Proceed to self-terminate immediately.", true); } else { WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)27, Layer = (LG_LayerType)0, Delay = 0f }, 0f); terminal.AddLine("Congrats, you win!", true); } } } [CompilerGenerated] private sealed class d__15 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private LG_ComputerTerminal terminal; public LG_ComputerTerminal <>3__terminal; public InstantWinItem <>4__this; private <>c__DisplayClass15_0 <>8__1; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass15_0(); <>8__1.terminal = terminal; <>8__1.<>4__this = <>4__this; <>2__current = delegate { <>8__1.terminal.AddLine((TerminalLineType)2, "Retrieving your win event", 2f); }; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = delegate { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0071: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (<>8__1.<>4__this.OnDeath) { WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)26, Layer = (LG_LayerType)0, Delay = 0f }, 0f); <>8__1.terminal.AddLine("<#F00>ERROR: Prisoner death required. Proceed to self-terminate immediately.", true); } else { WorldEventManager.ExecuteEvent(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)27, Layer = (LG_LayerType)0, Delay = 0f }, 0f); <>8__1.terminal.AddLine("Congrats, you win!", true); } }; <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__15 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__15(0) { <>4__this = <>4__this }; } d__.terminal = <>3__terminal; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public Expedition.Data ExpeditionData { get; set; } public bool OnDeath { get; set; } public override ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem PathReqs => GetInstantWinPathReqs(ExpeditionData); public InstantWinItem(Expedition.Data data, bool onDeath) : base(MakeTag(data, onDeath), MakeRandData()) { ExpeditionData = data; OnDeath = onDeath; } public static TagResolver MakeTag(Expedition.Data data, bool onDeath) { Expedition.Data data2 = data; return new TagResolver(data2, (Game.Data gd) => gd.LookupOrCreateTag(onDeath ? (data2.ExpeditionName + " Win on Death") : (data2.ExpeditionName + " Instant Win"), "An instant win event instance", WinEventHandler_Tags.get_Tag_WinEventItemForExpedition(data2))); } public static ItemData MakeRandData() { ItemData result = new ItemData(); result.IsProgression = true; return result; } public override void OnItemObtained(StateTracker stateTracker, LocationID sourceLocationId, PlayerAgent? player) { if (ExpeditionData.IsCurrentlyInExpedition()) { stateTracker.AddItemToTerminal(this); } } public override void OnStartExpeditionWithItem(StateTracker stateTracker, Expedition.Data data) { if (ExpeditionData.IsSameExpedition(data)) { stateTracker.AddItemToTerminal(this); } } [IteratorStateMachine(typeof(d__15))] public override IEnumerable OnRetrieveFromTerminalSystem(StateTracker stateTracker, LG_ComputerTerminal terminal) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(-2) { <>4__this = this, <>3__terminal = terminal }; } } private static IArchiveLogger? m_featureLogger; public override string Name => "Win Event Handler"; public override string Description => "Handles the Win event type.\nWin events immediately complete the main sector and end the expedition, skipping extract.\nThe WinOnDeath event is treated as a win event, with the assumption you will die very soon."; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_EventHandlers(); public new static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? Plugin.Get().Logger; } set { m_featureLogger = value; } } public static KeyedItem GetInstantWinItem(Expedition.Data data, bool onDeath) { if (data.TryLookupItem(InstantWinItem.MakeTag(data, onDeath), out var item)) { return item; } Item item2 = new InstantWinItem(data, onDeath); return new KeyedItem(data.AddItem(item2), item2); } public static ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem GetInstantWinPathReqs(Expedition.Data data) { return new ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem(ReTFO.Archipelago.ModdedInstanceData.Model.Path.RequiredItem.eType.Category, WinEventHandler_Tags.get_Tag_WinEventItemForExpedition(data)); } [Event.Callback] public void ProcessWinEvents(Event.Data data) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 int num = 0; foreach (WardenObjectiveEventData datum in data) { if ((int)datum.Type == 27 || (int)datum.Type == 26) { num++; KeyedItem instantWinItem = GetInstantWinItem(data, (int)datum.Type == 26); FeatureLogger.Notice("Adding instant win item: " + data.LookupTagDef(instantWinItem.NameTag).Name); EventHelper.ConvertToCheckLocationEvent(data, datum, num, instantWinItem.ID); } } } } } namespace ReTFO.Archipelago.FeaturesAPI { public class ArchipelagoFeature : Feature { private static IArchiveLogger? m_featureLogger; public override string Name => "Archipelago Feature"; public override string Description => "Abstract base class used by Archipelago features and handlers"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public static IArchiveLogger FeatureLogger { get { return m_featureLogger ?? (m_featureLogger = Plugin.Get().Logger); } set { m_featureLogger = value; } } public override bool ShouldInit() { if (!Plugin.TryGet(out Plugin _)) { FeatureLogger.Error("Failed to find plugin during init for feature: " + ((object)this).GetType().FullName); return false; } if (((object)this).GetType() == typeof(ArchipelagoFeature)) { return false; } return ((Feature)this).ShouldInit(); } public override void OnEnable() { ((Feature)this).OnEnable(); ArchipelagoFeatureHelper.RegisterInstancedCallbacks(this); } public override void OnDisable() { ((Feature)this).OnDisable(); ArchipelagoFeatureHelper.UnregisterInstancedCallbacks(this); } public override bool Equals(object? obj) { if (obj is ArchipelagoFeatureHelper.FakeFeature fakeFeature) { return ((object)this).GetType().Equals(fakeFeature.WrappedType); } return ((object)this).GetType().Equals(obj?.GetType()); } public override int GetHashCode() { return ((object)this).GetType().GetHashCode(); } } public static class ArchipelagoFeatureHelper { [ForceDisable("Internal archipelago feature used only for finding features")] [HideInModSettings] internal class FakeFeature : ArchipelagoFeature { public override string Name => "Archipelago Fake Feature"; public override string Description => "Feature used by Archipelago for hash lookups"; public override FeatureGroup Group => ArchipelagoFeatureGroups.get_Archipelago(); public Type? WrappedType { get; set; } public FakeFeature() { WrappedType = null; } public FakeFeature(Type intendedType) { WrappedType = intendedType; } public override bool Equals(object? obj) { return WrappedType?.Equals(obj?.GetType()) ?? (obj == null); } public override int GetHashCode() { return WrappedType?.GetHashCode() ?? 0; } } public static TFeature GetFeature() where TFeature : ArchipelagoFeature { Exception ex = null; if (!InitSingletonBase.Instance.RegisteredFeatures.TryGetValue((Feature)(object)new FakeFeature(typeof(TFeature)), out var actualValue)) { ex = new KeyNotFoundException("Could not find a registered feature of type " + typeof(TFeature).FullName); FeatureLogger.Exception(ex); throw ex; } if (!(actualValue is TFeature result)) { ex = new NotSupportedException("When searching for registered feature of type " + typeof(TFeature).FullName + ", instead got a feature of type " + ((object)actualValue).GetType().FullName); FeatureLogger.Exception(ex); throw ex; } return result; } public static IEnumerable GetProcessorCallbacks(Type type) { return from m in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.CustomAttributes.Any((CustomAttributeData a) => a.AttributeType.IsAssignableTo(typeof(MidManager.Processor.CallbackBase))) select m; } public static IEnumerable GetInstancedProcessorCallbacks(Type type) { return from m in GetProcessorCallbacks(type) where !m.IsStatic select m; } public static void RegisterInstancedCallbacks(object instance) { IEnumerable instancedProcessorCallbacks = GetInstancedProcessorCallbacks(instance.GetType()); MidManager midManager = Plugin.Get().MidManager; foreach (MethodInfo item in instancedProcessorCallbacks) { MidManager.Processor.CallbackBase customAttribute = item.GetCustomAttribute(); if (customAttribute == null) { throw new NotSupportedException("After checking for the Callback attribute, it was still somehow null!"); } MidManager.Processor processor = midManager.GetProcessor(customAttribute.DataType); Delegate @delegate = Delegate.CreateDelegate(customAttribute.DelegateType, instance, item, throwOnBindFailure: false); if ((object)@delegate == null) { FeatureLogger.Error($"Failed to bind delegate! Method: {item.DeclaringType.FullName}.{item.Name} Delegate Type: {customAttribute.DelegateType.DeclaringType}.{customAttribute.DelegateType.Name}"); } else { processor.UntypedRegisterCallback(@delegate); } } } public static void UnregisterInstancedCallbacks(object instance) { IEnumerable instancedProcessorCallbacks = GetInstancedProcessorCallbacks(instance.GetType()); MidManager midManager = Plugin.Get().MidManager; foreach (MethodInfo item in instancedProcessorCallbacks) { MidManager.Processor.CallbackBase customAttribute = item.GetCustomAttribute(); if (customAttribute == null) { throw new NotSupportedException("After checking for the Callback attribute, it was still somehow null!"); } MidManager.Processor processor = midManager.GetProcessor(customAttribute.DataType); Delegate callback = Delegate.CreateDelegate(customAttribute.DelegateType, instance, item); processor.UntypedUnregisterCallback(callback); } } } public static class FeatureLogger { private static IArchiveLogger? m_current; public static IArchiveLogger Current { get { return m_current ?? (m_current = Plugin.Get().Logger); } set { m_current = value; } } public static void Success(string msg) { Current.Success(msg); } public static void Notice(string msg) { Current.Notice(msg); } public static void Msg(ConsoleColor col, string msg) { Current.Msg(col, msg); } public static void Info(string msg) { Current.Info(msg); } public static void Fail(string msg) { Current.Fail(msg); } public static void Debug(string msg) { Current.Debug(msg); } public static void Warning(string msg) { Current.Warning(msg); } public static void Error(string msg) { Current.Error(msg); } public static void Exception(Exception ex) { Current.Exception(ex); } } }