diff --git a/DunGenPlus/DunGenPlus/Collections/TileExtenderProxy.cs b/DunGenPlus/DunGenPlus/Collections/TileExtenderProxy.cs new file mode 100644 index 0000000..4cdb249 --- /dev/null +++ b/DunGenPlus/DunGenPlus/Collections/TileExtenderProxy.cs @@ -0,0 +1,47 @@ +using DunGen; +using DunGenPlus.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace DunGenPlus.Collections { + internal class TileExtenderProxy { + public TileProxy TileProxy { get; internal set; } + public TileExtender PrefabTileExtender { get; internal set; } + public List Entrances { get; internal set; } + public List Exits { get; internal set; } + + public TileExtenderProxy(TileExtenderProxy existingTileExtenderProxy) { + TileProxy = existingTileExtenderProxy.TileProxy; + PrefabTileExtender = existingTileExtenderProxy.PrefabTileExtender; + Entrances = new List(); + Exits = new List(); + + foreach(var existingDoorway in TileProxy.doorways) { + if (existingTileExtenderProxy.Entrances.Contains(existingDoorway)) Entrances.Add(existingDoorway); + if (existingTileExtenderProxy.Exits.Contains(existingDoorway)) Exits.Add(existingDoorway); + } + } + + public TileExtenderProxy(TileProxy tileProxy) { + TileProxy = tileProxy; + PrefabTileExtender = tileProxy.Prefab.GetComponent(); + Entrances = new List(); + Exits = new List(); + + if (PrefabTileExtender == null) { + if (tileProxy.Entrance != null) Entrances.Add(tileProxy.Entrance); + if (tileProxy.Exit != null) Exits.Add(tileProxy.Exit); + return; + } + + foreach(var proxyDoorway in tileProxy.doorways) { + if (PrefabTileExtender.entrances.Contains(proxyDoorway.DoorwayComponent)) Entrances.Add(proxyDoorway); + if (PrefabTileExtender.exits.Contains(proxyDoorway.DoorwayComponent)) Exits.Add(proxyDoorway); + } + } + } +} diff --git a/DunGenPlus/DunGenPlus/Components/TileExtender.cs b/DunGenPlus/DunGenPlus/Components/TileExtender.cs new file mode 100644 index 0000000..8aae94c --- /dev/null +++ b/DunGenPlus/DunGenPlus/Components/TileExtender.cs @@ -0,0 +1,18 @@ +using DunGen; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace DunGenPlus.Components { + public class TileExtender : MonoBehaviour { + + public List entrances = new List(); + public List exits = new List(); + public List overlappingDoorways = new List(); + + + } +} diff --git a/DunGenPlus/DunGenPlus/DunGenPlus.csproj b/DunGenPlus/DunGenPlus/DunGenPlus.csproj index ce6d631..afe53a0 100644 --- a/DunGenPlus/DunGenPlus/DunGenPlus.csproj +++ b/DunGenPlus/DunGenPlus/DunGenPlus.csproj @@ -145,6 +145,7 @@ + @@ -163,6 +164,9 @@ + + + @@ -196,7 +200,7 @@ - + @@ -204,6 +208,7 @@ + diff --git a/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll b/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll index 4aee102..f168764 100644 Binary files a/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll and b/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll differ diff --git a/DunGenPlus/DunGenPlus/Patches/BranchCountHelperPatch.cs b/DunGenPlus/DunGenPlus/Patches/BranchCountHelperPatch.cs new file mode 100644 index 0000000..fc38139 --- /dev/null +++ b/DunGenPlus/DunGenPlus/Patches/BranchCountHelperPatch.cs @@ -0,0 +1,73 @@ +using DunGen; +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Collections; +using DunGenPlus.Utils; +using DunGenPlus.Generation; +using DunGenPlus.Managers; +using DunGenPlus.Collections; +using DunGenPlus.DevTools; +using DunGen.Graph; +using UnityEngine; +using DunGenPlus.Components; + +namespace DunGenPlus.Patches +{ + internal class BranchCountHelperPatch { + + [HarmonyTranspiler] + [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCounts")] + public static IEnumerable ComputeBranchCountsPatch(IEnumerable instructions){ + + var branchModeField = typeof(DungeonFlow).GetField("BranchMode", BindingFlags.Instance | BindingFlags.Public); + + var branchSequence = new InstructionSequenceStandard("BranchMode", false); + branchSequence.AddBasic(OpCodes.Ldfld, branchModeField); + + foreach(var instruction in instructions){ + if (branchSequence.VerifyStage(instruction)) { + var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchMode", BindingFlags.Static | BindingFlags.Public); + + yield return new CodeInstruction(OpCodes.Call, specialFunction); + + continue; + } + + yield return instruction; + } + + branchSequence.ReportComplete(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCountsGlobal")] + public static IEnumerable ComputeBranchCountsGlobalPatch(IEnumerable instructions){ + + var branchCountField = typeof(DungeonFlow).GetField("BranchCount", BindingFlags.Instance | BindingFlags.Public); + + var branchSequence = new InstructionSequenceStandard("BranchCount"); + branchSequence.AddBasic(OpCodes.Ldfld, branchCountField); + + foreach(var instruction in instructions){ + if (branchSequence.VerifyStage(instruction)) { + var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchCount", BindingFlags.Static | BindingFlags.Public); + + yield return new CodeInstruction(OpCodes.Call, specialFunction); + + continue; + } + + yield return instruction; + } + + branchSequence.ReportComplete(); + } + + } +} diff --git a/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs b/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs index 0c3e7db..1707fcb 100644 --- a/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs +++ b/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs @@ -47,6 +47,7 @@ namespace DunGenPlus.Patches { } if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) { + TileProxyPatch.ResetDictionary(); DunGenPlusGenerator.SetCurrentMainPathExtender(0); MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviourSimpleOnce = false; } @@ -157,53 +158,6 @@ namespace DunGenPlus.Patches { nodesSequence.ReportComplete(); } - [HarmonyTranspiler] - [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCounts")] - public static IEnumerable ComputeBranchCountsPatch(IEnumerable instructions){ - - var branchModeField = typeof(DungeonFlow).GetField("BranchMode", BindingFlags.Instance | BindingFlags.Public); - - var branchSequence = new InstructionSequenceStandard("BranchMode", false); - branchSequence.AddBasic(OpCodes.Ldfld, branchModeField); - - foreach(var instruction in instructions){ - if (branchSequence.VerifyStage(instruction)) { - var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchMode", BindingFlags.Static | BindingFlags.Public); - - yield return new CodeInstruction(OpCodes.Call, specialFunction); - - continue; - } - - yield return instruction; - } - - branchSequence.ReportComplete(); - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(BranchCountHelper), "ComputeBranchCountsGlobal")] - public static IEnumerable ComputeBranchCountsGlobalPatch(IEnumerable instructions){ - - var branchCountField = typeof(DungeonFlow).GetField("BranchCount", BindingFlags.Instance | BindingFlags.Public); - - var branchSequence = new InstructionSequenceStandard("BranchCount"); - branchSequence.AddBasic(OpCodes.Ldfld, branchCountField); - - foreach(var instruction in instructions){ - if (branchSequence.VerifyStage(instruction)) { - var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetBranchCount", BindingFlags.Static | BindingFlags.Public); - - yield return new CodeInstruction(OpCodes.Call, specialFunction); - - continue; - } - - yield return instruction; - } - - branchSequence.ReportComplete(); - } [HarmonyTranspiler] [HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate", MethodType.Enumerator)] @@ -243,90 +197,6 @@ namespace DunGenPlus.Patches { editorCheck.ReportComplete(); } - /* - [HarmonyTranspiler] - [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] - public static IEnumerable AddTilePatch(IEnumerable instructions, ILGenerator generator) { - - var getCountFunction = typeof(Queue).GetMethod("get_Count", BindingFlags.Instance | BindingFlags.Public); - - var whileLoopSequence = new InstructionSequenceHold("while loop"); - whileLoopSequence.AddBasic(OpCodes.Br); - whileLoopSequence.AddBasicLocal(OpCodes.Ldloc_S, 8); - whileLoopSequence.AddAny(); - whileLoopSequence.AddBasic(OpCodes.Ldc_I4_0); - whileLoopSequence.AddBasic(OpCodes.Bgt); - - foreach(var instruction in instructions){ - var yieldInstruction = true; - var result = whileLoopSequence.VerifyStage(instruction); - - switch(result) { - case InstructionSequenceHold.HoldResult.None: - break; - case InstructionSequenceHold.HoldResult.Hold: - yieldInstruction = false; - break; - case InstructionSequenceHold.HoldResult.Release: - foreach(var i in whileLoopSequence.Instructions){ - yield return i; - } - whileLoopSequence.ClearInstructions(); - yieldInstruction = false; - break; - case InstructionSequenceHold.HoldResult.Finished: - - // my special function - var specialFunction = typeof(DunGenPlusGenerator).GetMethod("ProcessDoorwayPairs"); - var resultLocal = generator.DeclareLocal(typeof((TilePlacementResult result, TileProxy tile))); - - yield return new CodeInstruction(OpCodes.Ldarg_0); - yield return new CodeInstruction(OpCodes.Ldarg_S, 4); - yield return new CodeInstruction(OpCodes.Ldloc_S, 8); - yield return new CodeInstruction(OpCodes.Call, specialFunction); - - var item1Field = typeof((TilePlacementResult result, TileProxy tile)).GetField("Item1"); - var item2Field = typeof((TilePlacementResult result, TileProxy tile)).GetField("Item2"); - - yield return new CodeInstruction(OpCodes.Stloc_S, resultLocal); - - yield return new CodeInstruction(OpCodes.Ldloc_S, resultLocal); - yield return new CodeInstruction(OpCodes.Ldfld, item1Field); - yield return new CodeInstruction(OpCodes.Stloc_S, 9); - - yield return new CodeInstruction(OpCodes.Ldloc_S, resultLocal); - yield return new CodeInstruction(OpCodes.Ldfld, item2Field); - yield return new CodeInstruction(OpCodes.Stloc_S, 10); - - whileLoopSequence.ClearInstructions(); - yieldInstruction = false; - - break; - } - - if (yieldInstruction) yield return instruction; - } - - whileLoopSequence.ReportComplete(); - - } - - */ - - [HarmonyPostfix] - [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] - public static void GenerateBranchPathsPatch(){ - if (DunGenPlusGenerator.Active) { - Plugin.logger.LogDebug("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){ @@ -363,33 +233,6 @@ namespace DunGenPlus.Patches { addTileSequence.ReportComplete(); } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(Dungeon), "FromProxy")] - public static IEnumerable FromProxyPatch(IEnumerable instructions){ - var endSequence = new InstructionSequenceStandard("Forloop End"); - endSequence.AddBasicLocal(OpCodes.Ldloca_S, 1); - endSequence.AddBasic(OpCodes.Constrained); - endSequence.AddBasic(OpCodes.Callvirt); - endSequence.AddBasic(OpCodes.Endfinally); - - // WE MUST INJECT BEFORE ENDFINALLY - // DiFFoZ says cause try/catch block something - // Idk that makes no sense - // But if it works it works - - foreach(var instruction in instructions){ - if (endSequence.VerifyStage(instruction)) { - var specialFunction = typeof(DunGenPlusGenerator).GetMethod("AddTileToMainPathDictionary", BindingFlags.Static | BindingFlags.Public); - - yield return new CodeInstruction(OpCodes.Ldloc_0); - yield return new CodeInstruction(OpCodes.Call, specialFunction); - } - yield return instruction; - } - - endSequence.ReportComplete(); - } [HarmonyPrefix] [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")] @@ -453,76 +296,5 @@ namespace DunGenPlus.Patches { lastArchetype = archetype; } - /* - [HarmonyTranspiler] - [HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)] - public static IEnumerable GenerateMainPathPatch(IEnumerable instructions){ - - var addArchFunction = typeof(List).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public); - //var addNodeFunction = typeof(List).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public); - - var archSequence = new InstructionSequence("archetype node"); - archSequence.AddOperandTypeCheck(OpCodes.Ldfld, typeof(List)); - archSequence.AddBasic(OpCodes.Ldnull); - archSequence.AddBasic(OpCodes.Callvirt, addArchFunction); - - var nodeSequence = new InstructionSequence("graph node"); - nodeSequence.AddBasicLocal(OpCodes.Ldloc_S, 12); - nodeSequence.AddBasicLocal(OpCodes.Stloc_S, 8); - - var limitSequence = new InstructionSequence("limit nodes"); - limitSequence.AddBasic(OpCodes.Ldnull); - limitSequence.AddBasicLocal(OpCodes.Stloc_S, 13); - limitSequence.AddBasic(OpCodes.Ldloc_1); - limitSequence.AddBasicLocal(OpCodes.Ldloc_S, 13); - - foreach(var instruction in instructions){ - - if (archSequence.VerifyStage(instruction)){ - - var method = typeof(GeneratePath).GetMethod("ModifyMainBranchNodeArchetype", BindingFlags.Public | BindingFlags.Static); - - yield return new CodeInstruction(OpCodes.Ldloc_S, 8); - yield return new CodeInstruction(OpCodes.Call, method); - yield return instruction; - - continue; - } - - - if (nodeSequence.VerifyStage(instruction)){ - - var method = typeof(GeneratePath).GetMethod("ModifyGraphNode", BindingFlags.Public | BindingFlags.Static); - - yield return new CodeInstruction(OpCodes.Call, method); - yield return instruction; - - continue; - } - - if (limitSequence.VerifyStage(instruction)){ - - var method = typeof(GeneratePath).GetMethod("LimitTilesToFirstFloor", BindingFlags.Public | BindingFlags.Static); - var field = typeof(DungeonGenerator).Assembly.GetType("DunGen.DungeonGenerator+d__100").GetField("5__8", BindingFlags.NonPublic | BindingFlags.Instance); - - yield return instruction; - yield return new CodeInstruction(OpCodes.Ldarg_0); - yield return new CodeInstruction(OpCodes.Ldfld, field); - - - yield return new CodeInstruction(OpCodes.Call, method); - - continue; - } - - yield return instruction; - } - - archSequence.ReportComplete(); - nodeSequence.ReportComplete(); - limitSequence.ReportComplete(); - } - */ - } } diff --git a/DunGenPlus/DunGenPlus/Patches/DungeonPatch.cs b/DunGenPlus/DunGenPlus/Patches/DungeonPatch.cs new file mode 100644 index 0000000..64623f9 --- /dev/null +++ b/DunGenPlus/DunGenPlus/Patches/DungeonPatch.cs @@ -0,0 +1,52 @@ +using DunGen; +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Collections; +using DunGenPlus.Utils; +using DunGenPlus.Generation; +using DunGenPlus.Managers; +using DunGenPlus.Collections; +using DunGenPlus.DevTools; +using DunGen.Graph; +using UnityEngine; +using DunGenPlus.Components; + +namespace DunGenPlus.Patches +{ + internal class DungeonPatch { + + [HarmonyTranspiler] + [HarmonyPatch(typeof(Dungeon), "FromProxy")] + public static IEnumerable FromProxyPatch(IEnumerable instructions){ + var endSequence = new InstructionSequenceStandard("Forloop End"); + endSequence.AddBasicLocal(OpCodes.Ldloca_S, 1); + endSequence.AddBasic(OpCodes.Constrained); + endSequence.AddBasic(OpCodes.Callvirt); + endSequence.AddBasic(OpCodes.Endfinally); + + // WE MUST INJECT BEFORE ENDFINALLY + // DiFFoZ says cause try/catch block something + // Idk that makes no sense + // But if it works it works + + foreach(var instruction in instructions){ + if (endSequence.VerifyStage(instruction)) { + var specialFunction = typeof(DunGenPlusGenerator).GetMethod("AddTileToMainPathDictionary", BindingFlags.Static | BindingFlags.Public); + + yield return new CodeInstruction(OpCodes.Ldloc_0); + yield return new CodeInstruction(OpCodes.Call, specialFunction); + } + yield return instruction; + } + + endSequence.ReportComplete(); + } + + } +} diff --git a/DunGenPlus/DunGenPlus/Patches/DoorwayConnectionPatch.cs b/DunGenPlus/DunGenPlus/Patches/DungeonProxyPatch.cs similarity index 98% rename from DunGenPlus/DunGenPlus/Patches/DoorwayConnectionPatch.cs rename to DunGenPlus/DunGenPlus/Patches/DungeonProxyPatch.cs index 90fa4b5..f79d7e6 100644 --- a/DunGenPlus/DunGenPlus/Patches/DoorwayConnectionPatch.cs +++ b/DunGenPlus/DunGenPlus/Patches/DungeonProxyPatch.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using DunGenPlus.Generation; namespace DunGenPlus.Patches { - internal class DoorwayConnectionPatch { + internal class DungeonProxyPatch { [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] [HarmonyPrefix] diff --git a/DunGenPlus/DunGenPlus/Patches/RoundManagerPatch.cs b/DunGenPlus/DunGenPlus/Patches/RoundManagerPatch.cs index ba8d42d..ea1cd17 100644 --- a/DunGenPlus/DunGenPlus/Patches/RoundManagerPatch.cs +++ b/DunGenPlus/DunGenPlus/Patches/RoundManagerPatch.cs @@ -14,7 +14,22 @@ using Unity.Netcode; using UnityEngine; namespace DunGenPlus.Patches { - public class RoundManagerPatch { + internal class RoundManagerPatch { + + [HarmonyPostfix] + [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] + public static void GenerateBranchPathsPatch(){ + if (DunGenPlusGenerator.Active) { + Plugin.logger.LogDebug("Alt. InnerGenerate() function complete"); + } + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(RoundManager), "SetPowerOffAtStart")] + public static void SetPowerOffAtStartPatch(){ + DoorwayManager.onMainEntranceTeleportSpawnedEvent.Call(); + } + [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "Awake")] diff --git a/DunGenPlus/DunGenPlus/Patches/TileProxyPatch.cs b/DunGenPlus/DunGenPlus/Patches/TileProxyPatch.cs new file mode 100644 index 0000000..bcfb7e9 --- /dev/null +++ b/DunGenPlus/DunGenPlus/Patches/TileProxyPatch.cs @@ -0,0 +1,42 @@ +using DunGen; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using DunGenPlus.Collections; +using UnityEngine; + +namespace DunGenPlus.Patches { + internal class TileProxyPatch { + + public static Dictionary TileExtenderProxyDictionary = new Dictionary(); + + public static void ResetDictionary(){ + TileExtenderProxyDictionary.Clear(); + } + + public static TileExtenderProxy GetTileExtenderProxy(TileProxy proxy){ + return TileExtenderProxyDictionary[proxy]; + } + + public static void AddTileExtenderProxy(TileProxy tileProxy, TileExtenderProxy tileExtenderProxy){ + TileExtenderProxyDictionary.Add(tileProxy, tileExtenderProxy); + } + + + [HarmonyPatch(typeof(TileProxy), MethodType.Constructor, new Type[] { typeof(GameObject), typeof(bool), typeof(Vector3) })] + [HarmonyPostfix] + public static void TileProxyConstructorNewPatch(ref TileProxy __instance){ + AddTileExtenderProxy(__instance, new TileExtenderProxy(__instance)); + } + + [HarmonyPatch(typeof(TileProxy), MethodType.Constructor, new Type[] { typeof(TileProxy) })] + [HarmonyPostfix] + public static void TileProxyConstructorExistingPatch(ref TileProxy __instance, TileProxy existingTile){ + AddTileExtenderProxy(__instance, new TileExtenderProxy(GetTileExtenderProxy(existingTile))); + } + + } +} diff --git a/DunGenPlus/DunGenPlus/Plugin.cs b/DunGenPlus/DunGenPlus/Plugin.cs index 644b459..62f81b0 100644 --- a/DunGenPlus/DunGenPlus/Plugin.cs +++ b/DunGenPlus/DunGenPlus/Plugin.cs @@ -2,6 +2,7 @@ using BepInEx.Logging; using DunGen; using DunGen.Graph; +using DunGenPlus.Collections; using DunGenPlus.Generation; using DunGenPlus.Managers; using DunGenPlus.Patches; @@ -44,9 +45,12 @@ namespace DunGenPlus { PluginConfig.SetupConfig(Config); Harmony.PatchAll(typeof(DungeonGeneratorPatch)); - Harmony.PatchAll(typeof(DoorwayConnectionPatch)); + Harmony.PatchAll(typeof(DungeonPatch)); + Harmony.PatchAll(typeof(DungeonProxyPatch)); Harmony.PatchAll(typeof(RoundManagerPatch)); - + Harmony.PatchAll(typeof(BranchCountHelperPatch)); + Harmony.PatchAll(typeof(TileProxyPatch)); + try { Harmony.PatchAll(typeof(LethalLevelLoaderPatches)); } catch (Exception e) {