Decompiled source of DungeonGenerationPlus v1.3.3
DunGenPlus.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.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 bool IsDunGenExtenderActive(DungeonFlow dungeonFlow) { return IsDunGenExtenderActive(GetDunGenExtender(dungeonFlow)); } public static bool IsDunGenExtenderActive(DunGenExtender extender) { return (Object)(object)extender != (Object)null && (Object)(object)extender == (Object)(object)DunGenPlusGenerator.Instance; } public static DunGenExtender CreateDunGenExtender(DungeonFlow dungeonFlow) { DunGenExtender dunGenExtender = ScriptableObject.CreateInstance<DunGenExtender>(); dunGenExtender.DungeonFlow = dungeonFlow; return dunGenExtender; } public static void AddTileToMainPathDictionary(Dictionary<TileProxy, Tile> dictionary) { DunGenPlusGenerator.AddTileToMainPathDictionary(dictionary); } public static bool IsDevDebugModeActive() { return DevDebugManager.IsActive; } } 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 { internal const string LocalMainPathGlobalPropsTooltip = "Limits the amount of Global Props that can spawn on a single main path.\n\nThis does not afffect the global limit defined in DungeonFlow."; 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>()); [Tooltip("Limits the amount of Global Props that can spawn on a single main path.\n\nThis does not afffect the global limit defined in DungeonFlow.")] public List<LocalGlobalPropSettings> LocalGroupProps = new List<LocalGlobalPropSettings>(); [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.3.3")] [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.3.3"; 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(); DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction); } } } 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) { PrintInstruction(instruction); } } public static void PrintInstruction(CodeInstruction inst) { string text = inst.opcode.ToString(); string text2 = ((inst.operand != null) ? inst.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 TileProxy lastAttachTo; public static IEnumerable<TileSet> lastUseableTileSets; public static float lastNormalizedDepth; public static DungeonArchetype lastArchetype; [HarmonyPriority(800)] [HarmonyPatch(typeof(DungeonGenerator), "Generate")] [HarmonyPrefix] public static void GeneratePatch(ref DungeonGenerator __instance) { DunGenPlusGenerator.Deactivate(); DungeonFlow dungeonFlow = __instance.DungeonFlow; DunGenExtender dunGenExtender = API.GetDunGenExtender(dungeonFlow); if (Object.op_Implicit((Object)(object)dunGenExtender) && dunGenExtender.Active) { Plugin.logger.LogInfo((object)("Loading DunGenExtender for " + ((Object)dungeonFlow).name)); DunGenPlusGenerator.Activate(__instance, dunGenExtender); } else { Plugin.logger.LogInfo((object)"Did not load a DunGenExtenderer"); DunGenPlusGenerator.Deactivate(); } } [HarmonyPostfix] [HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate")] public static void InnerGeneratePatch(ref DungeonGenerator __instance, bool isRetry, ref IEnumerator __result) { if (API.IsDevDebugModeActive() && !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); } } [HarmonyTranspiler] [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] public static IEnumerable<CodeInstruction> AddTileDebugPatch(IEnumerable<CodeInstruction> instructions) { InstructionSequenceStandard addTileSequence = new InstructionSequenceStandard("Add Tile Placement"); addTileSequence.AddBasic(OpCodes.Callvirt); addTileSequence.AddBasic(OpCodes.Ldc_I4_0); addTileSequence.AddBasic(OpCodes.Bgt); addTileSequence.AddBasicLocal(OpCodes.Ldloc_S, 9); foreach (CodeInstruction instruction in instructions) { if (addTileSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("RecordLastTilePlacementResult", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)9); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); yield return instruction; } else { yield return instruction; } } addTileSequence.ReportComplete(); } [HarmonyTranspiler] [HarmonyPatch(typeof(Dungeon), "FromProxy")] public static IEnumerable<CodeInstruction> FromProxyPatch(IEnumerable<CodeInstruction> instructions) { InstructionSequenceStandard endSequence = new InstructionSequenceStandard("Forloop End"); endSequence.AddBasicLocal(OpCodes.Ldloca_S, 1); endSequence.AddBasic(OpCodes.Constrained); endSequence.AddBasic(OpCodes.Callvirt); endSequence.AddBasic(OpCodes.Endfinally); foreach (CodeInstruction instruction in instructions) { if (endSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("AddTileToMainPathDictionary", BindingFlags.Static | BindingFlags.Public); yield return new CodeInstruction(OpCodes.Ldloc_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } yield return instruction; } endSequence.ReportComplete(); } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")] public static bool ProcessGlobalPropsPatch(ref DungeonGenerator __instance) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.Properties.MainPathProperties.MainPathDetails.Any((MainPathExtender d) => d.LocalGroupProps.Count > 0)) { Plugin.logger.LogDebug((object)"Performing Local Global Props algorithm"); DunGenPlusGenerator.ProcessGlobalPropsPerMainPath(__instance); return false; } return true; } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static IEnumerable<CodeInstruction> GenerateMainPathDebugPatch(IEnumerable<CodeInstruction> instructions) { InstructionSequenceStandard tileProxyNullSequence = new InstructionSequenceStandard("TileProxyNull"); tileProxyNullSequence.AddBasic(OpCodes.Br); tileProxyNullSequence.AddBasicLocal(OpCodes.Ldloc_S, 14); tileProxyNullSequence.AddBasic(OpCodes.Brtrue); foreach (CodeInstruction instruction in instructions) { if (tileProxyNullSequence.VerifyStage(instruction)) { MethodInfo specialFunction = typeof(DunGenPlusGenerator).GetMethod("PrintAddTileErrorQuick", BindingFlags.Static | BindingFlags.Public); FieldInfo field = typeof(DungeonGenerator).Assembly.GetType("DunGen.DungeonGenerator+<GenerateMainPath>d__100").GetField("<j>5__8", BindingFlags.Instance | BindingFlags.NonPublic); yield return instruction; yield return new CodeInstruction(OpCodes.Ldloc_1, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldfld, (object)field); yield return new CodeInstruction(OpCodes.Call, (object)specialFunction); } else { yield return instruction; } } tileProxyNullSequence.ReportComplete(); } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] public static void AddTileDebugPatch(TileProxy attachTo, IEnumerable<TileSet> useableTileSets, float normalizedDepth, DungeonArchetype archetype) { lastAttachTo = attachTo; lastUseableTileSets = useableTileSets; lastNormalizedDepth = normalizedDepth; lastArchetype = archetype; } } internal class LethalLevelLoaderPatches { [HarmonyPrefix] [HarmonyPatch(typeof(Patches), "DungeonGeneratorGenerate_Prefix")] public static bool DungeonGeneratorGenerate_Prefix_Patches_Prefix() { return (Object)(object)DevDebugManager.Instance == (Object)null; } [HarmonyPatch(typeof(EventPatches), "DungeonGeneratorGenerate_Prefix")] [HarmonyPrefix] public static void DungeonGeneratorGenerate_Prefix_EventPatches_Prefix() { ScrapItemManager.Initialize(Patches.RoundManager); EnemyManager.Initialize(Patches.RoundManager); } } 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) }); } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "Start")] public static void StartPatch(ref RoundManager __instance) { ScrapItemManager.UndoPreviousChanges(); EnemyManager.UndoPreviousChanges(); } [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 { } } namespace DunGenPlus.Managers { public static class EnemyManager { internal static SelectableLevel previousLevel; internal static List<SpawnableEnemyWithRarity> previouslyAddedEnemies = new List<SpawnableEnemyWithRarity>(); internal static List<SpawnableEnemyWithRarity> previouslyModifiedEnemies = new List<SpawnableEnemyWithRarity>(); internal static void UndoPreviousChanges() { if (!((Object)(object)previousLevel != (Object)null)) { return; } Plugin.logger.LogDebug((object)("Undoing changes of EnemyManager for " + previousLevel.PlanetName)); List<SpawnableEnemyWithRarity> enemies = previousLevel.Enemies; if (previouslyAddedEnemies.Count > 0) { for (int num = previouslyAddedEnemies.Count - 1; num >= 0; num--) { SpawnableEnemyWithRarity val = previouslyAddedEnemies[num]; int num2 = enemies.Count - 1; while (true) { if (num2 >= 0) { SpawnableEnemyWithRarity val2 = enemies[num2]; if (val2 == val) { enemies.RemoveAt(num2); Plugin.logger.LogDebug((object)("Properly removed temporary enemy " + val.enemyType.enemyName)); break; } num2--; continue; } Plugin.logger.LogWarning((object)("Couldn't find/remove temporary enemy " + val.enemyType.enemyName)); break; } } previouslyAddedEnemies.Clear(); } if (previouslyModifiedEnemies.Count > 0) { for (int i = 0; i < previouslyModifiedEnemies.Count; i++) { SpawnableEnemyWithRarity val3 = previouslyModifiedEnemies[i]; int num3 = 0; while (true) { if (num3 < enemies.Count) { if ((Object)(object)enemies[num3].enemyType == (Object)(object)val3.enemyType) { enemies[num3] = val3; Plugin.logger.LogDebug((object)("Properly fixed modified enemy " + val3.enemyType.enemyName)); break; } num3++; continue; } Plugin.logger.LogWarning((object)("Couldn't find/fix modified enemy " + val3.enemyType.enemyName)); break; } } previouslyModifiedEnemies.Clear(); } previousLevel = null; } internal static void Initialize(RoundManager roundManager) { UndoPreviousChanges(); previousLevel = roundManager.currentLevel; Plugin.logger.LogDebug((object)("Initialized EnemyManager to " + previousLevel.PlanetName)); } public static void AddEnemies(IEnumerable<SpawnableEnemyWithRarity> newEnemies) { foreach (SpawnableEnemyWithRarity newEnemy in newEnemies) { AddEnemy(newEnemy); } } public static void AddEnemy(SpawnableEnemyWithRarity newEnemy) { List<SpawnableEnemyWithRarity> enemies = previousLevel.Enemies; for (int i = 0; i < enemies.Count; i++) { if ((Object)(object)enemies[i].enemyType == (Object)(object)newEnemy.enemyType) { if (enemies[i].rarity == newEnemy.rarity) { Plugin.logger.LogDebug((object)("Skipping " + newEnemy.enemyType.enemyName + " as it has the same rarity")); return; } previouslyModifiedEnemies.Add(enemies[i]); enemies[i] = newEnemy; Plugin.logger.LogDebug((object)$"Modifying already existing enemy {newEnemy.enemyType.enemyName} to new weight {newEnemy.rarity}"); return; } } previouslyAddedEnemies.Add(newEnemy); enemies.Add(newEnemy); Plugin.logger.LogDebug((object)$"Adding temporary enemy {newEnemy.enemyType.enemyName} with weight {newEnemy.rarity}"); } } public static class ScrapItemManager { internal static SelectableLevel previousLevel; internal static List<SpawnableItemWithRarity> previouslyAddedItems = new List<SpawnableItemWithRarity>(); internal static List<SpawnableItemWithRarity> previouslyModifiedItems = new List<SpawnableItemWithRarity>(); internal static void UndoPreviousChanges() { if (!((Object)(object)previousLevel != (Object)null)) { return; } Plugin.logger.LogDebug((object)("Undoing changes of ScrapItemManager for " + previousLevel.PlanetName)); List<SpawnableItemWithRarity> spawnableScrap = previousLevel.spawnableScrap; if (previouslyAddedItems.Count > 0) { for (int num = previouslyAddedItems.Count - 1; num >= 0; num--) { SpawnableItemWithRarity val = previouslyAddedItems[num]; int num2 = spawnableScrap.Count - 1; while (true) { if (num2 >= 0) { SpawnableItemWithRarity val2 = spawnableScrap[num2]; if (val2 == val) { spawnableScrap.RemoveAt(num2); Plugin.logger.LogDebug((object)("Properly removed temporary item " + val.spawnableItem.itemName)); break; } num2--; continue; } Plugin.logger.LogWarning((object)("Couldn't find/remove temporary item " + val.spawnableItem.itemName)); break; } } previouslyAddedItems.Clear(); } if (previouslyModifiedItems.Count > 0) { for (int i = 0; i < previouslyModifiedItems.Count; i++) { SpawnableItemWithRarity val3 = previouslyModifiedItems[i]; int num3 = 0; while (true) { if (num3 < spawnableScrap.Count) { if ((Object)(object)spawnableScrap[num3].spawnableItem == (Object)(object)val3.spawnableItem) { spawnableScrap[num3] = val3; Plugin.logger.LogDebug((object)("Properly fixed modified item " + val3.spawnableItem.itemName)); break; } num3++; continue; } Plugin.logger.LogWarning((object)("Couldn't find/fix modified item " + val3.spawnableItem.itemName)); break; } } previouslyModifiedItems.Clear(); } previousLevel = null; } internal static void Initialize(RoundManager roundManager) { UndoPreviousChanges(); previousLevel = roundManager.currentLevel; Plugin.logger.LogDebug((object)("Initialized ScrapItemManager to " + previousLevel.PlanetName)); } public static void AddItems(IEnumerable<SpawnableItemWithRarity> newItems) { foreach (SpawnableItemWithRarity newItem in newItems) { AddItem(newItem); } } public static void AddItem(SpawnableItemWithRarity newItem) { List<SpawnableItemWithRarity> spawnableScrap = previousLevel.spawnableScrap; for (int i = 0; i < spawnableScrap.Count; i++) { if ((Object)(object)spawnableScrap[i].spawnableItem == (Object)(object)newItem.spawnableItem) { if (spawnableScrap[i].rarity == newItem.rarity) { Plugin.logger.LogDebug((object)("Skipping " + newItem.spawnableItem.itemName + " as it has the same rarity")); return; } previouslyModifiedItems.Add(spawnableScrap[i]); spawnableScrap[i] = newItem; Plugin.logger.LogDebug((object)$"Modifying already existing item {newItem.spawnableItem.itemName} to new weight {newItem.rarity}"); return; } } previouslyAddedItems.Add(newItem); spawnableScrap.Add(newItem); Plugin.logger.LogDebug((object)$"Adding temporary item {newItem.spawnableItem.itemName} with weight {newItem.rarity}"); } } 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(); } if (doorwayCleanupList.Count != 0) { 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; public static TilePlacementResult lastTilePlacementResult; internal static HDRenderPipelineAsset previousHDRPAsset; internal static HDRenderPipelineAsset newHDRPAsset; private static Dictionary<TileProxy, int> tileProxyMainPath = new Dictionary<TileProxy, int>(); private static Dictionary<Tile, int> tileMainPath = new Dictionary<Tile, 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 PrintAddTileError(DungeonGenerator gen, TileProxy previousTile, DungeonArchetype archetype, IEnumerable<TileSet> useableTileSets, int branchId, int lineLength, float lineRatio) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) string text = ((previousTile != null) ? ((Object)previousTile.Prefab).name : "NULL"); string text2 = (Object.op_Implicit((Object)(object)archetype) ? ((Object)archetype).name : "NULL"); string text3 = string.Join(", ", useableTileSets); List<string> list = new List<string>(); list.Add($"Main branch gen failed at Branch {branchId} (Length: {lineLength}, Ratio: {lineRatio})"); list.Add("Prev tile: " + text); list.Add("Archetype: " + text2); list.Add("Tilesets: " + text3); list.Add($"Reason: {lastTilePlacementResult}"); if (previousTile != null) { string text4 = string.Join(", ", previousTile.UnusedDoorways.Select((DoorwayProxy d) => ((Object)((Component)d.DoorwayComponent).gameObject).name)); string text5 = string.Join(", ", previousTile.UsedDoorways.Select((DoorwayProxy d) => ((Object)((Component)d.DoorwayComponent).gameObject).name)); list.Add("Available Doorways: " + text4); list.Add("Used Doorways: " + text5); if (API.IsDevDebugModeActive()) { Queue<DoorwayPair> doorwayPairs = GetDoorwayPairs(gen, previousTile, useableTileSets, archetype, lineRatio); string text6 = string.Join(", ", from d in doorwayPairs.Select((DoorwayPair t) => ((DoorwayPair)(ref t)).NextTemplate.Prefab).Distinct() select ((Object)d).name); list.Add("Next Possible Tiles: " + text6); } } list.Add(string.Empty); Plugin.logger.LogDebug((object)string.Join("\n", list)); } public static void PrintAddTileErrorQuick(DungeonGenerator gen, int lineLength) { PrintAddTileError(gen, DungeonGeneratorPatch.lastAttachTo, DungeonGeneratorPatch.lastArchetype, DungeonGeneratorPatch.lastUseableTileSets, 0, lineLength, DungeonGeneratorPatch.lastNormalizedDepth); } public static void RecordLastTilePlacementResult(DungeonGenerator gen, 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; } public static void ProcessGlobalPropsPerMainPath(DungeonGenerator dungeonGenerator) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown HashSet<int> hashSet = (from x in Properties.MainPathProperties.MainPathDetails.SelectMany((MainPathExtender d) => d.LocalGroupProps) select x.ID).ToHashSet(); Dictionary<int, Dictionary<int, GameObjectChanceTable>> dictionary = new Dictionary<int, Dictionary<int, GameObjectChanceTable>>(); Dictionary<int, GameObjectChanceTable> dictionary2 = new Dictionary<int, GameObjectChanceTable>(); foreach (Tile allTile in dungeonGenerator.CurrentDungeon.AllTiles) { GlobalProp[] componentsInChildren = ((Component)allTile).GetComponentsInChildren<GlobalProp>(); foreach (GlobalProp val in componentsInChildren) { GameObjectChanceTable value2; if (hashSet.Contains(val.PropGroupID)) { if (!dictionary.TryGetValue(val.PropGroupID, out var value)) { value = new Dictionary<int, GameObjectChanceTable>(); dictionary.Add(val.PropGroupID, value); } int mainPathIndexFromTile = GetMainPathIndexFromTile(allTile); if (!value.TryGetValue(mainPathIndexFromTile, out value2)) { value2 = new GameObjectChanceTable(); value.Add(mainPathIndexFromTile, value2); } } else if (!dictionary2.TryGetValue(val.PropGroupID, out value2)) { value2 = new GameObjectChanceTable(); dictionary2.Add(val.PropGroupID, value2); } float num = (allTile.Placement.IsOnMainPath ? val.MainPathWeight : val.BranchPathWeight); num *= val.DepthWeightScale.Evaluate(allTile.Placement.NormalizedDepth); value2.Weights.Add(new GameObjectChance(((Component)val).gameObject, num, 0f, (TileSet)null)); } } foreach (Dictionary<int, GameObjectChanceTable> value4 in dictionary.Values) { foreach (GameObjectChanceTable value5 in value4.Values) { foreach (GameObjectChance weight in value5.Weights) { weight.Value.SetActive(false); } } } foreach (GameObjectChanceTable value6 in dictionary2.Values) { foreach (GameObjectChance weight2 in value6.Weights) { weight2.Value.SetActive(false); } } List<int> list = new List<int>(dictionary.Count + dictionary2.Count); foreach (KeyValuePair<int, GameObjectChanceTable> pair in dictionary2) { if (list.Contains(pair.Key)) { Plugin.logger.LogWarning((object)("Dungeon Flow contains multiple entries for the global prop group ID: " + pair.Key + ". Only the first entry will be used.")); continue; } GlobalPropSettings val2 = dungeonGenerator.DungeonFlow.GlobalProps.Where((GlobalPropSettings x) => x.ID == pair.Key).FirstOrDefault(); if (val2 != null) { GameObjectChanceTable table2 = pair.Value.Clone(); int random = val2.Count.GetRandom(dungeonGenerator.RandomStream); int num2 = ProcessGlobalPropID(table2, random, 0, random); Plugin.logger.LogDebug((object)$"Global ID: {pair.Key} ({num2} / {random})"); list.Add(pair.Key); } } foreach (KeyValuePair<int, Dictionary<int, GameObjectChanceTable>> item in dictionary) { int globalPropId = item.Key; if (list.Contains(globalPropId)) { Plugin.logger.LogWarning((object)("Dungeon Flow contains multiple entries for the global prop group ID: " + item.Key + ". Only the first entry will be used.")); continue; } GlobalPropSettings val3 = dungeonGenerator.DungeonFlow.GlobalProps.Where((GlobalPropSettings x) => x.ID == globalPropId).FirstOrDefault(); if (val3 == null) { continue; } int num3 = 0; int random2 = val3.Count.GetRandom(dungeonGenerator.RandomStream); Dictionary<int, GameObjectChanceTable> value3 = item.Value; Plugin.logger.LogDebug((object)$"Local ID: {item.Key} (Max {random2})"); List<int> list2 = new List<int>(); foreach (KeyValuePair<int, GameObjectChanceTable> item2 in value3) { int key = item2.Key; List<LocalGlobalPropSettings> localGroupProps = Properties.MainPathProperties.GetMainPathDetails(key).LocalGroupProps; LocalGlobalPropSettings localGlobalPropSettings = localGroupProps.Where((LocalGlobalPropSettings x) => x.ID == globalPropId).FirstOrDefault(); if (localGlobalPropSettings == null) { Plugin.logger.LogDebug((object)$"Main Path {key}: No local ID defined, skipping"); continue; } GameObjectChanceTable table3 = item2.Value.Clone(); int random3 = localGlobalPropSettings.Count.GetRandom(dungeonGenerator.RandomStream); int num4 = ProcessGlobalPropID(table3, random3, num3, random2); num3 += num4; Plugin.logger.LogDebug((object)$"Main Path {key}: Local ({num4} / {random3}), Global ({num3} / {random2})"); if (!localGlobalPropSettings.UseToReachGlobalPropLimit) { list2.Add(key); } } foreach (int item3 in list2) { value3.Remove(item3); } if (num3 < random2 && value3.Count > 0) { string text = string.Join(", ", value3.Keys); Plugin.logger.LogDebug((object)("Combining main paths (" + text + ") into one GameObjectChanceTable")); GameObjectChanceTable[] tables2 = value3.Select((KeyValuePair<int, GameObjectChanceTable> d) => d.Value).ToArray(); int num5 = ProcessRemainingGlobalPropID(tables2, random2 - num3); num3 += num5; Plugin.logger.LogDebug((object)$"Spawned remaining props ({num3} / {random2})"); } list.Add(item.Key); } int ProcessGlobalPropID(GameObjectChanceTable table, int localMax, int globalCount, int globalMax) { localMax = Mathf.Clamp(localMax, 0, table.Weights.Count); int k; for (k = 0; k < localMax && k + globalCount < globalMax; k++) { GameObjectChance random4 = table.GetRandom(dungeonGenerator.RandomStream, true, 0f, (GameObject)null, true, true); if (random4 != null && (Object)(object)random4.Value != (Object)null) { random4.Value.SetActive(true); } } return k; } int ProcessRemainingGlobalPropID(GameObjectChanceTable[] tables, int count) { count = Mathf.Clamp(count, 0, tables.Sum((GameObjectChanceTable t) => t.Weights.Count)); int j; for (j = 0; j < count; j++) { GameObject combinedRandom = GameObjectChanceTable.GetCombinedRandom(dungeonGenerator.RandomStream, true, 0f, tables); if ((Object)(object)combinedRandom != (Object)null) { combinedRandom.SetActive(true); } } return j; } } 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]; } public static int GetMainPathIndexFromTile(Tile tile) { if (tileMainPath.TryGetValue(tile, out var value)) { return value; } Plugin.logger.LogWarning((object)"Error with GetMainPathIndexFromTile.\nPLEASE REPORT TO MR. DEV WITH YOUR MOD PACK. THIS SHOULD NOT BE HAPPENING!"); return 0; } public static void AddTileProxy(TileProxy tileProxy, int index) { tileProxyMainPath.Add(tileProxy, index); } public static void AddMainPathTileProxies(IEnumerable<TileProxy> tileProxies, int index) { float num = tileProxies.Last().Placement.PathDepth; foreach (TileProxy tileProxy in tileProxies) { AddTileProxy(tileProxy, index); tileProxy.Placement.NormalizedPathDepth = (float)tileProxy.Placement.PathDepth / num; } } public static void BuildBranchPathTileProxiesDictionary(DungeonProxy dungeonProxy) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) int index = 0; foreach (ProxyDoorwayConnection connection in dungeonProxy.Connections) { ProxyDoorwayConnection current = connection; TileProxy tileProxy = ((ProxyDoorwayConnection)(ref current)).A.TileProxy; if (tileProxy.Placement.IsOnMainPath) { index = GetMainPathIndexFromTileProxy(tileProxy); } TileProxy tileProxy2 = ((ProxyDoorwayConnection)(ref current)).B.TileProxy; if (!tileProxy2.Placement.IsOnMainPath) { AddTileProxy(tileProxy2, index); } } } public static void AddTileToMainPathDictionary(Dictionary<TileProxy, Tile> dictionary) { if (!Active) { return; } foreach (KeyValuePair<TileProxy, Tile> item in dictionary) { tileMainPath.Add(item.Value, GetMainPathIndexFromTileProxy(item.Key)); } } 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(); tileMainPath.Clear(); List<TileProxy> firstMainPathTiles = gen.proxyDungeon.MainPathTiles.ToList(); AddMainPathTileProxies(firstMainPathTiles, 0); 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>> { firstMainPathTiles }; 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) { PrintAddTileError(gen, previousTile, archetype, useableTileSets, b + 1, t2, lineDepthRatio2); 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; } AddMainPathTileProxies(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]; if (!Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim) { BuildBranchPathTileProxiesDictionary(gen.proxyDungeon); } 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; BuildBranchPathTileProxiesDictionary(gen.proxyDungeon); 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; AddMainPathTileProxies(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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Invalid comparison between Unknown and I4 //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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)); DoorwayPairStopwatch.Reset(); DoorwayPairStopwatch.Start(); Queue<DoorwayPair> doorwayPairs = GetDoorwayPairs(gen, attachTo, collection, archetype, normalizedDepth); 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 Queue<DoorwayPair> GetDoorwayPairs(DungeonGenerator gen, TileProxy attachTo, IEnumerable<GameObjectChance> collection, DungeonArchetype archetype, float normalizedDepth) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_009c: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown bool value = attachTo.PrefabTile.AllowRotation; if (gen.OverrideAllowTileRotation) { value = gen.AllowTileRotation; } DoorwayPairFinder val = new DoorwayPairFinder(); val.DungeonFlow = gen.DungeonFlow; val.RandomStream = gen.RandomStream; val.Archetype = archetype; val.GetTileTemplateDelegate = new GetTileTemplateDelegate(gen.GetTileTemplate); val.IsOnMainPath = false; val.NormalizedDepth = normalizedDepth; val.PreviousTile = attachTo; val.UpVector = gen.UpVector; val.AllowRotation = value; val.TileWeights = new List<GameObjectChance>(collection); val.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 val2 = (TileRepeatMode)0; if (gen.OverrideRepeatMode) { val2 = gen.RepeatMode; } else if (next != null) { val2 = next.PrefabTile.RepeatMode; } TileRepeatMode val3 = val2; TileRepeatMode val4 = val3; return (int)val4 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 {val2} is not implemented"), }; }; int? num = (gen.UseMaximumPairingAttempts ? new int?(gen.MaxPairingAttempts) : null); return val.GetDoorwayPairs(num); } private static Queue<DoorwayPair> GetDoorwayPairs(DungeonGenerator gen, TileProxy attachTo, IEnumerable<TileSet> useableTileSets, DungeonArchetype archetype, float normalizedDepth) { IEnumerable<GameObjectChance> collection = useableTileSets.SelectMany((TileSet t) => t.TileWeights.Weights); return GetDoorwayPairs(gen, attachTo, collection, archetype, normalizedDepth); } 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; } AddTileProxy(val, GetMainPathIndexFromTileProxy(item2)); 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 || API.IsDevDebugModeActive(); } } 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 LayoutElement canvasLayoutElement; 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 bool canvasExtendedInAnimation; 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; AssetsPanel.Instance = null; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; EndDevCamera(); } private unsafe void Update() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or
LoadstoneNighty.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using DunGen; using DunGen.Graph; using DunGenPlus; using DunGenPlus.Collections; using HarmonyLib; using Loadstone.Patches; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LoadstoneNighty")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LoadstoneNighty")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b7c6eabd-16db-4de8-8013-1fa7da6e8de8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace LoadstoneNighty; public class PatchVer16 { public static void Activate() { try { Plugin.Instance.harmony.PatchAll(typeof(PatchVer16)); } catch { } Plugin.logger.LogInfo((object)"FromProxyEnd function has been patched!"); } [HarmonyPrefix] [HarmonyPatch(typeof(FromProxyPatches), "FromProxyEnd")] public static void FromProxyEndPatch(Dictionary<TileProxy, Tile> dictionary) { API.AddTileToMainPathDictionary(dictionary); } } public class PatchVer17 { public static void Activate() { DungenOptimizationPatches.tileCollectors.Add(GetTiles); Plugin.logger.LogInfo((object)"DungenOptimizationPatches function has been patched!"); } private static HashSet<Tile> GetTiles(DungeonGenerator generator) { DungeonFlow dungeonFlow = generator.DungeonFlow; DunGenExtender dunGenExtender = API.GetDunGenExtender(dungeonFlow); HashSet<Tile> tiles = new HashSet<Tile>(); if (API.IsDunGenExtenderActive(dunGenExtender)) { Plugin.logger.LogDebug((object)"Creating custom hashset for Loadstone"); DunGenExtenderProperties properties = dunGenExtender.Properties; GenerateTileHashSet(ref tiles, properties.MainPathProperties.MainPathDetails); GenerateTileHashSet(ref tiles, properties.AdditionalTilesProperties.AdditionalTileSets); GenerateTileHashSet(ref tiles, properties.NormalNodeArchetypesProperties.NormalNodeArchetypes); GenerateTileHashSet(ref tiles, properties.LineRandomizerProperties.Archetypes); } return tiles; } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<NodeArchetype> nodes) { foreach (NodeArchetype node in nodes) { GenerateTileHashSet(ref tiles, node.Archetypes); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<AdditionalTileSetList> list) { foreach (AdditionalTileSetList item in list) { GenerateTileHashSet(ref tiles, item.TileSets); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<MainPathExtender> extenders) { foreach (MainPathExtender extender in extenders) { GenerateTileHashSet(ref tiles, extender.Nodes.Value); GenerateTileHashSet(ref tiles, extender.Lines.Value); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<GraphNode> nodes) { foreach (GraphNode node in nodes) { GenerateTileHashSet(ref tiles, node.TileSets); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<GraphLine> lines) { foreach (GraphLine line in lines) { GenerateTileHashSet(ref tiles, line.DungeonArchetypes); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<DungeonArchetype> archetypes) { foreach (DungeonArchetype archetype in archetypes) { GenerateTileHashSet(ref tiles, archetype.TileSets); GenerateTileHashSet(ref tiles, archetype.BranchCapTileSets); } } private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<TileSet> tileSets) { foreach (TileSet tileSet in tileSets) { foreach (GameObjectChance weight in tileSet.TileWeights.Weights) { Tile component = weight.Value.GetComponent<Tile>(); if ((Object)(object)component != (Object)null) { tiles.Add(component); } } } } [HarmonyPrefix] [HarmonyPatch(typeof(FromProxyPatches), "FromProxyEnd")] public static void FromProxyEndPatch(Dictionary<TileProxy, Tile> dictionary) { API.AddTileToMainPathDictionary(dictionary); } } [BepInPlugin("dev.ladyalice.dungenplus.loadstonepatch", "Dungeon Generation Plus Loadstone Patch", "1.0.0")] [BepInDependency("dev.ladyalice.dungenplus", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string modGUID = "dev.ladyalice.dungenplus.loadstonepatch"; private const string modName = "Dungeon Generation Plus Loadstone Patch"; private const string modVersion = "1.0.0"; public const string targetModGUID = "com.adibtw.loadstone"; public const string targetModVersion = "0.1.17"; public readonly Harmony harmony = new Harmony("dev.ladyalice.dungenplus.loadstonepatch"); public static Plugin Instance { get; private set; } public static ManualLogSource logger { get; internal set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("dev.ladyalice.dungenplus.loadstonepatch"); if (Chainloader.PluginInfos.ContainsKey("com.adibtw.loadstone")) { logger.LogInfo((object)"Plugin Dungeon Generation Plus Loadstone Patch has been added!"); PatchVer16.Activate(); PluginInfo val = Chainloader.PluginInfos["com.adibtw.loadstone"]; Version version = val.Metadata.Version; bool flag; if (string.IsNullOrWhiteSpace("0.1.17")) { flag = true; } else { Version version2 = new Version("0.1.17"); flag = version >= version2; } if (flag) { PatchVer17.Activate(); } } } }