using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using Dawn.Interfaces; using Dawn.Internal; using Dawn.Utils; using DunGen; using DunGen.Graph; using DunGenPlus; using GameNetcodeStuff; using GoodItemScan; using HarmonyLib; using IL; using IL.GameNetcodeStuff; using LethalConfig.AutoConfig; using LethalConfig.ConfigItems; using LethalLevelLoader; using LethalLib.Modules; using LethalQuantities.Objects; using LethalQuantities.Patches; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MrovLib.Events; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using On; using On.BepInEx.Configuration; using On.DunGen; using On.GameNetcodeStuff; using On.TMPro; using On.Unity.Netcode; using PathfindingLib.API.SmartPathfinding; using Steamworks; using Steamworks.Data; using TMPro; using TerminalFormatter.Nodes; using Unity.Netcode; using Unity.Netcode.Components; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.InputSystem.Utilities; using UnityEngine.Pool; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.Serialization; using UnityEngine.UI; using WeatherRegistry; using com.github.teamxiaolan.dawnlib.NetcodePatcher; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("com.github.teamxiaolan.dawnlib.dusk")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("DunGenPlus")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("GoodItemScan")] [assembly: IgnoresAccessChecksTo("LethalConfig")] [assembly: IgnoresAccessChecksTo("LethalLevelLoader")] [assembly: IgnoresAccessChecksTo("LethalLib")] [assembly: IgnoresAccessChecksTo("LethalQuantities")] [assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("MMHOOK_BepInEx")] [assembly: IgnoresAccessChecksTo("MMHOOK_BepInEx.Preloader")] [assembly: IgnoresAccessChecksTo("MMHOOK_DunGen")] [assembly: IgnoresAccessChecksTo("MMHOOK_Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("MMHOOK_Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("MMHOOK_UnityEngine.CoreModule")] [assembly: IgnoresAccessChecksTo("MrovLib")] [assembly: IgnoresAccessChecksTo("StarlancerAI")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: IgnoresAccessChecksTo("WeatherRegistry")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("XuXiaolan,loaforc")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A modern API for Lethal Company content and all sizes of mods.")] [assembly: AssemblyFileVersion("0.9.21.0")] [assembly: AssemblyInformationalVersion("0.9.21+78d07c774d74f29674974668e8e7aca2a1029d4a")] [assembly: AssemblyProduct("DawnLib")] [assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.21.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public sealed class Vector3Converter : JsonConverter { public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer) { //IL_0012: 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_0040: Unknown result type (might be due to invalid IL or missing references) writer.WriteStartObject(); writer.WritePropertyName("x"); writer.WriteValue(value.x); writer.WritePropertyName("y"); writer.WriteValue(value.y); writer.WritePropertyName("z"); writer.WriteValue(value.z); writer.WriteEndObject(); } public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 float num = 0f; float num2 = 0f; float num3 = 0f; if ((int)reader.TokenType != 1) { throw new JsonSerializationException("Expected StartObject for Vector3"); } while (reader.Read() && (int)reader.TokenType != 13) { if ((int)reader.TokenType == 4) { string text = (string)reader.Value; reader.Read(); switch (text) { case "x": num = Convert.ToSingle(reader.Value); break; case "y": num2 = Convert.ToSingle(reader.Value); break; case "z": num3 = Convert.ToSingle(reader.Value); break; } } } return new Vector3(num, num2, num3); } } public class DawnMapObjectNamespacedKeyContainer : MonoBehaviour { [field: SerializeField] public NamespacedKey Value { get; internal set; } public DawnMapObjectInfo GetDawnMapObjectInfo() { return LethalContent.MapObjects[Value.AsTyped()]; } } public class DawnStoryLogNamespacedKeyContainer : MonoBehaviour { [field: SerializeField] public NamespacedKey Value { get; internal set; } } namespace Dawn { public abstract class BaseInfoBuilder { internal abstract void SoloAddTags(IEnumerable newTags); } public abstract class BaseInfoBuilder : BaseInfoBuilder where TInfo : INamespaced where TBuilder : BaseInfoBuilder { protected HashSet tags = new HashSet(); protected IDataContainer? customData; protected NamespacedKey key { get; private set; } protected T value { get; private set; } internal BaseInfoBuilder(NamespacedKey key, T value) { this.key = key; this.value = value; } public TBuilder AddTag(NamespacedKey tag) { tags.Add(tag); return (TBuilder)this; } public TBuilder AddTags(IEnumerable newTags) { foreach (NamespacedKey newTag in newTags) { AddTag(newTag); } return (TBuilder)this; } internal override void SoloAddTags(IEnumerable newTags) { AddTags(newTags); } public TBuilder EditCustomData(Action callback) { if (customData == null) { customData = new DataContainer(); } callback(customData); return (TBuilder)this; } internal abstract TInfo Build(); } [JsonObject(/*Could not decode attribute arguments.*/)] public class DataContainer : IDataContainer { private class NoOpDisposable : IDisposable { public void Dispose() { } } [JsonProperty] protected Dictionary dictionary = new Dictionary(); public IEnumerable Keys => dictionary.Keys; public int Count => dictionary.Count; public bool Has(NamespacedKey key) { return dictionary.ContainsKey(key); } public bool TryGet(NamespacedKey key, [NotNullWhen(true)] out T? value) { if (dictionary.TryGetValue(key, out object value2)) { JToken val = (JToken)((value2 is JToken) ? value2 : null); if (val != null) { value = val.ToObject(); return true; } if (value2 is T val2) { value = val2; return true; } if (typeof(T) == typeof(int) && value2 is long num) { value = (T)(object)(int)num; return true; } if (typeof(T) == typeof(long) && value2 is int num2) { value = (T)(object)(long)num2; return true; } throw new InvalidCastException($"type of '{key}' is {value2.GetType().Name} which can not be {typeof(T).Name}"); } value = default(T); return false; } public T GetOrSetDefault(NamespacedKey key, T defaultValue) { if (TryGet(key, out T value)) { return value; } Set(key, defaultValue); return defaultValue; } public T GetOrCreateDefault(NamespacedKey key) where T : new() { if (TryGet(key, out T value)) { return value; } value = new T(); Set(key, value); return value; } public virtual void Set(NamespacedKey key, T value) { if (value == null) { throw new ArgumentNullException("value"); } dictionary[key] = value; } public virtual void Remove(NamespacedKey key) { dictionary.Remove(key); } public virtual void Clear() { dictionary.Clear(); } public virtual void MarkDirty() { } public virtual IDisposable CreateEditContext() { return new NoOpDisposable(); } public bool Has(NamespacedKey key) { if (dictionary.ContainsKey(key)) { return dictionary[key] is T; } return false; } } public class FrozenEmptyDataContainer : IDataContainer { public static FrozenEmptyDataContainer Instance { get; private set; } = new FrozenEmptyDataContainer(); public IEnumerable Keys { get; } = Array.Empty(); public int Count => 0; private FrozenEmptyDataContainer() { } public bool TryGet(NamespacedKey key, [NotNullWhen(true)] out T? value) { value = default(T); return false; } public T GetOrSetDefault(NamespacedKey key, T defaultValue) { throw new RegistryFrozenException(); } public T GetOrCreateDefault(NamespacedKey key) where T : new() { throw new RegistryFrozenException(); } public void Set(NamespacedKey key, T value) { throw new RegistryFrozenException(); } public void Remove(NamespacedKey key) { throw new RegistryFrozenException(); } public void Clear() { throw new RegistryFrozenException(); } public void MarkDirty() { throw new RegistryFrozenException(); } public IDisposable CreateEditContext() { throw new RegistryFrozenException(); } public bool Has(NamespacedKey key) { throw new NotImplementedException(); } } public interface IDataContainer { IEnumerable Keys { get; } int Count { get; } bool Has(NamespacedKey key); bool TryGet(NamespacedKey key, [NotNullWhen(true)] out T? value); T GetOrSetDefault(NamespacedKey key, T defaultValue); T GetOrCreateDefault(NamespacedKey key) where T : new(); void Set(NamespacedKey key, T value); void Remove(NamespacedKey key); void Clear(); void MarkDirty(); IDisposable CreateEditContext(); } public interface INamespaced { NamespacedKey Key { get; } } public interface INamespaced : INamespaced where T : INamespaced { NamespacedKey TypedKey { get; } } public class JSONTagDefinition { public string Tag; public string[] Values; } [Serializable] public class NamespacedKey : INetworkSerializable { private static readonly Regex NamespacedKeyRegex = new Regex("[?!.\\n\\t\"`\\[\\]'-]"); private static readonly Dictionary CanonicalByFull = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary CanonicalByKey = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary> SmartPlaceholdersByKey = new Dictionary>(StringComparer.Ordinal); private static readonly Dictionary NumberWords = new Dictionary { { '0', "Zero" }, { '1', "One" }, { '2', "Two" }, { '3', "Three" }, { '4', "Four" }, { '5', "Five" }, { '6', "Six" }, { '7', "Seven" }, { '8', "Eight" }, { '9', "Nine" } }; public const char Separator = ':'; public const string VanillaNamespace = "lethal_company"; public const string SmartMatchingNamespace = "smart_matching"; [SerializeField] private string _namespace; [SerializeField] private string _key; public string Namespace => _namespace; public string Key => _key; public ulong NetworkID => ComputeStableHash64(ToString()); private static void PromoteSmartPlaceholders(string key, string newNamespace) { if (!SmartPlaceholdersByKey.TryGetValue(key, out List value) || value.Count == 0) { return; } foreach (NamespacedKey item in value) { if (item._namespace == "smart_matching") { Debuggers.NamespacedKeys?.Log($"Promoting placeholder {item} to {newNamespace}"); item._namespace = newNamespace; } } } internal static string NormalizeStringForNamespacedKey(string input, bool CSharpName) { if (string.IsNullOrWhiteSpace(input)) { return string.Empty; } string text = NamespacedKeyRegex.Replace(input, string.Empty); StringBuilder stringBuilder = new StringBuilder(text.Length); bool flag = false; string text2 = text; foreach (char c in text2) { if (flag || (!char.IsDigit(c) && c != ' ')) { flag = true; stringBuilder.Append(c); } } StringBuilder stringBuilder2 = new StringBuilder(stringBuilder.Length); string text3 = stringBuilder.ToString(); foreach (char c2 in text3) { if (NumberWords.TryGetValue(c2, out string value)) { stringBuilder2.Append(value); } else { stringBuilder2.Append(c2); } } string text4 = stringBuilder2.ToString(); if (CSharpName) { text4 = text4.Replace(" ", string.Empty); text4 = text4.Replace("_", string.Empty); return text4.ToCapitalized(); } return text4.ToLowerInvariant().Replace(" ", "_"); } private static string BuildFullKey(string @namespace, string key) { return $"{@namespace}{':'}{key}"; } private static bool ShouldReplaceCandidate(NamespacedKey existing, NamespacedKey candidate) { if (existing.Namespace == "smart_matching" && candidate.Namespace != "smart_matching") { return true; } if (candidate.Namespace == "lethal_company" && existing.Namespace != "lethal_company") { return true; } return false; } private static void Register(NamespacedKey key) { string key2 = BuildFullKey(key.Namespace, key.Key); CanonicalByFull.TryAdd(key2, key); NamespacedKey value2; if (key.Namespace == "smart_matching") { if (!SmartPlaceholdersByKey.TryGetValue(key.Key, out List value)) { value = new List(); SmartPlaceholdersByKey[key.Key] = value; } value.Add(key); if (!CanonicalByKey.ContainsKey(key.Key)) { CanonicalByKey[key.Key] = key; } } else if (CanonicalByKey.TryGetValue(key.Key, out value2)) { if (ShouldReplaceCandidate(value2, key)) { CanonicalByKey[key.Key] = key; PromoteSmartPlaceholders(key.Key, key.Namespace); } } else { CanonicalByKey[key.Key] = key; PromoteSmartPlaceholders(key.Key, key.Namespace); } } private static bool TrySmartResolveByKey(string normalizedKey, [NotNullWhen(true)] out NamespacedKey? match) { match = null; if (CanonicalByKey.TryGetValue(normalizedKey, out NamespacedKey value)) { match = value; return true; } return false; } protected NamespacedKey(string @namespace, string key) { _namespace = NormalizeStringForNamespacedKey(@namespace, CSharpName: false); _key = NormalizeStringForNamespacedKey(key, CSharpName: false); Register(this); } [EditorBrowsable(EditorBrowsableState.Never)] public NamespacedKey() { } public static NamespacedKey From(string @namespace, string key) { return new NamespacedKey(@namespace, key); } public static NamespacedKey Vanilla(string key) { return From("lethal_company", key); } public static NamespacedKey Parse(string input) { if (string.IsNullOrWhiteSpace(input)) { throw new ArgumentException("Input cannot be null or empty.", "input"); } string[] array = input.Split(':'); if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1])) { throw new FormatException($"Invalid namespaced key '{input}'. Expected 'namespace{':'}key'."); } return From(array[0], array[1]); } public static bool TryParse(string input, [NotNullWhen(true)] out NamespacedKey? result) { result = null; if (string.IsNullOrWhiteSpace(input)) { return false; } string[] array = input.Split(':'); if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1])) { return false; } result = From(array[0], array[1]); return true; } public static NamespacedKey ForceParse(string input) { return ForceParse(input, useSmartMatching: false); } public static NamespacedKey ForceParse(string input, bool useSmartMatching) { if (string.IsNullOrWhiteSpace(input)) { throw new ArgumentException("Input cannot be null or empty.", "input"); } string[] array = input.Split(':'); if (array.Length == 2) { return From(array[0], array[1]); } string input2 = array[0]; string text = NormalizeStringForNamespacedKey(input2, CSharpName: false); if (useSmartMatching) { if (TrySmartResolveByKey(text, out NamespacedKey match)) { return match; } return From("smart_matching", text); } return From("lethal_company", text); } public override string ToString() { return BuildFullKey(Namespace, Key); } public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref _namespace, false); serializer.SerializeValue(ref _key, false); } public override bool Equals(object? obj) { if (this == obj) { return true; } if (!(obj is NamespacedKey namespacedKey)) { return false; } if (string.Equals(Namespace, namespacedKey.Namespace, StringComparison.Ordinal)) { return string.Equals(Key, namespacedKey.Key, StringComparison.Ordinal); } return false; } private static ulong ComputeStableHash64(string value) { ulong num = 14695981039346656037uL; byte[] bytes = Encoding.UTF8.GetBytes(value); byte[] array = bytes; foreach (byte b in array) { num ^= b; num *= 1099511628211L; } return num; } public override int GetHashCode() { int num = 13; num = num * 17 + (Namespace?.GetHashCode() ?? 0); return num * 17 + (Key?.GetHashCode() ?? 0); } public NamespacedKey AsTyped() where T : INamespaced { return NamespacedKey.From(Namespace, Key); } public bool IsVanilla() { return Namespace == "lethal_company"; } public bool IsModded() { return !IsVanilla(); } } [Serializable] public class NamespacedKey : NamespacedKey where T : INamespaced { protected NamespacedKey(string @namespace, string key) : base(@namespace, key) { } [EditorBrowsable(EditorBrowsableState.Never)] public NamespacedKey() { } public new static NamespacedKey From(string @namespace, string key) { return new NamespacedKey(@namespace, key); } public new static NamespacedKey Vanilla(string key) { return From("lethal_company", key); } public new static NamespacedKey Parse(string input) { if (string.IsNullOrWhiteSpace(input)) { throw new ArgumentException("Input cannot be null or empty.", "input"); } string[] array = input.Split(':'); if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1])) { throw new FormatException($"Invalid namespaced key '{input}'. Expected 'namespace{':'}key'."); } return From(array[0], array[1]); } } public class NamespacedKeyConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (value is NamespacedKey namespacedKey) { writer.WriteValue(namespacedKey.ToString()); } else { writer.WriteNull(); } } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((int)reader.TokenType == 11) { return null; } string text = reader.Value?.ToString(); if (text == null) { return null; } NamespacedKey namespacedKey = NamespacedKey.ForceParse(text); if (objectType == typeof(NamespacedKey)) { return namespacedKey; } if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(NamespacedKey<>)) { MethodInfo method = typeof(NamespacedKey).GetMethod("AsTyped"); MethodInfo methodInfo = method.MakeGenericMethod(objectType.GetGenericArguments()[0]); return methodInfo.Invoke(namespacedKey, null); } throw new JsonSerializationException($"Cannot deserialize {objectType}"); } public override bool CanConvert(Type objectType) { if (objectType == typeof(NamespacedKey)) { return true; } if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(NamespacedKey<>)) { return true; } return false; } } public class NamespacedKeyDictionaryConverter : JsonConverter { public override bool CanConvert(Type objectType) { if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { return objectType.GetGenericArguments()[0] == typeof(NamespacedKey); } return false; } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { writer.WriteStartObject(); IDictionary dictionary = (IDictionary)value; List list = new List(); foreach (object key in dictionary.Keys) { list.Add(key); } foreach (object item in list) { NamespacedKey namespacedKey = (NamespacedKey)item; object obj = dictionary[item]; writer.WritePropertyName(namespacedKey.ToString()); serializer.Serialize(writer, obj); } writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { Type type = objectType.GetGenericArguments()[1]; Type type2 = typeof(Dictionary<, >).MakeGenericType(typeof(NamespacedKey), type); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type2); JObject val = JObject.Load(reader); foreach (JProperty item in val.Properties()) { NamespacedKey key = NamespacedKey.ForceParse(item.Name); object value = item.Value.ToObject(type, serializer); dictionary[key] = value; } return dictionary; } } public class PersistentDataContainer : DataContainer { public class EditContext : IDisposable { private PersistentDataContainer _container; private bool _prevAutoSave; public EditContext(PersistentDataContainer container) { _container = container; _prevAutoSave = _container.AutoSave; _container.AutoSave = false; } public void Dispose() { _container.AutoSave = _prevAutoSave; _container.MarkDirty(); } } private string _filePath; private readonly SemaphoreSlim _saveLock = new SemaphoreSlim(1, 1); public bool AutoSave { get; private set; } = true; internal static List HasCorruptedData { get; private set; } = new List(); public string FileName => Path.GetFileName(_filePath); public PersistentDataContainer(string filePath) { Debuggers.PersistentDataContainer?.Log("new PersistentDataContainer: " + Path.GetFileName(filePath)); _filePath = filePath; if (!File.Exists(filePath)) { return; } Debuggers.PersistentDataContainer?.Log("loading existing file"); try { dictionary = JsonConvert.DeserializeObject>(File.ReadAllText(_filePath), DawnLib.JSONSettings); } catch (Exception arg) { DawnPlugin.Logger.LogFatal((object)$"Exception when loading from persistent data container ({Path.GetFileName(_filePath)}):\n{arg}"); HasCorruptedData.Add(this); return; } if (dictionary == null) { DawnPlugin.Logger.LogFatal((object)("Failure when loading from persistent data container (" + Path.GetFileName(_filePath) + "), file likely corrupted, please delete.")); HasCorruptedData.Add(this); return; } foreach (object value in dictionary.Values) { if (value is ChildPersistentDataContainer childPersistentDataContainer) { Debuggers.PersistentDataContainer?.Log(string.Format("updated parent for a loaded persistent data container. count = {0}: {1}", childPersistentDataContainer.Count, string.Join(", ", childPersistentDataContainer.Keys.Select((NamespacedKey it) => it.ToString())))); childPersistentDataContainer.Internal_SetParent(this); } } Debuggers.PersistentDataContainer?.Log($"loaded {dictionary.Count} entries."); } public override void Set(NamespacedKey key, T value) { if (value is IDataContainer && !(value is ChildPersistentDataContainer)) { throw new NotSupportedException($"{key} is a {value.GetType().Name}, which is not supported by persistent data container. Only ChildPersistentDataContainer is supported."); } if ((object)value is ChildPersistentDataContainer childPersistentDataContainer && childPersistentDataContainer.Parent != this) { throw new NotSupportedException($"{key} is a child persistent data container being added to '{FileName}' when it belongs to '{childPersistentDataContainer.Parent.FileName}'."); } base.Set(key, value); if (AutoSave) { Task.Run((Func)SaveAsync); } } public override void Clear() { base.Clear(); if (AutoSave) { MarkDirty(); } } public override void Remove(NamespacedKey key) { base.Remove(key); if (AutoSave) { MarkDirty(); } } [Obsolete("Use CreateEditContext()")] public IDisposable LargeEdit() { return CreateEditContext(); } public override IDisposable CreateEditContext() { return new EditContext(this); } public override void MarkDirty() { Task.Run((Func)SaveAsync); } private async Task SaveAsync() { Debuggers.PersistentDataContainer?.Log("saving (" + Path.GetFileName(_filePath) + ")"); await _saveLock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false); try { FileStream stream = new FileStream(_filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true); try { StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); try { string value = JsonConvert.SerializeObject((object)dictionary, DawnLib.JSONSettings); await writer.WriteAsync(value).ConfigureAwait(continueOnCapturedContext: false); await writer.FlushAsync().ConfigureAwait(continueOnCapturedContext: false); await stream.FlushAsync().ConfigureAwait(continueOnCapturedContext: false); Debuggers.PersistentDataContainer?.Log("saved (" + Path.GetFileName(_filePath) + ")"); } finally { if (writer != null) { await writer.DisposeAsync(); } } } finally { if (stream != null) { await stream.DisposeAsync(); } } } catch (Exception arg) { DawnPlugin.Logger.LogError((object)$"Error happened while trying to save PersistentDataContainer ({Path.GetFileName(_filePath)}):\n{arg}"); } finally { _saveLock.Release(); } } internal void DeleteFile() { File.Delete(_filePath); } } public class ChildPersistentDataContainer : DataContainer { public PersistentDataContainer Parent { get; private set; } internal ChildPersistentDataContainer() { } public ChildPersistentDataContainer(PersistentDataContainer parent) { Parent = parent; } public override void MarkDirty() { if (Parent.AutoSave) { Parent.MarkDirty(); } } public override IDisposable CreateEditContext() { return Parent.CreateEditContext(); } internal void Internal_SetParent(PersistentDataContainer parent) { Parent = parent; } } public abstract class DawnBaseInfo : INamespaced, INamespaced, ITaggable, IRegistryEvents where T : DawnBaseInfo { private HashSet _tags; private IDataContainer? _customData; public IDataContainer CustomData { get { if (_customData == null) { _customData = new DataContainer(); } return _customData; } } public NamespacedKey Key => TypedKey; public NamespacedKey TypedKey { get; } protected DawnBaseInfo(NamespacedKey key, HashSet tags, IDataContainer? customData) { TypedKey = key; _tags = tags; _customData = customData; } public bool HasTag(NamespacedKey tag) { return _tags.Contains(tag); } public IEnumerable AllTags() { return _tags; } internal void Internal_AddTag(NamespacedKey tag) { Debuggers.Tags?.Log($"Internal_AddTag: {tag} !!!"); _tags.Add(tag); } public void OnFrozen() { if (_customData == null) { _customData = FrozenEmptyDataContainer.Instance; } } public bool ShouldSkipIgnoreOverride() { if (!Key.IsVanilla() && !HasTag(DawnLibTags.IsExternal)) { return HasTag(Tags.Unimplemented); } return true; } public bool ShouldSkipRespectOverride() { if (ShouldSkipIgnoreOverride()) { return !HasTag(DawnLibTags.LunarConfig); } return false; } } public class DawnInfoContainer : MonoBehaviour where T : DawnBaseInfo { public T Value { get; internal set; } } public static class DawnLib { public const string PLUGIN_GUID = "com.github.teamxiaolan.dawnlib"; internal static readonly JsonSerializerSettings JSONSettings = new JsonSerializerSettings { ReferenceLoopHandling = (ReferenceLoopHandling)1, PreserveReferencesHandling = (PreserveReferencesHandling)0, TypeNameHandling = (TypeNameHandling)3, Formatting = (Formatting)1, Converters = new List(3) { (JsonConverter)(object)new NamespacedKeyConverter(), (JsonConverter)(object)new NamespacedKeyDictionaryConverter(), (JsonConverter)(object)new Vector3Converter() } }; private static PersistentDataContainer? _profileContainer; public static PersistentDataContainer? GetCurrentSave() { return NetworkSingleton.Instance?.SaveContainer; } public static PersistentDataContainer? GetCurrentContract() { return NetworkSingleton.Instance?.ContractContainer; } public static PersistentDataContainer GetCurrentInstallSave() { if (_profileContainer == null) { _profileContainer = new PersistentDataContainer(Path.Combine(Paths.BepInExRootPath, "DawnLib.dawndata")); } return _profileContainer; } public static void RegisterNetworkPrefab(GameObject prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { throw new ArgumentNullException("prefab"); } MiscFixesPatch.networkPrefabsToAdd.Add(prefab); } public static void RegisterNetworkScene(string scenePath) { DawnNetworkSceneManager.AddScenePath(scenePath); } public static void FixMixerGroups(GameObject prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { throw new ArgumentNullException("prefab"); } MiscFixesPatch.soundPrefabsToFix.Add(prefab); } public static void FixDoorwaySockets(GameObject prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { throw new ArgumentNullException("prefab"); } MiscFixesPatch.tilesToFixSockets.Add(prefab); } public static DawnTerminalCommandInfo DefineTerminalCommand(NamespacedKey key, TerminalCommandBasicInformation commandBasicInformation, Action callback) { TerminalCommandInfoBuilder terminalCommandInfoBuilder = new TerminalCommandInfoBuilder(key, commandBasicInformation); callback(terminalCommandInfoBuilder); DawnTerminalCommandInfo dawnTerminalCommandInfo = terminalCommandInfoBuilder.Build(); LethalContent.TerminalCommands.Register(dawnTerminalCommandInfo); return dawnTerminalCommandInfo; } public static DawnSurfaceInfo DefineSurface(NamespacedKey key, FootstepSurface surface, Action callback) { SurfaceInfoBuilder surfaceInfoBuilder = new SurfaceInfoBuilder(key, surface); callback(surfaceInfoBuilder); DawnSurfaceInfo dawnSurfaceInfo = surfaceInfoBuilder.Build(); surface.SetDawnInfo(dawnSurfaceInfo); LethalContent.Surfaces.Register(dawnSurfaceInfo); return dawnSurfaceInfo; } public static DawnStoryLogInfo DefineStoryLog(NamespacedKey key, GameObject storyLogGameObject, Action callback) { StoryLogInfoBuilder storyLogInfoBuilder = new StoryLogInfoBuilder(key, storyLogGameObject); callback(storyLogInfoBuilder); DawnStoryLogInfo dawnStoryLogInfo = storyLogInfoBuilder.Build(); DawnStoryLogNamespacedKeyContainer dawnStoryLogNamespacedKeyContainer = storyLogGameObject.AddComponent(); dawnStoryLogNamespacedKeyContainer.Value = dawnStoryLogInfo.TypedKey; LethalContent.StoryLogs.Register(dawnStoryLogInfo); return dawnStoryLogInfo; } public static DawnDungeonInfo DefineDungeon(NamespacedKey key, string flowName, Action callback) { DungeonFlow val = ScriptableObject.CreateInstance(); ((Object)val).name = flowName; DungeonFlowInfoBuilder dungeonFlowInfoBuilder = new DungeonFlowInfoBuilder(key, val); callback(dungeonFlowInfoBuilder); DawnDungeonInfo dawnDungeonInfo = dungeonFlowInfoBuilder.Build(); val.SetDawnInfo(dawnDungeonInfo); LethalContent.Dungeons.Register(dawnDungeonInfo); return dawnDungeonInfo; } public static DawnTileSetInfo DefineTileSet(NamespacedKey key, TileSet tileSet, Action callback) { TilesetInfoBuilder tilesetInfoBuilder = new TilesetInfoBuilder(key, tileSet); callback(tilesetInfoBuilder); DawnTileSetInfo dawnTileSetInfo = tilesetInfoBuilder.Build(); tileSet.SetDawnInfo(dawnTileSetInfo); LethalContent.TileSets.Register(dawnTileSetInfo); return dawnTileSetInfo; } public static DawnMapObjectInfo DefineMapObject(NamespacedKey key, GameObject mapObject, Action callback) { MapObjectInfoBuilder mapObjectInfoBuilder = new MapObjectInfoBuilder(key, mapObject); callback(mapObjectInfoBuilder); DawnMapObjectInfo dawnMapObjectInfo = mapObjectInfoBuilder.Build(); IIndoorMapHazard val = default(IIndoorMapHazard); if (!mapObject.TryGetComponent(ref val)) { DawnMapObjectNamespacedKeyContainer dawnMapObjectNamespacedKeyContainer = mapObject.AddComponent(); dawnMapObjectNamespacedKeyContainer.Value = dawnMapObjectInfo.Key; } if (dawnMapObjectInfo.InsideInfo != null) { dawnMapObjectInfo.InsideInfo.IndoorMapHazardType.SetDawnInfo(dawnMapObjectInfo); } if (dawnMapObjectInfo.OutsideInfo != null) { dawnMapObjectInfo.OutsideInfo.SpawnableOutsideObject.SetDawnInfo(dawnMapObjectInfo); } LethalContent.MapObjects.Register(dawnMapObjectInfo); return dawnMapObjectInfo; } public static DawnUnlockableItemInfo DefineUnlockable(NamespacedKey key, UnlockableItem unlockableItem, Action callback) { UnlockableInfoBuilder unlockableInfoBuilder = new UnlockableInfoBuilder(key, unlockableItem); callback(unlockableInfoBuilder); DawnUnlockableItemInfo dawnUnlockableItemInfo = unlockableInfoBuilder.Build(); unlockableItem.SetDawnInfo(dawnUnlockableItemInfo); LethalContent.Unlockables.Register(dawnUnlockableItemInfo); return dawnUnlockableItemInfo; } public static DawnItemInfo DefineItem(NamespacedKey key, Item item, Action callback) { ItemInfoBuilder itemInfoBuilder = new ItemInfoBuilder(key, item); callback(itemInfoBuilder); DawnItemInfo dawnItemInfo = itemInfoBuilder.Build(); item.SetDawnInfo(dawnItemInfo); LethalContent.Items.Register(dawnItemInfo); return dawnItemInfo; } public static DawnEnemyInfo DefineEnemy(NamespacedKey key, EnemyType enemy, Action callback) { EnemyInfoBuilder enemyInfoBuilder = new EnemyInfoBuilder(key, enemy); callback(enemyInfoBuilder); DawnEnemyInfo dawnEnemyInfo = enemyInfoBuilder.Build(); enemy.SetDawnInfo(dawnEnemyInfo); LethalContent.Enemies.Register(dawnEnemyInfo); return dawnEnemyInfo; } public static DawnMoonInfo DefineMoon(NamespacedKey key, SelectableLevel level, Action callback) { MoonInfoBuilder moonInfoBuilder = new MoonInfoBuilder(key, level); callback(moonInfoBuilder); DawnMoonInfo dawnMoonInfo = moonInfoBuilder.Build(); level.SetDawnInfo(dawnMoonInfo); LethalContent.Moons.Register(dawnMoonInfo); return dawnMoonInfo; } public static void ApplyTag(JSONTagDefinition definition) { JSONTagDefinition definition2 = definition; NamespacedKey namespacedKey2 = NamespacedKey.Parse(definition2.Tag); ListenToRegistry(LethalContent.Moons, namespacedKey2); ListenToRegistry(LethalContent.MapObjects, namespacedKey2); ListenToRegistry(LethalContent.Enemies, namespacedKey2); ListenToRegistry(LethalContent.Items, namespacedKey2); ListenToRegistry(LethalContent.Weathers, namespacedKey2); ListenToRegistry(LethalContent.Dungeons, namespacedKey2); ListenToRegistry(LethalContent.Unlockables, namespacedKey2); Debuggers.Tags?.Log($"Scheduled applying tag: {namespacedKey2}"); void ListenToRegistry(TaggedRegistry registry, NamespacedKey namespacedKey) where T : notnull, DawnBaseInfo { TaggedRegistry registry2 = registry; NamespacedKey namespacedKey3 = namespacedKey; registry2.OnFreeze += delegate { string[] values = definition2.Values; foreach (string input in values) { if (registry2.TryGetValue(NamespacedKey.Parse(input), out var value)) { value.Internal_AddTag(namespacedKey3); } } }; } } public static void ApplyAllTagsInFolder(string path) { string[] files = Directory.GetFiles(path, "*.tag.json", SearchOption.AllDirectories); foreach (string path2 in files) { JSONTagDefinition definition = JsonConvert.DeserializeObject(File.ReadAllText(path2)); ApplyTag(definition); } } } public class DawnNamespacedKeyContainer : MonoBehaviour where T : NamespacedKey { public T Value { get; internal set; } } [HarmonyPatch] internal static class DungeonRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__RegisterDawnDungeons; public static Action, RandomMapObject> <1>__FixRandomMapObjects; public static Action <2>__AddDawnDungeonsToMoons; public static Action <3>__CollectNonDawnDungeons; public static hook_SetPlanetsWeather <4>__UpdateAllDungeonWeights; public static hook_EndOfGame <5>__UnloadDungeonBundleForAllPlayers; public static hook_Awake <6>__DeleteLLLTranspilerAndEnsureDelayedDungeon; public static hook_Awake <7>__RemoveHotloadingIfDebugDunGenPlus; public static Manipulator <8>__MakeExtraScrapGenerationMoreModular; public static Action <9>__CleanDawnDungeonReferences; public static hook_TeleportPlayer <10>__HandleStingerAudio; public static Manipulator <11>__DelayDungeonGeneration; public static Func <12>__LoadDungeonBundle; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_GenerateNewFloor <>9__0_0; public static hook_Start <>9__0_1; public static hook_Generate <>9__0_2; public static Func <>9__2_0; public static Func <>9__2_1; public static Func <>9__2_2; public static Func <>9__2_3; public static Func <>9__2_4; public static Func <>9__2_5; public static Func <>9__2_6; public static Func <>9__2_7; public static Func <>9__9_0; public static Func <>9__9_1; public static Func <>9__9_2; public static Func <>9__11_0; public static Func <>9__12_0; public static Func <>9__12_1; public static Func <>9__15_0; public static Func <>9__17_0; internal void b__0_0(orig_GenerateNewFloor orig, RoundManager self) { UpdateDungeonWeightOnLevel(self.currentLevel); orig.Invoke(self); } internal void b__0_1(orig_Start orig, RuntimeDungeon self) { self.GenerateOnStart = false; orig.Invoke(self); } internal void b__0_2(orig_Generate orig, RuntimeDungeon self) { AdjustFireExits(self.Generator.DungeonFlow); TryInjectTileSets(self.Generator.DungeonFlow); orig.Invoke(self); } internal bool b__2_0(Instruction instr) { return ILPatternMatchingExt.MatchLdarg(instr, 0); } internal bool b__2_1(Instruction instr) { return ILPatternMatchingExt.MatchLdfld(instr, "currentDungeonType"); } internal bool b__2_2(Instruction instr) { return ILPatternMatchingExt.MatchLdcI4(instr, 4); } internal bool b__2_3(Instruction instr) { ILLabel val = default(ILLabel); return ILPatternMatchingExt.MatchBneUn(instr, ref val); } internal bool b__2_4(Instruction instr) { return ILPatternMatchingExt.MatchLdloc(instr, 1); } internal bool b__2_5(Instruction instr) { return ILPatternMatchingExt.MatchLdcI4(instr, 6); } internal bool b__2_6(Instruction instr) { return ILPatternMatchingExt.MatchAdd(instr); } internal bool b__2_7(Instruction instr) { return ILPatternMatchingExt.MatchStloc(instr, 1); } internal bool b__9_0(Instruction i) { return ILPatternMatchingExt.MatchLdarg(i, 0); } internal bool b__9_1(Instruction i) { return ILPatternMatchingExt.MatchLdfld(i, "dungeonGenerator"); } internal bool b__9_2(Instruction i) { return ILPatternMatchingExt.MatchCallvirt(i, "Generate"); } internal bool b__11_0() { return NetworkSingleton.Instance.allPlayersDone; } internal bool b__12_0(EntranceTeleport e) { return e.entranceId != 0; } internal bool b__12_1(GlobalPropSettings p) { return p.ID == DawnDungeonInfo.FireExitGlobalPropID; } internal DungeonFlow b__15_0(IndoorMapType t) { return t.dungeonFlow; } internal bool b__17_0() { return true; } } [CompilerGenerated] private sealed class d__11 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private DawnDungeonInfo 5__2; private IEnumerator 5__3; object 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; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow.GetDawnInfo(); if (DungeonGenerationPlusCompat.Enabled && DungeonGenerationPlusCompat.IsDebugOn()) { break; } if (!5__2.ShouldSkipIgnoreOverride()) { NetworkSingleton.Instance.QueueDungeonBundleLoading(5__2.Key); 5__3 = (IEnumerator)new WaitUntil((Func)(() => NetworkSingleton.Instance.allPlayersDone)); goto IL_00c9; } goto IL_00dd; case 1: <>1__state = -1; goto IL_00c9; case 2: { <>1__state = -1; break; } IL_00dd: <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; IL_00c9: if (5__3.MoveNext()) { <>2__current = 5__3.Current; <>1__state = 1; return true; } 5__3 = null; goto IL_00dd; } if (LethalLevelLoaderCompat.Enabled && 5__2.ShouldSkipRespectOverride()) { LethalLevelLoaderCompat.LetLLLHandleGeneration(); } else { BoundedRange boundedRange = 5__2.DungeonClampRange; if (5__2.DungeonClampRange.Min == 0f && 5__2.DungeonClampRange.Max == 0f) { boundedRange = new BoundedRange(0f, 999f); } RoundManager.Instance.dungeonGenerator.Generator.LengthMultiplier = Mathf.Clamp(RoundManager.Instance.dungeonGenerator.Generator.LengthMultiplier, boundedRange.Min, boundedRange.Max); RoundManager.Instance.dungeonGenerator.Generate(); } 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(); } } [CompilerGenerated] private sealed class d__10 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public orig_EndOfGame orig; public StartOfRound self; public int bodiesInsured; public int connectedPlayersOnServer; public int scrapCollected; private IEnumerator 5__2; private IEnumerator 5__3; object 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; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!DungeonGenerationPlusCompat.Enabled || !DungeonGenerationPlusCompat.IsDebugOn()) { if ((Object)(object)NetworkSingleton.Instance != (Object)null) { 5__3 = NetworkSingleton.Instance.UnloadExisting(); goto IL_007b; } if (!DawnConfig.VanillaCompatibility.Value) { DawnPlugin.Logger.LogError((object)"DawnDungeonNetworker is null, but VanillaCompatibility is false! This is a bug!"); } } goto IL_00c6; case 1: <>1__state = -1; goto IL_007b; case 2: { <>1__state = -1; break; } IL_00c6: 5__2 = orig.Invoke(self, bodiesInsured, connectedPlayersOnServer, scrapCollected); break; IL_007b: if (5__3.MoveNext()) { <>2__current = 5__3.Current; <>1__state = 1; return true; } NetworkSingleton.Instance.PlayerSetBundleStateRpc(GameNetworkManager.Instance.localPlayerController, DawnMoonNetworker.BundleState.Done); 5__3 = null; goto IL_00c6; } if (5__2.MoveNext()) { <>2__current = 5__2.Current; <>1__state = 2; return true; } 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 bool _alreadyPatched = false; private static readonly Dictionary _internalToHumanDungeonNames = new Dictionary { { "LevelOne", "Facility" }, { "LevelTwo", "Mansion" }, { "LevelThree", "Mineshaft" } }; internal static void Init() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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_0026: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00e8: 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_00f3: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //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_0197: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_01f5: 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_0200: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown DetourContext val = new DetourContext(int.MaxValue); try { object obj = <>O.<0>__RegisterDawnDungeons; if (obj == null) { hook_Awake val2 = RegisterDawnDungeons; <>O.<0>__RegisterDawnDungeons = val2; obj = (object)val2; } StartOfRound.Awake += (hook_Awake)obj; } finally { ((IDisposable)val)?.Dispose(); } DetourContext val3 = new DetourContext(200); try { DawnPlugin.Hooks.Add(new Hook((MethodBase)AccessTools.DeclaredMethod(typeof(RandomMapObject), "Awake", (Type[])null, (Type[])null), (Delegate)new Action, RandomMapObject>(FixRandomMapObjects))); } finally { ((IDisposable)val3)?.Dispose(); } LethalContent.Moons.OnFreeze += AddDawnDungeonsToMoons; LethalContent.Moons.OnFreeze += CollectNonDawnDungeons; object obj2 = <>O.<4>__UpdateAllDungeonWeights; if (obj2 == null) { hook_SetPlanetsWeather val4 = UpdateAllDungeonWeights; <>O.<4>__UpdateAllDungeonWeights = val4; obj2 = (object)val4; } StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj2; object obj3 = <>O.<5>__UnloadDungeonBundleForAllPlayers; if (obj3 == null) { hook_EndOfGame val5 = UnloadDungeonBundleForAllPlayers; <>O.<5>__UnloadDungeonBundleForAllPlayers = val5; obj3 = (object)val5; } StartOfRound.EndOfGame += (hook_EndOfGame)obj3; object obj4 = <>O.<6>__DeleteLLLTranspilerAndEnsureDelayedDungeon; if (obj4 == null) { hook_Awake val6 = DeleteLLLTranspilerAndEnsureDelayedDungeon; <>O.<6>__DeleteLLLTranspilerAndEnsureDelayedDungeon = val6; obj4 = (object)val6; } MenuManager.Awake += (hook_Awake)obj4; object obj5 = <>O.<7>__RemoveHotloadingIfDebugDunGenPlus; if (obj5 == null) { hook_Awake val7 = RemoveHotloadingIfDebugDunGenPlus; <>O.<7>__RemoveHotloadingIfDebugDunGenPlus = val7; obj5 = (object)val7; } MenuManager.Awake += (hook_Awake)obj5; object obj6 = <>O.<8>__MakeExtraScrapGenerationMoreModular; if (obj6 == null) { Manipulator val8 = MakeExtraScrapGenerationMoreModular; <>O.<8>__MakeExtraScrapGenerationMoreModular = val8; obj6 = (object)val8; } RoundManager.SpawnScrapInLevel += (Manipulator)obj6; object obj7 = <>c.<>9__0_0; if (obj7 == null) { hook_GenerateNewFloor val9 = delegate(orig_GenerateNewFloor orig, RoundManager self) { UpdateDungeonWeightOnLevel(self.currentLevel); orig.Invoke(self); }; <>c.<>9__0_0 = val9; obj7 = (object)val9; } RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj7; LethalContent.Dungeons.BeforeFreeze += CleanDawnDungeonReferences; object obj8 = <>O.<10>__HandleStingerAudio; if (obj8 == null) { hook_TeleportPlayer val10 = HandleStingerAudio; <>O.<10>__HandleStingerAudio = val10; obj8 = (object)val10; } EntranceTeleport.TeleportPlayer += (hook_TeleportPlayer)obj8; object obj9 = <>c.<>9__0_1; if (obj9 == null) { hook_Start val11 = delegate(orig_Start orig, RuntimeDungeon self) { self.GenerateOnStart = false; orig.Invoke(self); }; <>c.<>9__0_1 = val11; obj9 = (object)val11; } RuntimeDungeon.Start += (hook_Start)obj9; object obj10 = <>c.<>9__0_2; if (obj10 == null) { hook_Generate val12 = delegate(orig_Generate orig, RuntimeDungeon self) { AdjustFireExits(self.Generator.DungeonFlow); TryInjectTileSets(self.Generator.DungeonFlow); orig.Invoke(self); }; <>c.<>9__0_2 = val12; obj10 = (object)val12; } RuntimeDungeon.Generate += (hook_Generate)obj10; } private static void RemoveHotloadingIfDebugDunGenPlus(orig_Awake orig, MenuManager self) { if ((Object)(object)self.versionNumberText == (Object)null) { orig.Invoke(self); return; } if (DungeonGenerationPlusCompat.Enabled && DungeonGenerationPlusCompat.IsDebugOn() && !DungeonGenerationPlusCompat.RemovedHotloading) { DungeonGenerationPlusCompat.RemovedHotloading = true; foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values) { if (!value.ShouldSkipIgnoreOverride()) { AssetBundle val = AssetBundle.LoadFromFile(value.AssetBundlePath); DungeonFlow val2 = val.LoadAsset(((Object)value.DungeonFlow).name ?? ""); if ((Object)(object)val2 == (Object)null) { DawnPlugin.Logger.LogError((object)("Bundle: " + Path.GetFileName(value.AssetBundlePath) + " does not contain DungeonFlow: " + ((Object)value.DungeonFlow).name + ".")); return; } DawnDungeonNetworker.TryApplyLoadedDungeonFlow(val2, val); } } } orig.Invoke(self); } private static void MakeExtraScrapGenerationMoreModular(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel val2 = default(ILLabel); if (!val.TryGotoNext((MoveType)0, new Func[8] { (Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0), (Instruction instr) => ILPatternMatchingExt.MatchLdfld(instr, "currentDungeonType"), (Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 4), (Instruction instr) => ILPatternMatchingExt.MatchBneUn(instr, ref val2), (Instruction instr) => ILPatternMatchingExt.MatchLdloc(instr, 1), (Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 6), (Instruction instr) => ILPatternMatchingExt.MatchAdd(instr), (Instruction instr) => ILPatternMatchingExt.MatchStloc(instr, 1) })) { DawnPlugin.Logger.LogWarning((object)"Failed to find IL for RoundManager.SpawnScrapInLevel (MakeExtraScrapGenerationMoreModular)."); return; } val.RemoveRange(8); val.Emit(OpCodes.Ldloc_1); val.Emit(OpCodes.Call, (MethodBase)AccessTools.DeclaredMethod(typeof(DungeonRegistrationHandler), "GetExtraScrapForCurrentlyLoadedInterior", (Type[])null, (Type[])null)); val.Emit(OpCodes.Add); val.Emit(OpCodes.Stloc_1); } private static int GetExtraScrapForCurrentlyLoadedInterior() { return (RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow?.GetDawnInfo())?.ExtraScrapGeneration ?? 0; } private static void HandleStingerAudio(orig_TeleportPlayer orig, EntranceTeleport self) { if (!self.checkedForFirstTime) { self.checkedForFirstTime = true; DawnDungeonInfo dawnDungeonInfo = RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow.GetDawnInfo(); if (dawnDungeonInfo == null || (Object)(object)dawnDungeonInfo.StingerDetail.FirstTimeAudio == (Object)null) { orig.Invoke(self); return; } if (!dawnDungeonInfo.StingerDetail.AllowStingerToPlay.Provide()) { orig.Invoke(self); return; } if (!dawnDungeonInfo.CustomData.TryGet(DawnKeys.StingerPlayed, out var value)) { DawnPlugin.Logger.LogError((object)$"Failed to get {DawnKeys.StingerPlayed} from dungeon: {dawnDungeonInfo.Key}."); orig.Invoke(self); return; } if (value && !dawnDungeonInfo.StingerDetail.PlaysMoreThanOnce) { orig.Invoke(self); return; } float num = Random.Range(0f, 100f); if (num > dawnDungeonInfo.StingerDetail.PlayChance) { orig.Invoke(self); return; } Debuggers.Dungeons?.Log($"Playing dungeon stinger for dungeon {dawnDungeonInfo.Key}, alreadyPlayed: {value} (Chance Roll: {num} <= {dawnDungeonInfo.StingerDetail.PlayChance})"); dawnDungeonInfo.CustomData.Set(DawnKeys.StingerPlayed, value: true); ((MonoBehaviour)self).StartCoroutine(self.playMusicOnDelay()); } orig.Invoke(self); } private static void FixRandomMapObjects(Action orig, RandomMapObject self) { foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values) { for (int i = 0; i < self.spawnablePrefabs.Count; i++) { if (!((Object)(object)self.spawnablePrefabs[i] == (Object)null)) { GameObject mapObjectPrefab = value.GetMapObjectPrefab(); if (!((Object)(object)mapObjectPrefab == (Object)null) && ((Object)self.spawnablePrefabs[i]).name.Equals(((Object)mapObjectPrefab).name, StringComparison.OrdinalIgnoreCase)) { self.spawnablePrefabs[i] = mapObjectPrefab; break; } } } } orig.Invoke(self); } private static void DeleteLLLTranspilerAndEnsureDelayedDungeon(orig_Awake orig, MenuManager self) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown orig.Invoke(self); if (!_alreadyPatched) { if (LethalLevelLoaderCompat.Enabled) { DawnPlugin.Logger.LogDebug((object)"Removing LethalLevelLoader dungeon generation transpiler."); LethalLevelLoaderCompat.TryRemoveLLLDungeonTranspiler(); LethalLevelLoaderCompat.ScrewWithLLLDynamicDungeonRarity(); } object obj = <>O.<11>__DelayDungeonGeneration; if (obj == null) { Manipulator val = DelayDungeonGeneration; <>O.<11>__DelayDungeonGeneration = val; obj = (object)val; } RoundManager.GenerateNewFloor += (Manipulator)obj; _alreadyPatched = true; } } private static void CleanDawnDungeonReferences() { foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values) { if (!value.ShouldSkipIgnoreOverride()) { List list = value.DungeonFlow.GetUsedArchetypes().Distinct().ToList(); List list2 = value.DungeonFlow.GetUsedTileSets().Distinct().ToList(); value.DungeonFlow.Nodes.Clear(); value.DungeonFlow.Lines.Clear(); for (int num = list.Count - 1; num >= 0; num--) { Object.Destroy((Object)(object)list[num]); } for (int num2 = list2.Count - 1; num2 >= 0; num2--) { Object.Destroy((Object)(object)list2[num2]); } } } } private static void DelayDungeonGeneration(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func[3] { (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0), (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, "dungeonGenerator"), (Instruction i) => ILPatternMatchingExt.MatchCallvirt(i, "Generate") })) { val.RemoveRange(3); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)LoadDungeonBundle); MethodInfo method = typeof(MonoBehaviour).GetMethod("StartCoroutine", new Type[1] { typeof(IEnumerator) }); val.Emit(OpCodes.Callvirt, (MethodBase)method); val.Emit(OpCodes.Pop); } else { DawnPlugin.Logger.LogError((object)"Failed to apply DawnLib dungeon generation delay patch!"); DawnPlugin.Logger.LogError((object)"IL code:"); DawnPlugin.Logger.LogError((object)((object)il).ToString()); } } [IteratorStateMachine(typeof(d__10))] private static IEnumerator UnloadDungeonBundleForAllPlayers(orig_EndOfGame orig, StartOfRound self, int bodiesInsured, int connectedPlayersOnServer, int scrapCollected) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(0) { orig = orig, self = self, bodiesInsured = bodiesInsured, connectedPlayersOnServer = connectedPlayersOnServer, scrapCollected = scrapCollected }; } [IteratorStateMachine(typeof(d__11))] private static IEnumerator LoadDungeonBundle() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__11(0); } private static void AdjustFireExits(DungeonFlow dungeonFlow) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown EntranceTeleport[] array = (from e in Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0) where e.entranceId != 0 select e).ToArray(); for (int i = 0; i < array.Length; i++) { EntranceTeleport val = array[i]; val.entranceId = i + 1; } foreach (GlobalPropSettings item in dungeonFlow.GlobalProps.Where((GlobalPropSettings p) => p.ID == DawnDungeonInfo.FireExitGlobalPropID)) { item.Count = new IntRange(array.Length, array.Length); } } private static void UpdateAllDungeonWeights(orig_SetPlanetsWeather orig, StartOfRound self, int connectedPlayersOnServer) { orig.Invoke(self, connectedPlayersOnServer); UpdateDungeonWeightOnLevel(self.currentLevel); } internal static void UpdateDungeonWeightOnLevel(SelectableLevel level) { if (!LethalContent.Weathers.IsFrozen || !LethalContent.Dungeons.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady())) { return; } IntWithRarity[] dungeonFlowTypes = level.dungeonFlowTypes; foreach (IntWithRarity val in dungeonFlowTypes) { DawnDungeonInfo dawnInfo = RoundManagerRefs.Instance.dungeonFlowTypes[val.id].dungeonFlow.GetDawnInfo(); if (!dawnInfo.ShouldSkipRespectOverride()) { SpawnWeightContext ctx = new SpawnWeightContext(level.GetDawnInfo(), null, TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault = (dawnInfo.Weights?.GetFor(in ctx)).GetValueOrDefault(); val.rarity = valueOrDefault.Clamp0(); } } } private static void AddDawnDungeonsToMoons() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown foreach (DawnMoonInfo value in LethalContent.Moons.Values) { List list = value.Level.dungeonFlowTypes.ToList(); foreach (DawnDungeonInfo value2 in LethalContent.Dungeons.Values) { if (!value2.ShouldSkipIgnoreOverride()) { int num = Array.IndexOf(RoundManagerRefs.Instance.dungeonFlowTypes.Select((IndoorMapType t) => t.dungeonFlow).ToArray(), value2.DungeonFlow); IntWithRarity item = new IntWithRarity(num, 0, (LevelAmbienceLibrary)null); list.Add(item); } } value.Level.dungeonFlowTypes = list.ToArray(); } } private static void RegisterDawnDungeons(orig_Awake orig, StartOfRound self) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown List list = RoundManagerRefs.Instance.dungeonFlowTypes.ToList(); foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values) { if (!value.ShouldSkipIgnoreOverride()) { IndoorMapType item = new IndoorMapType(value.DungeonFlow, value.MapTileSize, value.StingerDetail.FirstTimeAudio); list.Add(item); } } RoundManagerRefs.Instance.dungeonFlowTypes = list.ToArray(); orig.Invoke(self); } private static void CollectNonDawnDungeons() { Dictionary> dictionary = new Dictionary>(); foreach (DawnMoonInfo value3 in LethalContent.Moons.Values) { SelectableLevel level = value3.Level; List list = level.dungeonFlowTypes.ToList(); if (LethalLevelLoaderCompat.Enabled) { list.AddRange(LethalLevelLoaderCompat.GetCustomDungeonsWithRarities(level)); } foreach (IntWithRarity item in list) { DungeonFlow dungeonFlow = RoundManagerRefs.Instance.dungeonFlowTypes[item.id].dungeonFlow; if (!dictionary.TryGetValue(((Object)dungeonFlow).name, out var value)) { value = new WeightTableBuilder(); dictionary[((Object)dungeonFlow).name] = value; } Debuggers.Dungeons?.Log($"Grabbing weight {item.rarity} to {((Object)dungeonFlow).name} on level {level.PlanetName}"); value.AddWeight(value3.TypedKey, item.rarity); } } IndoorMapType[] dungeonFlowTypes = RoundManagerRefs.Instance.dungeonFlowTypes; foreach (IndoorMapType val in dungeonFlowTypes) { if (val == null || (Object)(object)val.dungeonFlow == (Object)null || val.dungeonFlow.HasDawnInfo()) { continue; } string name = FormatFlowName(val.dungeonFlow); NamespacedKey namespacedKey = DungeonKeys.GetByReflection(name); BoundedRange dungeonClampRange = new BoundedRange(0f, 999f); if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedDungeonModName(val.dungeonFlow, out string modName)) { namespacedKey = NamespacedKey.From(modName, ((Object)val.dungeonFlow).name); dungeonClampRange = LethalLevelLoaderCompat.GetDungeonClamp(val.dungeonFlow); } else if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_modded", ((Object)val.dungeonFlow).name); } if (LethalContent.Dungeons.ContainsKey(namespacedKey)) { Debuggers.Dungeons?.Log($"LethalContent.Dungeons already contains {namespacedKey}"); val.dungeonFlow.SetDawnInfo(LethalContent.Dungeons[namespacedKey]); continue; } HashSet tags = new HashSet { DawnLibTags.IsExternal }; CollectLLLTags(val.dungeonFlow, tags); dictionary.TryGetValue(((Object)val.dungeonFlow).name, out var value2); if (value2 == null) { value2 = new WeightTableBuilder(); } PersistentDataContainer persistentDataContainer = new PersistentDataContainer(Path.Combine(PersistentDataHandler.RootPath, "dungeon_" + namespacedKey.Namespace + "_" + namespacedKey.Key)); if (!persistentDataContainer.Has(DawnKeys.StingerPlayed)) { persistentDataContainer.Set(DawnKeys.StingerPlayed, value: false); } DawnStingerDetail stingerDetail = new DawnStingerDetail(val.firstTimeAudio, playsMoreThanOnce: false, 100f, new FuncProvider(() => true)); int extraScrapGeneration = 0; if (namespacedKey == DungeonKeys.MineshaftFlow) { extraScrapGeneration = 6; } DawnDungeonInfo dawnDungeonInfo = new DawnDungeonInfo(namespacedKey, tags, val.dungeonFlow, value2.Build(), val.MapTileSize, stingerDetail, string.Empty, dungeonClampRange, extraScrapGeneration, persistentDataContainer); val.dungeonFlow.SetDawnInfo(dawnDungeonInfo); LethalContent.Dungeons.Register(dawnDungeonInfo); } CollectArchetypesAndTileSets(); LethalContent.Dungeons.Freeze(); } private static void CollectArchetypesAndTileSets() { foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values) { DungeonArchetype[] usedArchetypes = value.DungeonFlow.GetUsedArchetypes(); foreach (DungeonArchetype val in usedArchetypes) { Debuggers.Dungeons?.Log("dungeonArchetype.name: " + ((Object)val).name); NamespacedKey namespacedKey; if (value.Key.IsVanilla()) { string text = FormatArchetypeName(val); namespacedKey = DungeonArchetypeKeys.GetByReflection(text); if (namespacedKey == null) { DawnPlugin.Logger.LogWarning((object)$"archetype: '{((Object)val).name}' (part of {value.Key}) is vanilla, but DawnLib couldn't get a corresponding NamespacedKey, archetype has formatted name: {text}!"); continue; } } else { namespacedKey = NamespacedKey.From(value.Key.Namespace, ((Object)val).name); } if (LethalContent.Archetypes.ContainsKey(namespacedKey)) { Debuggers.Dungeons?.Log($"LethalContent.Archetypes already contains {namespacedKey}"); val.SetDawnInfo(LethalContent.Archetypes[namespacedKey]); continue; } HashSet hashSet = new HashSet(); if (value.HasTag(DawnLibTags.IsExternal)) { hashSet.Add(DawnLibTags.IsExternal); } DawnArchetypeInfo dawnArchetypeInfo = new DawnArchetypeInfo(namespacedKey, hashSet, val, null); val.SetDawnInfo(dawnArchetypeInfo); dawnArchetypeInfo.ParentInfo = value; LethalContent.Archetypes.Register(dawnArchetypeInfo); List tileSets = val.TileSets; List branchCapTileSets = val.BranchCapTileSets; List list = new List(tileSets.Count + branchCapTileSets.Count); list.AddRange(tileSets); list.AddRange(branchCapTileSets); List list2 = list; foreach (TileSet item in list2) { Debuggers.Dungeons?.Log("tileSet.name: " + ((Object)item).name); NamespacedKey namespacedKey2; if (value.Key.IsVanilla()) { string text2 = FormatTileSetName(item); namespacedKey2 = DungeonTileSetKeys.GetByReflection(text2); if (namespacedKey2 == null) { DawnPlugin.Logger.LogWarning((object)$"tileset: '{((Object)item).name}' (part of {namespacedKey}) is vanilla, but DawnLib couldn't get a corresponding NamespacedKey, tileset has formatted name: {text2}!"); continue; } } else { namespacedKey2 = NamespacedKey.From(value.Key.Namespace, ((Object)item).name); } if (LethalContent.TileSets.ContainsKey(namespacedKey2)) { Debuggers.Dungeons?.Log($"LethalContent.TileSets already contains {namespacedKey2}"); item.SetDawnInfo(LethalContent.TileSets[namespacedKey2]); continue; } HashSet hashSet2 = new HashSet(); if (value.HasTag(DawnLibTags.IsExternal)) { hashSet2.Add(DawnLibTags.IsExternal); } DawnTileSetInfo dawnTileSetInfo = new DawnTileSetInfo(namespacedKey2, hashSet2, ConstantPredicate.True, item, val.BranchCapTileSets.Contains(item), val.TileSets.Contains(item), null); dawnArchetypeInfo.AddTileSet(dawnTileSetInfo); item.SetDawnInfo(dawnTileSetInfo); LethalContent.TileSets.Register(dawnTileSetInfo); } } } LethalContent.Archetypes.Freeze(); LethalContent.TileSets.Freeze(); } private static string FormatTileSetName(TileSet tileSet) { string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)tileSet).name, CSharpName: true); return ReplaceInternalLevelNames(input).Replace("Tiles", string.Empty); } private static string FormatArchetypeName(DungeonArchetype dungeonArchetype) { string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)dungeonArchetype).name, CSharpName: true); return ReplaceInternalLevelNames(input).Replace("Archetype", string.Empty); } private static string FormatFlowName(DungeonFlow dungeonFlow) { string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)dungeonFlow).name, CSharpName: true); return ReplaceInternalLevelNames(input); } private static string ReplaceInternalLevelNames(string input) { string text = input; foreach (KeyValuePair internalToHumanDungeonName in _internalToHumanDungeonNames) { internalToHumanDungeonName.Deconstruct(out var key, out var value); string oldValue = key; string newValue = value; text = text.Replace(oldValue, newValue); } return text; } private static void CollectLLLTags(DungeonFlow dungeonFlow, HashSet tags) { if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetAllTagsWithModNames(dungeonFlow, out List<(string, string)> allTagsWithModNames)) { tags.AddToList(allTagsWithModNames, Debuggers.Dungeons, ((Object)dungeonFlow).name); } } private static void TryInjectTileSets(DungeonFlow dungeonFlow) { DungeonArchetype[] usedArchetypes = dungeonFlow.GetUsedArchetypes(); foreach (DungeonArchetype val in usedArchetypes) { if ((Object)(object)val == (Object)null) { Debuggers.Dungeons?.Log("Archetype is null in dungeonflow: " + ((Object)dungeonFlow).name); continue; } Debuggers.Dungeons?.Log("Injecting tile sets for " + ((Object)val).name); foreach (DawnTileSetInfo tileSet in val.GetDawnInfo().TileSets) { if (tileSet.ShouldSkipIgnoreOverride()) { continue; } val.BranchCapTileSets.Remove(tileSet.TileSet); val.TileSets.Remove(tileSet.TileSet); if (tileSet.InjectionPredicate.Evaluate()) { if (tileSet.IsBranchCap) { val.BranchCapTileSets.Add(tileSet.TileSet); } if (tileSet.IsRegular) { val.TileSets.Add(tileSet.TileSet); } } } } } } public class DawnArchetypeInfo : DawnBaseInfo { private List _tileSets = new List(); public DungeonArchetype DungeonArchetype { get; } public IReadOnlyList TileSets => _tileSets.AsReadOnly(); public DawnDungeonInfo ParentInfo { get; internal set; } internal DawnArchetypeInfo(NamespacedKey key, HashSet tags, DungeonArchetype archetype, IDataContainer? customData) : base(key, tags, customData) { DungeonArchetype = archetype; } public void AddTileSet(DawnTileSetInfo info) { if (LethalContent.Dungeons.IsFrozen) { throw new RegistryFrozenException(); } _tileSets.Add(info); } } public class DawnDungeonInfo : DawnBaseInfo { internal List sockets = new List(); internal List doorways = new List(); internal List spawnSyncedObjects = new List(); internal List tiles = new List(); public static int FireExitGlobalPropID = 1231; public DungeonFlow DungeonFlow { get; } public string AssetBundlePath { get; } public ProviderTable Weights { get; private set; } public float MapTileSize { get; private set; } public DawnStingerDetail StingerDetail { get; private set; } public BoundedRange DungeonClampRange { get; private set; } public int ExtraScrapGeneration { get; private set; } public IReadOnlyList Tiles => tiles.AsReadOnly(); public IReadOnlyList Doorways => doorways.AsReadOnly(); public IReadOnlyList SpawnSyncedObjects => spawnSyncedObjects.AsReadOnly(); public IReadOnlyList Sockets => sockets.AsReadOnly(); internal DawnDungeonInfo(NamespacedKey key, HashSet tags, DungeonFlow dungeonFlow, ProviderTable weights, float mapTileSize, DawnStingerDetail stingerDetail, string assetBundlePath, BoundedRange dungeonClampRange, int extraScrapGeneration, IDataContainer? customData) : base(key, tags, customData) { DungeonFlow = dungeonFlow; Weights = weights; MapTileSize = mapTileSize; StingerDetail = stingerDetail; AssetBundlePath = assetBundlePath; DungeonClampRange = dungeonClampRange; ExtraScrapGeneration = extraScrapGeneration; if (!ShouldSkipIgnoreOverride()) { return; } sockets = new List(); List list = new List(); TileSet[] usedTileSets = DungeonFlow.GetUsedTileSets(); foreach (TileSet val in usedTileSets) { if ((Object)(object)val == (Object)null) { DawnPlugin.Logger.LogWarning((object)("TileSet is null in dungeonflow: " + ((Object)DungeonFlow).name)); } else if (!list.Contains(val)) { list.Add(val); } } foreach (TileInjectionRule tileInjectionRule in DungeonFlow.TileInjectionRules) { if ((Object)(object)tileInjectionRule.TileSet == (Object)null) { DawnPlugin.Logger.LogWarning((object)"TileSet is null in a tileInjectionRule"); } else if (!list.Contains(tileInjectionRule.TileSet)) { list.Add(tileInjectionRule.TileSet); } } foreach (TileSet item in list) { foreach (GameObjectChance weight in item.TileWeights.Weights) { if ((Object)(object)weight.Value == (Object)null) { DawnPlugin.Logger.LogWarning((object)("GameObject is null in tileSet: " + ((Object)item).name)); continue; } Tile[] componentsInChildren = weight.Value.GetComponentsInChildren(); foreach (Tile val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { DawnPlugin.Logger.LogWarning((object)("Tile is null in tileSet: " + ((Object)item).name)); } else if (!tiles.Contains(val2)) { tiles.Add(val2); } } } } doorways = new List(); spawnSyncedObjects = new List(); foreach (Tile tile in Tiles) { Doorway[] componentsInChildren2 = ((Component)tile).gameObject.GetComponentsInChildren(); foreach (Doorway val3 in componentsInChildren2) { if (!Doorways.Contains(val3)) { doorways.Add(val3); } if (!Sockets.Contains(val3.socket)) { if ((Object)(object)val3.socket == (Object)null) { DawnPlugin.Logger.LogWarning((object)("DungeonFlow: " + ((Object)DungeonFlow).name + " has a null socket in doorway: " + ((Object)val3).name + " from Tile: " + ((Object)tile).name)); continue; } sockets.Add(val3.socket); } foreach (GameObjectWeight connectorPrefabWeight in val3.ConnectorPrefabWeights) { SpawnSyncedObject[] componentsInChildren3 = connectorPrefabWeight.GameObject.GetComponentsInChildren(); foreach (SpawnSyncedObject val4 in componentsInChildren3) { if (!SpawnSyncedObjects.Contains(val4)) { spawnSyncedObjects.Add(val4); } } } foreach (GameObjectWeight blockerPrefabWeight in val3.BlockerPrefabWeights) { SpawnSyncedObject[] componentsInChildren4 = blockerPrefabWeight.GameObject.GetComponentsInChildren(); foreach (SpawnSyncedObject val5 in componentsInChildren4) { if (!SpawnSyncedObjects.Contains(val5)) { spawnSyncedObjects.Add(val5); } } } } SpawnSyncedObject[] componentsInChildren5 = ((Component)tile).gameObject.GetComponentsInChildren(); foreach (SpawnSyncedObject val6 in componentsInChildren5) { if (!SpawnSyncedObjects.Contains(val6)) { spawnSyncedObjects.Add(val6); } } } } } public class DawnStingerDetail { public AudioClip? FirstTimeAudio { get; private set; } public bool PlaysMoreThanOnce { get; private set; } public float PlayChance { get; private set; } public FuncProvider AllowStingerToPlay { get; private set; } public DawnStingerDetail(AudioClip? firstTimeAudio, bool playsMoreThanOnce, float playChance, FuncProvider allowStingerToPlay) { FirstTimeAudio = firstTimeAudio; PlaysMoreThanOnce = playsMoreThanOnce; PlayChance = playChance; AllowStingerToPlay = allowStingerToPlay; base..ctor(); } } public class DawnTileSetInfo : DawnBaseInfo { public TileSet TileSet { get; } public bool IsBranchCap { get; } public bool IsRegular { get; } public IPredicate InjectionPredicate { get; } internal DawnTileSetInfo(NamespacedKey key, HashSet tags, IPredicate injectionRule, TileSet tileSet, bool isBranchCap, bool isRegular, IDataContainer? customData) : base(key, tags, customData) { TileSet = tileSet; IsBranchCap = isBranchCap; IsRegular = isRegular; InjectionPredicate = injectionRule; } } public static class DungeonArchetypeExtensions { public static DawnArchetypeInfo GetDawnInfo(this DungeonArchetype archetype) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnArchetypeInfo)((IDawnObject)archetype).DawnInfo; } internal static bool HasDawnInfo(this DungeonArchetype archetype) { return archetype.GetDawnInfo() != null; } internal static void SetDawnInfo(this DungeonArchetype archetype, DawnArchetypeInfo archetypeInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)archetype).DawnInfo = archetypeInfo; } } public static class DungeonFlowExtensions { public static DawnDungeonInfo GetDawnInfo(this DungeonFlow dungeonFlow) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnDungeonInfo)((IDawnObject)dungeonFlow).DawnInfo; } public static bool TryGetDawnInfo(this DungeonFlow dungeonFlow, [NotNullWhen(true)] out DawnDungeonInfo? dungeonInfo) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) dungeonInfo = (DawnDungeonInfo)((IDawnObject)dungeonFlow).DawnInfo; return dungeonInfo != null; } internal static bool HasDawnInfo(this DungeonFlow dungeonFlow) { return dungeonFlow.GetDawnInfo() != null; } internal static void SetDawnInfo(this DungeonFlow dungeonFlow, DawnDungeonInfo dungeonInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)dungeonFlow).DawnInfo = dungeonInfo; } } public class DungeonFlowInfoBuilder : BaseInfoBuilder { private float _mapTileSize; private AudioClip? _firstTimeAudio; private ProviderTable _weights; private string _assetBundlePath = string.Empty; private BoundedRange _dungeonRangeClamp = new BoundedRange(0f, 999f); private bool _stingerPlaysMoreThanOnce; private float _stingerPlayChance = 100f; private FuncProvider _allowStingerToPlay = new FuncProvider(() => true); private int _extraScrapGeneration; internal DungeonFlowInfoBuilder(NamespacedKey key, DungeonFlow value) : base(key, value) { } public DungeonFlowInfoBuilder SetArchetypeTileSetMapping(string archetypeName, IEnumerable tileSetNames) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GraphLine val = new GraphLine(base.value); base.value.Lines.Add(val); TileSet[] array = base.value.GetUsedTileSets() ?? Array.Empty(); Dictionary dictionary = new Dictionary(StringComparer.Ordinal); TileSet[] array2 = array; foreach (TileSet val2 in array2) { if (!dictionary.ContainsKey(((Object)val2).name)) { dictionary.Add(((Object)val2).name, val2); } } List list = new List(); foreach (string tileSetName in tileSetNames) { string name = tileSetName.Trim(); if (!dictionary.TryGetValue(name, out var val3)) { val3 = ScriptableObject.CreateInstance(); ((Object)val3).name = name; dictionary.Add(name, val3); } if (!list.Contains(val3)) { list.Add(val3); } } DungeonArchetype val4 = null; DungeonArchetype[] usedArchetypes = base.value.GetUsedArchetypes(); if (usedArchetypes != null) { DungeonArchetype[] array3 = usedArchetypes; foreach (DungeonArchetype val5 in array3) { if (!((Object)(object)val5 == (Object)null) && string.Equals(((Object)val5).name, archetypeName, StringComparison.Ordinal)) { val4 = val5; break; } } } if ((Object)(object)val4 == (Object)null) { val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = archetypeName; } if (val4.TileSets == null) { val4.TileSets = new List(); } else { val4.TileSets.Clear(); } val4.TileSets.AddRange(list); if (val.DungeonArchetypes == null) { val.DungeonArchetypes = new List(); } else { val.DungeonArchetypes.Clear(); } val.DungeonArchetypes.Add(val4); return this; } public DungeonFlowInfoBuilder SetMapTileSize(float mapTileSize) { _mapTileSize = mapTileSize; return this; } public DungeonFlowInfoBuilder SetExtraScrapGeneration(int extraScrapGeneration) { _extraScrapGeneration = extraScrapGeneration; return this; } public DungeonFlowInfoBuilder SetAssetBundlePath(string assetBundlePath) { _assetBundlePath = assetBundlePath; return this; } public DungeonFlowInfoBuilder SetFirstTimeAudio(AudioClip firstTimeAudio) { _firstTimeAudio = firstTimeAudio; return this; } public DungeonFlowInfoBuilder OverrideStingerPlaysMoreThanOnce(bool stingerPlaysMoreThanOnce) { _stingerPlaysMoreThanOnce = stingerPlaysMoreThanOnce; return this; } public DungeonFlowInfoBuilder OverrideStingerPlayChance(float stingerPlayChance) { _stingerPlayChance = stingerPlayChance; return this; } public DungeonFlowInfoBuilder SetWeights(Action> callback) { WeightTableBuilder weightTableBuilder = new WeightTableBuilder(); callback(weightTableBuilder); _weights = weightTableBuilder.Build(); return this; } public DungeonFlowInfoBuilder SetDungeonRangeClamp(BoundedRange dungeonRangeClamp) { _dungeonRangeClamp = dungeonRangeClamp; return this; } public DungeonFlowInfoBuilder OverrideAllowStingerToPlay(FuncProvider allowStingerToPlay) { _allowStingerToPlay = allowStingerToPlay; return this; } internal override DawnDungeonInfo Build() { if (_weights == null) { DawnPlugin.Logger.LogWarning((object)$"DungeonFlow '{base.key}' didn't set weights. If you intend to have no weights (doing something special), call .SetWeights(() => {{}})"); _weights = ProviderTable.Empty(); } DawnStingerDetail stingerDetail = new DawnStingerDetail(_firstTimeAudio, _stingerPlaysMoreThanOnce, _stingerPlayChance, _allowStingerToPlay); return new DawnDungeonInfo(base.key, new HashSet(), base.value, _weights, _mapTileSize, stingerDetail, _assetBundlePath, _dungeonRangeClamp, _extraScrapGeneration, customData); } } public static class TileSetExtensions { public static DawnTileSetInfo GetDawnInfo(this TileSet tileSet) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnTileSetInfo)((IDawnObject)tileSet).DawnInfo; } internal static bool HasDawnInfo(this TileSet tileSet) { return tileSet.GetDawnInfo() != null; } internal static void SetDawnInfo(this TileSet tileSet, DawnTileSetInfo tileSetInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)tileSet).DawnInfo = tileSetInfo; } } public class TilesetInfoBuilder : BaseInfoBuilder { private bool _branchCap; private bool _regular = true; private IPredicate? _predicate; internal TilesetInfoBuilder(NamespacedKey key, TileSet value) : base(key, value) { } public TilesetInfoBuilder SetIsBranchCap(bool value) { _branchCap = value; return this; } public TilesetInfoBuilder SetIsRegular(bool value) { _regular = value; return this; } public TilesetInfoBuilder SetInjectionPredicate(IPredicate predicate) { _predicate = predicate; return this; } internal override DawnTileSetInfo Build() { if (_predicate == null) { _predicate = ConstantPredicate.True; } return new DawnTileSetInfo(base.key, new HashSet(), _predicate, base.value, _branchCap, _regular, customData); } } internal static class EnemyRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_RefreshEnemiesList <0>__UpdateEnemyWeights; public static hook_AssignRandomEnemyToVent <1>__CheckIfEnemyCanSpawn; public static hook_SetPlanetsWeather <2>__UpdateEnemyWeights; public static hook_Start <3>__EnsureCorrectEnemyVariables; public static hook_Start <4>__AddEnemiesToDebugList; public static Manipulator <5>__StopDawnEnemyResetting; public static hook_Awake <6>__AddBestiaryNodes; public static hook_Start <7>__CollectAllEnemyTypes; public static Action <8>__RegisterEnemies; public static Action <9>__RedoEnemiesDebugMenu; public static Action <10>__FixDawnEnemyReferences; public static Func <11>__DawnLibHandledEnemy; } private static List _networkPrefabEnemyTypes = new List(); internal static void Init() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0150: 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_015b: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //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_019b: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Expected O, but got Unknown //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_0226: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown LethalContent.Enemies.AddAutoTaggers(new SimpleAutoTagger(Tags.Killable, (DawnEnemyInfo info) => info.EnemyType.canDie), new SimpleAutoTagger(Tags.Small, (DawnEnemyInfo info) => (int)info.EnemyType.EnemySize == 0), new SimpleAutoTagger(Tags.Medium, (DawnEnemyInfo info) => (int)info.EnemyType.EnemySize == 2), new SimpleAutoTagger(Tags.Large, (DawnEnemyInfo info) => (int)info.EnemyType.EnemySize == 1)); object obj = <>O.<0>__UpdateEnemyWeights; if (obj == null) { hook_RefreshEnemiesList val = UpdateEnemyWeights; <>O.<0>__UpdateEnemyWeights = val; obj = (object)val; } RoundManager.RefreshEnemiesList += (hook_RefreshEnemiesList)obj; object obj2 = <>O.<1>__CheckIfEnemyCanSpawn; if (obj2 == null) { hook_AssignRandomEnemyToVent val2 = CheckIfEnemyCanSpawn; <>O.<1>__CheckIfEnemyCanSpawn = val2; obj2 = (object)val2; } RoundManager.AssignRandomEnemyToVent += (hook_AssignRandomEnemyToVent)obj2; object obj3 = <>O.<2>__UpdateEnemyWeights; if (obj3 == null) { hook_SetPlanetsWeather val3 = UpdateEnemyWeights; <>O.<2>__UpdateEnemyWeights = val3; obj3 = (object)val3; } StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj3; object obj4 = <>O.<3>__EnsureCorrectEnemyVariables; if (obj4 == null) { hook_Start val4 = EnsureCorrectEnemyVariables; <>O.<3>__EnsureCorrectEnemyVariables = val4; obj4 = (object)val4; } EnemyAI.Start += (hook_Start)obj4; object obj5 = <>O.<4>__AddEnemiesToDebugList; if (obj5 == null) { hook_Start val5 = AddEnemiesToDebugList; <>O.<4>__AddEnemiesToDebugList = val5; obj5 = (object)val5; } QuickMenuManager.Start += (hook_Start)obj5; object obj6 = <>O.<5>__StopDawnEnemyResetting; if (obj6 == null) { Manipulator val6 = StopDawnEnemyResetting; <>O.<5>__StopDawnEnemyResetting = val6; obj6 = (object)val6; } RoundManager.SpawnRandomDaytimeEnemy += (Manipulator)obj6; object obj7 = <>O.<5>__StopDawnEnemyResetting; if (obj7 == null) { Manipulator val7 = StopDawnEnemyResetting; <>O.<5>__StopDawnEnemyResetting = val7; obj7 = (object)val7; } RoundManager.AssignRandomEnemyToVent += (Manipulator)obj7; object obj8 = <>O.<5>__StopDawnEnemyResetting; if (obj8 == null) { Manipulator val8 = StopDawnEnemyResetting; <>O.<5>__StopDawnEnemyResetting = val8; obj8 = (object)val8; } RoundManager.SpawnRandomOutsideEnemy += (Manipulator)obj8; object obj9 = <>O.<5>__StopDawnEnemyResetting; if (obj9 == null) { Manipulator val9 = StopDawnEnemyResetting; <>O.<5>__StopDawnEnemyResetting = val9; obj9 = (object)val9; } RoundManager.SpawnRandomWeedEnemy += (Manipulator)obj9; object obj10 = <>O.<5>__StopDawnEnemyResetting; if (obj10 == null) { Manipulator val10 = StopDawnEnemyResetting; <>O.<5>__StopDawnEnemyResetting = val10; obj10 = (object)val10; } RoundManager.PredictAllOutsideEnemies += (Manipulator)obj10; DetourContext val11 = new DetourContext(int.MaxValue); try { object obj11 = <>O.<6>__AddBestiaryNodes; if (obj11 == null) { hook_Awake val12 = AddBestiaryNodes; <>O.<6>__AddBestiaryNodes = val12; obj11 = (object)val12; } Terminal.Awake += (hook_Awake)obj11; object obj12 = <>O.<7>__CollectAllEnemyTypes; if (obj12 == null) { hook_Start val13 = CollectAllEnemyTypes; <>O.<7>__CollectAllEnemyTypes = val13; obj12 = (object)val13; } GameNetworkManager.Start += (hook_Start)obj12; } finally { ((IDisposable)val11)?.Dispose(); } LethalContent.Moons.OnFreeze += RegisterEnemies; LethalContent.Enemies.OnFreeze += RedoEnemiesDebugMenu; LethalContent.Enemies.OnFreeze += FixDawnEnemyReferences; } private static void StopDawnEnemyResetting(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int firstEnemyTypeLoc = -1; ILLabel firstSkip = null; if (!val.TryGotoNext((MoveType)2, new Func[2] { (Instruction c) => ILPatternMatchingExt.MatchLdfld(c, "enemyType"), (Instruction c) => ILPatternMatchingExt.MatchStloc(c, ref firstEnemyTypeLoc) })) { DawnPlugin.Logger.LogError((object)("Failed to apply " + ((MemberReference)il.Method).Name + " patch (0)!")); return; } if (!val.TryGotoNext((MoveType)2, new Func[1] { (Instruction c) => ILPatternMatchingExt.MatchBrfalse(c, ref firstSkip) })) { DawnPlugin.Logger.LogError((object)("Failed to apply " + ((MemberReference)il.Method).Name + " patch (1)!")); return; } val.Emit(OpCodes.Ldloc, firstEnemyTypeLoc); val.EmitDelegate>((Func)DawnLibHandledEnemy); val.Emit(OpCodes.Brfalse_S, (object)firstSkip); if (!((MemberReference)il.Method).Name.Contains("PredictAllOutsideEnemies") && !((MemberReference)il.Method).Name.Contains("SpawnRandomWeedEnemy")) { int secondEnemyTypeLoc = -1; ILLabel secondSkip = null; FieldReference val2 = default(FieldReference); if (!val.TryGotoNext((MoveType)2, new Func[5] { (Instruction c) => ILPatternMatchingExt.MatchLdfld(c, "enemyType"), (Instruction c) => ILPatternMatchingExt.MatchStloc(c, ref secondEnemyTypeLoc), (Instruction c) => ILPatternMatchingExt.MatchLdarg(c, 0), (Instruction c) => ILPatternMatchingExt.MatchLdfld(c, ref val2), (Instruction c) => ILPatternMatchingExt.MatchBrfalse(c, ref secondSkip) })) { DawnPlugin.Logger.LogError((object)("Failed to apply " + ((MemberReference)il.Method).Name + " patch (2)!")); return; } val.Emit(OpCodes.Ldloc, secondEnemyTypeLoc); val.EmitDelegate>((Func)DawnLibHandledEnemy); val.Emit(OpCodes.Brfalse_S, (object)secondSkip); } } private static bool DawnLibHandledEnemy(EnemyType enemyType) { return enemyType.GetDawnInfo()?.ShouldSkipRespectOverride() ?? true; } private static void FixDawnEnemyReferences() { CadaverGrowthAI component = LethalContent.Enemies[EnemyKeys.CadaverGrowths].EnemyType.enemyPrefab.GetComponent(); GameObject faceSporesPrefab = component.faceSporesPrefab; GameObject cadaverSporesParticle = component.CadaverSporesParticle; CadaverGrowthAI val = default(CadaverGrowthAI); foreach (DawnEnemyInfo value in LethalContent.Enemies.Values) { if (!value.ShouldSkipIgnoreOverride() && value.EnemyType.enemyPrefab.TryGetComponent(ref val)) { val.faceSporesPrefab = faceSporesPrefab; val.CadaverSporesParticle = cadaverSporesParticle; } } } private static bool CheckIfEnemyCanSpawn(orig_AssignRandomEnemyToVent orig, RoundManager self, EnemyVent vent, float spawnTime) { if (self.enemyRushIndex == -1) { return orig.Invoke(self, vent, spawnTime); } List list = new List(); foreach (EnemyType item in self.currentLevel.Enemies.Select((SpawnableEnemyWithRarity def) => def.enemyType)) { if (!item.HasDawnInfo()) { continue; } DawnEnemyInfo dawnInfo = item.GetDawnInfo(); if (!dawnInfo.ShouldSkipRespectOverride() && !dawnInfo.EnemyType.spawningDisabled && dawnInfo.Inside != null) { SpawnWeightContext ctx = new SpawnWeightContext(self.currentLevel.GetDawnInfo(), self.dungeonGenerator.Generator.DungeonFlow.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(self.currentLevel)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, self.currentLevel.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); if (!(dawnInfo.Inside.Weights.GetFor(in ctx) > 0)) { item.spawningDisabled = true; list.Add(item); } } } orig.Invoke(self, vent, spawnTime); foreach (EnemyType item2 in list) { item2.spawningDisabled = false; } return true; } private static void RedoEnemiesDebugMenu() { QuickMenuManagerRefs.Instance.Debug_SetEnemyDropdownOptions(); } private static void CollectAllEnemyTypes(orig_Start orig, GameNetworkManager self) { orig.Invoke(self); EnemyAI val = default(EnemyAI); foreach (NetworkPrefab prefab in NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs) { if (prefab.Prefab.TryGetComponent(ref val) && !((Object)(object)val.enemyType == (Object)null) && !_networkPrefabEnemyTypes.Contains(val.enemyType)) { _networkPrefabEnemyTypes.Add(val.enemyType); } } } private static void AddBestiaryNodes(orig_Awake orig, Terminal self) { foreach (DawnEnemyInfo value in LethalContent.Enemies.Values) { if (!value.ShouldSkipIgnoreOverride() && Object.op_Implicit((Object)(object)value.BestiaryNode) && Object.op_Implicit((Object)(object)value.NameKeyword)) { AddScanNodeToBestiaryEvent(value.EnemyType.enemyPrefab, value.BestiaryNode, value.NameKeyword); } } orig.Invoke(self); } private static void AddScanNodeToBestiaryEvent(GameObject gameObjectWithScanNodes, TerminalNode bestiaryNode, TerminalKeyword nameKeyword) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown List list = TerminalRefs.Instance.terminalNodes.allKeywords.ToList(); List list2 = TerminalRefs.InfoKeyword.compatibleNouns.ToList(); bestiaryNode.creatureFileID = TerminalRefs.Instance.enemyFiles.Count; TerminalRefs.Instance.enemyFiles.Add(bestiaryNode); ScanNodeProperties[] componentsInChildren = gameObjectWithScanNodes.GetComponentsInChildren(); ScanNodeProperties[] array = componentsInChildren; foreach (ScanNodeProperties val in array) { val.creatureScanID = bestiaryNode.creatureFileID; } if (!list.Contains(nameKeyword)) { nameKeyword.defaultVerb = TerminalRefs.InfoKeyword; list.Add(nameKeyword); list2.Add(new CompatibleNoun(nameKeyword, bestiaryNode)); TerminalRefs.InfoKeyword.compatibleNouns = list2.ToArray(); TerminalRefs.Instance.terminalNodes.allKeywords = list.ToArray(); } } private static void AddEnemiesToDebugList(orig_Start orig, QuickMenuManager self) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown SelectableLevel level = LethalContent.Moons[MoonKeys.Test].Level; foreach (DawnEnemyInfo enemyInfo in LethalContent.Enemies.Values) { if (!enemyInfo.ShouldSkipIgnoreOverride()) { SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(enemyInfo.EnemyType, 0); if (enemyInfo.Inside != null && level.Enemies.All((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType != (Object)(object)enemyInfo.EnemyType)) { Debuggers.Enemies?.Log($"Adding {enemyInfo.EnemyType} to test level {((Object)level).name} inside."); level.Enemies.Add(item); } if (enemyInfo.Outside != null && level.OutsideEnemies.All((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType != (Object)(object)enemyInfo.EnemyType)) { Debuggers.Enemies?.Log($"Adding {enemyInfo.EnemyType} to test level {((Object)level).name} outside."); level.OutsideEnemies.Add(item); } if (enemyInfo.Daytime != null && level.DaytimeEnemies.All((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType != (Object)(object)enemyInfo.EnemyType)) { Debuggers.Enemies?.Log($"Adding {enemyInfo.EnemyType} to test level {((Object)level).name} daytime."); level.DaytimeEnemies.Add(item); } } } orig.Invoke(self); } private static void EnsureCorrectEnemyVariables(orig_Start orig, EnemyAI self) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if (!self.enemyType.HasDawnInfo()) { DawnPlugin.Logger.LogError((object)("Enemy with names " + ((Object)self.enemyType).name + " and " + self.enemyType.enemyName + " has no DawnEnemyInfo, this means this enemy is not properly registered.")); orig.Invoke(self); return; } DawnEnemyInfo dawnInfo = self.enemyType.GetDawnInfo(); if (dawnInfo.ShouldSkipRespectOverride() || StarlancerAIFixCompat.Enabled) { orig.Invoke(self); return; } bool isDaytimeEnemy = self.enemyType.isDaytimeEnemy; if (dawnInfo.Daytime != null) { self.enemyType.isDaytimeEnemy = true; } GameObject[] insideAINodes = RoundManager.Instance.insideAINodes; GameObject[] outsideAINodes = RoundManager.Instance.outsideAINodes; bool flag = true; float num = float.MaxValue; if (insideAINodes != null) { GameObject[] array = insideAINodes; foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(val.transform.position, ((Component)self).transform.position); if (!(num2 >= num)) { num = num2; } } } } if (outsideAINodes != null) { GameObject[] array2 = outsideAINodes; foreach (GameObject val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { float num3 = Vector3.Distance(val2.transform.position, ((Component)self).transform.position); if (num3 < num) { num = num3; flag = false; break; } } } } bool isOutsideEnemy = self.enemyType.isOutsideEnemy; if (flag) { self.enemyType.isOutsideEnemy = false; } else { self.enemyType.isOutsideEnemy = true; } orig.Invoke(self); if (isDaytimeEnemy != self.enemyType.isDaytimeEnemy) { self.enemyType.isDaytimeEnemy = isDaytimeEnemy; } if (isOutsideEnemy != self.enemyType.isOutsideEnemy) { self.enemyType.isOutsideEnemy = isOutsideEnemy; } } private static void UpdateEnemyWeights(orig_RefreshEnemiesList orig, RoundManager self) { UpdateEnemyWeightsOnLevel(self.currentLevel); orig.Invoke(self); } private static void UpdateEnemyWeights(orig_SetPlanetsWeather orig, StartOfRound self, int connectedPlayersOnServer) { orig.Invoke(self, connectedPlayersOnServer); UpdateEnemyWeightsOnLevel(self.currentLevel); } internal static void UpdateEnemyWeightsOnLevel(SelectableLevel level) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown if (!LethalContent.Weathers.IsFrozen || !LethalContent.Enemies.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady())) { return; } DungeonFlow val = RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow; foreach (DawnEnemyInfo enemyInfo in LethalContent.Enemies.Values) { if (enemyInfo.ShouldSkipRespectOverride()) { continue; } Debuggers.Enemies?.Log($"Updating weights for {enemyInfo.EnemyType} on level {level.PlanetName}"); if (enemyInfo.Outside != null) { SpawnableEnemyWithRarity val2 = ((IEnumerable)level.OutsideEnemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyInfo.EnemyType)); if (val2 == null) { val2 = new SpawnableEnemyWithRarity(enemyInfo.EnemyType, 0); level.OutsideEnemies.Add(val2); } SpawnWeightContext ctx = new SpawnWeightContext(level.GetDawnInfo(), val?.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault = enemyInfo.Outside.Weights.GetFor(in ctx).GetValueOrDefault(); val2.rarity = valueOrDefault.Clamp0(); } if (enemyInfo.Inside != null) { SpawnableEnemyWithRarity val3 = ((IEnumerable)level.Enemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyInfo.EnemyType)); if (val3 == null) { val3 = new SpawnableEnemyWithRarity(enemyInfo.EnemyType, 0); level.Enemies.Add(val3); } SpawnWeightContext ctx2 = new SpawnWeightContext(level.GetDawnInfo(), val?.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault2 = enemyInfo.Inside.Weights.GetFor(in ctx2).GetValueOrDefault(); val3.rarity = valueOrDefault2.Clamp0(); } if (enemyInfo.Daytime != null) { SpawnableEnemyWithRarity val4 = ((IEnumerable)level.DaytimeEnemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyInfo.EnemyType)); if (val4 == null) { val4 = new SpawnableEnemyWithRarity(enemyInfo.EnemyType, 0); level.DaytimeEnemies.Add(val4); } SpawnWeightContext ctx3 = new SpawnWeightContext(level.GetDawnInfo(), val?.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault3 = enemyInfo.Daytime.Weights.GetFor(in ctx3).GetValueOrDefault(); val4.rarity = valueOrDefault3.Clamp0(); } } } private static void RegisterEnemies() { Dictionary> dictionary = new Dictionary>(); Dictionary> dictionary2 = new Dictionary>(); Dictionary> dictionary3 = new Dictionary>(); foreach (DawnMoonInfo value4 in LethalContent.Moons.Values) { SelectableLevel level = value4.Level; NamespacedKey typedKey = value4.TypedKey; foreach (SpawnableEnemyWithRarity enemy in level.Enemies) { if (!((Object)(object)enemy.enemyType == (Object)null)) { if (!dictionary.TryGetValue(((Object)enemy.enemyType).name, out var value)) { value = new WeightTableBuilder(); dictionary[((Object)enemy.enemyType).name] = value; } Debuggers.Enemies?.Log($"Adding inside weight {enemy.rarity} for {enemy.enemyType} on level {level.PlanetName}"); value.AddWeight(typedKey, enemy.rarity); } } foreach (SpawnableEnemyWithRarity outsideEnemy in level.OutsideEnemies) { if (!((Object)(object)outsideEnemy.enemyType == (Object)null)) { if (!dictionary2.TryGetValue(((Object)outsideEnemy.enemyType).name, out var value2)) { value2 = new WeightTableBuilder(); dictionary2[((Object)outsideEnemy.enemyType).name] = value2; } Debuggers.Enemies?.Log($"Adding outside weight {outsideEnemy.rarity} for {outsideEnemy.enemyType} on level {level.PlanetName}"); value2.AddWeight(typedKey, outsideEnemy.rarity); } } foreach (SpawnableEnemyWithRarity daytimeEnemy in level.DaytimeEnemies) { if (!((Object)(object)daytimeEnemy.enemyType == (Object)null)) { if (!dictionary3.TryGetValue(((Object)daytimeEnemy.enemyType).name, out var value3)) { value3 = new WeightTableBuilder(); dictionary3[((Object)daytimeEnemy.enemyType).name] = value3; } Debuggers.Enemies?.Log($"Adding daytime weight {daytimeEnemy.rarity} for {daytimeEnemy.enemyType} on level {level.PlanetName}"); value3.AddWeight(typedKey, daytimeEnemy.rarity); } } } TerminalKeyword infoKeyword = TerminalRefs.InfoKeyword; foreach (EnemyType networkPrefabEnemyType in _networkPrefabEnemyTypes) { if ((Object)(object)networkPrefabEnemyType == (Object)null || (Object)(object)networkPrefabEnemyType.enemyPrefab == (Object)null || networkPrefabEnemyType.HasDawnInfo()) { continue; } string name = NamespacedKey.NormalizeStringForNamespacedKey(networkPrefabEnemyType.enemyName, CSharpName: true); NamespacedKey namespacedKey = EnemyKeys.GetByReflection(name); string modName2; if (namespacedKey == null && LethalLibCompat.Enabled && LethalLibCompat.TryGetEnemyTypeFromLethalLib(networkPrefabEnemyType, out string modName)) { namespacedKey = NamespacedKey.From(modName, networkPrefabEnemyType.enemyName); } else if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedEnemyTypeModName(networkPrefabEnemyType, out modName2)) { namespacedKey = NamespacedKey.From(modName2, networkPrefabEnemyType.enemyName); } else if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_lib", networkPrefabEnemyType.enemyName); } if (LethalContent.Enemies.ContainsKey(namespacedKey)) { DawnPlugin.Logger.LogWarning((object)("Enemy " + networkPrefabEnemyType.enemyName + " is already registered by the same creator to LethalContent. This is likely to cause issues.")); networkPrefabEnemyType.SetDawnInfo(LethalContent.Enemies[namespacedKey]); continue; } if (!Object.op_Implicit((Object)(object)networkPrefabEnemyType.enemyPrefab)) { DawnPlugin.Logger.LogWarning((object)(networkPrefabEnemyType.enemyName + " (" + ((Object)networkPrefabEnemyType).name + ") didn't have a spawn prefab?")); continue; } DawnEnemyLocationInfo inside = null; DawnEnemyLocationInfo outside = null; DawnEnemyLocationInfo daytime = null; if (dictionary.ContainsKey(((Object)networkPrefabEnemyType).name)) { inside = new DawnEnemyLocationInfo(dictionary[((Object)networkPrefabEnemyType).name].Build()); } if (dictionary2.ContainsKey(((Object)networkPrefabEnemyType).name)) { outside = new DawnEnemyLocationInfo(dictionary2[((Object)networkPrefabEnemyType).name].Build()); } if (dictionary3.ContainsKey(((Object)networkPrefabEnemyType).name)) { daytime = new DawnEnemyLocationInfo(dictionary3[((Object)networkPrefabEnemyType).name].Build()); } HashSet tags = new HashSet { DawnLibTags.IsExternal }; CollectLLLTags(networkPrefabEnemyType, tags); TerminalNode bestiaryNode = null; TerminalKeyword nameKeyword = null; ScanNodeProperties componentInChildren = networkPrefabEnemyType.enemyPrefab.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { int creatureScanID = componentInChildren.creatureScanID; CompatibleNoun[] compatibleNouns = infoKeyword.compatibleNouns; foreach (CompatibleNoun val in compatibleNouns) { if (val.result.creatureFileID == creatureScanID) { bestiaryNode = val.result; nameKeyword = val.noun; } } } DawnEnemyInfo dawnEnemyInfo = new DawnEnemyInfo(namespacedKey, tags, networkPrefabEnemyType, outside, inside, daytime, bestiaryNode, nameKeyword, null); networkPrefabEnemyType.SetDawnInfo(dawnEnemyInfo); LethalContent.Enemies.Register(dawnEnemyInfo); } foreach (DawnMoonInfo value5 in LethalContent.Moons.Values) { SelectableLevel level2 = value5.Level; foreach (DawnEnemyInfo value6 in LethalContent.Enemies.Values) { if (!value6.ShouldSkipRespectOverride()) { if (value6.Outside != null) { TryAddToEnemyList(value6, level2.OutsideEnemies); } if (value6.Daytime != null) { TryAddToEnemyList(value6, level2.DaytimeEnemies); } if (value6.Inside != null) { TryAddToEnemyList(value6, level2.Enemies); } } } } LethalContent.Enemies.Freeze(); } private static void CollectLLLTags(EnemyType enemyType, HashSet tags) { if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetAllTagsWithModNames(enemyType, out List<(string, string)> allTagsWithModNames)) { tags.AddToList(allTagsWithModNames, Debuggers.Enemies, ((Object)enemyType).name); } } private static void TryAddToEnemyList(DawnEnemyInfo enemyInfo, List list) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown foreach (SpawnableEnemyWithRarity item2 in list) { if ((Object)(object)item2.enemyType == (Object)(object)enemyInfo.EnemyType) { return; } } SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(enemyInfo.EnemyType, 0); list.Add(item); } } public sealed class DawnEnemyInfo : DawnBaseInfo { [CompilerGenerated] private sealed class d__22 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable where T : EnemyAI { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; public DawnEnemyInfo <>4__this; private List.Enumerator <>7__wrap1; T? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(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 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; DawnEnemyInfo dawnEnemyInfo = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = RoundManager.Instance.SpawnedEnemies.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { EnemyAI current = <>7__wrap1.Current; if ((Object)(object)current.enemyType == (Object)(object)dawnEnemyInfo.EnemyType) { <>2__current = (T)(object)current; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap1 = default(List.Enumerator); 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; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__22 result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new d__22(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } public EnemyType EnemyType { get; } public DawnEnemyLocationInfo? Outside { get; private set; } public DawnEnemyLocationInfo? Inside { get; private set; } public DawnEnemyLocationInfo? Daytime { get; private set; } public TerminalNode? BestiaryNode { get; } public TerminalKeyword? NameKeyword { get; } internal DawnEnemyInfo(NamespacedKey key, HashSet tags, EnemyType enemyType, DawnEnemyLocationInfo? outside, DawnEnemyLocationInfo? inside, DawnEnemyLocationInfo? daytime, TerminalNode? bestiaryNode, TerminalKeyword? nameKeyword, IDataContainer? customData) : base(key, tags, customData) { EnemyType = enemyType; Outside = outside; if (Outside != null) { Outside.ParentInfo = this; } Inside = inside; if (Inside != null) { Inside.ParentInfo = this; } Daytime = daytime; if (Daytime != null) { Daytime.ParentInfo = this; } BestiaryNode = bestiaryNode; NameKeyword = nameKeyword; } [IteratorStateMachine(typeof(d__22<>))] public IEnumerable GetAllSpawned() where T : EnemyAI { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(-2) { <>4__this = this }; } } public sealed class DawnEnemyLocationInfo { public DawnEnemyInfo ParentInfo { get; internal set; } public ProviderTable Weights { get; private set; } internal DawnEnemyLocationInfo(ProviderTable weights) { Weights = weights; } } public class EnemyInfoBuilder : BaseInfoBuilder { public class EnemyLocationBuilder { private ProviderTable? _weights; private EnemyInfoBuilder _parent; public EnemyLocationBuilder SetWeights(Action> callback) { WeightTableBuilder weightTableBuilder = new WeightTableBuilder(); callback(weightTableBuilder); _weights = weightTableBuilder.Build(); return this; } internal EnemyLocationBuilder(EnemyInfoBuilder parent) { _parent = parent; } internal DawnEnemyLocationInfo Build() { if (_weights == null) { DawnPlugin.Logger.LogWarning((object)$"Enemy '{_parent.key}' didn't set weights. If you intend to have no weights (doing something special), call .SetWeights(() => {{}})"); _weights = ProviderTable.Empty(); } return new DawnEnemyLocationInfo(_weights); } } private DawnEnemyLocationInfo? _inside; private DawnEnemyLocationInfo? _outside; private DawnEnemyLocationInfo? _daytime; private TerminalNode? _bestiaryNode; private TerminalKeyword? _nameKeyword; internal EnemyInfoBuilder(NamespacedKey key, EnemyType enemyType) : base(key, enemyType) { } public EnemyInfoBuilder DefineOutside(Action callback) { EnemyLocationBuilder enemyLocationBuilder = new EnemyLocationBuilder(this); callback(enemyLocationBuilder); _outside = enemyLocationBuilder.Build(); return this; } public EnemyInfoBuilder DefineInside(Action callback) { EnemyLocationBuilder enemyLocationBuilder = new EnemyLocationBuilder(this); callback(enemyLocationBuilder); _inside = enemyLocationBuilder.Build(); return this; } public EnemyInfoBuilder DefineDaytime(Action callback) { EnemyLocationBuilder enemyLocationBuilder = new EnemyLocationBuilder(this); callback(enemyLocationBuilder); _daytime = enemyLocationBuilder.Build(); return this; } public EnemyInfoBuilder CreateBestiaryNode(string bestiaryNodeText) { _bestiaryNode = new TerminalNodeBuilder(base.value.enemyName + "BestiaryNode").SetDisplayText(bestiaryNodeText).SetCreatureName(base.value.enemyName).SetClearPreviousText(clearPreviousText: true) .SetMaxCharactersToType(35) .Build(); return this; } public EnemyInfoBuilder CreateNameKeyword(string wordOverride) { if (string.IsNullOrWhiteSpace(wordOverride)) { wordOverride = base.value.enemyName.ToLowerInvariant(); } _nameKeyword = new TerminalKeywordBuilder(base.value.enemyName + "NameKeyword", wordOverride, (DawnKeywordType)6).Build(); return this; } internal override DawnEnemyInfo Build() { return new DawnEnemyInfo(base.key, tags, base.value, _outside, _inside, _daytime, _bestiaryNode, _nameKeyword, customData); } } public static class EnemyTypeExtensions { public static DawnEnemyInfo GetDawnInfo(this EnemyType enemyType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return (DawnEnemyInfo)((IDawnObject)enemyType).DawnInfo; } internal static bool HasDawnInfo(this EnemyType enemyType) { return enemyType.GetDawnInfo() != null; } internal static void SetDawnInfo(this EnemyType enemyType, DawnEnemyInfo enemyInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)enemyType).DawnInfo = enemyInfo; } } public class BundleException : Exception { public AssetBundle Bundle { get; } public BundleException(AssetBundle bundle, string message) { Bundle = bundle; base..ctor(message); } } public class MalformedAnimationCurveConfigException : Exception { public string Pair { get; } public MalformedAnimationCurveConfigException(string pair) { Pair = pair; base..ctor(); } public void LogNicely(ManualLogSource? logger) { if (logger != null) { string[] array = (from s in Pair.Split(',') select s.Trim()).ToArray(); logger.LogError((object)("Invalid key,value pair format: '" + Pair + "'! More details:")); logger.LogError((object)$" Found '{array.Length}' parts"); if (array.Length != 2) { logger.LogError((object)" FAIL -> Should have only 2 parts!"); return; } LogNicelyFloatParse(logger, "first", array[0]); LogNicelyFloatParse(logger, "second", array[1]); } } private void LogNicelyFloatParse(ManualLogSource logger, string context, string value) { logger.LogError((object)(" Attempting to parse " + context + " value: '" + value + "'")); if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { logger.LogError((object)$" Parsed {context} value! Parsed Value is {result}"); } else { logger.LogError((object)$" FAIL -> Couldn't parse {context} value! Parsed Value is {result}"); } } } public interface IPredicate { bool Evaluate(); } public class ConstantPredicate : IPredicate { public static readonly ConstantPredicate True = new ConstantPredicate(value: true); public static readonly ConstantPredicate False = new ConstantPredicate(value: false); private bool _value; private ConstantPredicate(bool value) { _value = value; } public bool Evaluate() { return _value; } } public interface IProvider { T Provide(); } public class SimpleProvider : IProvider { [CompilerGenerated] private T P; public SimpleProvider(T value) { P = value; base..ctor(); } public T Provide() { return P; } } public class ConfigEntryProvider : IProvider { [CompilerGenerated] private ConfigEntry P; public ConfigEntryProvider(ConfigEntry configEntry) { P = configEntry; base..ctor(); } public T Provide() { return P.Value; } } public class FuncProvider : IProvider { [CompilerGenerated] private Func P; public FuncProvider(Func function) { P = function; base..ctor(); } public T Provide() { return P(); } } internal static class ItemRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__RegisterScrapItems; public static hook_Awake <1>__RegisterShopItemsToTerminal; public static hook_SpawnScrapInLevel <2>__UpdateItemWeights; public static hook_SetPlanetsWeather <3>__UpdateItemWeights; public static Action <4>__FreezeItemContent; public static Action <5>__RedoItemsDebugMenu; } internal static void Init() { //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Expected O, but got Unknown //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0312: 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_031d: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown LethalContent.Items.AddAutoTaggers(new AutoNonInteractableTagger(), new SimpleAutoTagger(Tags.Conductive, (DawnItemInfo itemInfo) => itemInfo.Item.isConductiveMetal), new SimpleAutoTagger(Tags.Noisy, (DawnItemInfo itemInfo) => (Object)(object)itemInfo.Item.spawnPrefab.GetComponent() != (Object)null), new SimpleAutoTagger(Tags.Interactable, (DawnItemInfo itemInfo) => !itemInfo.HasTag(Tags.NonInteractable) && !itemInfo.HasTag(Tags.Noisy)), new SimpleAutoTagger(Tags.Paid, (DawnItemInfo itemInfo) => itemInfo.ShopInfo != null), new SimpleAutoTagger(Tags.Scrap, (DawnItemInfo itemInfo) => itemInfo.ScrapInfo != null), new SimpleAutoTagger(Tags.Chargeable, (DawnItemInfo itemInfo) => itemInfo.Item.requiresBattery), new SimpleAutoTagger(Tags.TwoHanded, (DawnItemInfo itemInfo) => itemInfo.Item.twoHanded), new SimpleAutoTagger(Tags.OneHanded, (DawnItemInfo itemInfo) => !itemInfo.Item.twoHanded), new SimpleAutoTagger(Tags.Weapon, (DawnItemInfo itemInfo) => itemInfo.Item.isDefensiveWeapon), new AutoItemGroupTagger(Tags.GeneralItemClassGroup, "GeneralItemClass"), new AutoItemGroupTagger(Tags.SmallItemsGroup, "SmallItems"), new AutoItemGroupTagger(Tags.TabletopItemsGroup, "TabletopItems"), new AutoItemGroupTagger(Tags.TestItemGroup, "TestItem"), new AutoValueTagger(Tags.LowValue, new BoundedRange(0f, 100f)), new AutoValueTagger(Tags.MediumValue, new BoundedRange(100f, 200f)), new AutoValueTagger(Tags.HighValue, new BoundedRange(200f, 2.1474836E+09f)), new AutoWeightTagger(Tags.LightWeight, new BoundedRange(0f, 1.2f)), new AutoWeightTagger(Tags.MediumWeight, new BoundedRange(1.2f, 1.4f)), new AutoWeightTagger(Tags.HeavyWeight, new BoundedRange(1.4f, 2.1474836E+09f))); DetourContext val = new DetourContext(2147483638); try { object obj = <>O.<0>__RegisterScrapItems; if (obj == null) { hook_Awake val2 = RegisterScrapItems; <>O.<0>__RegisterScrapItems = val2; obj = (object)val2; } StartOfRound.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__RegisterShopItemsToTerminal; if (obj2 == null) { hook_Awake val3 = RegisterShopItemsToTerminal; <>O.<1>__RegisterShopItemsToTerminal = val3; obj2 = (object)val3; } Terminal.Awake += (hook_Awake)obj2; } finally { ((IDisposable)val)?.Dispose(); } DetourContext val4 = new DetourContext(int.MinValue); try { object obj3 = <>O.<2>__UpdateItemWeights; if (obj3 == null) { hook_SpawnScrapInLevel val5 = UpdateItemWeights; <>O.<2>__UpdateItemWeights = val5; obj3 = (object)val5; } RoundManager.SpawnScrapInLevel += (hook_SpawnScrapInLevel)obj3; } finally { ((IDisposable)val4)?.Dispose(); } object obj4 = <>O.<3>__UpdateItemWeights; if (obj4 == null) { hook_SetPlanetsWeather val6 = UpdateItemWeights; <>O.<3>__UpdateItemWeights = val6; obj4 = (object)val6; } StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj4; LethalContent.Moons.OnFreeze += FreezeItemContent; LethalContent.Items.OnFreeze += RedoItemsDebugMenu; } private static void RegisterScrapItems(orig_Awake orig, StartOfRound self) { if (LethalContent.Items.IsFrozen) { orig.Invoke(self); return; } foreach (DawnItemInfo value in LethalContent.Items.Values) { if (!value.ShouldSkipIgnoreOverride() && !self.allItemsList.itemsList.Contains(value.Item)) { self.allItemsList.itemsList.Add(value.Item); } } orig.Invoke(self); } private static void RedoItemsDebugMenu() { QuickMenuManagerRefs.Instance.Debug_SetAllItemsDropdownOptions(); } internal static void UpdateAllShopItemPrices() { foreach (DawnItemInfo value in LethalContent.Items.Values) { DawnShopItemInfo shopInfo = value.ShopInfo; if (shopInfo != null && !value.ShouldSkipRespectOverride()) { UpdateShopItemPrices(shopInfo); } } } private static void UpdateShopItemPrices(DawnShopItemInfo shopInfo) { int num = shopInfo.DawnPurchaseInfo.Cost.Provide(); shopInfo.ParentInfo.Item.creditsWorth = num; shopInfo.ReceiptNode.itemCost = num; shopInfo.RequestNode.itemCost = num; } private static void UpdateItemWeights(orig_SpawnScrapInLevel orig, RoundManager self) { UpdateItemWeightsOnLevel(self.currentLevel); List list = new List(); SpawnableItemWithRarity[] array = self.currentLevel.spawnableScrap.ToArray(); foreach (SpawnableItemWithRarity val in array) { if (val.rarity <= 0) { list.Add(val); self.currentLevel.spawnableScrap.Remove(val); } } orig.Invoke(self); foreach (SpawnableItemWithRarity item in list) { self.currentLevel.spawnableScrap.Add(item); } } private static void UpdateItemWeights(orig_SetPlanetsWeather orig, StartOfRound self, int connectedPlayersOnServer) { orig.Invoke(self, connectedPlayersOnServer); UpdateItemWeightsOnLevel(self.currentLevel); } internal static void UpdateItemWeightsOnLevel(SelectableLevel level) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown if (!LethalContent.Weathers.IsFrozen || !LethalContent.Items.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady())) { return; } foreach (DawnItemInfo itemInfo in LethalContent.Items.Values) { DawnScrapItemInfo scrapInfo = itemInfo.ScrapInfo; if (scrapInfo != null && !itemInfo.ShouldSkipRespectOverride()) { Debuggers.Items?.Log("Updating " + itemInfo.Item.itemName + "'s weights on level " + level.PlanetName + "."); SpawnableItemWithRarity val = ((IEnumerable)level.spawnableScrap).FirstOrDefault((Func)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)itemInfo.Item)); if (val == null) { val = new SpawnableItemWithRarity(itemInfo.Item, 0); level.spawnableScrap.Add(val); } SpawnWeightContext ctx = new SpawnWeightContext(level.GetDawnInfo(), RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow?.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault = scrapInfo.Weights.GetFor(in ctx).GetValueOrDefault(); val.rarity = valueOrDefault.Clamp0(); } } } private static void FreezeItemContent() { //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Expected O, but got Unknown Dictionary> dictionary = new Dictionary>(); Dictionary dictionary2 = new Dictionary(); foreach (DawnMoonInfo value5 in LethalContent.Moons.Values) { SelectableLevel level = value5.Level; Dictionary dictionary3 = new Dictionary(); for (int num = level.spawnableScrap.Count - 1; num >= 0; num--) { SpawnableItemWithRarity val = level.spawnableScrap[num]; if (dictionary3.ContainsKey(val.spawnableItem)) { DawnPlugin.Logger.LogWarning((object)("Duplicate item found in level " + level.PlanetName + " with name " + ((Object)val.spawnableItem).name + ", adding weight to previous entry to avoid issues.")); level.spawnableScrap.Remove(val); SpawnableItemWithRarity obj = dictionary3[val.spawnableItem]; obj.rarity += val.rarity; } else { dictionary3[val.spawnableItem] = val; } } foreach (var (val4, val5) in dictionary3) { if (!dictionary.TryGetValue(((Object)val4).name, out var value)) { value = new WeightTableBuilder(); dictionary[((Object)val4).name] = value; } Debuggers.Items?.Log($"Adding weight {val5.rarity} to {((Object)val4).name} on level {level.PlanetName}"); value.AddWeight(value5.TypedKey, val5.rarity); } } Terminal instance = TerminalRefs.Instance; TerminalKeyword buyKeyword = TerminalRefs.BuyKeyword; TerminalKeyword infoKeyword = TerminalRefs.InfoKeyword; List list = buyKeyword.compatibleNouns.ToList(); List list2 = infoKeyword.compatibleNouns.ToList(); List list3 = instance.terminalNodes.allKeywords.ToList(); int i; for (i = 0; i < instance.buyableItemsList.Length; i++) { Item val6 = instance.buyableItemsList[i]; TerminalNode val7 = null; TerminalNode requestNode = null; TerminalNode val8 = null; string text = val6.itemName.ToLowerInvariant(); requestNode = (from noun in TerminalRefs.BuyKeyword.compatibleNouns where noun.result.buyItemIndex == i select noun.result).FirstOrDefault(); if ((Object)(object)requestNode == (Object)null) { DawnPlugin.Logger.LogWarning((object)("No request Node found for " + val6.itemName + " despite it being a buyable item, this is likely the result of an item being removed from the shop items list by LethalLib, i.e. Night Vision Goggles from MoreShipUpgrades")); continue; } val8 = requestNode.terminalOptions[0].result; TerminalKeyword val9 = (from noun in TerminalRefs.BuyKeyword.compatibleNouns where (Object)(object)noun.result == (Object)(object)requestNode select noun.noun).FirstOrDefault(); if ((Object)(object)val9 == (Object)null) { DawnPlugin.Logger.LogWarning((object)("No buy Keyword found for " + val6.itemName + " despite it being a buyable item, this is likely the result of an item being removed from the shop items list by LethalLib, i.e. Night Vision Goggles from MoreShipUpgrades")); continue; } CompatibleNoun[] compatibleNouns = infoKeyword.compatibleNouns; foreach (CompatibleNoun val10 in compatibleNouns) { if ((Object)(object)val10.noun == (Object)(object)val9) { val7 = val10.result; break; } } if ((Object)(object)val7 == (Object)null) { val7 = new TerminalNodeBuilder(text + "InfoNode").SetDisplayText("[No information about this object was found.]\n\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(25) .Build(); CompatibleNoun item = new CompatibleNoun(val9, val7); List list4 = infoKeyword.compatibleNouns.ToList(); list4.Add(item); infoKeyword.compatibleNouns = list4.ToArray(); } CompatibleNoun[] compatibleNouns2 = buyKeyword.compatibleNouns; foreach (CompatibleNoun val11 in compatibleNouns2) { if ((Object)(object)val11.noun == (Object)(object)val9) { requestNode = val11.result; break; } } DawnPurchaseInfo dawnPurchaseInfo = new DawnPurchaseInfo(new SimpleProvider(val6.creditsWorth), ITerminalPurchasePredicate.AlwaysSuccess()); DawnShopItemInfo value2 = new DawnShopItemInfo(dawnPurchaseInfo, val7, requestNode, val8); dictionary2[((Object)val6).name] = value2; } foreach (Item items in StartOfRound.Instance.allItemsList.itemsList) { if (items.HasDawnInfo()) { continue; } string name = NamespacedKey.NormalizeStringForNamespacedKey(items.itemName, CSharpName: true); NamespacedKey namespacedKey = ItemKeys.GetByReflection(name); string modName2; if (namespacedKey == null && LethalLibCompat.Enabled && LethalLibCompat.TryGetItemFromLethalLib(items, out string modName)) { namespacedKey = NamespacedKey.From(modName, items.itemName); } else if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedItemModName(items, out modName2)) { namespacedKey = NamespacedKey.From(modName2, items.itemName); } else if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_lib", items.itemName); } if (LethalContent.Items.ContainsKey(namespacedKey)) { DawnPlugin.Logger.LogWarning((object)("Item " + items.itemName + " is already registered by the same creator to LethalContent. This is likely to cause issues.")); items.SetDawnInfo(LethalContent.Items[namespacedKey]); continue; } dictionary.TryGetValue(((Object)items).name, out var value3); DawnScrapItemInfo scrapItemInfo = null; dictionary2.TryGetValue(((Object)items).name, out var value4); if (value3 != null) { scrapItemInfo = new DawnScrapItemInfo(value3.Build()); } if (!Object.op_Implicit((Object)(object)items.spawnPrefab)) { DawnPlugin.Logger.LogWarning((object)(items.itemName + " (" + ((Object)items).name + ") didn't have a spawn prefab?")); continue; } Debuggers.Items?.Log($"Registering {items.itemName} ({((Object)items).name}) with range of values: {(double)items.minValue * 0.4} and {(double)items.maxValue * 0.4}"); HashSet tags = new HashSet { DawnLibTags.IsExternal }; CollectLLLTags(items, tags); DawnItemInfo dawnItemInfo = new DawnItemInfo(namespacedKey, tags, items, scrapItemInfo, value4, null); items.SetDawnInfo(dawnItemInfo); LethalContent.Items.Register(dawnItemInfo); } RegisterScrapItemsToAllLevels(); LethalContent.Items.Freeze(); } private static void RegisterScrapItemsToAllLevels() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown foreach (DawnItemInfo value in LethalContent.Items.Values) { DawnScrapItemInfo scrapInfo = value.ScrapInfo; if (scrapInfo == null || value.ShouldSkipRespectOverride()) { continue; } foreach (DawnMoonInfo value2 in LethalContent.Moons.Values) { SelectableLevel level = value2.Level; bool flag = false; foreach (SpawnableItemWithRarity item2 in level.spawnableScrap) { if ((Object)(object)item2.spawnableItem == (Object)(object)value.Item) { flag = true; break; } } if (!flag) { SpawnableItemWithRarity item = new SpawnableItemWithRarity(value.Item, 0); level.spawnableScrap.Add(item); } } } } private static void RegisterShopItemsToTerminal(orig_Awake orig, Terminal self) { orig.Invoke(self); foreach (DawnItemInfo value in LethalContent.Items.Values) { TryRegisterItemIntoShop(value.Item); } } private static void TryRegisterItemIntoShop(Item item) { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown DawnItemInfo dawnInfo = item.GetDawnInfo(); if (dawnInfo == null) { DawnPlugin.Logger.LogWarning((object)("Item: " + item.itemName + " does not have a dawn info, this means they cannot be registered to the terminal as a shop item")); return; } _ = TerminalRefs.Instance; TerminalKeyword buyKeyword = TerminalRefs.BuyKeyword; TerminalKeyword infoKeyword = TerminalRefs.InfoKeyword; TerminalKeyword confirmPurchaseKeyword = TerminalRefs.ConfirmPurchaseKeyword; TerminalKeyword denyKeyword = TerminalRefs.DenyKeyword; TerminalNode cancelPurchaseNode = TerminalRefs.CancelPurchaseNode; DawnShopItemInfo shopInfo = dawnInfo.ShopInfo; if (shopInfo == null || dawnInfo.ShouldSkipRespectOverride() || TerminalRefs.Instance.buyableItemsList.Contains(item)) { return; } List list = TerminalRefs.Instance.buyableItemsList.ToList(); string text = dawnInfo.Item.itemName.ToLowerInvariant(); list.Add(dawnInfo.Item); TerminalKeyword[] allKeywords = TerminalRefs.Instance.terminalNodes.allKeywords; foreach (TerminalKeyword val in allKeywords) { if (((Object)val).name == text) { TerminalRefs.Instance.buyableItemsList = list.ToArray(); return; } } List list2 = buyKeyword.compatibleNouns.ToList(); List list3 = infoKeyword.compatibleNouns.ToList(); List list4 = TerminalRefs.Instance.terminalNodes.allKeywords.ToList(); TerminalKeyword val2 = new TerminalKeywordBuilder(text, text, (DawnKeywordType)5).SetIsVerb(isVerb: false).SetDefaultVerb(buyKeyword).SetAccessTerminalObjects(accessTerminalObjects: false) .Build(); list4.Add(val2); TerminalNode receiptNode = shopInfo.ReceiptNode; TerminalNode requestNode = shopInfo.RequestNode; UpdateShopItemPrices(shopInfo); receiptNode.buyItemIndex = list.Count - 1; requestNode.buyItemIndex = list.Count - 1; requestNode.isConfirmationNode = true; requestNode.overrideOptions = true; requestNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { new CompatibleNoun(confirmPurchaseKeyword, receiptNode), new CompatibleNoun(denyKeyword, cancelPurchaseNode) }; list2.Add(new CompatibleNoun(val2, requestNode)); list3.Add(new CompatibleNoun(val2, shopInfo.InfoNode)); TerminalRefs.Instance.buyableItemsList = list.ToArray(); infoKeyword.compatibleNouns = list3.ToArray(); buyKeyword.compatibleNouns = list2.ToArray(); TerminalRefs.Instance.terminalNodes.allKeywords = list4.ToArray(); } private static void CollectLLLTags(Item item, HashSet tags) { if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetAllTagsWithModNames(item, out List<(string, string)> allTagsWithModNames)) { tags.AddToList(allTagsWithModNames, Debuggers.Items, ((Object)item).name); } } } public class AutoItemGroupTagger : IAutoTagger { [CompilerGenerated] private NamespacedKey P; [CompilerGenerated] private string P; public NamespacedKey Tag => P; public AutoItemGroupTagger(NamespacedKey tag, string itemGroupName) { P = tag; P = itemGroupName; base..ctor(); } public bool ShouldApply(DawnItemInfo info) { if (info.Item.spawnPositionTypes == null) { return false; } foreach (ItemGroup spawnPositionType in info.Item.spawnPositionTypes) { if ((Object)(object)spawnPositionType == (Object)null) { DawnPlugin.Logger.LogWarning((object)$"Item: {info.Key} has a null ItemGroup, why!?!?"); } else if (((Object)spawnPositionType).name == P) { return true; } } return false; } } public class AutoNonInteractableTagger : IAutoTagger { public NamespacedKey Tag => Tags.NonInteractable; public bool ShouldApply(DawnItemInfo info) { GrabbableObject val = default(GrabbableObject); if (info.Item.spawnPrefab.TryGetComponent(ref val)) { return ((object)val).GetType() == typeof(GrabbableObject); } return false; } } public class AutoValueTagger : IAutoTagger { [CompilerGenerated] private NamespacedKey P; [CompilerGenerated] private BoundedRange P; public NamespacedKey Tag => P; public AutoValueTagger(NamespacedKey tag, BoundedRange range) { P = tag; P = range; base..ctor(); } public bool ShouldApply(DawnItemInfo info) { float value = (float)(info.Item.maxValue + info.Item.minValue) / 2f; return P.IsInRange(value); } } public class AutoWeightTagger : IAutoTagger { [CompilerGenerated] private NamespacedKey P; [CompilerGenerated] private BoundedRange P; public NamespacedKey Tag => P; public AutoWeightTagger(NamespacedKey tag, BoundedRange range) { P = tag; P = range; base..ctor(); } public bool ShouldApply(DawnItemInfo info) { return P.IsInRange(info.Item.weight); } } public sealed class DawnItemInfo : DawnBaseInfo { public Item Item { get; } public DawnScrapItemInfo? ScrapInfo { get; private set; } public DawnShopItemInfo? ShopInfo { get; private set; } internal DawnItemInfo(NamespacedKey key, HashSet tags, Item item, DawnScrapItemInfo? scrapItemInfo, DawnShopItemInfo? shopItemInfo, IDataContainer? customData) : base(key, tags, customData) { Item = item; ScrapInfo = scrapItemInfo; if (ScrapInfo != null) { ScrapInfo.ParentInfo = this; } ShopInfo = shopItemInfo; if (ShopInfo != null) { ShopInfo.ParentInfo = this; } } } public sealed class DawnScrapItemInfo { public DawnItemInfo ParentInfo { get; internal set; } public ProviderTable Weights { get; private set; } internal DawnScrapItemInfo(ProviderTable weights) { Weights = weights; } } public sealed class DawnShopItemInfo { public DawnItemInfo ParentInfo { get; internal set; } public TerminalNode? InfoNode { get; private set; } public TerminalNode RequestNode { get; } public TerminalNode ReceiptNode { get; } public DawnPurchaseInfo DawnPurchaseInfo { get; } internal DawnShopItemInfo(DawnPurchaseInfo dawnPurchaseInfo, TerminalNode? infoNode, TerminalNode requestNode, TerminalNode receiptNode) { DawnPurchaseInfo = dawnPurchaseInfo; InfoNode = infoNode; RequestNode = requestNode; ReceiptNode = receiptNode; } public void AddToDropship(bool ignoreMax = false, int count = 1) { Terminal instance = TerminalRefs.Instance; for (int i = 0; i < count; i++) { if (!ignoreMax && instance.orderedItemsFromTerminal.Count > 12) { break; } instance.orderedItemsFromTerminal.Add(RequestNode.buyItemIndex); instance.numberOfItemsInDropship++; } } public int GetSalePercentage() { return TerminalRefs.Instance.itemSalesPercentages[RequestNode.buyItemIndex]; } } public static class ItemExtensions { public static DawnItemInfo GetDawnInfo(this Item item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return (DawnItemInfo)((IDawnObject)item).DawnInfo; } internal static bool HasDawnInfo(this Item item) { return item.GetDawnInfo() != null; } internal static void SetDawnInfo(this Item item, DawnItemInfo itemInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)item).DawnInfo = itemInfo; } } public class ItemInfoBuilder : BaseInfoBuilder { public class ScrapBuilder { private ItemInfoBuilder _parentBuilder; private ProviderTable? _weights; internal ScrapBuilder(ItemInfoBuilder parent) { _parentBuilder = parent; } public ScrapBuilder SetWeights(Action> callback) { WeightTableBuilder weightTableBuilder = new WeightTableBuilder(); callback(weightTableBuilder); _weights = weightTableBuilder.Build(); return this; } internal DawnScrapItemInfo Build() { if (_weights == null) { DawnPlugin.Logger.LogWarning((object)("Scrap item '" + _parentBuilder.value.itemName + "' didn't set weights. If you intend to have no weights (doing something special), call .SetWeights(() => {})")); _weights = ProviderTable.Empty(); } return new DawnScrapItemInfo(_weights); } } public class ShopBuilder { private ItemInfoBuilder _parentBuilder; private TerminalNode? _infoNode; private TerminalNode? _requestNode; private TerminalNode? _receiptNode; private IProvider? _costOverride; private ITerminalPurchasePredicate? _purchasePredicate; internal ShopBuilder(ItemInfoBuilder parent) { _parentBuilder = parent; } public ShopBuilder OverrideCost(int cost) { return OverrideCost(new SimpleProvider(cost)); } public ShopBuilder OverrideCost(IProvider cost) { _costOverride = cost; return this; } public ShopBuilder SetPurchasePredicate(ITerminalPurchasePredicate predicate) { _purchasePredicate = predicate; return this; } public ShopBuilder OverrideInfoNode(TerminalNode infoNode) { _infoNode = infoNode; return this; } public ShopBuilder OverrideRequestNode(TerminalNode requestNode) { _requestNode = requestNode; return this; } public ShopBuilder OverrideReceiptNode(TerminalNode receiptNode) { _receiptNode = receiptNode; return this; } internal DawnShopItemInfo Build() { if ((Object)(object)_receiptNode == (Object)null) { _receiptNode = new TerminalNodeBuilder(_parentBuilder.value.itemName + "ReceiptNode").SetDisplayText("Ordered [variableAmount] " + _parentBuilder.value.itemName + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(15) .SetPlaySyncedClip(0) .Build(); } if ((Object)(object)_requestNode == (Object)null) { _requestNode = new TerminalNodeBuilder(_parentBuilder.value.itemName + "RequestNode").SetDisplayText("You have requested to order " + _parentBuilder.value.itemName + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(35) .Build(); } if ((Object)(object)_infoNode == (Object)null) { _infoNode = new TerminalNodeBuilder(_parentBuilder.value.itemName + "InfoNode").SetDisplayText("[No information about this object was found.]\n\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(25) .Build(); } if (_purchasePredicate == null) { _purchasePredicate = ITerminalPurchasePredicate.AlwaysSuccess(); } if (_costOverride == null) { _costOverride = new SimpleProvider(_parentBuilder.value.creditsWorth); } return new DawnShopItemInfo(new DawnPurchaseInfo(_costOverride, _purchasePredicate), _infoNode, _requestNode, _receiptNode); } } private DawnScrapItemInfo? _scrapInfo; private DawnShopItemInfo? _shopInfo; internal ItemInfoBuilder(NamespacedKey key, Item item) : base(key, item) { } public ItemInfoBuilder DefineShop(Action callback) { ShopBuilder shopBuilder = new ShopBuilder(this); callback(shopBuilder); _shopInfo = shopBuilder.Build(); return this; } public ItemInfoBuilder DefineScrap(Action callback) { ScrapBuilder scrapBuilder = new ScrapBuilder(this); callback(scrapBuilder); _scrapInfo = scrapBuilder.Build(); return this; } internal override DawnItemInfo Build() { return new DawnItemInfo(base.key, tags, base.value, _scrapInfo, _shopInfo, customData); } } public static class LethalContent { public static TaggedRegistry Items = new TaggedRegistry(); public static TaggedRegistry Enemies = new TaggedRegistry(); public static TaggedRegistry MapObjects = new TaggedRegistry(); public static TaggedRegistry Moons = new TaggedRegistry(); public static Registry TileSets = new Registry(); public static TaggedRegistry Dungeons = new TaggedRegistry(); public static TaggedRegistry Unlockables = new TaggedRegistry(); public static TaggedRegistry Weathers = new TaggedRegistry(); public static Registry Archetypes = new Registry(); public static Registry StoryLogs = new Registry(); public static Registry Surfaces = new Registry(); public static Registry TerminalCommands = new Registry(); } public static class DawnLibTags { public static readonly NamespacedKey IsExternal = NamespacedKey.From("dawn_lib", "is_external"); public static readonly NamespacedKey LunarConfig = NamespacedKey.From("dawn_lib", "lunar_config"); public static readonly NamespacedKey HasBuyingPercent = NamespacedKey.From("dawn_lib", "has_buying_percent"); } internal static class MapObjectRegistrationHandler { [CompilerGenerated] private static class <>O { public static Action, RandomMapObject> <0>__AddPrefabsToRandomMapObjects; public static hook_SpawnOutsideHazards <1>__SpawnOutsideMapObjects; public static Manipulator <2>__RegenerateNavMeshTranspiler; public static hook_SetPlanetsWeather <3>__UpdateMapObjectSpawnWeights; public static hook_SpawnMapObjects <4>__UpdateMapObjectSpawnWeights; public static Action <5>__RegisterMapObjects; public static Action <6>__FixMapObjectBlanksOnDawnMoons; } private static int _spawnedObjects; internal static void Init() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //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_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0090: 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: Expected O, but got Unknown //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_00bb: Expected O, but got Unknown DawnPlugin.Hooks.Add(new Hook((MethodBase)AccessTools.DeclaredMethod(typeof(RandomMapObject), "Awake", (Type[])null, (Type[])null), (Delegate)new Action, RandomMapObject>(AddPrefabsToRandomMapObjects))); object obj = <>O.<1>__SpawnOutsideMapObjects; if (obj == null) { hook_SpawnOutsideHazards val = SpawnOutsideMapObjects; <>O.<1>__SpawnOutsideMapObjects = val; obj = (object)val; } RoundManager.SpawnOutsideHazards += (hook_SpawnOutsideHazards)obj; object obj2 = <>O.<2>__RegenerateNavMeshTranspiler; if (obj2 == null) { Manipulator val2 = RegenerateNavMeshTranspiler; <>O.<2>__RegenerateNavMeshTranspiler = val2; obj2 = (object)val2; } RoundManager.SpawnOutsideHazards += (Manipulator)obj2; object obj3 = <>O.<3>__UpdateMapObjectSpawnWeights; if (obj3 == null) { hook_SetPlanetsWeather val3 = UpdateMapObjectSpawnWeights; <>O.<3>__UpdateMapObjectSpawnWeights = val3; obj3 = (object)val3; } StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj3; object obj4 = <>O.<4>__UpdateMapObjectSpawnWeights; if (obj4 == null) { hook_SpawnMapObjects val4 = UpdateMapObjectSpawnWeights; <>O.<4>__UpdateMapObjectSpawnWeights = val4; obj4 = (object)val4; } RoundManager.SpawnMapObjects += (hook_SpawnMapObjects)obj4; LethalContent.Moons.OnFreeze += RegisterMapObjects; LethalContent.MapObjects.OnFreeze += FixMapObjectBlanksOnDawnMoons; } private static void AddPrefabsToRandomMapObjects(Action orig, RandomMapObject self) { foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values) { if (value.InsideInfo != null && !value.ShouldSkipRespectOverride() && value.HasNetworkObject) { if ((Object)(object)value.InsideInfo.IndoorMapHazardType.prefabToSpawn == (Object)null) { DawnPlugin.Logger.LogWarning((object)("MapObject Inside prefab is null for " + ((Object)value.InsideInfo.IndoorMapHazardType).name)); } else { self.spawnablePrefabs.Add(value.InsideInfo.IndoorMapHazardType.prefabToSpawn); } } } orig.Invoke(self); } private static void FixMapObjectBlanksOnDawnMoons() { List list = new List(); foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (value.ShouldSkipIgnoreOverride()) { continue; } IndoorMapHazard[] indoorMapHazards = value.Level.indoorMapHazards; foreach (IndoorMapHazard val in indoorMapHazards) { if ((Object)(object)val.hazardType == (Object)null) { continue; } foreach (DawnMapObjectInfo value2 in LethalContent.MapObjects.Values) { if (value2.InsideInfo != null && ((Object)value2.InsideInfo.IndoorMapHazardType).name == ((Object)val.hazardType).name) { list.Add((ScriptableObject)(object)val.hazardType); val.hazardType = value2.InsideInfo.IndoorMapHazardType; break; } } } SpawnableOutsideObjectWithRarity[] spawnableOutsideObjects = value.Level.spawnableOutsideObjects; foreach (SpawnableOutsideObjectWithRarity val2 in spawnableOutsideObjects) { if ((Object)(object)val2.spawnableObject == (Object)null) { continue; } foreach (DawnMapObjectInfo value3 in LethalContent.MapObjects.Values) { if (value3.OutsideInfo != null && ((Object)value3.OutsideInfo.SpawnableOutsideObject).name == ((Object)val2.spawnableObject).name) { list.Add((ScriptableObject)(object)val2.spawnableObject); val2.spawnableObject = value3.OutsideInfo.SpawnableOutsideObject; break; } } } } for (int num = list.Count - 1; num >= 0; num--) { Object.Destroy((Object)(object)list[num]); } } private static void RegenerateNavMeshTranspiler(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num2 = default(int); ILLabel val3 = default(ILLabel); if (!val.TryGotoNext(new Func[3] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref num2), (Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 0), (Instruction i) => ILPatternMatchingExt.MatchBgt(i, ref val3) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply RoundManager.SpawnOutsideHazards patch (1)!"); return; } if (!val.TryGotoNext(new Func[1] { (Instruction i) => ILPatternMatchingExt.MatchLdstr(i, "OutsideLevelNavMesh") })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply RoundManager.SpawnOutsideHazards patch (2)!"); return; } int num = default(int); ILLabel val2 = default(ILLabel); val.GotoPrev((MoveType)0, new Func[3] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref num), (Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 0), (Instruction i) => ILPatternMatchingExt.MatchBgt(i, ref val2) }); int index = val.Index; val.Index = index + 1; val.EmitDelegate>((Func)((int spawned) => spawned + _spawnedObjects)); } private static void FreezeMapObjectContents() { Dictionary> dictionary = new Dictionary>(); Dictionary> dictionary2 = new Dictionary>(); foreach (DawnMoonInfo value8 in LethalContent.Moons.Values) { SelectableLevel level = value8.Level; IndoorMapHazard[] indoorMapHazards = level.indoorMapHazards; foreach (IndoorMapHazard val in indoorMapHazards) { IndoorMapHazardType hazardType = val.hazardType; if (!((Object)(object)hazardType == (Object)null) && !((Object)(object)hazardType.prefabToSpawn == (Object)null) && !hazardType.HasDawnInfo()) { if (!dictionary.TryGetValue(hazardType, out var value)) { value = (dictionary[hazardType] = new CurveTableBuilder()); } value.AddCurve(value8.TypedKey, val.numberToSpawn); } } SpawnableOutsideObjectWithRarity[] spawnableOutsideObjects = level.spawnableOutsideObjects; foreach (SpawnableOutsideObjectWithRarity val2 in spawnableOutsideObjects) { SpawnableOutsideObject spawnableObject = val2.spawnableObject; if (!((Object)(object)spawnableObject == (Object)null) && !((Object)(object)spawnableObject.prefabToSpawn == (Object)null) && !spawnableObject.HasDawnInfo()) { if (!dictionary2.TryGetValue(spawnableObject, out var value2)) { value2 = (dictionary2[spawnableObject] = new CurveTableBuilder()); } value2.AddCurve(value8.TypedKey, val2.randomAmount); } } } Dictionary dictionary3 = new Dictionary(); foreach (KeyValuePair> item in dictionary) { IndoorMapHazardType key = item.Key; ProviderTable spawnWeights = item.Value.Build(); DawnInsideMapObjectInfo value3 = new DawnInsideMapObjectInfo(item.Key, spawnWeights); dictionary3[key.prefabToSpawn] = value3; } Dictionary dictionary4 = new Dictionary(); foreach (KeyValuePair> item2 in dictionary2) { SpawnableOutsideObject key2 = item2.Key; ProviderTable spawnWeights2 = item2.Value.Build(); DawnOutsideMapObjectInfo value4 = new DawnOutsideMapObjectInfo(key2, spawnWeights2, alignWithTerrain: false, 0); dictionary4[key2.prefabToSpawn] = value4; } List list = dictionary.Keys.Select((IndoorMapHazardType x) => x.prefabToSpawn).Concat(dictionary2.Keys.Select((SpawnableOutsideObject x) => x.prefabToSpawn)).Distinct() .ToList(); IIndoorMapHazard val3 = default(IIndoorMapHazard); foreach (GameObject item3 in list) { string name = NamespacedKey.NormalizeStringForNamespacedKey(((Object)item3).name, CSharpName: true); NamespacedKey namespacedKey = MapObjectKeys.GetByReflection(name); string modName2; if (namespacedKey == null && LethalLibCompat.Enabled && LethalLibCompat.TryGetMapObjectFromLethalLib(item3, out string modName)) { namespacedKey = NamespacedKey.From(modName, ((Object)item3).name); } else if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedMapObjectModName(item3, out modName2)) { namespacedKey = NamespacedKey.From(modName2, ((Object)item3).name); } else if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_lib", ((Object)item3).name); } dictionary3.TryGetValue(item3, out var value5); dictionary4.TryGetValue(item3, out var value6); DawnMapObjectInfo dawnMapObjectInfo = new DawnMapObjectInfo(namespacedKey, new HashSet { DawnLibTags.IsExternal }, value5, value6, null); if (!item3.TryGetComponent(ref val3)) { DawnMapObjectNamespacedKeyContainer dawnMapObjectNamespacedKeyContainer = item3.AddComponent(); dawnMapObjectNamespacedKeyContainer.Value = namespacedKey; } value5?.IndoorMapHazardType.SetDawnInfo(dawnMapObjectInfo); value6?.SpawnableOutsideObject.SetDawnInfo(dawnMapObjectInfo); if (LethalContent.MapObjects.TryGetValue(dawnMapObjectInfo.TypedKey, out DawnMapObjectInfo value7)) { value5?.IndoorMapHazardType.SetDawnInfo(value7); value6?.SpawnableOutsideObject.SetDawnInfo(value7); } else { LethalContent.MapObjects.Register(dawnMapObjectInfo); } } LethalContent.MapObjects.Freeze(); } private static void UpdateMapObjectSpawnWeights(orig_SpawnMapObjects orig, RoundManager self) { UpdateIndoorMapHazardSpawnWeightsOnLevel(self.currentLevel); orig.Invoke(self); } private static void SpawnOutsideMapObjects(orig_SpawnOutsideHazards orig, RoundManager self) { UpdateOutsideMapObjectSpawnWeightsOnLevel(self.currentLevel); Random everyoneRandom = new Random(StartOfRound.Instance.randomMapSeed + 69); Random serverOnlyRandom = new Random(StartOfRound.Instance.randomMapSeed + 6969); List<(DawnOutsideMapObjectInfo, Vector3)> occupiedPositions = new List<(DawnOutsideMapObjectInfo, Vector3)>(); EntranceTeleport[] entranceTeleports = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)1); Transform[] shipSpawnPathPoints = RoundManager.Instance.shipSpawnPathPoints; GameObject[] spawnDenialPoints = GameObject.FindGameObjectsWithTag("SpawnDenialPoint"); GameObject itemShipLandingNode = GameObject.FindGameObjectWithTag("ItemShipLandingNode"); foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values) { DawnOutsideMapObjectInfo outsideInfo = value.OutsideInfo; if (outsideInfo != null && !value.ShouldSkipRespectOverride()) { if (outsideInfo.ParentInfo == null) { DawnPlugin.Logger.LogError((object)("Failed to get outside parent info for " + ((Object)outsideInfo.SpawnableOutsideObject.prefabToSpawn).name)); } else { HandleSpawningOutsideObjects(outsideInfo, occupiedPositions, everyoneRandom, serverOnlyRandom, entranceTeleports, shipSpawnPathPoints, spawnDenialPoints, itemShipLandingNode); } } } orig.Invoke(self); _spawnedObjects = 0; } private static void HandleSpawningOutsideObjects(DawnOutsideMapObjectInfo outsideInfo, List<(DawnOutsideMapObjectInfo outsideMapObjectInfo, Vector3 position)> occupiedPositions, Random everyoneRandom, Random serverOnlyRandom, EntranceTeleport[] entranceTeleports, Transform[] shipSpawnPathPoints, GameObject[] spawnDenialPoints, GameObject itemShipLandingNode) { //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: 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_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_051a: 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_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_05d3: Unknown result type (might be due to invalid IL or missing references) if (RoundManager.Instance.outsideAINodes.Length <= outsideInfo.MinimumAINodeSpawnRequirement) { return; } SelectableLevel currentLevel = RoundManager.Instance.currentLevel; DawnMapObjectInfo parentInfo = outsideInfo.ParentInfo; GameObject prefabToSpawn = outsideInfo.SpawnableOutsideObject.prefabToSpawn; SpawnWeightContext ctx = new SpawnWeightContext(currentLevel.GetDawnInfo(), RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(currentLevel)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, currentLevel.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); AnimationCurve val = outsideInfo.SpawnWeights.GetFor(in ctx) ?? AnimationCurve.Constant(0f, 1f, 0f); int num2; if (parentInfo.HasNetworkObject) { if (!NetworkManager.Singleton.IsServer) { return; } float num = val.Evaluate(serverOnlyRandom.NextFloat(0f, 1f)) + 0.5f; Debuggers.MapObjects?.Log($"number generated for host only: {num}"); num2 = Mathf.FloorToInt(num); } else { float num3 = val.Evaluate(everyoneRandom.NextFloat(0f, 1f)) + 0.5f; Debuggers.MapObjects?.Log("number generated for everyone: " + num3); num2 = Mathf.FloorToInt(num3); } Debuggers.MapObjects?.Log($"Spawning {num2} of {((Object)prefabToSpawn).name} for level {currentLevel}"); float num4 = outsideInfo.SpawnableOutsideObject.objectWidth; int num5 = 0; int num6 = num2; RaycastHit val3 = default(RaycastHit); DawnSurface dawnSurface = default(DawnSurface); while (num2 > 0 && num5 < 10 * num6) { Debuggers.MapObjects?.Log($"Attempt number: {num5} with {num2} left to spawn with initial number: {num6}."); num5++; Random random = (parentInfo.HasNetworkObject ? serverOnlyRandom : everyoneRandom); GameObject val2 = RoundManager.Instance.outsideAINodes[random.Next(0, RoundManager.Instance.outsideAINodes.Length)]; if ((Object)(object)val2 == (Object)null) { DawnPlugin.Logger.LogWarning((object)("Failed to get a valid outside AI node to spawn map object at level: " + currentLevel.sceneName + ".")); continue; } Vector3 position = val2.transform.position; position = RoundManager.Instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), random, -1, 1f) + Vector3.up * 2f; if (!Physics.Raycast(position, Vector3.down, ref val3, 100f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) || !Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).collider)) { continue; } string[] spawnableFloorTags = outsideInfo.SpawnableOutsideObject.spawnableFloorTags; if (spawnableFloorTags != null && spawnableFloorTags.Length != 0) { bool flag = false; Transform transform = ((Component)((RaycastHit)(ref val3)).collider).transform; int footstepIndex = -1; if (((Component)transform).TryGetComponent(ref dawnSurface) && (dawnSurface.SurfaceIndex > -1 || dawnSurface.TerrainIndices.Count > 0)) { dawnSurface.TryGetFootstepIndex(((RaycastHit)(ref val3)).point, checkStandingOnTerrain: false, out footstepIndex); } for (int i = 0; i < spawnableFloorTags.Length; i++) { if (footstepIndex != -1) { DawnSurfaceInfo dawnInfo = StartOfRound.Instance.footstepSurfaces[footstepIndex].GetDawnInfo(); if (dawnInfo.Surface.surfaceTag.Equals(spawnableFloorTags[i], StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } else if (((Component)transform).CompareTag(spawnableFloorTags[i])) { flag = true; break; } } if (!flag) { continue; } } Vector3 val4 = RoundManager.Instance.PositionEdgeCheck(((RaycastHit)(ref val3)).point, num4, -1, default(Vector3)); if (val4 == Vector3.zero) { continue; } bool flag2 = false; if (shipSpawnPathPoints != null) { for (int j = 0; j < shipSpawnPathPoints.Length; j++) { if (Vector3.Distance(((Component)shipSpawnPathPoints[j]).transform.position, val4) < num4 + 6f) { flag2 = true; break; } } } foreach (EntranceTeleport val5 in entranceTeleports) { if (Vector3.Distance(((Component)val5).transform.position, val4) < num4 + 6f) { flag2 = true; break; } } if (flag2) { continue; } if (spawnDenialPoints != null) { for (int l = 0; l < spawnDenialPoints.Length; l++) { if (Vector3.Distance(spawnDenialPoints[l].transform.position, val4) < num4) { flag2 = true; break; } } } if (flag2 || ((Object)(object)itemShipLandingNode != (Object)null && Vector3.Distance(itemShipLandingNode.transform.position, val4) < num4)) { continue; } if (num4 > 4f) { for (int m = 0; m < occupiedPositions.Count; m++) { if (Vector3.Distance(val4, occupiedPositions[m].position) < num4) { flag2 = true; break; } } if (flag2) { continue; } } num2--; occupiedPositions.Add((outsideInfo, val4)); GameObject val6 = Object.Instantiate(prefabToSpawn, val4, Quaternion.identity, RoundManager.Instance.mapPropsContainer.transform); Debuggers.MapObjects?.Log($"Spawning {((Object)val6).name} at {val4}"); if (outsideInfo.AlignWithTerrain) { val6.transform.up = ((RaycastHit)(ref val3)).normal; } Vector3 eulerAngles = val6.transform.eulerAngles; if (outsideInfo.SpawnableOutsideObject.spawnFacingAwayFromWall) { float y = RoundManager.Instance.YRotationThatFacesTheFarthestFromPosition(val4 + Vector3.up * 0.2f, 25f, 6); eulerAngles.y = y; } else { int num7 = random.Next(0, 360); eulerAngles.y = num7; } val6.transform.eulerAngles = eulerAngles; Transform transform2 = val6.transform; transform2.localEulerAngles += outsideInfo.SpawnableOutsideObject.rotationOffset; _spawnedObjects++; if (parentInfo.HasNetworkObject) { val6.GetComponent().Spawn(true); } } if (!NetworkManager.Singleton.IsServer) { return; } List list = GameObject.FindGameObjectsWithTag("Tree").ToList(); for (int n = 0; n < occupiedPositions.Count; n++) { if (!occupiedPositions[n].outsideMapObjectInfo.SpawnableOutsideObject.destroyTrees) { continue; } for (int num8 = list.Count - 1; num8 >= 0; num8--) { float num9 = Vector3.Distance(list[num8].transform.position, occupiedPositions[n].position); if (num9 < (float)occupiedPositions[n].outsideMapObjectInfo.SpawnableOutsideObject.objectWidth) { RoundManager.Instance.DestroyTreeAtPosition(list[num8].transform.position, 5f); list.RemoveAt(num8); } } } } private static void UpdateMapObjectSpawnWeights(orig_SetPlanetsWeather orig, StartOfRound self, int connectedPlayersOnServer) { orig.Invoke(self, connectedPlayersOnServer); UpdateIndoorMapHazardSpawnWeightsOnLevel(self.currentLevel); UpdateOutsideMapObjectSpawnWeightsOnLevel(self.currentLevel); } internal static void UpdateIndoorMapHazardSpawnWeightsOnLevel(SelectableLevel level) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown if (!LethalContent.Weathers.IsFrozen || !LethalContent.MapObjects.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady())) { return; } foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values) { DawnInsideMapObjectInfo insideInfo = value.InsideInfo; if (insideInfo != null && !value.ShouldSkipRespectOverride()) { Debuggers.MapObjects?.Log("Updating weights for " + ((Object)insideInfo.IndoorMapHazardType.prefabToSpawn).name + " on level " + level.PlanetName); IndoorMapHazard val = ((IEnumerable)level.indoorMapHazards).FirstOrDefault((Func)((IndoorMapHazard mapObject) => (Object)(object)mapObject.hazardType == (Object)(object)insideInfo.IndoorMapHazardType)); if (val == null) { val = new IndoorMapHazard { hazardType = insideInfo.IndoorMapHazardType, numberToSpawn = AnimationCurve.Constant(0f, 1f, 0f) }; List list = level.indoorMapHazards.ToList(); list.Add(val); level.indoorMapHazards = list.ToArray(); } SpawnWeightContext ctx = new SpawnWeightContext(level.GetDawnInfo(), RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow?.GetDawnInfo(), TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); val.numberToSpawn = insideInfo.SpawnWeights.GetFor(in ctx) ?? AnimationCurve.Constant(0f, 1f, 0f); } } } internal static void UpdateOutsideMapObjectSpawnWeightsOnLevel(SelectableLevel level) { if (!LethalContent.Weathers.IsFrozen || !LethalContent.MapObjects.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady())) { return; } foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values) { DawnOutsideMapObjectInfo outsideInfo = value.OutsideInfo; if (outsideInfo != null && !value.ShouldSkipRespectOverride()) { SpawnableOutsideObjectWithRarity val = ((IEnumerable)level.spawnableOutsideObjects).FirstOrDefault((Func)((SpawnableOutsideObjectWithRarity mapObject) => (Object)(object)mapObject.spawnableObject.prefabToSpawn == (Object)(object)outsideInfo.SpawnableOutsideObject.prefabToSpawn)); if (val != null) { List list = level.spawnableOutsideObjects.ToList(); list.Remove(val); level.spawnableOutsideObjects = list.ToArray(); Debuggers.MapObjects?.Log("Updating weights for " + ((Object)outsideInfo.SpawnableOutsideObject.prefabToSpawn).name + " on level " + level.PlanetName); } } } } private static void RegisterMapObjects() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown foreach (DawnMoonInfo value in LethalContent.Moons.Values) { List list = value.Level.indoorMapHazards.ToList(); foreach (DawnMapObjectInfo value2 in LethalContent.MapObjects.Values) { if (value2.InsideInfo != null && !value2.ShouldSkipRespectOverride()) { IndoorMapHazard item = new IndoorMapHazard { hazardType = value2.InsideInfo.IndoorMapHazardType, numberToSpawn = AnimationCurve.Constant(0f, 1f, 0f) }; list.Add(item); } } value.Level.indoorMapHazards = list.ToArray(); } FreezeMapObjectContents(); } } public sealed class DawnInsideMapObjectInfo { public DawnMapObjectInfo ParentInfo { get; internal set; } public IndoorMapHazardType IndoorMapHazardType { get; set; } public ProviderTable SpawnWeights { get; private set; } internal DawnInsideMapObjectInfo(IndoorMapHazardType indoorMapHazardType, ProviderTable spawnWeights) { IndoorMapHazardType = indoorMapHazardType; SpawnWeights = spawnWeights; } } public sealed class DawnMapObjectInfo : DawnBaseInfo { public DawnInsideMapObjectInfo? InsideInfo { get; private set; } public DawnOutsideMapObjectInfo? OutsideInfo { get; private set; } public bool HasNetworkObject { get; } internal DawnMapObjectInfo(NamespacedKey key, HashSet tags, DawnInsideMapObjectInfo? insideInfo, DawnOutsideMapObjectInfo? outsideInfo, IDataContainer? customData) : base(key, tags, customData) { InsideInfo = insideInfo; if (InsideInfo != null) { InsideInfo.ParentInfo = this; HasNetworkObject = (Object)(object)InsideInfo.IndoorMapHazardType.prefabToSpawn.GetComponent() != (Object)null; } OutsideInfo = outsideInfo; if (OutsideInfo != null) { OutsideInfo.ParentInfo = this; HasNetworkObject = (Object)(object)OutsideInfo.SpawnableOutsideObject.prefabToSpawn.GetComponent() != (Object)null; } } public GameObject GetMapObjectPrefab() { if (InsideInfo != null) { return InsideInfo.IndoorMapHazardType.prefabToSpawn; } if (OutsideInfo != null) { return OutsideInfo.SpawnableOutsideObject.prefabToSpawn; } DawnPlugin.Logger.LogError((object)$"Failed to get map object prefab for {base.Key}"); return null; } } public sealed class DawnOutsideMapObjectInfo { public DawnMapObjectInfo ParentInfo { get; internal set; } public SpawnableOutsideObject SpawnableOutsideObject { get; private set; } public ProviderTable SpawnWeights { get; private set; } public bool AlignWithTerrain { get; private set; } public int MinimumAINodeSpawnRequirement { get; private set; } internal DawnOutsideMapObjectInfo(SpawnableOutsideObject spawnableOutsideObject, ProviderTable spawnWeights, bool alignWithTerrain, int minimumAINodeSpawnRequirement) { SpawnableOutsideObject = spawnableOutsideObject; SpawnWeights = spawnWeights; AlignWithTerrain = alignWithTerrain; MinimumAINodeSpawnRequirement = minimumAINodeSpawnRequirement; } } public static class IndoorMapHazardTypeExtensions { public static DawnMapObjectInfo GetDawnInfo(this IndoorMapHazardType IndoorMapHazardType) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnMapObjectInfo)((IDawnObject)IndoorMapHazardType).DawnInfo; } internal static bool HasDawnInfo(this IndoorMapHazardType IndoorMapHazardType) { return IndoorMapHazardType.GetDawnInfo() != null; } internal static void SetDawnInfo(this IndoorMapHazardType IndoorMapHazardType, DawnMapObjectInfo IndoorMapHazardTypeInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)IndoorMapHazardType).DawnInfo = IndoorMapHazardTypeInfo; } } [Serializable] public class InsideMapObjectSettings { public bool spawnFacingAwayFromWall; public bool spawnFacingWall; public bool spawnWithBackToWall; public bool spawnWithBackFlushAgainstWall; public bool requireDistanceBetweenSpawns; public bool disallowSpawningNearEntrances; public bool allowInMineshaft; } public class MapObjectInfoBuilder : BaseInfoBuilder { public class InsideBuilder { private MapObjectInfoBuilder _parentBuilder; private bool _spawnFacingAwayFromWall; private bool _spawnFacingWall; private bool _spawnWithBackToWall; private bool _spawnWithBackFlushAgainstWall; private bool _requireDistanceBetweenSpawns; private bool _disallowSpawningNearEntrances; private bool _allowInMineshaft; private ProviderTable? _weights; internal InsideBuilder(MapObjectInfoBuilder parent) { _parentBuilder = parent; } public InsideBuilder OverrideSpawnFacingAwayFromWall(bool spawnFacingAwayFromWall) { _spawnFacingAwayFromWall = spawnFacingAwayFromWall; return this; } public InsideBuilder OverrideSpawnFacingWall(bool spawnFacingWall) { _spawnFacingWall = spawnFacingWall; return this; } public InsideBuilder OverrideSpawnWithBackToWall(bool spawnWWithBackToWall) { _spawnWithBackToWall = spawnWWithBackToWall; return this; } public InsideBuilder OverrideSpawnWithBackFlushAgainstWall(bool spawnWithBackFlushAgainstWall) { _spawnWithBackFlushAgainstWall = spawnWithBackFlushAgainstWall; return this; } public InsideBuilder OverrideRequireDistanceBetweenSpawns(bool requireDistanceBetweenSpawns) { _requireDistanceBetweenSpawns = requireDistanceBetweenSpawns; return this; } public InsideBuilder OverrideDisallowSpawningNearEntrances(bool disallowSpawningNearEntrances) { _disallowSpawningNearEntrances = disallowSpawningNearEntrances; return this; } public InsideBuilder OverrideAllowInMineshaft(bool allowInMineshaft) { _allowInMineshaft = allowInMineshaft; return this; } public InsideBuilder SetWeights(Action> callback) { CurveTableBuilder curveTableBuilder = new CurveTableBuilder(); callback(curveTableBuilder); _weights = curveTableBuilder.Build(); return this; } internal DawnInsideMapObjectInfo Build() { if (_weights == null) { DawnPlugin.Logger.LogWarning((object)$"MapObject: '{_parentBuilder.key}' didn't set inside weights. If you intend to have no weights (doing something special), call .SetWeights(() => {{}})"); _weights = ProviderTable.Empty(); } IndoorMapHazardType val = ScriptableObject.CreateInstance(); ((Object)val).name = _parentBuilder.key.Key; val.prefabToSpawn = _parentBuilder.value; val.spawnFacingAwayFromWall = _spawnFacingAwayFromWall; val.spawnFacingWall = _spawnFacingWall; val.spawnWithBackToWall = _spawnWithBackToWall; val.spawnWithBackFlushAgainstWall = _spawnWithBackFlushAgainstWall; val.requireDistanceBetweenSpawns = _requireDistanceBetweenSpawns; val.disallowSpawningNearEntrances = _disallowSpawningNearEntrances; val.allowInMineshaft = _allowInMineshaft; return new DawnInsideMapObjectInfo(val, _weights); } } public class OutsideBuilder { private MapObjectInfoBuilder _parentBuilder; private bool _alignWithTerrain; private bool _destroyTrees; private bool _spawnFacingAwayFromWall; private int _objectWidth = 6; private int _minimumNodeSpawnRequirement; private Vector3 _rotationOffset = Vector3.zero; private string[] _spawnableFloorTags = Array.Empty(); private ProviderTable? _weights; internal OutsideBuilder(MapObjectInfoBuilder parent) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) _parentBuilder = parent; } public OutsideBuilder OverrideAlignWithTerrain(bool alignWithTerrain) { _alignWithTerrain = alignWithTerrain; return this; } public OutsideBuilder OverrideSpawnFacingAwayFromWall(bool spawnFacingAwayFromWall) { _spawnFacingAwayFromWall = spawnFacingAwayFromWall; return this; } public OutsideBuilder OverrideMinimumNodeSpawnRequirement(int minimumAINodeRequirement) { _minimumNodeSpawnRequirement = minimumAINodeRequirement; return this; } public OutsideBuilder OverrideRotationOffset(Vector3 rotationOffset) { //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) _rotationOffset = rotationOffset; return this; } public OutsideBuilder OverrideSpawnableFloorTags(string[] spawnableFloorTags) { _spawnableFloorTags = spawnableFloorTags; return this; } public OutsideBuilder OverrideObjectWidth(int objectWidth) { _objectWidth = objectWidth; return this; } public OutsideBuilder OverrideDestroyTrees(bool destroyTrees) { _destroyTrees = destroyTrees; return this; } public OutsideBuilder SetWeights(Action> callback) { CurveTableBuilder curveTableBuilder = new CurveTableBuilder(); callback(curveTableBuilder); _weights = curveTableBuilder.Build(); return this; } internal DawnOutsideMapObjectInfo Build() { //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) if (_weights == null) { DawnPlugin.Logger.LogWarning((object)$"MapObject: '{_parentBuilder.key}' didn't set inside weights. If you intend to have no weights (doing something special), call .SetWeights(() => {{}})"); _weights = ProviderTable.Empty(); } SpawnableOutsideObject val = ScriptableObject.CreateInstance(); ((Object)val).name = _parentBuilder.key.Key; val.prefabToSpawn = _parentBuilder.value; val.spawnFacingAwayFromWall = _spawnFacingAwayFromWall; val.rotationOffset = _rotationOffset; val.destroyTrees = _destroyTrees; val.spawnableFloorTags = _spawnableFloorTags; val.objectWidth = _objectWidth; return new DawnOutsideMapObjectInfo(val, _weights, _alignWithTerrain, _minimumNodeSpawnRequirement); } } private DawnInsideMapObjectInfo? _insideInfo; private DawnOutsideMapObjectInfo? _outsideInfo; internal MapObjectInfoBuilder(NamespacedKey key, GameObject mapObject) : base(key, mapObject) { } public MapObjectInfoBuilder DefineInside(Action callback) { InsideBuilder insideBuilder = new InsideBuilder(this); callback(insideBuilder); _insideInfo = insideBuilder.Build(); return this; } public MapObjectInfoBuilder DefineOutside(Action callback) { OutsideBuilder outsideBuilder = new OutsideBuilder(this); callback(outsideBuilder); _outsideInfo = outsideBuilder.Build(); return this; } internal override DawnMapObjectInfo Build() { return new DawnMapObjectInfo(base.key, tags, _insideInfo, _outsideInfo, customData); } } [Serializable] public class OutsideMapObjectSettings { [FormerlySerializedAs("SpawnFacingAwayFromWall")] public bool spawnFacingAwayFromWall; [FormerlySerializedAs("ObjectWidth")] public int objectWidth = 6; public bool destroyTrees; [FormerlySerializedAs("RotationOffset")] public Vector3 rotationOffset = Vector3.zero; [FormerlySerializedAs("SpawnableFloorTags")] public string[] spawnableFloorTags = Array.Empty(); [FormerlySerializedAs("MinimumAINodeSpawnRequirement")] public int minimumAINodeSpawnRequirement; [FormerlySerializedAs("AlignWithTerrain")] public bool alignWithTerrain; } public static class SpawnableOutsideObjectExtensions { public static DawnMapObjectInfo GetDawnInfo(this SpawnableOutsideObject SpawnableOutsideObject) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnMapObjectInfo)((IDawnObject)SpawnableOutsideObject).DawnInfo; } internal static bool HasDawnInfo(this SpawnableOutsideObject SpawnableOutsideObject) { return SpawnableOutsideObject.GetDawnInfo() != null; } internal static void SetDawnInfo(this SpawnableOutsideObject SpawnableOutsideObject, DawnMapObjectInfo SpawnableOutsideObjectInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)SpawnableOutsideObject).DawnInfo = SpawnableOutsideObjectInfo; } } [HarmonyPatch] internal static class MoonRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__CollectTestLevel; public static hook_Awake <1>__CollectLevels; public static hook_Awake <2>__SpawnRouteProgressUI; public static hook_Awake <3>__RegisterDawnLevels; public static Action <4>__FixAmbienceLibraries; public static Action <5>__FixDawnMoonEnemies; public static Action <6>__FixDawnMoonItems; public static hook_ChangeLevel <7>__StartOfRoundOnChangeLevel; public static hook_OnClientConnect <8>__StartOfRoundOnClientConnect; public static hook_OnClientDisconnect <9>__StartOfRoundOnClientDisconnect; public static hook_TravelToLevelEffects <10>__DelayTravelEffects; public static hook_TextPostProcess <11>__DynamicMoonCatalogue; public static Manipulator <12>__ReplaceStaticOutsideEnemyProbabilityRange; public static Manipulator <13>__MultiplyGlobalTimeMultiplierToDaySpeedMultiplier; public static Manipulator <14>__IgnoreDaySpeedMultiplier; } [CompilerGenerated] private sealed class d__15 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public orig_TravelToLevelEffects orig; public StartOfRound self; private IEnumerator 5__2; object 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; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = orig.Invoke(self); break; case 1: { <>1__state = -1; object current = 5__2.Current; WaitForSeconds val = (WaitForSeconds)((current is WaitForSeconds) ? current : null); if (val != null && Mathf.Approximately(val.m_Seconds, self.currentLevel.timeToArrive)) { <>2__current = (object)new WaitUntil((Func)(() => NetworkSingleton.Instance.allPlayersDone)); <>1__state = 2; return true; } break; } case 2: <>1__state = -1; break; } if (5__2.MoveNext()) { <>2__current = 5__2.Current; <>1__state = 1; return true; } self.shipTravelCoroutine = 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(); } } [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SelectableLevel level; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func)(() => (Object)(object)NetworkSingleton.Instance != (Object)null && (Object)(object)Singleton.Instance != (Object)null)); <>1__state = 1; return true; case 1: <>1__state = -1; NetworkSingleton.Instance.HostDecide(level.GetDawnInfo()); 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(); } } public static MainGroupAlgorithm MoonGroupAlgorithm = new MainGroupAlgorithm(); internal static GameObject RouteProgressUIPrefab; internal static void Init() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown //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) //IL_021c: Expected O, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Expected O, but got Unknown //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Expected O, but got Unknown //IL_0251: 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_025c: Expected O, but got Unknown //IL_0271: 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_027c: Expected O, but got Unknown //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown LethalContent.Moons.AddAutoTaggers(new SimpleAutoTagger(Tags.Company, (DawnMoonInfo moonInfo) => !moonInfo.Level.spawnEnemiesAndScrap), new SimpleAutoTagger(Tags.Free, (DawnMoonInfo moonInfo) => Object.op_Implicit((Object)(object)moonInfo.RouteNode) && moonInfo.RouteNode.itemCost == 0), new SimpleAutoTagger(Tags.Paid, (DawnMoonInfo moonInfo) => Object.op_Implicit((Object)(object)moonInfo.RouteNode) && moonInfo.RouteNode.itemCost > 0), new SimpleAutoTagger(DawnLibTags.HasBuyingPercent, (DawnMoonInfo moonInfo) => moonInfo.GetNumberlessPlanetName() == "Gordion")); DetourContext val = new DetourContext(2147483637); try { object obj = <>O.<0>__CollectTestLevel; if (obj == null) { hook_Awake val2 = CollectTestLevel; <>O.<0>__CollectTestLevel = val2; obj = (object)val2; } StartOfRound.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__CollectLevels; if (obj2 == null) { hook_Awake val3 = CollectLevels; <>O.<1>__CollectLevels = val3; obj2 = (object)val3; } StartOfRound.Awake += (hook_Awake)obj2; if (!DawnConfig.VanillaCompatibility.Value) { object obj3 = <>O.<2>__SpawnRouteProgressUI; if (obj3 == null) { hook_Awake val4 = SpawnRouteProgressUI; <>O.<2>__SpawnRouteProgressUI = val4; obj3 = (object)val4; } StartOfRound.Awake += (hook_Awake)obj3; object obj4 = <>O.<3>__RegisterDawnLevels; if (obj4 == null) { hook_Awake val5 = RegisterDawnLevels; <>O.<3>__RegisterDawnLevels = val5; obj4 = (object)val5; } Terminal.Awake += (hook_Awake)obj4; } } finally { ((IDisposable)val)?.Dispose(); } LethalContent.Moons.OnFreeze += FixAmbienceLibraries; LethalContent.Enemies.OnFreeze += FixDawnMoonEnemies; LethalContent.Items.OnFreeze += FixDawnMoonItems; if (!DawnConfig.VanillaCompatibility.Value) { object obj5 = <>O.<7>__StartOfRoundOnChangeLevel; if (obj5 == null) { hook_ChangeLevel val6 = StartOfRoundOnChangeLevel; <>O.<7>__StartOfRoundOnChangeLevel = val6; obj5 = (object)val6; } StartOfRound.ChangeLevel += (hook_ChangeLevel)obj5; object obj6 = <>O.<8>__StartOfRoundOnClientConnect; if (obj6 == null) { hook_OnClientConnect val7 = StartOfRoundOnClientConnect; <>O.<8>__StartOfRoundOnClientConnect = val7; obj6 = (object)val7; } StartOfRound.OnClientConnect += (hook_OnClientConnect)obj6; object obj7 = <>O.<9>__StartOfRoundOnClientDisconnect; if (obj7 == null) { hook_OnClientDisconnect val8 = StartOfRoundOnClientDisconnect; <>O.<9>__StartOfRoundOnClientDisconnect = val8; obj7 = (object)val8; } StartOfRound.OnClientDisconnect += (hook_OnClientDisconnect)obj7; object obj8 = <>O.<10>__DelayTravelEffects; if (obj8 == null) { hook_TravelToLevelEffects val9 = DelayTravelEffects; <>O.<10>__DelayTravelEffects = val9; obj8 = (object)val9; } StartOfRound.TravelToLevelEffects += (hook_TravelToLevelEffects)obj8; object obj9 = <>O.<11>__DynamicMoonCatalogue; if (obj9 == null) { hook_TextPostProcess val10 = DynamicMoonCatalogue; <>O.<11>__DynamicMoonCatalogue = val10; obj9 = (object)val10; } Terminal.TextPostProcess += (hook_TextPostProcess)obj9; object obj10 = <>O.<12>__ReplaceStaticOutsideEnemyProbabilityRange; if (obj10 == null) { Manipulator val11 = ReplaceStaticOutsideEnemyProbabilityRange; <>O.<12>__ReplaceStaticOutsideEnemyProbabilityRange = val11; obj10 = (object)val11; } RoundManager.PredictAllOutsideEnemies += (Manipulator)obj10; } if (!MoonDaySpeedMultiplierPatcherCompat.Enabled) { object obj11 = <>O.<13>__MultiplyGlobalTimeMultiplierToDaySpeedMultiplier; if (obj11 == null) { Manipulator val12 = MultiplyGlobalTimeMultiplierToDaySpeedMultiplier; <>O.<13>__MultiplyGlobalTimeMultiplierToDaySpeedMultiplier = val12; obj11 = (object)val12; } TimeOfDay.MoveGlobalTime += (Manipulator)obj11; object obj12 = <>O.<14>__IgnoreDaySpeedMultiplier; if (obj12 == null) { Manipulator val13 = IgnoreDaySpeedMultiplier; <>O.<14>__IgnoreDaySpeedMultiplier = val13; obj12 = (object)val13; } TimeOfDay.CalculatePlanetTime += (Manipulator)obj12; object obj13 = <>O.<14>__IgnoreDaySpeedMultiplier; if (obj13 == null) { Manipulator val14 = IgnoreDaySpeedMultiplier; <>O.<14>__IgnoreDaySpeedMultiplier = val14; obj13 = (object)val14; } TimeOfDay.Update += (Manipulator)obj13; } } private static void ReplaceStaticOutsideEnemyProbabilityRange(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num3 = default(int); int num2 = default(int); if (!val.TryGotoNext((MoveType)2, new Func[3] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref num3), (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref num2), (Instruction i) => ILPatternMatchingExt.MatchLdcR4(i, 3f) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply RoundManager.PredictAllOutsideEnemies patch (1)"); return; } val.Emit(OpCodes.Pop); val.Emit(OpCodes.Call, (MethodBase)typeof(MoonRegistrationHandler).GetMethod("GetMoonOutsideEnemyProbabilitySpawnRange", BindingFlags.Static | BindingFlags.NonPublic)); int num = default(int); if (!val.TryGotoNext((MoveType)2, new Func[3] { (Instruction i) => ILPatternMatchingExt.MatchConvI4(i), (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref num), (Instruction i) => ILPatternMatchingExt.MatchLdcR4(i, 3f) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply RoundManager.PredictAllOutsideEnemies patch (2)"); return; } val.Emit(OpCodes.Pop); val.Emit(OpCodes.Call, (MethodBase)typeof(MoonRegistrationHandler).GetMethod("GetMoonOutsideEnemyProbabilitySpawnRange", BindingFlags.Static | BindingFlags.NonPublic)); } private static float GetMoonOutsideEnemyProbabilitySpawnRange() { if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null || !StartOfRound.Instance.currentLevel.HasDawnInfo()) { return 3f; } return StartOfRound.Instance.currentLevel.GetDawnInfo().OutsideEnemiesProbabilityRange; } private static void MultiplyGlobalTimeMultiplierToDaySpeedMultiplier(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[2] { (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0), (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, "globalTimeSpeedMultiplier") })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply TimeOfDay.MoveGlobalTime patch"); return; } val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldfld, typeof(TimeOfDay).GetField("currentLevel")); val.Emit(OpCodes.Ldfld, typeof(SelectableLevel).GetField("DaySpeedMultiplier")); val.Emit(OpCodes.Mul); } private static void IgnoreDaySpeedMultiplier(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[1] { (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, "DaySpeedMultiplier") })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply TimeOfDay.Update patch"); return; } val.Emit(OpCodes.Pop); val.Emit(OpCodes.Ldc_R4, 1f); } private static void SpawnRouteProgressUI(orig_Awake orig, StartOfRound self) { Object.Instantiate(RouteProgressUIPrefab, ((Component)self.radarCanvas).transform); orig.Invoke(self); } private static void FixAmbienceLibraries() { List vanillaLevelAmbienceLibraries = new List(); foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (value.TypedKey.IsVanilla()) { if ((Object)(object)value.Level.levelAmbienceClips != (Object)null) { vanillaLevelAmbienceLibraries.Add(value.Level.levelAmbienceClips); } vanillaLevelAmbienceLibraries.AddRange(from dungeonFlowType in value.Level.dungeonFlowTypes select dungeonFlowType.overrideLevelAmbience into x where (Object)(object)x != (Object)null select x); } } vanillaLevelAmbienceLibraries = vanillaLevelAmbienceLibraries.Distinct().ToList(); List list = new List(); foreach (DawnMoonInfo value2 in LethalContent.Moons.Values) { if (value2.ShouldSkipIgnoreOverride()) { continue; } foreach (LevelAmbienceLibrary item in vanillaLevelAmbienceLibraries) { if ((Object)(object)value2.Level.levelAmbienceClips != (Object)null && ((Object)value2.Level.levelAmbienceClips).name == ((Object)item).name) { list.Add(value2.Level.levelAmbienceClips); value2.Level.levelAmbienceClips = item; } for (int i = 0; i < value2.Level.dungeonFlowTypes.Length; i++) { LevelAmbienceLibrary overrideLevelAmbience = value2.Level.dungeonFlowTypes[i].overrideLevelAmbience; if (!((Object)(object)overrideLevelAmbience == (Object)null) && !(((Object)overrideLevelAmbience).name != ((Object)item).name)) { list.Add(overrideLevelAmbience); value2.Level.dungeonFlowTypes[i].overrideLevelAmbience = item; } } } } list = list.Where((LevelAmbienceLibrary x) => !vanillaLevelAmbienceLibraries.Contains(x)).Distinct().ToList(); for (int num = list.Count - 1; num >= 0; num--) { Object.Destroy((Object)(object)list[num]); } } private static void RegisterDawnLevels(orig_Awake orig, Terminal self) { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown List list = StartOfRoundRefs.Instance.levels.ToList(); foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (!value.ShouldSkipIgnoreOverride()) { value.Level.levelID = list.Count; list.Add(value.Level); UpdateMoonPrice(value); } } StartOfRoundRefs.Instance.levels = list.ToArray(); if (LethalContent.Moons.IsFrozen) { orig.Invoke(self); return; } List list2 = TerminalRefs.Instance.terminalNodes.allKeywords.ToList(); List list3 = TerminalRefs.RouteKeyword.compatibleNouns.ToList(); List list4 = TerminalRefs.Instance.moonsCatalogueList.ToList(); foreach (DawnMoonInfo value2 in LethalContent.Moons.Values) { if (!value2.ShouldSkipIgnoreOverride() && !((Object)(object)value2.ReceiptNode == (Object)null) && !((Object)(object)value2.RouteNode == (Object)null) && !((Object)(object)value2.NameKeyword == (Object)null)) { value2.ReceiptNode.buyRerouteToMoon = value2.Level.levelID; value2.RouteNode.displayPlanetInfo = value2.Level.levelID; list3.Add(new CompatibleNoun(value2.NameKeyword, value2.RouteNode)); list2.Add(value2.NameKeyword); value2.NameKeyword.defaultVerb = TerminalRefs.RouteKeyword; value2.RouteNode.overrideOptions = true; value2.RouteNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { new CompatibleNoun(TerminalRefs.DenyKeyword, TerminalRefs.CancelRouteNode), new CompatibleNoun(TerminalRefs.ConfirmPurchaseKeyword, value2.ReceiptNode) }; if (!(value2.DawnPurchaseInfo.PurchasePredicate.CanPurchase() is TerminalPurchaseResult.HiddenPurchaseResult)) { list4.Add(value2.Level); } } } TerminalRefs.Instance.moonsCatalogueList = list4.ToArray(); TerminalRefs.RouteKeyword.compatibleNouns = list3.ToArray(); TerminalRefs.Instance.terminalNodes.allKeywords = list2.ToArray(); orig.Invoke(self); } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPrefix] [HarmonyPriority(-999)] private static void FreezeMoonRegistry() { foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (value.Level.indoorMapHazards == null) { value.Level.indoorMapHazards = Array.Empty(); } } if (!LethalContent.Moons.IsFrozen) { LethalContent.Moons.Freeze(); } } private static void FixDawnMoonItems() { List list = new List(); foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (value.ShouldSkipIgnoreOverride()) { continue; } SpawnableItemWithRarity[] array = value.Level.spawnableScrap.ToArray(); foreach (SpawnableItemWithRarity val in array) { if ((Object)(object)val.spawnableItem == (Object)null) { value.Level.spawnableScrap.Remove(val); continue; } bool flag = val.spawnableItem.HasDawnInfo(); foreach (DawnItemInfo value2 in LethalContent.Items.Values) { if (!flag && ((Object)value2.Item).name == ((Object)val.spawnableItem).name) { list.Add(val.spawnableItem); val.spawnableItem = value2.Item; break; } } } } for (int num = list.Count - 1; num >= 0; num--) { Object.Destroy((Object)(object)list[num]); } } private static void FixDawnMoonEnemies() { List list = new List(); foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (value.ShouldSkipIgnoreOverride()) { continue; } SpawnableEnemyWithRarity[] array = value.Level.Enemies.ToArray(); foreach (SpawnableEnemyWithRarity val in array) { if ((Object)(object)val.enemyType == (Object)null) { value.Level.Enemies.Remove(val); continue; } bool flag = val.enemyType.HasDawnInfo(); foreach (DawnEnemyInfo value2 in LethalContent.Enemies.Values) { if (!flag && ((Object)value2.EnemyType).name == ((Object)val.enemyType).name) { Debuggers.Moons?.Log("replacing fake SO " + ((Object)val.enemyType).name + " with " + ((Object)value2.EnemyType).name); list.Add(val.enemyType); val.enemyType = value2.EnemyType; break; } } } SpawnableEnemyWithRarity[] array2 = value.Level.OutsideEnemies.ToArray(); foreach (SpawnableEnemyWithRarity val2 in array2) { if ((Object)(object)val2.enemyType == (Object)null) { value.Level.OutsideEnemies.Remove(val2); continue; } bool flag2 = val2.enemyType.HasDawnInfo(); foreach (DawnEnemyInfo value3 in LethalContent.Enemies.Values) { if (!flag2 && ((Object)value3.EnemyType).name == ((Object)val2.enemyType).name) { Debuggers.Moons?.Log("replacing fake SO " + ((Object)val2.enemyType).name + " with " + ((Object)value3.EnemyType).name); list.Add(val2.enemyType); val2.enemyType = value3.EnemyType; break; } } } SpawnableEnemyWithRarity[] array3 = value.Level.DaytimeEnemies.ToArray(); foreach (SpawnableEnemyWithRarity val3 in array3) { if ((Object)(object)val3.enemyType == (Object)null) { value.Level.DaytimeEnemies.Remove(val3); continue; } bool flag3 = val3.enemyType.HasDawnInfo(); foreach (DawnEnemyInfo value4 in LethalContent.Enemies.Values) { if (!flag3 && ((Object)value4.EnemyType).name == ((Object)val3.enemyType).name) { Debuggers.Moons?.Log("replacing fake SO " + ((Object)val3.enemyType).name + " with " + ((Object)value4.EnemyType).name); list.Add(val3.enemyType); val3.enemyType = value4.EnemyType; break; } } } } for (int num = list.Count - 1; num >= 0; num--) { Object.Destroy((Object)(object)list[num]); } } private static string DynamicMoonCatalogue(orig_TextPostProcess orig, Terminal self, string modifieddisplaytext, TerminalNode node) { if ((Object)(object)node != (Object)(object)TerminalRefs.MoonCatalogueNode) { return orig.Invoke(self, modifieddisplaytext, node); } StringBuilder stringBuilder = new StringBuilder("\n\nWelcome to the exomoons catalogue.\nTo route the autopilot to a moon, use the word ROUTE.\nTo learn about any moon, use INFO.\n____________________________\n"); IEnumerable input = from it in LethalContent.Moons.Values where !it.HasTag(Tags.Unimplemented) orderby it.HasTag(Tags.Vanilla) descending select it; List list = MoonGroupAlgorithm.Group(input); foreach (MoonGroup item in list) { stringBuilder.AppendLine(""); if (!string.IsNullOrWhiteSpace(item.GroupName)) { stringBuilder.AppendLine(item.GroupName); } foreach (DawnMoonInfo moon in item.Moons) { TerminalPurchaseResult result = moon.DawnPurchaseInfo.PurchasePredicate.CanPurchase(); stringBuilder.AppendLine(FormatMoonEntry(moon, result)); } } return orig.Invoke(self, stringBuilder.ToString(), node); } private static string FormatMoonEntry(DawnMoonInfo moonInfo, TerminalPurchaseResult result) { StringBuilder stringBuilder = new StringBuilder(); string text = moonInfo.GetNumberlessPlanetName(); if (result is TerminalPurchaseResult.FailedPurchaseResult failedPurchaseResult) { text = failedPurchaseResult.OverrideName ?? text; } if (text == "Gordion") { text = "The Company building"; } stringBuilder.Append("* " + text + " "); if (moonInfo.HasTag(DawnLibTags.HasBuyingPercent)) { stringBuilder.Append("// Buying at [companyBuyingPercent]."); } else { DawnWeatherEffectInfo currentWeather = moonInfo.GetCurrentWeather(); if (currentWeather != null) { stringBuilder.Append("(" + ((object)(LevelWeatherType)(ref moonInfo.Level.currentWeather)).ToString() + ")"); } } return stringBuilder.ToString(); } [IteratorStateMachine(typeof(d__15))] private static IEnumerator DelayTravelEffects(orig_TravelToLevelEffects orig, StartOfRound self) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { orig = orig, self = self }; } private static void StartOfRoundOnClientDisconnect(orig_OnClientDisconnect orig, StartOfRound self, ulong clientid) { orig.Invoke(self, clientid); if (((NetworkBehaviour)self).IsServer && self.inShipPhase) { NetworkSingleton.Instance?.HostRebroadcastQueue(); } } private static void StartOfRoundOnClientConnect(orig_OnClientConnect orig, StartOfRound self, ulong clientid) { orig.Invoke(self, clientid); if (((NetworkBehaviour)self).IsServer && self.inShipPhase) { NetworkSingleton.Instance?.HostRebroadcastQueue(); } } private static void StartOfRoundOnChangeLevel(orig_ChangeLevel orig, StartOfRound self, int levelid) { orig.Invoke(self, levelid); if (((NetworkBehaviour)self).IsServer) { ((MonoBehaviour)self).StartCoroutine(DoHotloadSceneStuff(self.currentLevel)); } } [IteratorStateMachine(typeof(d__19))] private static IEnumerator DoHotloadSceneStuff(SelectableLevel level) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { level = level }; } private static void CollectLevels(orig_Awake orig, StartOfRound self) { orig.Invoke(self); if (LethalContent.Moons.IsFrozen) { return; } _ = TerminalRefs.Instance; SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (val.HasDawnInfo()) { continue; } Debuggers.Moons?.Log($"Registering level: {val.PlanetName} with scrap spawn range of: {val.minScrap} and {val.maxScrap}"); NamespacedKey namespacedKey = MoonKeys.GetByReflection(NamespacedKey.NormalizeStringForNamespacedKey(val.PlanetName, CSharpName: true).RemoveEnd("Level")); if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedLevelModName(val, out string modName)) { namespacedKey = NamespacedKey.From(modName, val.PlanetName); } else if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_modded", val.PlanetName); } HashSet tags = new HashSet { DawnLibTags.IsExternal }; CollectLLLTags(val, tags); TerminalNode val2 = null; TerminalNode receiptNode = null; TerminalKeyword nameKeyword = null; CompatibleNoun[] compatibleNouns = TerminalRefs.RouteKeyword.compatibleNouns; foreach (CompatibleNoun val3 in compatibleNouns) { if (val3.result.displayPlanetInfo == val.levelID) { val2 = val3.result; if (val2.terminalOptions.Length > 1) { receiptNode = val2.terminalOptions[1].result; } nameKeyword = val3.noun; break; } } ITerminalPurchasePredicate purchasePredicate = ITerminalPurchasePredicate.AlwaysSuccess(); if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.ExtendedLevelIsModded(val, out object extendedLevelObject)) { purchasePredicate = new LethalLevelLoaderTerminalPredicate(extendedLevelObject); } else if (LethalLevelLoaderCompat.Enabled && DawnConfig.AllowLLLToOverrideVanillaStatus.Value && namespacedKey.Namespace == "lethal_company") { purchasePredicate = new LethalLevelLoaderTerminalPredicate(val); } else if (object.Equals(namespacedKey, MoonKeys.Embrion) || object.Equals(namespacedKey, MoonKeys.Artifice)) { purchasePredicate = new ConstantTerminalPredicate(TerminalPurchaseResult.Hidden().SetFailure(isFailure: false)); } DawnMoonInfo dawnMoonInfo = new DawnMoonInfo(namespacedKey, tags, val, 3f, new List(new <>z__ReadOnlySingleElementList(new VanillaMoonSceneInfo(namespacedKey.AsTyped(), val.sceneName))), val2, receiptNode, nameKeyword, new DawnPurchaseInfo(new SimpleProvider(val2?.itemCost ?? (-1)), purchasePredicate), null); val.SetDawnInfo(dawnMoonInfo); LethalContent.Moons.Register(dawnMoonInfo); } } private static void CollectTestLevel(orig_Awake orig, StartOfRound self) { if (LethalContent.Moons.IsFrozen) { orig.Invoke(self); return; } DawnMoonInfo dawnMoonInfo = new DawnMoonInfo(MoonKeys.Test, new HashSet { DawnLibTags.IsExternal }, self.currentLevel, 3f, new List(), null, null, null, new DawnPurchaseInfo(new SimpleProvider(-1), ITerminalPurchasePredicate.AlwaysHide()), null); self.currentLevel.SetDawnInfo(dawnMoonInfo); LethalContent.Moons.Register(dawnMoonInfo); orig.Invoke(self); } private static void CollectLLLTags(SelectableLevel moon, HashSet tags) { if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetAllTagsWithModNames(moon, out List<(string, string)> allTagsWithModNames)) { tags.AddToList(allTagsWithModNames, Debuggers.Moons, ((Object)moon).name); } } internal static void UpdateAllPrices() { foreach (DawnMoonInfo value in LethalContent.Moons.Values) { if (!value.ShouldSkipRespectOverride()) { UpdateMoonPrice(value); } } } private static void UpdateMoonPrice(DawnMoonInfo moonInfo) { int itemCost = moonInfo.DawnPurchaseInfo.Cost.Provide(); if ((Object)(object)moonInfo.RouteNode != (Object)null) { moonInfo.RouteNode.itemCost = itemCost; } if ((Object)(object)moonInfo.ReceiptNode != (Object)null) { moonInfo.ReceiptNode.itemCost = itemCost; } } } public class DawnMoonInfo : DawnBaseInfo { public SelectableLevel Level { get; } public TerminalNode? RouteNode { get; } public TerminalNode? ReceiptNode { get; } public TerminalKeyword? NameKeyword { get; } public float OutsideEnemiesProbabilityRange { get; private set; } public List Scenes { get; } = new List(); public DawnPurchaseInfo DawnPurchaseInfo { get; } internal DawnMoonInfo(NamespacedKey key, HashSet tags, SelectableLevel level, float outsideEnemiesProbabilityRange, List scenes, TerminalNode? routeNode, TerminalNode? receiptNode, TerminalKeyword? nameKeyword, DawnPurchaseInfo dawnPurchaseInfo, IDataContainer? customData) : base(key, tags, customData) { Level = level; OutsideEnemiesProbabilityRange = outsideEnemiesProbabilityRange; Scenes.AddRange(scenes); RouteNode = routeNode; ReceiptNode = receiptNode; NameKeyword = nameKeyword; DawnPurchaseInfo = dawnPurchaseInfo; } public DawnWeatherEffectInfo? GetCurrentWeather() { //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_000e: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) LevelWeatherType currentWeather = Level.currentWeather; if ((int)currentWeather == -1) { return null; } WeatherEffect weatherEffect = TimeOfDay.Instance.effects[currentWeather]; if (weatherEffect.HasDawnInfo()) { return weatherEffect.GetDawnInfo(); } return null; } public string GetConfigName() { string text = StripSpecialCharacters(Level.PlanetName); if (!text.EndsWith("Level", ignoreCase: true, CultureInfo.InvariantCulture)) { text += "Level"; } return text.ToLowerInvariant(); } public string GetNumberlessPlanetName() { return StripSpecialCharacters(Level.PlanetName); } public void RouteTo() { int num = Array.IndexOf(StartOfRound.Instance.levels, Level); StartOfRound.Instance.ChangeLevelServerRpc(num, TerminalRefs.Instance.groupCredits); } public void ChangeWeatherTo(LevelWeatherType levelWeatherType) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002a: 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_000d: Unknown result type (might be due to invalid IL or missing references) if (WeatherRegistryCompat.Enabled) { WeatherRegistryCompat.SetCurrentWeather(Level, levelWeatherType); return; } EveryoneRpcTarget val = new EveryoneRpcTarget(NetworkManager.Singleton); NetworkSingleton.Instance.ChangeWeatherToRpc(base.Key, levelWeatherType, RpcParams.op_Implicit((BaseRpcTarget)(object)val)); ((BaseRpcTarget)val).Dispose(); } public void ChangeWeatherTo(DawnWeatherEffectInfo weatherEffectInfo) { ChangeWeatherTo((LevelWeatherType)MiscHelpers.IndexOf((IEnumerable)TimeOfDayRefs.Instance.effects, weatherEffectInfo.WeatherEffect)); } private static string StripSpecialCharacters(string input) { string text = string.Empty; for (int i = 0; i < input.Length; i++) { char c = input[i]; if (char.IsLetter(c)) { text += c; } } return text; } } public class MoonGroup { public string GroupName = ""; public List Moons = new List(); } public interface IMoonFilterStep { IEnumerable Filter(IEnumerable input); } public interface IMoonOrderingStep { IOrderedEnumerable ApplyInitial(IEnumerable input, bool reverse = false); IOrderedEnumerable ApplyNext(IOrderedEnumerable input, bool reverse = false); } public interface IMoonGroupingAlgorithm { List Group(IEnumerable input); } public class VisibleFilterStep : IMoonFilterStep { public IEnumerable Filter(IEnumerable input) { return input.Where((DawnMoonInfo moon) => !(moon.DawnPurchaseInfo.PurchasePredicate.CanPurchase() is TerminalPurchaseResult.HiddenPurchaseResult)); } } public class TagFilterStep : IMoonFilterStep { [CompilerGenerated] private NamespacedKey P; public TagFilterStep(NamespacedKey tag) { P = tag; base..ctor(); } public IEnumerable Filter(IEnumerable input) { return input.Where((DawnMoonInfo moon) => moon.HasTag(P)); } } public class FixedGroupSizeGroupingAlgorithm : IMoonGroupingAlgorithm { [CompilerGenerated] private int P; public FixedGroupSizeGroupingAlgorithm(int groupSize = 3) { P = groupSize; base..ctor(); } public List Group(IEnumerable input) { MoonGroup moonGroup = new MoonGroup(); MoonGroup moonGroup2 = new MoonGroup(); List list = new List(1) { moonGroup2 }; int num = 0; foreach (DawnMoonInfo item in input) { if (item.HasTag(Tags.Company)) { moonGroup.Moons.Add(item); continue; } moonGroup2.Moons.Add(item); if (!(item.DawnPurchaseInfo.PurchasePredicate.CanPurchase() is TerminalPurchaseResult.HiddenPurchaseResult)) { num++; } if (num == P) { moonGroup2 = new MoonGroup(); num = 0; list.Add(moonGroup2); } } list.RemoveAll((MoonGroup group) => group.Moons.Count == 0); if (moonGroup.Moons.Count > 0) { list.Insert(0, moonGroup); } return list; } } public class RankOrderingStep : IMoonOrderingStep { private static readonly string[] RiskIndexes = new string[8] { "F", "E", "D", "C", "B", "A", "S", "UNKNOWN" }; public IOrderedEnumerable ApplyInitial(IEnumerable input, bool reverse = false) { if (!reverse) { return input.OrderBy(GetRiskIndex); } return input.OrderByDescending(GetRiskIndex); } public IOrderedEnumerable ApplyNext(IOrderedEnumerable input, bool reverse = false) { if (!reverse) { return input.ThenBy(GetRiskIndex); } return input.ThenByDescending(GetRiskIndex); } private int GetRiskIndex(DawnMoonInfo moonInfo) { string input = moonInfo.Level.riskLevel ?? "UNKNOWN"; input = input.StripSpecialCharacters(); int num = Array.IndexOf(RiskIndexes, input); if (num < 0) { return RiskIndexes.Length - 1; } return num; } } public class PriceOrderingStep : IMoonOrderingStep { public IOrderedEnumerable ApplyInitial(IEnumerable input, bool reverse = false) { if (!reverse) { return input.OrderBy(GetPrice); } return input.OrderByDescending(GetPrice); } public IOrderedEnumerable ApplyNext(IOrderedEnumerable input, bool reverse = false) { if (!reverse) { return input.ThenBy(GetPrice); } return input.ThenByDescending(GetPrice); } private int GetPrice(DawnMoonInfo moonInfo) { return moonInfo.DawnPurchaseInfo.Cost.Provide(); } } public class IndexBasedOrderingStep : IMoonOrderingStep { public IOrderedEnumerable ApplyInitial(IEnumerable input, bool reverse = false) { if (!reverse) { return input.OrderBy(GetIndex); } return input.OrderByDescending(GetIndex); } public IOrderedEnumerable ApplyNext(IOrderedEnumerable input, bool reverse = false) { if (!reverse) { return input.ThenBy(GetIndex); } return input.ThenByDescending(GetIndex); } private int GetIndex(DawnMoonInfo moonInfo) { return LethalContent.Moons.Values.ToList().IndexOf(moonInfo); } } public class MainGroupAlgorithm { public List FilterSteps = new List(1) { new VisibleFilterStep() }; public List OrderingSteps = new List(3) { new RankOrderingStep(), new PriceOrderingStep(), new IndexBasedOrderingStep() }; public IMoonGroupingAlgorithm GroupingAlgorithm = new FixedGroupSizeGroupingAlgorithm(); public List Group(IEnumerable input, bool reverse = false) { IEnumerable enumerable = input; foreach (IMoonFilterStep filterStep in FilterSteps) { enumerable = filterStep.Filter(enumerable); } IOrderedEnumerable orderedEnumerable = null; for (int i = 0; i < OrderingSteps.Count; i++) { IMoonOrderingStep moonOrderingStep = OrderingSteps[i]; orderedEnumerable = ((i == 0) ? moonOrderingStep.ApplyInitial(enumerable, reverse) : moonOrderingStep.ApplyNext(orderedEnumerable, reverse)); } IEnumerable enumerable2 = orderedEnumerable; IEnumerable input2 = enumerable2 ?? enumerable; return GroupingAlgorithm.Group(input2); } } public class MoonInfoBuilder : BaseInfoBuilder { private TerminalNode? _routeNode; private TerminalNode? _receiptNode; private TerminalKeyword? _nameKeyword; private List _scenes = new List(); private IProvider? _costOverride; private ITerminalPurchasePredicate? _purchasePredicate; private float _outsideEnemiesProbabilityRange = 3f; public MoonInfoBuilder(NamespacedKey key, SelectableLevel value) : base(key, value) { } public MoonInfoBuilder OverrideRouteNode(TerminalNode node) { _routeNode = node; return this; } public MoonInfoBuilder CreateNameKeyword(string wordOverride) { if (string.IsNullOrWhiteSpace(wordOverride)) { wordOverride = base.value.PlanetName.ToLowerInvariant().Replace(' ', '-'); } _nameKeyword = new TerminalKeywordBuilder(base.value.PlanetName + "NameKeyword", wordOverride, (DawnKeywordType)3).Build(); _nameKeyword.compatibleNouns = Array.Empty(); return this; } public MoonInfoBuilder AddScene(NamespacedKey sceneKey, AnimationClip shipLandingOverrideAnimation, AnimationClip shipTakeoffOverrideAnimation, ProviderTable weight, string assetBundlePath, string scenePath) { _scenes.Add(new CustomMoonSceneInfo(sceneKey, shipLandingOverrideAnimation, shipTakeoffOverrideAnimation, weight, assetBundlePath, scenePath)); return this; } private static string StripSpecialCharacters(string input) { string text = string.Empty; for (int i = 0; i < input.Length; i++) { char c = input[i]; if (char.IsLetter(c)) { text += c; } } return text; } public MoonInfoBuilder OverrideCost(int cost) { return OverrideCost(new SimpleProvider(cost)); } public MoonInfoBuilder OverrideTimeMultiplier(float multiplier) { base.value.DaySpeedMultiplier = multiplier; return this; } public MoonInfoBuilder OverrideMinMaxScrap(BoundedRange range) { base.value.minScrap = (int)range.Min; base.value.maxScrap = (int)range.Max; return this; } public MoonInfoBuilder OverrideEnemyPowerCount(int maxInsidePowerCount, int maxOutsidePowerCount, int maxDaytimePowerCount) { base.value.maxEnemyPowerCount = maxInsidePowerCount; base.value.maxOutsideEnemyPowerCount = maxOutsidePowerCount; base.value.maxDaytimeEnemyPowerCount = maxDaytimePowerCount; return this; } public MoonInfoBuilder OverrideEnemySpawnCurves(AnimationCurve insideAnimationCurve, AnimationCurve outsideAnimationCurve, AnimationCurve daytimeAnimationCurve) { base.value.enemySpawnChanceThroughoutDay = insideAnimationCurve; base.value.outsideEnemySpawnChanceThroughDay = outsideAnimationCurve; base.value.daytimeEnemySpawnChanceThroughDay = daytimeAnimationCurve; return this; } public MoonInfoBuilder OverrideEnemySpawnRanges(float insideSpawnRange, float outsideSpawnRange, float daytimeSpawnRange) { base.value.spawnProbabilityRange = insideSpawnRange; _outsideEnemiesProbabilityRange = outsideSpawnRange; base.value.daytimeEnemiesProbabilityRange = daytimeSpawnRange; return this; } public MoonInfoBuilder OverrideCost(IProvider cost) { _costOverride = cost; return this; } public MoonInfoBuilder SetPurchasePredicate(ITerminalPurchasePredicate predicate) { _purchasePredicate = predicate; return this; } internal override DawnMoonInfo Build() { if ((Object)(object)_routeNode == (Object)null) { _routeNode = new TerminalNodeBuilder(base.value.PlanetName + "RouteNode").SetDisplayText("The cost to route to " + base.value.PlanetName + " is [totalCost]. It is \ncurrently [currentPlanetTime] on this moon.\n\nPlease CONFIRM or DENY.\n\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(25) .Build(); } if ((Object)(object)_receiptNode == (Object)null) { _receiptNode = new TerminalNodeBuilder(base.value.PlanetName + "RecieptNode").SetDisplayText("Routing autopilot to " + base.value.PlanetName + ".\nYour new balance is [playerCredits].\n\nPlease enjoy your flight.\n\n").SetClearPreviousText(clearPreviousText: true).SetMaxCharactersToType(25) .Build(); } if ((Object)(object)_nameKeyword == (Object)null) { CreateNameKeyword(StripSpecialCharacters(base.value.PlanetName).ToLowerInvariant()); } if (_scenes.Count == 0) { DawnPlugin.Logger.LogError((object)$"Moon: '{base.key}' has 0 scenes."); } if (_purchasePredicate == null) { _purchasePredicate = ITerminalPurchasePredicate.AlwaysSuccess(); } if (_costOverride == null) { _costOverride = new SimpleProvider(_routeNode.itemCost); } return new DawnMoonInfo(base.key, tags, base.value, _outsideEnemiesProbabilityRange, _scenes, _routeNode, _receiptNode, _nameKeyword, new DawnPurchaseInfo(_costOverride, _purchasePredicate), customData); } } public interface IMoonSceneInfo : INamespaced, INamespaced { string SceneName { get; } ProviderTable Weight { get; } } public class VanillaMoonSceneInfo : IMoonSceneInfo, INamespaced, INamespaced { public string SceneName { get; private set; } public ProviderTable Weight { get; private set; } = new WeightTableBuilder().SetGlobalWeight(100).Build(); public NamespacedKey Key => TypedKey; public NamespacedKey TypedKey { get; } internal VanillaMoonSceneInfo(NamespacedKey key, string sceneName) { SceneName = sceneName; TypedKey = key; } public int GetWeight() { return 100; } } public class CustomMoonSceneInfo : IMoonSceneInfo, INamespaced, INamespaced { internal string AssetBundlePath; public string SceneName { get; } public string ScenePath { get; } public ProviderTable Weight { get; private set; } public AnimationClip? ShipLandingOverrideAnimation { get; private set; } public AnimationClip? ShipTakeoffOverrideAnimation { get; private set; } public NamespacedKey Key => TypedKey; public NamespacedKey TypedKey { get; } internal CustomMoonSceneInfo(NamespacedKey key, AnimationClip? shipLandingOverrideAnimation, AnimationClip? shipTakeoffOverrideAnimation, ProviderTable weight, string assetBundlePath, string scenePath) { AssetBundlePath = assetBundlePath; Weight = weight; TypedKey = key; ShipLandingOverrideAnimation = shipLandingOverrideAnimation; ShipTakeoffOverrideAnimation = shipTakeoffOverrideAnimation; ScenePath = scenePath; SceneName = DawnNetworkSceneManager.GetSceneNameFromPath(scenePath); DawnLib.RegisterNetworkScene(scenePath); } } public static class SelectableLevelExtensions { public static DawnMoonInfo GetDawnInfo(this SelectableLevel selectableLevel) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return (DawnMoonInfo)((IDawnObject)selectableLevel).DawnInfo; } internal static bool HasDawnInfo(this SelectableLevel selectableLevel) { return selectableLevel.GetDawnInfo() != null; } internal static void SetDawnInfo(this SelectableLevel level, DawnMoonInfo moonInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)level).DawnInfo = moonInfo; } } public class RegistryFrozenException : Exception { public RegistryFrozenException() : base("Registry is frozen") { } } public class Registry : IReadOnlyDictionary, T>, IEnumerable, T>>, IEnumerable, IReadOnlyCollection, T>> where T : INamespaced { private readonly Dictionary, T> _dictionary = new Dictionary, T>(); public bool IsFrozen { get; private set; } public int Count => _dictionary.Count; public T this[NamespacedKey key] => _dictionary[key]; public IEnumerable> Keys => _dictionary.Keys; public IEnumerable Values => _dictionary.Values; public event Action BeforeFreeze { add { Action value2 = value; _beforeFreeze += delegate { try { value2(); } catch (Exception arg) { DawnPlugin.Logger.LogError((object)$"(BeforeFreeze) An exception occured in firing an event for a registry:\n{arg}"); } }; } remove { DawnPlugin.Logger.LogError((object)"Registry.BeforeFreeze -= is not supported."); } } public event Action OnFreeze { add { Action value2 = value; _onFreeze += delegate { try { value2(); } catch (Exception arg) { DawnPlugin.Logger.LogError((object)$"(OnFreeze) An exception occured in firing an event for a registry:\n{arg}"); } }; } remove { DawnPlugin.Logger.LogError((object)"Registry.OnFreeze -= is not supported."); } } public event Action _onFreeze = delegate { }; public event Action _beforeFreeze = delegate { }; internal virtual void Freeze() { if (IsFrozen) { throw new RegistryFrozenException(); } this._beforeFreeze(); IsFrozen = true; foreach (T value in Values) { if ((object)value is IRegistryEvents registryEvents) { registryEvents.OnFrozen(); } } this._onFreeze(); } internal virtual void Register(T value) { if (IsFrozen) { throw new RegistryFrozenException(); } NamespacedKey typedKey = value.TypedKey; if (ContainsKey(typedKey)) { throw new ArgumentException($"'{typedKey}' has already been added to this registry."); } _dictionary[typedKey] = value; } public IEnumerator, T>> GetEnumerator() { return _dictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool ContainsKey(NamespacedKey key) { return _dictionary.ContainsKey(key); } public bool TryGetValue(NamespacedKey key, out T value) { return _dictionary.TryGetValue(key, out value); } public bool TryGetValue(NamespacedKey key, out T value) { return TryGetValue(key.AsTyped(), out value); } } public interface IRegistryEvents { void OnFrozen(); } internal static class StoryLogRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Start <0>__CollectAllStoryLogs; public static hook_Start <1>__RegisterStoryLogs; } private static List _networkPrefabStoryLogTypes = new List(); internal static void Init() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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_0026: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown DetourContext val = new DetourContext(int.MaxValue); try { object obj = <>O.<0>__CollectAllStoryLogs; if (obj == null) { hook_Start val2 = CollectAllStoryLogs; <>O.<0>__CollectAllStoryLogs = val2; obj = (object)val2; } GameNetworkManager.Start += (hook_Start)obj; } finally { ((IDisposable)val)?.Dispose(); } object obj2 = <>O.<1>__RegisterStoryLogs; if (obj2 == null) { hook_Start val3 = RegisterStoryLogs; <>O.<1>__RegisterStoryLogs = val3; obj2 = (object)val3; } Terminal.Start += (hook_Start)obj2; } private static void RegisterStoryLogs(orig_Start orig, Terminal self) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown orig.Invoke(self); _ = TerminalRefs.Instance; List list = TerminalRefs.ViewKeyword.compatibleNouns.ToList(); List list2 = TerminalRefs.Instance.terminalNodes.allKeywords.ToList(); foreach (DawnStoryLogInfo value2 in LethalContent.StoryLogs.Values) { if (!value2.ShouldSkipIgnoreOverride()) { self.logEntryFiles.Add(value2.StoryLogTerminalNode); if (!LethalContent.StoryLogs.IsFrozen) { value2.StoryLogTerminalKeyword.defaultVerb = TerminalRefs.ViewKeyword; int num = self.logEntryFiles.Count - 1; value2.StoryLogGameObject.GetComponent().SetStoryLogID(num); value2.StoryLogTerminalNode.storyLogFileID = num; CompatibleNoun item = new CompatibleNoun(value2.StoryLogTerminalKeyword, value2.StoryLogTerminalNode); list.Add(item); list2.Add(value2.StoryLogTerminalKeyword); } } } if (LethalContent.StoryLogs.IsFrozen) { return; } TerminalRefs.Instance.terminalNodes.allKeywords = list2.ToArray(); TerminalRefs.ViewKeyword.compatibleNouns = list.ToArray(); foreach (CompatibleNoun item2 in TerminalRefs.ViewKeyword.compatibleNouns.Where((CompatibleNoun x) => (Object)(object)x.result != (Object)null && x.result.storyLogFileID > -1)) { string name = NamespacedKey.NormalizeStringForNamespacedKey(item2.result.creatureName, CSharpName: true); NamespacedKey namespacedKey = StoryLogKeys.GetByReflection(name); if (namespacedKey == null) { namespacedKey = NamespacedKey.From("unknown_lib", item2.result.creatureName); } if (LethalContent.StoryLogs.ContainsKey(namespacedKey)) { DawnPlugin.Logger.LogWarning((object)("StoryLog " + item2.result.creatureName + " is already registered by the same creator to LethalContent. This is likely to cause issues.")); continue; } GameObject storyLogGameObject = null; foreach (GameObject networkPrefabStoryLogType in _networkPrefabStoryLogTypes) { if (networkPrefabStoryLogType.GetComponent().storyLogID == item2.result.storyLogFileID) { storyLogGameObject = networkPrefabStoryLogType; break; } } DawnStoryLogInfo value = new DawnStoryLogInfo(namespacedKey, new HashSet { DawnLibTags.IsExternal }, storyLogGameObject, item2.result, item2.noun, null); LethalContent.StoryLogs.Register(value); } LethalContent.StoryLogs.Freeze(); } private static void CollectAllStoryLogs(orig_Start orig, GameNetworkManager self) { orig.Invoke(self); StoryLog val = default(StoryLog); foreach (NetworkPrefab prefab in NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs) { if (prefab.Prefab.TryGetComponent(ref val) && !_networkPrefabStoryLogTypes.Contains(prefab.Prefab)) { _networkPrefabStoryLogTypes.Add(prefab.Prefab); } } } } public sealed class DawnStoryLogInfo : DawnBaseInfo { public GameObject? StoryLogGameObject { get; } public TerminalNode StoryLogTerminalNode { get; } public TerminalKeyword StoryLogTerminalKeyword { get; } internal DawnStoryLogInfo(NamespacedKey key, HashSet tags, GameObject? storyLogGameObject, TerminalNode storyLogTerminalNode, TerminalKeyword storyLogTerminalKeyword, IDataContainer? customData) : base(key, tags, customData) { StoryLogGameObject = storyLogGameObject; StoryLogTerminalNode = storyLogTerminalNode; StoryLogTerminalKeyword = storyLogTerminalKeyword; } } public class StoryLogInfoBuilder : BaseInfoBuilder { private TerminalNode? _storyLogTerminalNode; private string _storyLogTitle; private string _storyLogKeyword; private string _storyLogDescription = "The developer of this story log left this empty!"; public StoryLogInfoBuilder(NamespacedKey key, GameObject value) : base(key, value) { } public StoryLogInfoBuilder OverrideTerminalNode(TerminalNode? terminalNode) { _storyLogTerminalNode = terminalNode; return this; } public StoryLogInfoBuilder SetDescription(string description) { _storyLogDescription = description; return this; } public StoryLogInfoBuilder SetTitle(string title) { _storyLogTitle = title; return this; } public StoryLogInfoBuilder SetKeyword(string keyword) { _storyLogKeyword = keyword.ToLowerInvariant(); return this; } internal override DawnStoryLogInfo Build() { if ((Object)(object)_storyLogTerminalNode == (Object)null) { _storyLogTerminalNode = new TerminalNodeBuilder($"{base.key}TerminalNode").SetClearPreviousText(clearPreviousText: true).SetCreatureName(_storyLogTitle).SetMaxCharactersToType(35) .SetDisplayText(_storyLogDescription) .Build(); } if (string.IsNullOrEmpty(_storyLogKeyword)) { DawnPlugin.Logger.LogWarning((object)$"StoryLog: '{base.key}' didn't set keyword, please call .SetKeyword on the builder."); } TerminalKeyword storyLogTerminalKeyword = new TerminalKeywordBuilder($"{base.key}TerminalKeyword", _storyLogKeyword, (DawnKeywordType)7).Build(); return new DawnStoryLogInfo(base.key, tags, base.value, _storyLogTerminalNode, storyLogTerminalKeyword, customData); } } [HarmonyPatch] internal static class SurfaceRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__RegisterDawnSurfaces; public static Manipulator <1>__PlayerGetCurrentMaterialStandingOn; public static Manipulator <2>__EditGravityDirection; public static Manipulator <3>__EditFallValueForGravity; public static Manipulator <4>__EditUncappedFallValueForGravity; public static Manipulator <5>__AllowCustomSurfacesInQuicksand; public static Manipulator <6>__AllowEmergingAtCustomSurfaces; public static UnityAction <7>__OnVowOrMarchLoaded; public static UnityAction <8>__TryFixMoonTerrainFootsteps; public static hook_Start <9>__AddCrouchingFootsteps; public static Action, PlayerAnimationEvents> <10>__PlayCrouchFootstepSound; } private static readonly List CrouchingAnimationEvents = new List { new AnimationEventData { AnimationEventName = "PlayCrouchFootstepSound", Time = 0.33f }, new AnimationEventData { AnimationEventName = "PlayCrouchFootstepSound", Time = 0.66f } }; private static bool addedCrouchingSteps = false; internal static void Init() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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_0026: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //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 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00a7: 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_00b2: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown DetourContext val = new DetourContext(int.MaxValue); try { object obj = <>O.<0>__RegisterDawnSurfaces; if (obj == null) { hook_Awake val2 = RegisterDawnSurfaces; <>O.<0>__RegisterDawnSurfaces = val2; obj = (object)val2; } StartOfRound.Awake += (hook_Awake)obj; } finally { ((IDisposable)val)?.Dispose(); } object obj2 = <>O.<1>__PlayerGetCurrentMaterialStandingOn; if (obj2 == null) { Manipulator val3 = PlayerGetCurrentMaterialStandingOn; <>O.<1>__PlayerGetCurrentMaterialStandingOn = val3; obj2 = (object)val3; } PlayerControllerB.GetCurrentMaterialStandingOn += (Manipulator)obj2; object obj3 = <>O.<2>__EditGravityDirection; if (obj3 == null) { Manipulator val4 = EditGravityDirection; <>O.<2>__EditGravityDirection = val4; obj3 = (object)val4; } PlayerControllerB.Update += (Manipulator)obj3; object obj4 = <>O.<3>__EditFallValueForGravity; if (obj4 == null) { Manipulator val5 = EditFallValueForGravity; <>O.<3>__EditFallValueForGravity = val5; obj4 = (object)val5; } PlayerControllerB.Update += (Manipulator)obj4; object obj5 = <>O.<4>__EditUncappedFallValueForGravity; if (obj5 == null) { Manipulator val6 = EditUncappedFallValueForGravity; <>O.<4>__EditUncappedFallValueForGravity = val6; obj5 = (object)val6; } PlayerControllerB.Update += (Manipulator)obj5; PlayerControllerB.PlayFootstepSound += EditFootstepSound(typeof(PlayerControllerB)); MaskedPlayerEnemy.PlayFootstepSound += EditFootstepSound(typeof(MaskedPlayerEnemy)); object obj6 = <>O.<5>__AllowCustomSurfacesInQuicksand; if (obj6 == null) { Manipulator val7 = AllowCustomSurfacesInQuicksand; <>O.<5>__AllowCustomSurfacesInQuicksand = val7; obj6 = (object)val7; } PlayerControllerB.CheckConditionsForSinkingInQuicksand += (Manipulator)obj6; object obj7 = <>O.<6>__AllowEmergingAtCustomSurfaces; if (obj7 == null) { Manipulator val8 = AllowEmergingAtCustomSurfaces; <>O.<6>__AllowEmergingAtCustomSurfaces = val8; obj7 = (object)val8; } SandWormAI.StartEmergeAnimation += (Manipulator)obj7; SceneManager.sceneLoaded += OnVowOrMarchLoaded; SceneManager.sceneLoaded += TryFixMoonTerrainFootsteps; object obj8 = <>O.<9>__AddCrouchingFootsteps; if (obj8 == null) { hook_Start val9 = AddCrouchingFootsteps; <>O.<9>__AddCrouchingFootsteps = val9; obj8 = (object)val9; } PlayerControllerB.Start += (hook_Start)obj8; DawnPlugin.Hooks.Add(new Hook((MethodBase)AccessTools.DeclaredMethod(typeof(PlayerAnimationEvents), "PlayCrouchFootstepSound", (Type[])null, (Type[])null), (Delegate)new Action, PlayerAnimationEvents>(PlayCrouchFootstepSound))); } private static void PlayCrouchFootstepSound(Action orig, PlayerAnimationEvents self) { PlayerControllerB thisPlayerController = self.thisPlayerController; if (thisPlayerController.isClimbingLadder || thisPlayerController.inSpecialInteractAnimation) { orig.Invoke(self); return; } if ((((NetworkBehaviour)thisPlayerController).IsOwner && thisPlayerController.slipperyFloor > 0.5f) || (!((NetworkBehaviour)thisPlayerController).IsOwner && thisPlayerController.slimeSlipAudioVolumeSync > 0f)) { thisPlayerController.currentFootstepSurfaceIndex = 12; } else { thisPlayerController.GetCurrentMaterialStandingOn(false); } DawnSurfaceInfo dawnInfo = StartOfRound.Instance.footstepSurfaces[thisPlayerController.currentFootstepSurfaceIndex].GetDawnInfo(); if (dawnInfo == null || dawnInfo.CrouchClips == null || dawnInfo.CrouchClips.Count == 0) { orig.Invoke(self); return; } int num = Random.Range(0, dawnInfo.CrouchClips.Count); if (num == thisPlayerController.previousFootstepClip) { num = (num + 1) % dawnInfo.CrouchClips.Count; } thisPlayerController.movementAudio.pitch = Random.Range(0.93f, 1.07f); float num2 = 0.3f; num2 *= dawnInfo.Volume; thisPlayerController.movementAudio.PlayOneShot(dawnInfo.CrouchClips[num], num2); thisPlayerController.previousFootstepClip = num; WalkieTalkie.TransmitOneShotAudio(thisPlayerController.movementAudio, dawnInfo.CrouchClips[num], num2); orig.Invoke(self); } private static void AddCrouchingFootsteps(orig_Start orig, PlayerControllerB self) { //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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown orig.Invoke(self); if (addedCrouchingSteps) { return; } addedCrouchingSteps = true; AnimationClip val = null; AnimationClip[] animationClips = self.playerBodyAnimator.runtimeAnimatorController.animationClips; foreach (AnimationClip val2 in animationClips) { if (((Object)val2).name == "CrouchWalk") { val = val2; break; } } foreach (AnimationEventData crouchingAnimationEvent in CrouchingAnimationEvents) { AnimationEvent val3 = new AnimationEvent { functionName = crouchingAnimationEvent.AnimationEventName, time = crouchingAnimationEvent.Time }; val.AddEvent(val3); } } private static Manipulator EditFootstepSound(Type type) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Type type2 = type; return (Manipulator)delegate(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0143: 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) ILCursor val = new ILCursor(il); int location = -1; if (!val.TryGotoNext((MoveType)0, new Func[6] { (Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref location), (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0), (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, type2, "movementAudio"), (Instruction i) => ILPatternMatchingExt.MatchCall(i, "get_Instance"), (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, "footstepSurfaces"), (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0) })) { DawnPlugin.Logger.LogWarning((object)("Failed to apply " + type2.Name + ".PlayFootstepSound patch (0)!")); } else { val.GotoNext((MoveType)2, new Func[1] { (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0) }); val.EmitLdfld(type2, "currentFootstepSurfaceIndex"); val.Emit(OpCodes.Ldloca, location); val.EmitDelegate<<>A{00000008}>((<>A{00000008})delegate(int currentFootstepSurfaceIndex, ref float volume) { FootstepSurface surface = StartOfRound.Instance.footstepSurfaces[currentFootstepSurfaceIndex]; DawnSurfaceInfo dawnInfo = surface.GetDawnInfo(); if (dawnInfo != null) { volume *= dawnInfo.Volume; } }); val.Emit(OpCodes.Ldarg_0); } }; } private static void AllowEmergingAtCustomSurfaces(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel val3 = default(ILLabel); if (!val.TryGotoNext((MoveType)0, new Func[5] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 2), (Instruction i) => ILPatternMatchingExt.MatchBrfalse(i, ref val3), (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 5), (Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 1), (Instruction i) => ILPatternMatchingExt.MatchAdd(i) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply SandWormAI.StartEmergeAnimation patch (0)!"); return; } ILLabel val2 = val.DefineLabel(); val.MarkLabel(val2); if (!val.TryGotoPrev((MoveType)0, new Func[4] { (Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 0), (Instruction i) => ILPatternMatchingExt.MatchStloc(i, 2), (Instruction i) => ILPatternMatchingExt.MatchCall(i, "get_activeTerrain"), (Instruction i) => ILPatternMatchingExt.MatchLdnull(i) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply SandWormAI.StartEmergeAnimation patch (1)!"); return; } val.Emit(OpCodes.Ldloc_1); val.Emit(OpCodes.Ldloca, 2); val.EmitDelegate<<>F{00000008}>((<>F{00000008})delegate(RaycastHit hit, ref bool flag) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) DawnSurface dawnSurface = default(DawnSurface); if (!((Component)((RaycastHit)(ref hit)).collider).TryGetComponent(ref dawnSurface)) { return false; } if (!dawnSurface.TryGetFootstepIndex(((RaycastHit)(ref hit)).point, checkStandingOnTerrain: true, out var footstepIndex) || footstepIndex == -1) { return false; } DawnSurfaceInfo dawnSurfaceInfo = null; foreach (DawnSurfaceInfo value in LethalContent.Surfaces.Values) { if (value.SurfaceIndex == footstepIndex) { dawnSurfaceInfo = value; break; } } if (dawnSurfaceInfo == null) { return false; } if (StartOfRoundRefs.Instance.currentLevel.GetDawnInfo() == LethalContent.Moons[MoonKeys.Embrion] && dawnSurfaceInfo == LethalContent.Surfaces[SurfaceKeys.Rock]) { flag = true; return true; } if (dawnSurfaceInfo.IsNatural) { flag = true; return true; } return true; }); val.Emit(OpCodes.Brtrue_S, (object)val2); } private static void AllowCustomSurfacesInQuicksand(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00a9: 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_00fb: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel branchLabel = null; if (!val.TryGotoNext((MoveType)0, new Func[4] { (Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0), (Instruction i) => ILPatternMatchingExt.MatchLdfld(i, "currentFootstepSurfaceIndex"), (Instruction i) => ILPatternMatchingExt.MatchLdcI4(i, 1), (Instruction i) => ILPatternMatchingExt.MatchBeq(i, ref branchLabel) })) { DawnPlugin.Logger.LogWarning((object)"Failed to apply PlayerControllerB.CheckConditionsForSinkingInQuicksand patch (0)!"); return; } val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerControllerB), "currentFootstepSurfaceIndex")); val.EmitDelegate>((Func)delegate(int currentFootstepSurfaceIndex) { foreach (DawnSurfaceInfo value in LethalContent.Surfaces.Values) { if (!value.ShouldSkipIgnoreOverride() && value.SurfaceIndex == currentFootstepSurfaceIndex) { if (value.QuicksandCompatible) { return true; } return false; } } return false; }); val.Emit(OpCodes.Brtrue_S, (object)branchLabel); } private static void TryFixMoonTerrainFootsteps(Scene arg0, LoadSceneMode arg1) { if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null) { return; } if (LethalLevelLoaderCompat.Enabled && Version.Parse("1.6.9") < Chainloader.PluginInfos["imabatby.lethallevelloader"].Metadata.Version) { SceneManager.sceneLoaded -= TryFixMoonTerrainFootsteps; return; } DawnMoonInfo dawnInfo = StartOfRound.Instance.currentLevel.GetDawnInfo(); if (dawnInfo == null || dawnInfo.TypedKey.IsVanilla()) { return; } Terrain[] activeTerrains = Terrain.activeTerrains; DawnSurface dawnSurface = default(DawnSurface); foreach (Terrain val in activeTerrains) { TerrainData terrainData = val.terrainData; int num = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight).Length / (terrainData.alphamapWidth * terrainData.alphamapHeight); if (num == 0) { break; } if (((Component)val).CompareTag("Untagged")) { continue; } if (((Component)val).TryGetComponent(ref dawnSurface)) { break; } dawnSurface = ((Component)val).gameObject.AddComponent(); foreach (DawnSurfaceInfo value in LethalContent.Surfaces.Values) { if (value.Surface.surfaceTag.Equals(((Component)val).tag, StringComparison.OrdinalIgnoreCase)) { for (int j = 0; j < num; j++) { dawnSurface.NamespacedKeysForTerrain.Add(value.Key); } } } } } private static void OnVowOrMarchLoaded(Scene arg0, LoadSceneMode arg1) { if (!((Object)(object)StartOfRound.Instance == (Object)null)) { SelectableLevel currentLevel = RoundManager.Instance.currentLevel; if ((Object)(object)currentLevel == (Object)(object)LethalContent.Moons[MoonKeys.March].Level) { GameObject gameObject = ((Component)GameObject.FindGameObjectWithTag("OutsideLevelNavMesh").transform.Find("Map/MarchTerrainNew")).gameObject; DawnSurface dawnSurface = gameObject.AddComponent(); dawnSurface.NamespacedKeysForTerrain.AddRange(new <>z__ReadOnlyArray(new NamespacedKey[3] { SurfaceKeys.Grass, SurfaceKeys.Rock, SurfaceKeys.Gravel })); } else if ((Object)(object)currentLevel == (Object)(object)LethalContent.Moons[MoonKeys.Vow].Level) { GameObject gameObject2 = ((Component)GameObject.FindGameObjectWithTag("OutsideLevelNavMesh").transform.Find("VowTerrain")).gameObject; DawnSurface dawnSurface2 = gameObject2.AddComponent(); dawnSurface2.NamespacedKeysForTerrain.AddRange(new <>z__ReadOnlyArray(new NamespacedKey[3] { SurfaceKeys.Grass, SurfaceKeys.Gravel, SurfaceKeys.Rock })); } } } private static void PlayerGetCurrentMaterialStandingOn(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel val3 = default(ILLabel); if (!val.TryGotoNext((MoveType)2, new Func[5] { (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, (MethodBase)AccessTools.Method(typeof(StartOfRound), "get_Instance", (Type[])null, (Type[])null)), (Instruction instr) => ILPatternMatchingExt.MatchLdfld(instr, AccessTools.Field(typeof(StartOfRound), "walkableSurfacesMask")), (Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 1), (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, (MethodBase)AccessTools.Method(typeof(Physics), "Raycast", new Type[5] { typeof(Ray), typeof(RaycastHit).MakeByRefType(), typeof(float), typeof(int), typeof(QueryTriggerInteraction) }, (Type[])null)), (Instruction instr) => ILPatternMatchingExt.MatchBrfalse(instr, ref val3) })) { DawnPlugin.Logger.LogError((object)"Couldn't match GameNetcodeStuff.PlayerControllerB.GetCurrentMaterialStandingOn IL."); return; } ILLabel val2 = val.DefineLabel(); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.Emit(OpCodes.Ldarg_0); val.EmitLdflda("hit"); val.Emit(OpCodes.Ldarg_0); val.EmitLdflda("currentFootstepSurfaceIndex"); val.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(SurfaceRegistrationHandler), "TryGetAndSetDawnSurfaceIndexPlayer", (Type[])null, (Type[])null)); val.Emit(OpCodes.Brfalse, (object)val2); val.Emit(OpCodes.Ret); val.MarkLabel(val2); } private static void EditUncappedFallValueForGravity(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[6] { (Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0), (Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0), (Instruction instr) => ILPatternMatchingExt.MatchLdfld(instr, "fallValueUncapped"), (Instruction instr) => ILPatternMatchingExt.MatchLdcR4(instr, 26f), (Instruction instr) => ILPatternMatchingExt.MatchCall