Decompiled source of DungeonGenerationPlus v1.2.0
DunGenPlus.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using DunGen.Adapters; using DunGen.Graph; using DunGenPlus.Attributes; using DunGenPlus.Collections; using DunGenPlus.Components; using DunGenPlus.Components.DoorwayCleanupScripting; using DunGenPlus.Components.Props; using DunGenPlus.Components.Scrap; using DunGenPlus.DevTools; using DunGenPlus.DevTools.HoverUI; using DunGenPlus.DevTools.Panels; using DunGenPlus.DevTools.Panels.Collections; using DunGenPlus.DevTools.UIElements; using DunGenPlus.DevTools.UIElements.Collections; using DunGenPlus.Generation; using DunGenPlus.Managers; using DunGenPlus.Patches; using DunGenPlus.Utils; using HarmonyLib; using LethalLevelLoader; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DunGenPlus")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DunGenPlus")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("13cde60e-1975-463b-9da1-ccb3f3ebabd8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] namespace DunGenPlus { public class API { public static bool AddDunGenExtender(DungeonFlow dungeonFlow, DunGenExtender dunGenExtender) { if ((Object)(object)dungeonFlow == (Object)null) { Plugin.logger.LogError((object)"dungeonFlow was null"); return false; } if (ContainsDungeonFlow(dungeonFlow)) { Plugin.logger.LogWarning((object)("Already contains DunGenExtender asset for " + ((Object)dungeonFlow).name)); return false; } Plugin.DunGenExtenders.Add(dungeonFlow, dunGenExtender); Plugin.logger.LogInfo((object)("Added DunGenExtender asset for " + ((Object)dungeonFlow).name)); return true; } public static bool AddDunGenExtender(DunGenExtender dunGenExtender) { if ((Object)(object)dunGenExtender == (Object)null) { Plugin.logger.LogError((object)"dunGenExtender was null"); return false; } return AddDunGenExtender(dunGenExtender.DungeonFlow, dunGenExtender); } public static bool ContainsDungeonFlow(DungeonFlow dungeonFlow) { return Plugin.DunGenExtenders.ContainsKey(dungeonFlow); } public static bool ContainsDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow) { if ((Object)(object)extendedDungeonFlow == (Object)null) { return false; } return ContainsDungeonFlow(extendedDungeonFlow.DungeonFlow); } public static DunGenExtender GetDunGenExtender(DungeonFlow dungeonFlow) { if (Plugin.DunGenExtenders.TryGetValue(dungeonFlow, out var value)) { return value; } return null; } public static DunGenExtender CreateDunGenExtender(DungeonFlow dungeonFlow) { DunGenExtender dunGenExtender = ScriptableObject.CreateInstance<DunGenExtender>(); dunGenExtender.DungeonFlow = dungeonFlow; return dunGenExtender; } } internal class Assets { public static AssetBundle MainAssetBundle; public static GameObject DevDebugPrefab; public static void LoadAssets() { string[] files = Directory.GetFiles(Paths.PluginPath, "*.lethalbundle", SearchOption.AllDirectories); foreach (string fileName in files) { FileInfo fileInfo = new FileInfo(fileName); AssetBundleLoader.AddOnLethalBundleLoadedListener((Action<AssetBundle>)AutoAddLethalBundle, fileInfo.Name); } } private static void AutoAddLethalBundle(AssetBundle assetBundle) { if (!assetBundle.isStreamedSceneAssetBundle) { DunGenExtender[] array = assetBundle.LoadAllAssets<DunGenExtender>(); ExtendedContent[] array2 = assetBundle.LoadAllAssets<ExtendedContent>(); if (array2.Length == 0 && array.Length != 0) { Plugin.logger.LogWarning((object)".lethalbundle does not contain any ExtendedContent. Unless you are manually creating and adding your ExtendedDungeonFlow with code, the DunGenExtender will probably not work."); } DunGenExtender[] array3 = array; foreach (DunGenExtender dunGenExtender in array3) { API.AddDunGenExtender(dunGenExtender); } } } public static T Load<T>(string name, bool onlyReportErrors = true) where T : Object { if ((Object)(object)MainAssetBundle == (Object)null) { Plugin.logger.LogError((object)"Trying to load in asset but asset bundle is missing"); return default(T); } T val = MainAssetBundle.LoadAsset<T>(name); bool flag = (Object)(object)val == (Object)null; if (flag || onlyReportErrors) { Plugin.logger.LogDebug((object)("Loading asset " + name)); } if (flag) { Plugin.logger.LogError((object)"...but it was not found"); } return val; } public static void LoadAssetBundle() { if ((Object)(object)MainAssetBundle == (Object)null) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); if (manifestResourceNames.Length >= 1) { string text = manifestResourceNames[0]; using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text); Plugin.logger.LogDebug((object)("Loading resource " + text)); MainAssetBundle = AssetBundle.LoadFromStream(stream); } } DevDebugPrefab = Assets.Load<GameObject>("DevDebug", onlyReportErrors: true); } } [Serializable] public class PropertyOverride<T> { [Tooltip("If false, use the value found in DungeonFlow. If true, use this Value instead.")] public bool Override; public T Value; public PropertyOverride(bool _override, T value) { Override = _override; Value = value; } } [CreateAssetMenu(fileName = "Main Path Extender", menuName = "DunGenExtender/Main Path Extender", order = 2)] public class MainPathExtender : ScriptableObject { public PropertyOverride<IntRange> Length = new PropertyOverride<IntRange>(_override: false, new IntRange(5, 10)); public PropertyOverride<BranchMode> BranchMode = new PropertyOverride<BranchMode>(_override: false, (BranchMode)0); public PropertyOverride<IntRange> BranchCount = new PropertyOverride<IntRange>(_override: false, new IntRange(1, 5)); public PropertyOverride<List<GraphNode>> Nodes = new PropertyOverride<List<GraphNode>>(_override: false, new List<GraphNode>()); public PropertyOverride<List<GraphLine>> Lines = new PropertyOverride<List<GraphLine>>(_override: false, new List<GraphLine>()); [Header("DEV ONLY: DON'T TOUCH")] [ReadOnly] public string Version = "0"; public static IntRange GetLength(MainPathExtender extender, DungeonFlow flow) { if (Object.op_Implicit((Object)(object)extender) && extender.Length.Override) { return extender.Length.Value; } return flow.Length; } public static BranchMode GetBranchMode(MainPathExtender extender, DungeonFlow flow) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)extender) && extender.BranchMode.Override) { return extender.BranchMode.Value; } return flow.BranchMode; } public static IntRange GetBranchCount(MainPathExtender extender, DungeonFlow flow) { if (Object.op_Implicit((Object)(object)extender) && extender.BranchCount.Override) { return extender.BranchCount.Value; } return flow.BranchCount; } public static List<GraphNode> GetNodes(MainPathExtender extender, DungeonFlow flow) { if (Object.op_Implicit((Object)(object)extender) && extender.Nodes.Override) { return extender.Nodes.Value; } return flow.Nodes; } public static List<GraphLine> GetLines(MainPathExtender extender, DungeonFlow flow) { if (Object.op_Implicit((Object)(object)extender) && extender.Lines.Override) { return extender.Lines.Value; } return flow.Lines; } } internal class PluginConfig { public static ConfigEntry<bool> EnableDevDebugTools; public static void SetupConfig(ConfigFile cfg) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown EnableDevDebugTools = cfg.Bind<bool>(new ConfigDefinition("Dev", "Enable Dev Debug Tools"), false, new ConfigDescription("If enabled, allows the dev debug tools to be usable in the ship.\n\nPress LeftAlt + M to activate.", (AcceptableValueBase)null, Array.Empty<object>())); } } [CreateAssetMenu(fileName = "DunGen Extender", menuName = "DunGenExtender/DunGen Extender", order = 1)] public class DunGenExtender : ScriptableObject { [Tooltip("DunGenExtender will only influence this DungeonFlow")] public DungeonFlow DungeonFlow; public DunGenExtenderProperties Properties = new DunGenExtenderProperties(); public DunGenExtenderEvents Events = new DunGenExtenderEvents(); [Header("DEV ONLY: DON'T TOUCH")] [ReadOnly] public string Version = CURRENT_VERSION; internal bool Active = true; public static readonly string CURRENT_VERSION = "1"; public void OnValidate() { if (Version == "0") { Properties.AdditionalTilesProperties.CopyFrom(Properties.ForcedTilesProperties); Version = "1"; } } } [BepInPlugin("dev.ladyalice.dungenplus", "Dungeon Generation Plus", "1.2.0")] [BepInDependency("imabatby.lethallevelloader", "1.2.0.3")] [BepInProcess("Lethal Company.exe")] public class Plugin : BaseUnityPlugin { internal const string modGUID = "dev.ladyalice.dungenplus"; private const string modName = "Dungeon Generation Plus"; private const string modVersion = "1.2.0"; internal readonly Harmony Harmony = new Harmony("dev.ladyalice.dungenplus"); internal static Dictionary<DungeonFlow, DunGenExtender> DunGenExtenders = new Dictionary<DungeonFlow, DunGenExtender>(); internal static Plugin Instance { get; private set; } internal static ManualLogSource logger { get; private set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("dev.ladyalice.dungenplus"); logger.LogInfo((object)"Plugin Dungeon Generation Plus has been added!"); PluginConfig.SetupConfig(((BaseUnityPlugin)this).Config); Harmony.PatchAll(typeof(DungeonGeneratorPatch)); Harmony.PatchAll(typeof(DoorwayConnectionPatch)); Harmony.PatchAll(typeof(RoundManagerPatch)); try { Harmony.PatchAll(typeof(LethalLevelLoaderPatches)); } catch (Exception ex) { logger.LogError((object)"Failed to patch LLL for dev debug. You can ignore this."); logger.LogError((object)ex); } Assets.LoadAssets(); Assets.LoadAssetBundle(); DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.AddListener((ParameterEvent<RoundManager>)OnDunGenExtenderLoad); DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction); } private void OnDunGenExtenderLoad(RoundManager roundManager) { DunGenPlusGenerator.Deactivate(); DungeonGenerator generator = roundManager.dungeonGenerator.Generator; DungeonFlow dungeonFlow = generator.DungeonFlow; DunGenExtender dunGenExtender = API.GetDunGenExtender(dungeonFlow); if (Object.op_Implicit((Object)(object)dunGenExtender) && dunGenExtender.Active) { logger.LogInfo((object)("Loading DunGenExtender for " + ((Object)dungeonFlow).name)); DunGenPlusGenerator.Activate(generator, dunGenExtender); } else { logger.LogInfo((object)"Did not load a DunGenExtenderer"); DunGenPlusGenerator.Deactivate(); } } } } namespace DunGenPlus.Utils { internal class InjectionDictionary { public string name; public List<CodeInstruction> instructions; public CodeInstruction[] injections; private int counter; public InjectionDictionary(string name, MethodInfo methodInjection, params CodeInstruction[] instructions) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown this.name = name; injections = (CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)methodInjection) }; this.instructions = instructions.ToList(); } public InjectionDictionary(string name, CodeInstruction[] codeInjections, params CodeInstruction[] instructions) { this.name = name; injections = codeInjections; this.instructions = instructions.ToList(); } public void ResetCounter() { counter = 0; } public void AddCounter() { counter++; } public void Report(string debugFunction, int? expectedCounter) { if (counter == 0) { Plugin.logger.LogError((object)(debugFunction + " could not inject " + name + ". Probably scary")); } else if (!expectedCounter.HasValue) { Plugin.logger.LogDebug((object)$"{debugFunction} inject {name} {counter} time(s)"); } else if (expectedCounter.Value != counter) { Plugin.logger.LogWarning((object)$"{debugFunction} inject {name} {counter} time(s) (Expected {expectedCounter.Value}). Probably not an error but be warned"); } } } internal abstract class InstructionSequence { protected enum AdvanceResult { Failed, Advanced, Finished } protected List<Func<CodeInstruction, bool>> seq; protected string name; protected string extraErrorMessage; protected int stage; protected bool completed; protected bool single; public InstructionSequence(string name, bool single = true, string extraErrorMessage = null) { seq = new List<Func<CodeInstruction, bool>>(); stage = 0; completed = false; this.name = name; this.single = single; this.extraErrorMessage = extraErrorMessage; } public void Add(Func<CodeInstruction, bool> next) { seq.Add(next); } public void AddBasic(OpCode opcode) { seq.Add((CodeInstruction i) => i.opcode == opcode); } public void AddBasic(OpCode opcode, object operand) { seq.Add((CodeInstruction i) => i.opcode == opcode && i.operand == operand); } public void AddBasicLocal(OpCode opcode, int operand) { seq.Add((CodeInstruction i) => i.opcode == opcode && (i.operand as LocalBuilder).LocalIndex == operand); } public void AddAny() { seq.Add(null); } public void AddOperandTypeCheck(OpCode opcode, Type operandType) { seq.Add(delegate(CodeInstruction i) { FieldInfo fieldInfo = i.operand as FieldInfo; return i.opcode == opcode && fieldInfo != null && fieldInfo.FieldType == operandType; }); } public void AddBasicWithAlternateMethodName(OpCode opcode, object operand, string methodName) { seq.Add(delegate(CodeInstruction i) { if (i.opcode == opcode && i.operand == operand) { return true; } MethodInfo methodInfo = i.operand as MethodInfo; return (methodInfo != null && methodInfo.Name == methodName) ? true : false; }); } public void AddSpecial(OpCode opcode, Func<CodeInstruction, bool> extra) { seq.Add((CodeInstruction i) => i.opcode == opcode && extra(i)); } public void ReportComplete() { if (!completed) { string text = (string.IsNullOrWhiteSpace(extraErrorMessage) ? "BIG PROBLEM!" : extraErrorMessage); Plugin.logger.LogError((object)("HarmonyTranspiler for " + name + " has failed. " + text)); } } protected AdvanceResult AdvanceStage(CodeInstruction current) { Func<CodeInstruction, bool> func = seq[stage]; AdvanceResult advanceResult = AdvanceResult.Failed; if (func == null) { func = seq[stage + 1]; if (func(current)) { stage += 2; } advanceResult = AdvanceResult.Advanced; } else if (func(current)) { stage++; advanceResult = AdvanceResult.Advanced; } else { stage = 0; advanceResult = AdvanceResult.Failed; } if (stage >= seq.Count) { if (completed && single) { throw new Exception("Found multiple valid " + name + " instructions"); } stage = 0; completed = true; advanceResult = AdvanceResult.Finished; } return advanceResult; } } internal class InstructionSequenceStandard : InstructionSequence { public InstructionSequenceStandard(string name, bool single = true, string extraErrorMessage = null) : base(name, single, extraErrorMessage) { } public bool VerifyStage(CodeInstruction current) { return AdvanceStage(current) == AdvanceResult.Finished; } } internal class InstructionSequenceHold : InstructionSequence { public enum HoldResult { None, Hold, Release, Finished } public List<CodeInstruction> Instructions; private new List<Func<CodeInstruction, bool>> seq; private new string name; private new string extraErrorMessage; private new int stage = 0; private new bool completed = false; public InstructionSequenceHold(string name, bool single = true, string extraErrorMessage = null) : base(name, single, extraErrorMessage) { Instructions = new List<CodeInstruction>(); } public HoldResult VerifyStage(CodeInstruction current) { switch (AdvanceStage(current)) { case AdvanceResult.Failed: if (Instructions.Count > 0) { Instructions.Add(current); return HoldResult.Release; } return HoldResult.None; case AdvanceResult.Advanced: Instructions.Add(current); return HoldResult.Hold; default: Instructions.Add(current); return HoldResult.Finished; } } public void ClearInstructions() { Instructions.Clear(); } } internal class TranspilerUtilities { public static IEnumerable<CodeInstruction> InjectMethod(IEnumerable<CodeInstruction> instructions, InjectionDictionary injection, string debugFunction, int? expectedCounter = null) { List<CodeInstruction> targets = injection.instructions; CodeInstruction[] codeInjections = injection.injections; injection.ResetCounter(); foreach (CodeInstruction i in instructions) { foreach (CodeInstruction t in targets) { if (!(i.opcode == t.opcode) || i.operand != t.operand) { continue; } yield return i; CodeInstruction[] array = codeInjections; for (int j = 0; j < array.Length; j++) { yield return array[j]; } injection.AddCounter(); goto IL_0215; } yield return i; IL_0215:; } injection.Report(debugFunction, expectedCounter); } public static bool IsInstructionNearFloatValue(CodeInstruction instruction, float value) { return Mathf.Abs((float)instruction.operand - value) < 0.1f; } public static void PrintInstructions(IEnumerable<CodeInstruction> instructions) { foreach (CodeInstruction instruction in instructions) { string text = instruction.opcode.ToString(); string text2 = ((instruction.operand != null) ? instruction.operand.ToString() : "NULL"); Plugin.logger.LogInfo((object)(text + ": " + text2)); } } } public class ActionList { public string name; public List<(string name, Action action)> actionList; public List<(string name, Action action)> temporaryActionList; public ActionList(string name) { this.name = name; actionList = new List<(string, Action)>(); temporaryActionList = new List<(string, Action)>(); } public void AddEvent(string name, Action act) { actionList.Add((name, act)); } public void AddTemporaryEvent(string name, Action act) { temporaryActionList.Add((name, act)); } public void Call() { foreach (var action in actionList) { try { action.action(); } catch (Exception ex) { Plugin.logger.LogError((object)("Error with event " + name + "/" + action.name)); Plugin.logger.LogError((object)ex.ToString()); } } foreach (var temporaryAction in temporaryActionList) { try { temporaryAction.action(); } catch (Exception ex2) { Plugin.logger.LogError((object)("Error with event " + name + "/" + temporaryAction.name)); Plugin.logger.LogError((object)ex2.ToString()); } } ClearTemporaryActionList(); } public void ClearTemporaryActionList() { temporaryActionList.Clear(); } } } namespace DunGenPlus.Patches { internal class DoorwayConnectionPatch { [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] [HarmonyPrefix] public static void ConnectOverlappingDoorwaysPrePatch(ref DungeonProxy __instance) { IEnumerable<DoorwayProxy> list = __instance.AllTiles.SelectMany((TileProxy t) => t.Doorways); DoorwaySistersRule.UpdateCache(list); } [HarmonyTranspiler] [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] public static IEnumerable<CodeInstruction> ConnectOverlappingDoorwaysPatch(IEnumerable<CodeInstruction> instructions) { MethodInfo callFunction = typeof(DungeonFlow).GetMethod("CanDoorwaysConnect", BindingFlags.Instance | BindingFlags.Public); InstructionSequenceStandard sequence = new InstructionSequenceStandard("doorway connect", single: false); sequence.AddBasic(OpCodes.Callvirt, callFunction); sequence.AddBasic(OpCodes.Brfalse); foreach (CodeInstruction instruction in instructions) { if (sequence.VerifyStage(instruction)) { MethodInfo method = typeof(DoorwaySistersRule).GetMethod("CanDoorwaysConnect", BindingFlags.Static | BindingFlags.Public); MethodInfo getTileProxy = typeof(DoorwayProxy).GetMethod("get_TileProxy", BindingFlags.Instance | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Ldloc_2, (object)null); yield return new CodeInstruction(OpCodes.Callvirt, (object)getTileProxy); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)4); yield return new CodeInstruction(OpCodes.Callvirt, (object)getTileProxy); yield return new CodeInstruction(OpCodes.Ldloc_2, (object)null); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)4); yield return new CodeInstruction(OpCodes.Call, (object)method); yield return instruction; } else { yield return instruction; } } sequence.ReportComplete(); } } internal class DungeonGeneratorPatch { public static TilePlacementResult lastTilePlacementResult; [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate")] public static void InnerGeneratePatch(ref DungeonGenerator __instance, bool isRetry, ref IEnumerator __result) { if (DevDebugManager.IsActive && !isRetry) { DevDebugManager.Instance.RecordNewSeed(__instance.ChosenSeed); } if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { DunGenPlusGenerator.SetCurrentMainPathExtender(0); MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviourSimpleOnce = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath")] public static void GenerateMainPathPatch(ref DungeonGenerator __instance, ref IEnumerator __result) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { DunGenPlusGenerator.RandomizeLineArchetypes(__instance, randomizeMainPath: true); } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "GenerateBranchPaths")] public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance, ref IEnumerator __result) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { __result = DunGenPlusGenerator.GenerateAlternativeMainPaths(__instance); } } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable<CodeInstruction> GenerateMainPathPatch(IEnumerable<CodeInstruction> instructions) { MethodInfo addArchFunction = typeof(List<DungeonArchetype>).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public); InstructionSequenceStandard archSequence = new InstructionSequenceStandard("archetype node"); archSequence.AddOperandTypeCheck(OpCodes.Ldfld, typeof(List<DungeonArchetype>)); archSequence.AddBasic(OpCodes.Ldnull); archSequence.AddBasic(OpCodes.Callvirt, addArchFunction); InstructionSequenceStandard attachToSequence = new InstructionSequenceStandard("attach to"); attachToSequence.AddBasicLocal(OpCodes.Stloc_S, 13); foreach (CodeInstruction instruction in instructions) { if (archSequence.VerifyStage(instruction)) { MethodInfo randomStreamMethod = typeof(DungeonGenerator).GetMethod("get_RandomStream", BindingFlags.Instance | BindingFlags.Public); MethodInfo modifyMethod2 = typeof(DunGenPlusGenerator).GetMethod("ModifyMainBranchNodeArchetype", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)8); yield return new CodeInstruction(OpCodes.Ldloc_1, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)randomStreamMethod); yield return new CodeInstruction(OpCodes.Call, (object)modifyMethod2); yield return instruction; } else if (attachToSequence.VerifyStage(instruction)) { yield return instruction; MethodInfo modifyMethod = typeof(MainRoomDoorwayGroups).GetMethod("ModifyGroupBasedOnBehaviourSimple", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)13); yield return new CodeInstruction(OpCodes.Call, (object)modifyMethod); } else { yield return instruction; } } archSequence.ReportComplete(); attachToSequence.ReportComplete(); } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable<CodeInstruction> GenerateMainPathGetLineAtDepthPatch(IEnumerable<CodeInstruction> instructions) { MethodInfo getLineFunction = typeof(DungeonFlow).GetMethod("GetLineAtDepth", BindingFlags.Instance | BindingFlags.Public); FieldInfo nodesField = typeof(DungeonFlow).GetField("Nodes", BindingFlags.Instance | BindingFlags.Public); InstructionSequenceStandard lineSequence = new InstructionSequenceStandard("GetLineAtDepth"); lineSequence.AddBasic(OpCodes.Callvirt, getLineFunction); InstructionSequenceStandard nodesSequence = new InstructionSequenceStandard("Nodes", single: false); nodesSequence.AddBasic(OpCodes.Ldfld, nodesField); foreach (CodeInstruction instruction in instructions) { if (lineSequence.VerifyStage(instruction)) { MethodInfo specialFunction2 = typeof(DunGenPlusGenerator).GetMethod("GetLineAtDepth", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction2); } else if (nodesSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetNodes", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } else { yield return instruction; } } lineSequence.ReportComplete(); nodesSequence.ReportComplete(); } [HarmonyTranspiler] [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCounts")] public static IEnumerable<CodeInstruction> ComputeBranchCountsPatch(IEnumerable<CodeInstruction> instructions) { FieldInfo branchModeField = typeof(DungeonFlow).GetField("BranchMode", BindingFlags.Instance | BindingFlags.Public); InstructionSequenceStandard branchSequence = new InstructionSequenceStandard("BranchMode", single: false); branchSequence.AddBasic(OpCodes.Ldfld, branchModeField); foreach (CodeInstruction instruction in instructions) { if (branchSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchMode", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } else { yield return instruction; } } branchSequence.ReportComplete(); } [HarmonyTranspiler] [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCountsGlobal")] public static IEnumerable<CodeInstruction> ComputeBranchCountsGlobalPatch(IEnumerable<CodeInstruction> instructions) { FieldInfo branchCountField = typeof(DungeonFlow).GetField("BranchCount", BindingFlags.Instance | BindingFlags.Public); InstructionSequenceStandard branchSequence = new InstructionSequenceStandard("BranchCount"); branchSequence.AddBasic(OpCodes.Ldfld, branchCountField); foreach (CodeInstruction instruction in instructions) { if (branchSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchCount", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } else { yield return instruction; } } branchSequence.ReportComplete(); } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable<CodeInstruction> InnerGenerateLengthPatch(IEnumerable<CodeInstruction> instructions) { FieldInfo lengthField = typeof(DungeonFlow).GetField("Length", BindingFlags.Instance | BindingFlags.Public); MethodInfo getIsEditor = typeof(Application).GetMethod("get_isEditor", BindingFlags.Static | BindingFlags.Public); InstructionSequenceStandard lengthSequence = new InstructionSequenceStandard("Length"); lengthSequence.AddBasic(OpCodes.Ldfld, lengthField); InstructionSequenceStandard editorCheck = new InstructionSequenceStandard("Editor"); editorCheck.AddBasic(OpCodes.Call, getIsEditor); foreach (CodeInstruction instruction in instructions) { if (lengthSequence.VerifyStage(instruction)) { MethodInfo specialFunction2 = typeof(DunGenPlusGenerator).GetMethod("GetLength", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction2); } else if (editorCheck.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("AllowRetryStop", BindingFlags.Static | BindingFlags.Public); yield return instruction; yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } else { yield return instruction; } } lengthSequence.ReportComplete(); editorCheck.ReportComplete(); } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] public static void GenerateBranchPathsPatch() { if (DunGenPlusGenerator.Active) { Plugin.logger.LogDebug((object)"Alt. InnerGenerate() function complete"); } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "SetPowerOffAtStart")] public static void SetPowerOffAtStartPatch() { DoorwayManager.onMainEntranceTeleportSpawnedEvent.Call(); } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "PostProcess")] public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance) { if (DunGenPlusGenerator.Active) { int value = __instance.RandomStream.Next(999); SpawnSyncedObjectCycle.UpdateCycle(value); } } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "AddTilePlacementResult")] public static void AddTilePlacementResultPatch(TilePlacementResult result) { //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) lastTilePlacementResult = result; } } internal class LethalLevelLoaderPatches { [HarmonyPrefix] [HarmonyPatch(typeof(Patches), "DungeonGeneratorGenerate_Prefix")] public static bool DungeonGeneratorGenerate_Prefix_Prefix() { return (Object)(object)DevDebugManager.Instance == (Object)null; } } public class RoundManagerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "Awake")] public static void AwakePatch() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (PluginConfig.EnableDevDebugTools.Value) { GameObject val = new GameObject("DevDebugOpen", new Type[1] { typeof(DevDebugOpen) }); } } [HarmonyPrefix] [HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")] public static void waitForScrapToSpawnToSyncPatch(ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn) { return; } List<NetworkObjectReference> list = spawnedScrap.ToList(); List<int> list2 = scrapValues.ToList(); RandomGuaranteedScrapSpawn[] array = Object.FindObjectsOfType<RandomGuaranteedScrapSpawn>(); RandomGuaranteedScrapSpawn.ResetCache(); RandomGuaranteedScrapSpawn[] array2 = array; foreach (RandomGuaranteedScrapSpawn randomGuaranteedScrapSpawn in array2) { (NetworkObject, int) tuple = randomGuaranteedScrapSpawn.CreateItem(__instance, __instance.currentLevel.spawnableScrap); if ((Object)(object)tuple.Item1 != (Object)null) { Plugin.logger.LogDebug((object)$"Created guaranteed item {((Object)((Component)tuple.Item1).gameObject).name} w/ value {tuple.Item2}"); list.Add(NetworkObjectReference.op_Implicit(tuple.Item1)); list2.Add(tuple.Item2); } } spawnedScrap = list.ToArray(); scrapValues = list2.ToArray(); } } internal class StartOfRoundPatch { public static readonly string[] validDungeonFlowTargets = new string[4] { "Level1Flow", "Level2Flow", "Level1FlowExtraLarge", "Level1Flow3Exits" }; public static readonly Dictionary<string, int> validStartTileTargets = new Dictionary<string, int> { { "StartRoom", 2 }, { "ManorStartRoom", 3 } }; [HarmonyPatch(typeof(RoundManager), "Awake")] [HarmonyPrefix] public static void AwakePatch(ref RoundManager __instance) { //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown IEnumerable<DungeonFlow> enumerable = __instance.dungeonFlowTypes.Select((IndoorMapType d) => d.dungeonFlow); foreach (DungeonFlow item in enumerable) { if (!validDungeonFlowTargets.Contains(((Object)item).name) || API.ContainsDungeonFlow(item)) { continue; } Plugin.logger.LogInfo((object)("Creating DunGenExtender for " + ((Object)item).name)); IEnumerable<GameObject> enumerable2 = from i in (from i in (from i in item.Lines.Select((GraphLine i) => i.DungeonArchetypes).SelectMany((List<DungeonArchetype> i) => i) select i.TileSets).SelectMany((List<TileSet> i) => i) select i.TileWeights.Weights).SelectMany((List<GameObjectChance> i) => i) select i.Value; foreach (GameObject item2 in enumerable2) { if (validStartTileTargets.TryGetValue(((Object)item2).name, out var value)) { DunGenExtender dunGenExtender = API.CreateDunGenExtender(item); DunGenExtenderProperties properties = dunGenExtender.Properties; properties.MainPathProperties.MainPathCount = value; properties.MainPathProperties.MainRoomTilePrefab = item2; item.Length = new IntRange(item.Length.Min / 2, item.Length.Max / 2); Plugin.logger.LogInfo((object)$"New length: {item.Length}"); if (((Object)item2).name == "StartRoom") { List<GraphLine> lines = item.Lines; lines[0].Length = 0.2f; GraphLine obj = lines[1]; obj.Length -= 0.2f - lines[1].Position; lines[1].Position = 0.2f; } API.AddDunGenExtender(dunGenExtender); break; } } } } } } namespace DunGenPlus.Managers { public static class DoorwayManager { public static ActionList onMainEntranceTeleportSpawnedEvent = new ActionList("onMainEntranceTeleportSpawned"); public static List<DoorwayCleanup> doorwayCleanupList; public static void ResetList() { doorwayCleanupList = new List<DoorwayCleanup>(); } public static void AddDoorwayCleanup(DoorwayCleanup cleanup) { doorwayCleanupList.Add(cleanup); } public static void onMainEntranceTeleportSpawnedFunction() { if (!DunGenPlusGenerator.Active) { return; } foreach (DoorwayCleanup doorwayCleanup in doorwayCleanupList) { doorwayCleanup.SetBlockers(state: false); doorwayCleanup.Cleanup(); } try { RuntimeDungeon dungeonGenerator = RoundManager.Instance.dungeonGenerator; UnityNavMeshAdapter componentInChildren = ((Component)((Component)dungeonGenerator).transform.parent).GetComponentInChildren<UnityNavMeshAdapter>(); ((BaseAdapter)componentInChildren).Run(dungeonGenerator.Generator); Plugin.logger.LogDebug((object)"Rebuild nav mesh"); } catch (Exception ex) { Plugin.logger.LogError((object)"Failed to rebuild nav mesh"); Plugin.logger.LogError((object)ex.ToString()); } } } } namespace DunGenPlus.Generation { internal class DunGenPlusGenerator { private class BranchPathProxy { public TileProxy mainPathTile; public int mainPathIndex; public List<TilePlacementResultProxy> list; public float weight; public Dictionary<TileProxy, InjectedTile> injectedTiles; public List<InjectedTile> tilesPendingInjection; public BranchPathProxy(DungeonGenerator gen, TileProxy attachTileProxy) { mainPathTile = attachTileProxy; mainPathIndex = GetMainPathIndexFromTileProxy(attachTileProxy); list = new List<TilePlacementResultProxy>(); weight = 0f; injectedTiles = new Dictionary<TileProxy, InjectedTile>(gen.injectedTiles); tilesPendingInjection = new List<InjectedTile>(gen.tilesPendingInjection); } public void CalculateWeight(DungeonGenerator gen) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) int count = list.Count; if (count == 0) { return; } TilePlacementResultProxy tilePlacementResultProxy = list[count - 1]; BranchPathMultiSimulationProperties branchPathMultiSimulationProperties = Properties.BranchPathMultiSimulationProperties; int branchDepth = tilePlacementResultProxy.tileProxy.Placement.BranchDepth; float normalizedBranchDepth = tilePlacementResultProxy.tileProxy.Placement.NormalizedBranchDepth; weight += branchPathMultiSimulationProperties.GetWeightBase(branchDepth, normalizedBranchDepth); IEnumerable<DoorwayProxy> enumerable = gen.proxyDungeon.AllTiles.SelectMany((TileProxy t) => t.Doorways); foreach (TilePlacementResultProxy item in list) { foreach (DoorwayProxy item2 in enumerable) { if (item2.TileProxy == mainPathTile) { continue; } int mainPathIndexFromTileProxy = GetMainPathIndexFromTileProxy(item2.TileProxy); foreach (DoorwayProxy doorway in item.tileProxy.doorways) { if (item2.TileProxy != item.previousDoorway.TileProxy && gen.DungeonFlow.CanDoorwaysConnect(item2.TileProxy.PrefabTile, doorway.TileProxy.PrefabTile, item2.DoorwayComponent, doorway.DoorwayComponent) && (double)Vector3.SqrMagnitude(item2.Position - doorway.Position) < 1E-05) { int num = Mathf.Abs(item2.TileProxy.Placement.PathDepth - doorway.TileProxy.Placement.PathDepth); float normalizedDepthDifference = Mathf.Abs(item2.TileProxy.Placement.NormalizedPathDepth - doorway.TileProxy.Placement.NormalizedPathDepth); bool samePath = mainPathIndex == mainPathIndexFromTileProxy; weight += branchPathMultiSimulationProperties.GetWeightPathConnection(samePath, num, normalizedDepthDifference); } } } } } } private class TilePlacementResultProxy { public TilePlacementResult result; public TileProxy tileProxy; public DoorwayProxy previousDoorway; public DoorwayProxy nextDoorway; public TilePlacementResultProxy(TilePlacementResult result) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) this.result = result; tileProxy = null; previousDoorway = null; nextDoorway = null; } public TilePlacementResultProxy(TilePlacementResult result, TileProxy tile, DoorwayProxy previousDoorway, DoorwayProxy nextDoorway) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) this.result = result; tileProxy = tile; this.previousDoorway = previousDoorway; this.nextDoorway = nextDoorway; } } public static MainPathExtender currentMainPathExtender; internal static HDRenderPipelineAsset previousHDRPAsset; internal static HDRenderPipelineAsset newHDRPAsset; private static Dictionary<TileProxy, int> tileProxyMainPath = new Dictionary<TileProxy, int>(); public static Stopwatch GenerateBranchBoostedPathsStopWatch = new Stopwatch(); public static float GenerateBranchBoostedPathsTime = 0f; public static Stopwatch GetTileResultStopwatch = new Stopwatch(); public static float GetTileResultTime = 0f; public static Stopwatch DoorwayPairStopwatch = new Stopwatch(); public static float DoorwayPairTime = 0f; public static Stopwatch CalculateWeightStopwatch = new Stopwatch(); public static float CalculateWeightTime = 0f; public static DunGenExtender Instance { get; internal set; } public static DunGenExtenderProperties Properties { get; internal set; } public static bool Active { get; internal set; } public static bool ActiveAlternative { get; internal set; } public static void SetCurrentMainPathExtender(int mainPathIndex) { currentMainPathExtender = Properties.MainPathProperties.GetMainPathDetails(mainPathIndex); } public static GraphLine GetLineAtDepth(DungeonFlow flow, float depth) { if (!Active) { return flow.GetLineAtDepth(depth); } List<GraphLine> lines = MainPathExtender.GetLines(currentMainPathExtender, flow); return GetLineAtDepthHelper(lines, depth); } public static GraphLine GetLineAtDepthHelper(List<GraphLine> graphLines, float normalizedDepth) { normalizedDepth = Mathf.Clamp(normalizedDepth, 0f, 1f); if (normalizedDepth == 0f) { return graphLines[0]; } if (normalizedDepth == 1f) { return graphLines[graphLines.Count - 1]; } foreach (GraphLine graphLine in graphLines) { if (normalizedDepth >= graphLine.Position && normalizedDepth < graphLine.Position + graphLine.Length) { return graphLine; } } Debug.LogError((object)("GetLineAtDepth was unable to find a line at depth " + normalizedDepth + ". This shouldn't happen.")); return null; } public static List<GraphNode> GetNodes(DungeonFlow flow) { if (!Active) { return flow.Nodes; } return MainPathExtender.GetNodes(currentMainPathExtender, flow); } public static BranchMode GetBranchMode(DungeonFlow flow) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return flow.BranchMode; } return MainPathExtender.GetBranchMode(currentMainPathExtender, flow); } public static IntRange GetBranchCount(DungeonFlow flow) { if (!Active) { return flow.BranchCount; } return MainPathExtender.GetBranchCount(currentMainPathExtender, flow); } public static IntRange GetLength(DungeonFlow flow) { if (!Active) { return flow.Length; } return MainPathExtender.GetLength(currentMainPathExtender, flow); } public static void Activate(DungeonGenerator generator, DunGenExtender extender) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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) Instance = extender; Active = true; ActiveAlternative = true; DunGenExtenderProperties dunGenExtenderProperties = extender.Properties.Copy(extender.Version); EventCallbackScenario param = new EventCallbackScenario(Object.op_Implicit((Object)(object)DevDebugManager.Instance)); Instance.Events.OnModifyDunGenExtenderProperties.Invoke(dunGenExtenderProperties, param); dunGenExtenderProperties.NormalNodeArchetypesProperties.SetupProperties(generator); Properties = dunGenExtenderProperties; if (Properties.DungeonBoundsProperties.UseDungeonBounds) { generator.DebugRender = true; generator.RestrictDungeonToBounds = true; Bounds val = (generator.TilePlacementBounds = Properties.DungeonBoundsProperties.GetDungeonBounds(generator.LengthMultiplier)); Plugin.logger.LogDebug((object)$"Dungeon Bounds: {val}"); } if (Properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate) { Plugin.logger.LogDebug((object)$"Updating HDRP asset: setting max shadows request to {Properties.MiscellaneousProperties.MaxShadowsRequestCount}"); try { RenderPipelineAsset renderPipeline = QualitySettings.renderPipeline; previousHDRPAsset = (HDRenderPipelineAsset)(object)((renderPipeline is HDRenderPipelineAsset) ? renderPipeline : null); newHDRPAsset = Object.Instantiate<HDRenderPipelineAsset>(previousHDRPAsset); RenderPipelineSettings currentPlatformRenderPipelineSettings = newHDRPAsset.currentPlatformRenderPipelineSettings; currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots = Properties.MiscellaneousProperties.MaxShadowsRequestCount; newHDRPAsset.currentPlatformRenderPipelineSettings = currentPlatformRenderPipelineSettings; QualitySettings.renderPipeline = (RenderPipelineAsset)(object)newHDRPAsset; } catch (Exception ex) { Plugin.logger.LogError((object)"Failed to update HDRP asset"); Plugin.logger.LogError((object)ex.ToString()); } } DoorwayManager.ResetList(); DoorwayManager.onMainEntranceTeleportSpawnedEvent.ClearTemporaryActionList(); } public static void Deactivate() { Instance = null; Properties = null; Active = false; ActiveAlternative = false; if (Object.op_Implicit((Object)(object)previousHDRPAsset) && (Object)(object)QualitySettings.renderPipeline == (Object)(object)newHDRPAsset) { Plugin.logger.LogDebug((object)"Restoring original HDRP asset"); QualitySettings.renderPipeline = (RenderPipelineAsset)(object)previousHDRPAsset; previousHDRPAsset = null; newHDRPAsset = null; } } public static int GetMainPathIndexFromTileProxy(TileProxy tileProxy) { return tileProxyMainPath[tileProxy]; } private static void AddTileProxyToMainPathDictionary(IEnumerable<TileProxy> tileProxies, int index) { float num = tileProxies.Last().Placement.PathDepth; foreach (TileProxy tileProxy in tileProxies) { tileProxyMainPath.Add(tileProxy, index); tileProxy.Placement.NormalizedPathDepth = (float)tileProxy.Placement.PathDepth / num; } } public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) { if (!Active) { ActiveAlternative = false; yield return gen.Wait(gen.GenerateBranchPaths()); ActiveAlternative = true; yield break; } int altCount = Properties.MainPathProperties.MainPathCount - 1; tileProxyMainPath.Clear(); GameObject mainRoomTilePrefab = Properties.MainPathProperties.MainRoomTilePrefab; DunGenExtenderProperties.CopyNodeBehaviour copyNodeBehaviour = Properties.MainPathProperties.CopyNodeBehaviour; if (altCount <= 0) { yield return gen.Wait(GenerateBranchPaths(gen, null, $"MainPathCount being {altCount + 1}", (LogLevel)16)); yield break; } if ((Object)(object)mainRoomTilePrefab == (Object)null) { yield return gen.Wait(GenerateBranchPaths(gen, null, "MainRoomTilePrefab being null", (LogLevel)4)); yield break; } List<List<TileProxy>> allMainPathTiles = new List<List<TileProxy>>(); List<TileProxy> firstMainPathTiles = gen.proxyDungeon.MainPathTiles.ToList(); allMainPathTiles.Add(firstMainPathTiles); AddTileProxyToMainPathDictionary(firstMainPathTiles, 0); TileProxy mainRoom = ((IEnumerable<TileProxy>)gen.proxyDungeon.MainPathTiles).FirstOrDefault((Func<TileProxy, bool>)((TileProxy t) => (Object)(object)t.Prefab == (Object)(object)mainRoomTilePrefab)); if (mainRoom == null) { yield return gen.Wait(GenerateBranchPaths(gen, null, "MainRoomTilePrefab not spawning on the main path", (LogLevel)4)); yield break; } int mainRoomStartingLengthIndex = mainRoom.Placement.Depth + 1; Plugin.logger.LogDebug((object)$"Main Room Length Index: {mainRoomStartingLengthIndex}"); gen.ChangeStatus((GenerationStatus)3); int b = 0; while (b < altCount) { SetCurrentMainPathExtender(b + 1); RandomizeLineArchetypes(gen, randomizeMainPath: true); TileProxy previousTile = mainRoom; int targetLength = Mathf.RoundToInt((float)GetLength(gen.DungeonFlow).GetRandom(gen.RandomStream) * gen.LengthMultiplier); List<DungeonArchetype> archetypes = new List<DungeonArchetype>(targetLength); List<TileProxy> newMainPathTiles = new List<TileProxy>(); List<GraphNode> nodesSorted = (from n in GetNodes(gen.DungeonFlow) orderby n.Position select n).ToList(); int startingNodeIndex; switch (copyNodeBehaviour) { case DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList: { int index = nodesSorted.FindIndex((GraphNode n) => n.TileSets.SelectMany((TileSet t) => t.TileWeights.Weights).Any((GameObjectChance t) => (Object)(object)t.Value == (Object)(object)mainRoomTilePrefab)); if (index == -1) { yield return gen.Wait(GenerateBranchPaths(gen, mainRoom, "CopyNodeBehaviour being CopyFromNodeList AND MainRoomTilePrefab not existing in the Nodes' tilesets", (LogLevel)4)); yield break; } startingNodeIndex = index + 1; break; } case DunGenExtenderProperties.CopyNodeBehaviour.CopyFromMainPathPosition: { float lineDepthRatio = Mathf.Clamp01(1f / (float)(targetLength - 1)); startingNodeIndex = nodesSorted.FindIndex((GraphNode n) => n.Position >= lineDepthRatio); break; } default: Plugin.logger.LogFatal((object)$"{copyNodeBehaviour} is not yet defined. Really really bad"); startingNodeIndex = -1; break; } IEnumerable<GraphNode> nodes = nodesSorted.Skip(startingNodeIndex); List<GraphNode> nodesVisited = new List<GraphNode>(nodes.Count()); MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviour(mainRoom, b + 1); bool reachedLastNode = false; GraphNode lastNode = nodes.ElementAt(nodes.Count() - 1); int t2 = mainRoomStartingLengthIndex; int num; while (t2 < targetLength && !reachedLastNode) { float lineDepthRatio2 = Mathf.Clamp01((float)t2 / (float)(targetLength - 1)); GraphLine lineAtDepth = GetLineAtDepth(gen.DungeonFlow, lineDepthRatio2); if (lineAtDepth == null) { yield return gen.Wait(gen.InnerGenerate(true)); yield break; } if (lineAtDepth != gen.previousLineSegment) { gen.currentArchetype = lineAtDepth.GetRandomArchetype(gen.RandomStream, (IList<DungeonArchetype>)archetypes); gen.previousLineSegment = lineAtDepth; } GraphNode graphNode = null; foreach (GraphNode g in nodes) { if (lineDepthRatio2 >= g.Position && !nodesVisited.Contains(g)) { graphNode = g; nodesVisited.Add(g); break; } } DungeonArchetype archetype; List<TileSet> useableTileSets; if (graphNode != null) { archetype = ModifyMainBranchNodeArchetype(null, graphNode, gen.RandomStream); useableTileSets = graphNode.TileSets; if (graphNode == lastNode) { reachedLastNode = true; } } else { archetype = gen.currentArchetype; useableTileSets = archetype.TileSets; } TileProxy tileProxy = gen.AddTile(previousTile, (IEnumerable<TileSet>)useableTileSets, lineDepthRatio2, archetype, (TilePlacementResult)0); if (tileProxy == null) { string prevName = ((previousTile != null) ? ((Object)previousTile.Prefab).name : "NULL"); string archetypeName = (Object.op_Implicit((Object)(object)archetype) ? ((Object)archetype).name : "NULL"); string tileSetNames = string.Join(", ", useableTileSets); Plugin.logger.LogDebug((object)$"Alt. main branch gen failed at Branch {b} (Length: {t2}, Ratio: {lineDepthRatio2})"); Plugin.logger.LogDebug((object)("Prev tile: " + prevName + "\nArchetype: " + archetypeName + "\nTilesets: " + tileSetNames)); Plugin.logger.LogDebug((object)$"Reason: {DungeonGeneratorPatch.lastTilePlacementResult}"); if (previousTile != null) { string availableDoorways = string.Join(",", previousTile.UnusedDoorways); string usedDoorways = string.Join(",", previousTile.UsedDoorways); Plugin.logger.LogDebug((object)("Available Doorways: " + availableDoorways)); Plugin.logger.LogDebug((object)("Used Doorways: " + usedDoorways)); } yield return gen.Wait(gen.InnerGenerate(true)); yield break; } if (reachedLastNode || lineDepthRatio2 >= 1f) { Plugin.logger.LogDebug((object)$"Alt. main branch at {b} ended with {((Object)tileProxy.PrefabTile).name}"); } tileProxy.Placement.BranchDepth = t2; tileProxy.Placement.NormalizedBranchDepth = lineDepthRatio2; if (graphNode != null) { tileProxy.Placement.GraphNode = graphNode; tileProxy.Placement.GraphLine = null; } else { tileProxy.Placement.GraphNode = null; tileProxy.Placement.GraphLine = lineAtDepth; } previousTile = tileProxy; newMainPathTiles.Add(tileProxy); if (gen.ShouldSkipFrame(true)) { yield return gen.GetRoomPause(); } num = t2 + 1; t2 = num; } AddTileProxyToMainPathDictionary(newMainPathTiles, b + 1); allMainPathTiles.Add(newMainPathTiles); num = b + 1; b = num; } MainRoomDoorwayGroups.RemoveFakeDoorwayProxies(mainRoom); ActiveAlternative = false; Plugin.logger.LogDebug((object)$"Created {altCount} alt. paths, creating branches now"); gen.ChangeStatus((GenerationStatus)4); int b2 = 0; while (b2 < altCount + 1) { Plugin.logger.LogDebug((object)$"Branch {b2}"); SetCurrentMainPathExtender(b2); RandomizeLineArchetypes(gen, randomizeMainPath: false); gen.proxyDungeon.MainPathTiles = allMainPathTiles[b2]; if (Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim) { GenerateBranchBoostedPathsStopWatch.Reset(); GenerateBranchBoostedPathsStopWatch.Start(); yield return gen.Wait(GenerateMultiBranchPaths(gen)); GenerateBranchBoostedPathsStopWatch.Stop(); GenerateBranchBoostedPathsTime += (float)GenerateBranchBoostedPathsStopWatch.Elapsed.TotalMilliseconds; } else { yield return gen.Wait(gen.GenerateBranchPaths()); } int num = b2 + 1; b2 = num; } ActiveAlternative = true; gen.proxyDungeon.MainPathTiles = allMainPathTiles[0]; AddForcedTiles(gen); } private static IEnumerator GenerateBranchPaths(DungeonGenerator gen, TileProxy mainRoom, string message, LogLevel logLevel) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Plugin.logger.Log(logLevel, (object)("Switching to default dungeon branch generation: " + message)); ActiveAlternative = false; SetCurrentMainPathExtender(0); if (mainRoom != null) { MainRoomDoorwayGroups.RemoveFakeDoorwayProxies(mainRoom); } yield return gen.Wait(gen.GenerateBranchPaths()); ActiveAlternative = true; AddForcedTiles(gen); } public static void FixDoorwaysToAllFloors(TileProxy mainRoom, MainRoomDoorwayGroups doorwayGroups) { List<Doorway> doorwayListFirst = doorwayGroups.doorwayListFirst; if (doorwayListFirst == null) { return; } foreach (DoorwayProxy usedDoorway in mainRoom.UsedDoorways) { if (usedDoorway.ConnectedDoorway.Index == int.MaxValue && !doorwayListFirst.Contains(usedDoorway.DoorwayComponent)) { usedDoorway.ConnectedDoorway = null; } } } public static IEnumerator GenerateMultiBranchPaths(DungeonGenerator gen) { gen.ChangeStatus((GenerationStatus)4); int[] mainPathBranches = new int[gen.proxyDungeon.MainPathTiles.Count]; BranchCountHelper.ComputeBranchCounts(gen.DungeonFlow, gen.RandomStream, gen.proxyDungeon, ref mainPathBranches); int b = 0; while (b < mainPathBranches.Length) { TileProxy tile = gen.proxyDungeon.MainPathTiles[b]; int branchCount = mainPathBranches[b]; int num; if (!((Object)(object)tile.Placement.Archetype == (Object)null) && branchCount != 0) { for (int i = 0; i < branchCount; i = num) { List<BranchPathProxy> pathProxys = new List<BranchPathProxy>(); for (int x2 = 0; x2 < Properties.BranchPathMultiSimulationProperties.SimulationCount; x2 = num) { BranchPathProxy currentPathProxy = new BranchPathProxy(gen, tile); TileProxy previousTile = tile; int branchDepth = tile.Placement.Archetype.BranchingDepth.GetRandom(gen.RandomStream); for (int depth = 0; depth < branchDepth; depth = num) { List<TileSet> useableTileSets = ((depth != branchDepth - 1 || !tile.Placement.Archetype.GetHasValidBranchCapTiles()) ? tile.Placement.Archetype.TileSets : (((int)tile.Placement.Archetype.BranchCapType != 0) ? tile.Placement.Archetype.TileSets.Concat(tile.Placement.Archetype.BranchCapTileSets).ToList() : tile.Placement.Archetype.BranchCapTileSets)); float normalizedDepth = ((branchDepth <= 1) ? 1f : ((float)depth / (float)(branchDepth - 1))); GetTileResultStopwatch.Reset(); GetTileResultStopwatch.Start(); TilePlacementResultProxy tileResult = GetTileResult(gen, currentPathProxy, previousTile, useableTileSets, normalizedDepth, tile.Placement.Archetype); GetTileResultStopwatch.Stop(); GetTileResultTime += (float)GetTileResultStopwatch.Elapsed.TotalMilliseconds; TileProxy tileProxy = tileResult.tileProxy; if (tileProxy == null) { break; } currentPathProxy.list.Add(tileResult); tileProxy.Placement.BranchDepth = depth; tileProxy.Placement.NormalizedBranchDepth = normalizedDepth; previousTile = tileProxy; num = depth + 1; } if (currentPathProxy.list.Count == 0) { break; } CalculateWeightStopwatch.Reset(); CalculateWeightStopwatch.Start(); currentPathProxy.CalculateWeight(gen); CalculateWeightStopwatch.Stop(); CalculateWeightTime += (float)CalculateWeightStopwatch.Elapsed.TotalMilliseconds; pathProxys.Add(currentPathProxy); num = x2 + 1; } BranchPathProxy bestPath = pathProxys.OrderByDescending((BranchPathProxy p) => p.weight).FirstOrDefault(); if (bestPath != null) { foreach (TilePlacementResultProxy item in bestPath.list) { MakeTileProxyConnection(gen, item); item.tileProxy.Placement.GraphNode = item.previousDoorway.TileProxy.Placement.GraphNode; item.tileProxy.Placement.GraphLine = item.previousDoorway.TileProxy.Placement.GraphLine; } gen.injectedTiles = bestPath.injectedTiles; gen.tilesPendingInjection = bestPath.tilesPendingInjection; AddTileProxyToMainPathDictionary(bestPath.list.Select((TilePlacementResultProxy x) => x.tileProxy), bestPath.mainPathIndex); if (gen.ShouldSkipFrame(true)) { yield return gen.GetRoomPause(); } } num = i + 1; } } num = b + 1; b = num; } } private static TilePlacementResultProxy GetTileResult(DungeonGenerator gen, BranchPathProxy pathProxy, TileProxy attachTo, IEnumerable<TileSet> useableTileSets, float normalizedDepth, DungeonArchetype archetype) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Invalid comparison between Unknown and I4 //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Invalid comparison between Unknown and I4 InjectedTile val = null; int index = -1; if (pathProxy.tilesPendingInjection != null) { float num = (float)attachTo.Placement.PathDepth / (float)gen.targetLength - 1f; for (int i = 0; i < pathProxy.tilesPendingInjection.Count; i++) { InjectedTile val2 = pathProxy.tilesPendingInjection[i]; if (val2.ShouldInjectTileAtPoint(false, num, normalizedDepth)) { val = val2; index = i; break; } } } IEnumerable<GameObjectChance> collection = ((val == null) ? useableTileSets.SelectMany((TileSet t) => t.TileWeights.Weights) : new List<GameObjectChance>(val.TileSet.TileWeights.Weights)); bool value = attachTo.PrefabTile.AllowRotation; if (gen.OverrideAllowTileRotation) { value = gen.AllowTileRotation; } DoorwayPairFinder val3 = new DoorwayPairFinder(); val3.DungeonFlow = gen.DungeonFlow; val3.RandomStream = gen.RandomStream; val3.Archetype = archetype; val3.GetTileTemplateDelegate = new GetTileTemplateDelegate(gen.GetTileTemplate); val3.IsOnMainPath = false; val3.NormalizedDepth = normalizedDepth; val3.PreviousTile = attachTo; val3.UpVector = gen.UpVector; val3.AllowRotation = value; val3.TileWeights = new List<GameObjectChance>(collection); val3.IsTileAllowedPredicate = (TileMatchDelegate)delegate(TileProxy prev, TileProxy next, ref float weight) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected I4, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) bool flag = prev != null && (Object)(object)next.Prefab == (Object)(object)prev.Prefab; TileRepeatMode val4 = (TileRepeatMode)0; if (gen.OverrideRepeatMode) { val4 = gen.RepeatMode; } else if (next != null) { val4 = next.PrefabTile.RepeatMode; } TileRepeatMode val5 = val4; TileRepeatMode val6 = val5; return (int)val6 switch { 0 => true, 1 => !flag, 2 => !gen.proxyDungeon.AllTiles.Where((TileProxy x) => (Object)(object)x.Prefab == (Object)(object)next.Prefab).Any(), _ => throw new NotImplementedException($"TileRepeatMode {val4} is not implemented"), }; }; int? num2 = (gen.UseMaximumPairingAttempts ? new int?(gen.MaxPairingAttempts) : null); DoorwayPairStopwatch.Reset(); DoorwayPairStopwatch.Start(); Queue<DoorwayPair> doorwayPairs = val3.GetDoorwayPairs(num2); DoorwayPairStopwatch.Stop(); DoorwayPairTime += (float)DoorwayPairStopwatch.Elapsed.TotalMilliseconds; TilePlacementResultProxy tilePlacementResultProxy = new TilePlacementResultProxy((TilePlacementResult)3); while (doorwayPairs.Count > 0) { DoorwayPair pair = doorwayPairs.Dequeue(); tilePlacementResultProxy = TryPlaceTileResult(gen, pathProxy, pair, archetype); if ((int)tilePlacementResultProxy.result == 0) { break; } } if ((int)tilePlacementResultProxy.result == 0) { if (val != null) { TileProxy tileProxy = tilePlacementResultProxy.tileProxy; tileProxy.Placement.InjectionData = val; pathProxy.injectedTiles[tileProxy] = val; pathProxy.tilesPendingInjection.RemoveAt(index); } return tilePlacementResultProxy; } return new TilePlacementResultProxy((TilePlacementResult)3); } private static TilePlacementResultProxy TryPlaceTileResult(DungeonGenerator gen, BranchPathProxy pathProxy, DoorwayPair pair, DungeonArchetype archetype) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) TileProxy nextTemplate = ((DoorwayPair)(ref pair)).NextTemplate; DoorwayProxy previousDoorway = ((DoorwayPair)(ref pair)).PreviousDoorway; if (nextTemplate == null) { return new TilePlacementResultProxy((TilePlacementResult)4); } int index = ((DoorwayPair)(ref pair)).NextTemplate.Doorways.IndexOf(((DoorwayPair)(ref pair)).NextDoorway); TileProxy val = new TileProxy(nextTemplate); val.Placement.IsOnMainPath = false; val.Placement.Archetype = archetype; val.Placement.TileSet = ((DoorwayPair)(ref pair)).NextTileSet; if (previousDoorway != null) { DoorwayProxy val2 = val.Doorways[index]; val.PositionBySocket(val2, previousDoorway); Bounds bounds = val.Placement.Bounds; if (gen.RestrictDungeonToBounds && !UnityUtil.Contains(gen.TilePlacementBounds, bounds)) { return new TilePlacementResultProxy((TilePlacementResult)8); } if (IsCollidingWithAnyTileAndTileResult(gen, pathProxy, val, previousDoorway.TileProxy)) { return new TilePlacementResultProxy((TilePlacementResult)6); } } if (val == null) { return new TilePlacementResultProxy((TilePlacementResult)7); } val.Placement.PathDepth = ((DoorwayPair)(ref pair)).PreviousTile.Placement.PathDepth; val.Placement.NormalizedPathDepth = ((DoorwayPair)(ref pair)).PreviousTile.Placement.NormalizedPathDepth; val.Placement.BranchDepth = ((!((DoorwayPair)(ref pair)).PreviousTile.Placement.IsOnMainPath) ? (((DoorwayPair)(ref pair)).PreviousTile.Placement.BranchDepth + 1) : 0); return new TilePlacementResultProxy((TilePlacementResult)0, val, previousDoorway, val.Doorways[index]); } private static bool IsCollidingWithAnyTileAndTileResult(DungeonGenerator gen, BranchPathProxy pathProxy, TileProxy newTile, TileProxy previousTile) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) foreach (TileProxy item in gen.proxyDungeon.AllTiles.Concat(pathProxy.list.Select((TilePlacementResultProxy t) => t.tileProxy))) { bool flag = previousTile == item; float num = (flag ? gen.OverlapThreshold : (0f - gen.Padding)); if (gen.DisallowOverhangs && !flag) { if (newTile.IsOverlappingOrOverhanging(item, gen.UpDirection, num)) { return true; } } else if (newTile.IsOverlapping(item, num)) { return true; } } return false; } private static void MakeTileProxyConnection(DungeonGenerator gen, TilePlacementResultProxy proxy) { if (proxy.previousDoorway != null) { gen.proxyDungeon.MakeConnection(proxy.previousDoorway, proxy.nextDoorway); } gen.proxyDungeon.AddTile(proxy.tileProxy); } public static void AddForcedTiles(DungeonGenerator gen) { if (!Properties.AdditionalTilesProperties.UseAdditionalTiles) { return; } List<AdditionalTileSetList> list = Properties.AdditionalTilesProperties.AdditionalTileSets.ToList(); while (list.Count > 0) { AdditionalTileSetList item = list[list.Count - 1]; IOrderedEnumerable<(TileProxy, double)> orderedEnumerable = from pair in gen.proxyDungeon.AllTiles.Select(delegate(TileProxy t) { float num = item.DepthWeightScale.Evaluate(t.Placement.NormalizedDepth); float num2 = (t.Placement.IsOnMainPath ? item.MainPathWeight : item.BranchPathWeight); return (t, (double)(num * num2) * gen.RandomStream.NextDouble()); }) where pair.Item2 > 0.0 orderby pair.Item2 select pair; foreach (var item3 in orderedEnumerable) { TileProxy item2 = item3.Item1; TileProxy val = gen.AddTile(item2, (IEnumerable<TileSet>)item.TileSets, item2.Placement.NormalizedDepth, (DungeonArchetype)null, (TilePlacementResult)0); if (val == null) { continue; } val.Placement.BranchDepth = item2.Placement.BranchDepth; val.Placement.NormalizedBranchDepth = item2.Placement.NormalizedDepth; val.Placement.GraphNode = item2.Placement.GraphNode; val.Placement.GraphLine = item2.Placement.GraphLine; Plugin.logger.LogDebug((object)("Forcefully added tile " + ((Object)val.Prefab).name)); break; } list.RemoveAt(list.Count - 1); } Plugin.logger.LogDebug((object)"Forcefully added all tiles"); } public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath) { if (!Properties.LineRandomizerProperties.UseLineRandomizer) { return; } DungeonFlow dungeonFlow = Instance.DungeonFlow; List<GraphLine> lines = dungeonFlow.Lines; Dictionary<TileSet, int> dictionary = new Dictionary<TileSet, int>(); foreach (TileSet tileSet in Properties.LineRandomizerProperties.TileSets) { dictionary.Add(tileSet, 0); } foreach (DungeonArchetype archetype in Properties.LineRandomizerProperties.Archetypes) { List<TileSet> targetTileSet = (randomizeMainPath ? archetype.TileSets : archetype.BranchCapTileSets); RandomizeArchetype(gen, targetTileSet, dictionary); } } public static void RandomizeArchetype(DungeonGenerator gen, List<TileSet> targetTileSet, Dictionary<TileSet, int> tilesetsUsed) { IEnumerable<TileSet> enumerable = Properties.LineRandomizerProperties.TileSets.OrderBy((TileSet t) => (double)tilesetsUsed[t] + gen.RandomStream.NextDouble()).Take(Properties.LineRandomizerProperties.TileSetsTakeCount); int num = targetTileSet.Count - 1; using IEnumerator<TileSet> enumerator = enumerable.GetEnumerator(); while (enumerator.MoveNext()) { TileSet key = (targetTileSet[num] = enumerator.Current); num--; tilesetsUsed[key]++; } } public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node, RandomStream randomStream) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 if (!Active) { return archetype; } if (Properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes && (int)node.NodeType == 0) { return Properties.NormalNodeArchetypesProperties.GetRandomArchetype(node.Label, randomStream); } return archetype; } public static bool AllowRetryStop(bool defaultState) { return defaultState || DevDebugManager.IsActive; } } internal static class DoorwaySistersRule { public class Data { public DoorwaySisters info; public List<DoorwayProxy> proxies; } public static Dictionary<Doorway, Data> doorwayDictionary; public static Dictionary<DoorwayProxy, Data> doorwayProxyDictionary; public static void UpdateCache(IEnumerable<DoorwayProxy> list) { if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) { return; } Plugin.logger.LogDebug((object)"Updating DoorwayProxy cache for DoorwaySistersRule"); doorwayDictionary = new Dictionary<Doorway, Data>(); doorwayProxyDictionary = new Dictionary<DoorwayProxy, Data>(); foreach (DoorwayProxy item in list) { Doorway doorwayComponent = item.DoorwayComponent; if (doorwayDictionary.TryGetValue(doorwayComponent, out var value)) { value.proxies.Add(item); doorwayProxyDictionary.Add(item, value); continue; } List<DoorwayProxy> list2 = new List<DoorwayProxy>(); list2.Add(item); Data value2 = new Data { info = ((Component)doorwayComponent).GetComponent<DoorwaySisters>(), proxies = list2 }; doorwayProxyDictionary.Add(item, value2); doorwayDictionary.Add(item.DoorwayComponent, value2); } } public static bool CanDoorwaysConnect(bool result, TileProxy tileA, TileProxy tileB, DoorwayProxy doorwayA, DoorwayProxy doorwayB) { if (!result) { return false; } if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) { return true; } DoorwaySisters info = doorwayProxyDictionary[doorwayA].info; DoorwaySisters info2 = doorwayProxyDictionary[doorwayB].info; if (CheckIfSisterActive(info, tileB)) { return false; } if (CheckIfSisterActive(info2, tileA)) { return false; } return true; } public static bool CheckIfSisterActive(DoorwaySisters info, TileProxy targetTile) { if ((Object)(object)info == (Object)null || info.sisters == null) { return false; } foreach (Doorway sister in info.sisters) { List<DoorwayProxy> proxies = doorwayDictionary[sister].proxies; foreach (DoorwayProxy item in proxies) { if (item.ConnectedDoorway != null && item.ConnectedDoorway.TileProxy == targetTile) { return true; } } } return false; } } } namespace DunGenPlus.DevTools { internal class DevDebugManager : MonoBehaviour { [Header("References")] public RuntimeDungeon dungeon; public GameObject devCamera; public BasePanel[] panels; public RectTransform canvasRectTransform; public TMP_Dropdown dungeonFlowSelectionDropDown; private ExtendedDungeonFlow[] dungeonFlows; internal ExtendedDungeonFlow selectedExtendedDungeonFlow; internal DungeonFlow selectedDungeonFlow; internal DungeonFlowCacheAssets selectedAssetCache; internal Dictionary<DungeonFlow, DungeonFlowCacheAssets> cacheDictionary = new Dictionary<DungeonFlow, DungeonFlowCacheAssets>(); public TextMeshProUGUI statusTextMesh; public TextMeshProUGUI statsTextMesh; private GameObject disabledGameObject; private RoundManager fakeRoundManager; private Camera lastMainCamera; private Vector3 lastCameraPosition; private Quaternion lastCameraRotation; private Vector2 cameraYRange; public bool canvasExtended; private float canvasWidthTarget; [Header("UI Prefabs")] [Header("UI")] public GameObject headerUIPrefab; public GameObject textUIPrefab; public GameObject spaceUIPrefab; public GameObject verticalLayoutUIPrefab; [Header("Input Fields")] public GameObject intInputFieldPrefab; public GameObject floatInputFieldPrefab; public GameObject boolInputFieldPrefab; public GameObject stringInputFieldPrefab; public GameObject vector3InputFieldPrefab; public GameObject intRangeInputFieldPrefab; public GameObject floatRangeInputFieldPrefab; public GameObject intSliderFieldPrefab; [Header("Special Fields")] public GameObject listUIPrefab; public GameObject optionsUIPrefab; public static DevDebugManager Instance { get; private set; } public static bool IsActive => (Object)(object)Instance != (Object)null; private void Awake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Instance = this; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; CacheMainCamera(); BeginDevCamera(); GetAllDungeonFlows(); BasePanel[] array = panels; foreach (BasePanel basePanel in array) { basePanel.AwakeCall(); } OpenPanel(0); UpdatePanels(); dungeon.Generator.OnGenerationStatusChanged += new GenerationStatusDelegate(OnDungeonFinished); disabledGameObject = new GameObject("Disabled GOBJ"); disabledGameObject.SetActive(false); disabledGameObject.transform.SetParent(((Component)this).transform); cameraYRange = new Vector2(devCamera.transform.position.y - 200f, devCamera.transform.position.y); canvasExtended = false; canvasWidthTarget = 440f; } private void OnDestroy() { Instance = null; MainPanel.Instance = null; DunFlowPanel.Instance = null; DunGenPlusPanel.Instance = null; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; EndDevCamera(); } private unsafe void Update() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) Vector2 sizeDelta = canvasRectTransform.sizeDelta; sizeDelta.x = Mathf.Lerp(sizeDelta.x, canvasWidthTarget, Time.deltaTime * 10f); canvasRectTransform.sizeDelta = sizeDelta; TextMeshProUGUI obj = statusTextMesh; GenerationStatus status = dungeon.Generator.Status; ((TMP_Text)obj).text = ((object)(GenerationStatus)(ref status)).ToString(); if (!DevDebugOpen.IsSinglePlayerInShip()) { CloseDevDebug(); } if (Mouse.current.middleButton.isPressed) { Vector2 value = System.Runtime.CompilerServices.Unsafe.Read<Vector2>((void*)((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).value); Vector2 val = value; Transform transform = devCamera.transform; transform.position += new Vector3(0f - val.x, 0f, 0f - val.y); } float y = ((Vector2)((InputControl<Vector2>)(object)Mouse.current.scroll).value).y; if (y != 0f) { Vector3 position = devCamera.transform.position; position.y = Mathf.Clamp(position.y + y * -0.05f, cameraYRange.x, cameraYRange.y); devCamera.transform.position = position; } } public void OpenPanel(int index) { for (int i = 0; i < panels.Length; i++) { panels[i].SetPanelVisibility(i == index); } } public void ToggleCanvasExtended() { canvasExtended = !canvasExtended; canvasWidthTarget = (canvasExtended ? 800f : 440f); } public void SelectDungeonFlow(int index) { selectedExtendedDungeonFlow = dungeonFlows[index]; selectedDungeonFlow = selectedExtendedDungeonFlow.DungeonFlow; dungeon.Generator.DungeonFlow = selectedDungeonFlow; if (!cacheDictionary.TryGetValue(selectedDungeonFlow, out var value)) { DunGenExtender dunGenExtender = API.GetDunGenExtender(selectedDungeonFlow); value = new DungeonFlowCacheAssets(selectedDungeonFlow, dunGenExtender); cacheDictionary.Add(selectedDungeonFlow, value); } selectedAssetCache = value; UpdatePanels(); Plugin.logger.LogInfo((object)("Selecting " + selectedExtendedDungeonFlow.DungeonName)); } public void GenerateDungeon() { DeleteDungeon(); Plugin.logger.LogInfo((object)$"Generating dungeon: {dungeon.Generator.IsGenerating}"); fakeRoundManager = disabledGameObject.AddComponent<RoundManager>(); fakeRoundManager.dungeonGenerator = dungeon; selectedExtendedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); DungeonManager.GlobalDungeonEvents?.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); DunGenPlusGenerator.GenerateBranchBoostedPathsTime = 0f; DunGenPlusGenerator.GetTileResultTime = 0f; DunGenPlusGenerator.DoorwayPairTime = 0f; DunGenPlusGenerator.CalculateWeightTime = 0f; dungeon.Generate(); } public void DeleteDungeon() { Plugin.logger.LogInfo((object)"Deleting dungeon"); dungeon.Generator.Clear(true); dungeon.Generator.Cancel(); dungeon.Generator.RestrictDungeonToBounds = false; if (Object.op_Implicit((Object)(object)fakeRoundManager)) { Object.Destroy((Object)(object)fakeRoundManager); } ClearTransformChildren(dungeon.Root.transform); } public void ClearTransformChildren(Transform root) { int childCount = root.childCount; for (int num = childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)root.GetChild(num)).gameObject); } } public void CloseDevDebug() { DeleteDungeon(); Object.Destroy((Object)(object)((Component)this).gameObject); } public void OnDungeonFinished(DungeonGenerator generator, GenerationStatus status) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Initial seed: " + MainPanel.Instance.seedInputField.inputField.text); stringBuilder.AppendLine($"Last seed: {generator.ChosenSeed}"); if ((int)status == 6) { stringBuilder.AppendLine($"Tiles: {generator.CurrentDungeon.AllTiles.Count}"); stringBuilder.AppendLine($"Main Tiles: {generator.CurrentDungeon.MainPathTiles.Count}"); stringBuilder.AppendLine($"Branch Tiles: {generator.CurrentDungeon.BranchPathTiles.Count}"); stringBuilder.AppendLine($"Doors: {generator.CurrentDungeon.Doors.Count}"); } else if ((int)status == 7) { stringBuilder.AppendLine("<color=red>Failed</color>"); } stringBuilder.AppendLine(); GenerationStats generationStats = generator.GenerationStats; stringBuilder.AppendLine("<u>DunGen</u>"); stringBuilder.AppendLine($"Retrys: {generationStats.TotalRetries}"); stringBuilder.AppendLine($"Pre Process Time: {generationStats.PreProcessTime:F2} ms"); stringBuilder.AppendLine($"Main Path Time: {generationStats.MainPathGenerationTime:F2} ms"); stringBuilder.AppendLine($"Branch Path Time: {generationStats.BranchPathGenerationTime:F2} ms"); stringBuilder.AppendLine($"Post Process Time: {generationStats.PostProcessTime:F2} ms"); stringBuilder.AppendLine($"Total Time: {generationStats.TotalTime:F2} ms"); stringBuilder.AppendLine(""); stringBuilder.AppendLine($"GenerateBranch Time: {DunGenPlusGenerator.GenerateBranchBoostedPathsTime:F2} ms"); stringBuilder.AppendLine($"GetTileResult Time: {DunGenPlusGenerator.GetTileResultTime:F2} ms"); stringBuilder.AppendLine($"DoorwayPair Time: {DunGenPlusGenerator.DoorwayPairTime:F2} ms"); stringBuilder.AppendLine($"CalculateWeight Time: {DunGenPlusGenerator.CalculateWeightTime:F2} ms"); ((TMP_Text)statsTextMesh).text = stringBuilder.ToString(); } public void RecordNewSeed(int seed) { MainPanel.Instance?.seedInputField.Set(seed); } private void UpdatePanels() { DunFlowPanel.Instance?.UpdatePanel(refreshPanel: true); DunGenPlusPanel.Instance?.UpdatePanel(refreshPanel: true); AssetsPanel.Instance?.UpdatePanel(refreshPanel: true); } public void UpdateDungeonBounds() { DunGenPlusPanel.Instance?.UpdateDungeonBoundsHelper(); } private void GetAllDungeonFlows() { dungeonFlows = PatchedContent.ExtendedDungeonFlows.ToArray(); dungeonFlowSelectionDropDown.options = ((IEnumerable<ExtendedDungeonFlow>)dungeonFlows).Select((Func<ExtendedDungeonFlow, OptionData>)((ExtendedDungeonFlow d) => new OptionData(d.DungeonName))).ToList(); SelectDungeonFlow(0); } private void CacheMainCamera() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if (Object.op_Implicit((Object)(object)main)) { lastMainCamera = main; lastCameraPosition = ((Component)main).transform.position; lastCameraRotation = ((Component)main).transform.rotation; } } private void BeginDevCamera() { Camera obj = lastMainCamera; if (obj != null) { ((Component)obj).gameObject.SetActive(false); } devCamera.SetActive(true); } private void EndDevCamera() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) devCamera.SetActive(false); if (Object.op_Implicit((Object)(object)lastMainCamera)) { ((Component)lastMainCamera).transform.position = lastCameraPosition; ((Component)lastMainCamera).transform.rotation = lastCameraRotation; ((Component)lastMainCamera).gameObject.SetActive(true); } } public TextUIElement CreateHeaderUIField(Transform parentTransform, TitleParameter titleParameter) { GameObject val = Object.Instantiate<GameObject>(headerUIPrefab, parentTransform); TextUIElement component = val.GetComponent<TextUIElement>(); component.SetupBase(titleParameter); return component; } public TextUIElement CreateTextUIField(Transform parentTransform, TitleParameter titleParameter) { GameObject val = Object.Instantiate<GameObject>(textUIPrefab, parentTransform); TextUIElement component = val.GetComponent<TextUIElement>(); component.SetupBase(titleParameter); return component; } public void CreateSpaceUIField(Transform parentTransform) { Object.Instantiate<GameObject>(spaceUIPrefab, parentTransform); } public Transform CreateVerticalLayoutUIField(Transform parentTransform) { return Object.Instantiate<GameObject>(verticalLayoutUIPrefab, parentTransform).transform; } public IntInputField CreateIntInputField(Transform parentTransform, TitleParameter titleParameter, IntParameter intParameter, Action<int> setAction) { GameObject val = Object.Instantiate<GameObject>(intInputFieldPrefab, parentTransform); IntInputField component = val.GetComponent<IntInputField>(); component.SetupInputField(titleParameter, intParameter, setAction); return component; } public FloatInputField CreateFloatInputField(Transform parentTransform, TitleParameter titleParameter, FloatParameter floatParameter, Action<float> setAction) { GameObject val = Object.Instantiate<GameObject>(floatInputFieldPrefab, parentTransform); FloatInputField component = val.GetComponent<FloatInputField>(); component.SetupInputField(titleParameter, floatParameter, setAction); return component; } public BoolInputField CreateBoolInputField(Transform parentTransform, TitleParameter titleParameter, bool baseValue, Action<bool> setAction) { GameObject val = Object.Instantiate<GameObject>(boolInputFieldPrefab, parentTransform); BoolInputField component = val.GetComponent<BoolInputField>(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public StringInputField CreateStringInputField(Transform parentTransform, TitleParameter titleParameter, string baseValue, Action<string> setAction) { GameObject val = Object.Instantiate<GameObject>(stringInputFieldPrefab, parentTransform); StringInputField component = val.GetComponent<StringInputField>(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public Vector3InputField CreateVector3InputField(Transform parentTransform, TitleParameter titleParameter, Vector3 baseValue, Action<Vector3> setAction) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(vector3InputFieldPrefab, parentTransform); Vector3InputField component = val.GetComponent<Vector3InputField>(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public IntRangeInputField CreateIntRangeInputField(Transform parentTransform, TitleParameter titleParameter, IntRange baseValue, Action<IntRange> setAction) { GameObject val = Object.Instantiate<GameObject>(intRangeInputFieldPrefab, parentTransform); IntRangeInputField component = val.GetComponent<IntRangeInputField>(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public FloatRangeInputField CreateFloatRangeInputField(Transform parentTransform, TitleParameter titleParameter, FloatRange baseValue, Action<FloatRange> setAction) { GameObject val = Object.Instantiate<GameObject>(floatRangeInputFieldPrefab, parentTransform); FloatRangeInputField component = val.GetComponent<FloatRangeInputField>(); component.SetupInputField(titleParameter, baseValue, setAction); return component; } public IntSliderField CreateIntSliderField(Transform parentTransform, TitleParameter titleParameter, IntParameter intParameter, Action<int> setAction) { GameObject val = Object.Instantiate<GameObject>(intSliderFieldPrefab, parentTransform); IntSliderField component = val.GetComponent<IntSliderField>(); component.SetupInputField(titleParameter, intParameter, setAction); return component; } public ListUIElement CreateListUIField<T>(Transform parentTransform, TitleParameter titleParameter, List<T> list, bool useAddRemove = true) { return CreateListSimpleUIField(parentTransform, titleParameter, list, useExtended: false, useAddRemove); } public ListUIElement CreateListExtendedUIField<T>(Transform parentTransform, TitleParameter titleParameter, List<T> list, bool useAddRemove = true) { return CreateListSimpleUIField(parentTransform, titleParameter, list, useExtended: true, useAddRemove); } private ListUIElement CreateListSimpleUIField<T>(Transform parentTransform, TitleParameter titleParameter, List<T> list, bool useExtended, bool useAddRemove) { GameObject val = Object.Instantiate<GameObject>(listUIPrefab, parentTransform); ListUIElement component = val.GetComponent<ListUIElement>(); component.SetupList(titleParameter, list, useExtended, useAddRemove); return component; } public DropdownInputField CreateOptionsUIField<T>(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<T> setAction, Func<int, T> convertIndex, IEnumerable<string> options) { GameObject val = Object.Instantiate<GameObject>(optionsUIPrefab, parentTransform); DropdownInputField component = val.GetComponent<DropdownInputField>(); component.SetupDropdown(titleParameter, baseValue, setAction, convertIndex, options); return component; } public DropdownInputField CreateLevelOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<ExtendedLevel> setAction) { MainPanel mainPanel = MainPanel.Instance; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => mainPanel.levels[i], mainPanel.levelOptions); } public DropdownInputField CreateMainPathExtenderUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<MainPathExtender> setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.mainPathExtenders.list[i].Item, assetCache.mainPathExtenders.options); } public DropdownInputField CreateTileOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<GameObject> setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.tiles.list[i].Item, assetCache.tiles.options); } public DropdownInputField CreateTileSetsOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<TileSet> setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.tileSets.list[i].Item, assetCache.tileSets.options); } public DropdownInputField CreateArchetypeOptionsUIField(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<DungeonArchetype> setAction) { DungeonFlowCacheAssets assetCache = Instance.selectedAssetCache; return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => assetCache.archetypes.list[i].Item, assetCache.archetypes.options); } public DropdownInputField CreateEnumOptionsUIField<T>(Transform parentTransform, TitleParameter titleParameter, int baseValue, Action<T> setAction) where T : Enum { string[] names = Enum.GetNames(typeof(T)); return CreateOptionsUIField(parentTransform, titleParameter, baseValue, setAction, (int i) => (T)Enum.ToObject(typeof(T), i), names); } public DropdownInputField CreateAnimationCurveOptionsUIField(Transform parentTransform, TitleParameter titleParameter, AnimationCurve baseValue, Action<AnimationCurve> setAction) { var (curves, options) = CreateAnimationCurves(baseValue); setAction(curves[0]); return CreateOptionsUIField(parentTransform, titleParameter, 0, setAction, (int i) => curves[i], options); } private (List<AnimationCurve> animationCurves, List<string> options) CreateAnimationCurves(AnimationCurve custom) { List<AnimationCurve> list = new List<AnimationCurve>(); List<string> list2 = new List<string>(); if (custom != null) { list.Add(custom); list2.Add("Custom"); } list.Add(AnimationCurve.Constant(0f, 1f, 1f)); list2.Add("Constant 1"); list.Add(AnimationCurve.Linear(0f, 0f, 1f, 1f)); list2.Add("Linear 0-1"); list.Add(AnimationCurve.Linear(1f, 1f, 0f, 0f)); list2.Add("Linear 1-0"); list.Add(AnimationCurve.EaseInOut(0f, 0f, 1f, 1f)); list2.Add("EaseInOut 0-1"); list.Add(AnimationCurve.EaseInOut(1f, 1f, 0f, 0f)); list2.Add("EaseInOut 1-0"); return (list, list2); } } internal class DevDebugOpen : MonoBehaviour { public static bool IsSinglePlayerInShip() { StartOfRound instance = StartOfRound.Instance; RoundManager instance2 = RoundManager.Instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance2)) { return instance.connectedPlayersAmount == 0 && instance.inShipPhase; } return false; } public void Update() { if (IfKeyPress(Keyboard.current.mKey, Keyboard.current.leftAltKey) && (Object)(object)DevDebugManager.Instance == (Object)null && IsSinglePlayerInShip()) { Object.Instantiate<GameObject>(Assets.DevDebugPrefab); } } private bool IfKeyPress(KeyControl key, KeyControl hold) { if (((ButtonControl)hold).isPressed && ((ButtonControl)key).wasPressedThisFrame) { return true; } return false; } } internal class PanelTab : MonoBehaviour { public bool active; [Header("References")] public RectTransform rectTransform; public Image image; private void Update() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_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_0096: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) float num = (active ? 48f : 36f); Color val = (active ? new Color(20f / 51f, 20f / 51f, 20f / 51f, 1f) : new Color(10f / 51f, 10f / 51f, 10f / 51f, 1f)); Vector2 sizeDelta = rectTransform.sizeDelta; sizeDelta.y = Mathf.Lerp(sizeDelta.y, num, Time.deltaTime * 10f); rectTransform.sizeDelta = sizeDelta; Color color = ((Graphic)image).color; color = Color.Lerp(color, val, Time.deltaTime * 10f); ((Graphic)image).color = color; } } } namespace DunGenPlus.DevTools.UIElements { internal abstract class BaseInputField<T> : BaseUIElement { public abstract void Set(T value); protected int ParseTextInt(string text, int defaultValue = 0) { if (int.TryParse(te