This was reading from the wrong index and always passing null, so the doorway groups were never taking effect at all for the first main path.
306 lines
12 KiB
C#
306 lines
12 KiB
C#
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 DungeonGeneratorPatch {
|
|
|
|
[HarmonyPriority(Priority.First)]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "Generate")]
|
|
[HarmonyPrefix]
|
|
public static void GeneratePatch(ref DungeonGenerator __instance){
|
|
DunGenPlusGenerator.Deactivate();
|
|
|
|
var flow = __instance.DungeonFlow;
|
|
var extender = API.GetDunGenExtender(flow);
|
|
|
|
if (extender && extender.Active) {
|
|
Plugin.logger.LogInfo($"Loading DunGenExtender for {flow.name}");
|
|
DunGenPlusGenerator.Activate(__instance, extender);
|
|
return;
|
|
}
|
|
|
|
Plugin.logger.LogInfo($"Did not load a DunGenExtenderer");
|
|
DunGenPlusGenerator.Deactivate();
|
|
}
|
|
|
|
[HarmonyPostfix]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate")]
|
|
public static void InnerGeneratePatch(ref DungeonGenerator __instance, bool isRetry){
|
|
if (API.IsDevDebugModeActive() && !isRetry) {
|
|
DevDebugManager.Instance.RecordNewSeed(__instance.ChosenSeed);
|
|
}
|
|
|
|
if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) {
|
|
TileProxyPatch.ResetDictionary();
|
|
DunGenPlusGenerator.SetCurrentMainPathExtender(0);
|
|
MainRoomDoorwayGroups.ModifyGroupBasedOnBehaviourSimpleOnce = false;
|
|
}
|
|
}
|
|
|
|
[HarmonyPostfix]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath")]
|
|
public static void GenerateMainPathPatch(ref DungeonGenerator __instance){
|
|
if (DunGenPlusGenerator.Active && DunGenPlusGenerator.ActiveAlternative) {
|
|
DunGenPlusGenerator.RandomizeLineArchetypes(__instance, 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(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)]
|
|
public static IEnumerable<CodeInstruction> GenerateMainPathPatch(IEnumerable<CodeInstruction> instructions){
|
|
var setNodeFunction = typeof(TilePlacementParameters).GetMethod("set_Node", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
// tilePlacementParameters.Node = graphNode;
|
|
var archSequence = new InstructionSequenceStandard("archetype node");
|
|
archSequence.AddBasicLocal(OpCodes.Ldloc_S, 10);
|
|
archSequence.AddBasicLocal(OpCodes.Ldloc_S, 8);
|
|
archSequence.AddBasic(OpCodes.Callvirt, setNodeFunction);
|
|
|
|
var attachToSequence = new InstructionSequenceStandard("attach to");
|
|
attachToSequence.AddBasicLocal(OpCodes.Stloc_S, 14);
|
|
|
|
foreach(var instruction in instructions){
|
|
if (archSequence.VerifyStage(instruction)){
|
|
//DunGenPlusGenerator.ModifyMainBranchNodeArchetype(tilePlacementParameters, graphNode, gen.RandomStream);
|
|
var randomStreamMethod = typeof(DungeonGenerator).GetMethod("get_RandomStream", BindingFlags.Public | BindingFlags.Instance);
|
|
var modifyMethod = typeof(DunGenPlusGenerator).GetMethod("ModifyMainBranchNodeArchetype", BindingFlags.Public | BindingFlags.Static);
|
|
|
|
yield return instruction;
|
|
|
|
yield return new CodeInstruction(OpCodes.Ldloc_S, 10); // tilePlacementParameters
|
|
yield return new CodeInstruction(OpCodes.Ldloc_S, 8); // graphNode
|
|
yield return new CodeInstruction(OpCodes.Ldloc_1); // this
|
|
yield return new CodeInstruction(OpCodes.Call, randomStreamMethod);
|
|
yield return new CodeInstruction(OpCodes.Call, modifyMethod);
|
|
|
|
continue;
|
|
}
|
|
|
|
if (attachToSequence.VerifyStage(instruction)){
|
|
yield return instruction;
|
|
|
|
var modifyMethod = typeof(MainRoomDoorwayGroups).GetMethod("ModifyGroupBasedOnBehaviourSimple", BindingFlags.Public | BindingFlags.Static);
|
|
|
|
yield return new CodeInstruction(OpCodes.Ldloc_S, 14);
|
|
yield return new CodeInstruction(OpCodes.Call, modifyMethod);
|
|
|
|
continue;
|
|
}
|
|
|
|
yield return instruction;
|
|
}
|
|
|
|
archSequence.ReportComplete();
|
|
attachToSequence.ReportComplete();
|
|
}
|
|
|
|
[HarmonyTranspiler]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)]
|
|
public static IEnumerable<CodeInstruction> GenerateMainPathGetLineAtDepthPatch(IEnumerable<CodeInstruction> instructions){
|
|
var getLineFunction = typeof(DungeonFlow).GetMethod("GetLineAtDepth", BindingFlags.Instance | BindingFlags.Public);
|
|
var nodesField = typeof(DungeonFlow).GetField("Nodes", BindingFlags.Instance | BindingFlags.Public);
|
|
|
|
var lineSequence = new InstructionSequenceStandard("GetLineAtDepth");
|
|
lineSequence.AddBasic(OpCodes.Callvirt, getLineFunction);
|
|
|
|
var nodesSequence = new InstructionSequenceStandard("Nodes", false);
|
|
nodesSequence.AddBasic(OpCodes.Ldfld, nodesField);
|
|
|
|
foreach(var instruction in instructions){
|
|
if (lineSequence.VerifyStage(instruction)) {
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetLineAtDepth", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
|
|
continue;
|
|
}
|
|
|
|
if (nodesSequence.VerifyStage(instruction)) {
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetNodes", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
|
|
continue;
|
|
}
|
|
yield return instruction;
|
|
}
|
|
|
|
lineSequence.ReportComplete();
|
|
nodesSequence.ReportComplete();
|
|
}
|
|
|
|
|
|
[HarmonyTranspiler]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "InnerGenerate", MethodType.Enumerator)]
|
|
public static IEnumerable<CodeInstruction> InnerGenerateLengthPatch(IEnumerable<CodeInstruction> instructions){
|
|
|
|
var lengthField = typeof(DungeonFlow).GetField("Length", BindingFlags.Instance | BindingFlags.Public);
|
|
var getIsEditor = typeof(Application).GetMethod("get_isEditor", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
var lengthSequence = new InstructionSequenceStandard("Length");
|
|
lengthSequence.AddBasic(OpCodes.Ldfld, lengthField);
|
|
|
|
var editorCheck = new InstructionSequenceStandard("Editor");
|
|
editorCheck.AddBasic(OpCodes.Call, getIsEditor);
|
|
|
|
foreach(var instruction in instructions){
|
|
if (lengthSequence.VerifyStage(instruction)) {
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("GetLength", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
|
|
continue;
|
|
}
|
|
|
|
if (editorCheck.VerifyStage(instruction)){
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("AllowRetryStop", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return instruction;
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
|
|
continue;
|
|
}
|
|
|
|
yield return instruction;
|
|
}
|
|
|
|
lengthSequence.ReportComplete();
|
|
editorCheck.ReportComplete();
|
|
}
|
|
|
|
[HarmonyPostfix]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "PostProcess")]
|
|
public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance){
|
|
if (DunGenPlusGenerator.Active) {
|
|
var value = __instance.RandomStream.Next(999);
|
|
Components.Props.SpawnSyncedObjectCycle.UpdateCycle(value);
|
|
}
|
|
}
|
|
|
|
[HarmonyTranspiler]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "AddTile")]
|
|
public static IEnumerable<CodeInstruction> AddTileDebugPatch(IEnumerable<CodeInstruction> instructions){
|
|
var 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, 8);
|
|
|
|
foreach(var instruction in instructions){
|
|
if (addTileSequence.VerifyStage(instruction)) {
|
|
//DunGenPlusGenerator.RecordLastTilePlacementResult
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("RecordLastTilePlacementResult", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return new CodeInstruction(OpCodes.Ldarg_0); // generator
|
|
yield return new CodeInstruction(OpCodes.Ldloc_S, 8); // TilePlacementResult
|
|
yield return new CodeInstruction(OpCodes.Ldarg_1); // attachTo
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
|
|
yield return instruction;
|
|
|
|
continue;
|
|
}
|
|
yield return instruction;
|
|
}
|
|
|
|
addTileSequence.ReportComplete();
|
|
}
|
|
|
|
[HarmonyPrefix]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")]
|
|
public static bool ProcessGlobalPropsPatch(ref DungeonGenerator __instance){
|
|
if (DunGenPlusGenerator.Active){
|
|
var anyGlobalSettings = DunGenPlusGenerator.Properties.MainPathProperties.DetailedGlobalPropSettings.Count > 0;
|
|
var anyLocalSettings = DunGenPlusGenerator.Properties.MainPathProperties.MainPathDetails.Any(d => d.LocalGroupProps.Count > 0);
|
|
if (anyGlobalSettings || anyLocalSettings){
|
|
Plugin.logger.LogDebug("Performing Local Global Props algorithm");
|
|
DunGenPlusGenerator.ProcessGlobalPropsPerMainPath(__instance);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
[HarmonyTranspiler]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)]
|
|
public static IEnumerable<CodeInstruction> GenerateMainPathDebugPatch(IEnumerable<CodeInstruction> instructions){
|
|
var tileProxyNullSequence = new InstructionSequenceStandard("TileProxyNull");
|
|
tileProxyNullSequence.AddBasic(OpCodes.Br);
|
|
tileProxyNullSequence.AddBasicLocal(OpCodes.Ldloc_S, 15);
|
|
tileProxyNullSequence.AddBasic(OpCodes.Brtrue);
|
|
|
|
FieldInfo indexField = null;
|
|
|
|
foreach(var instruction in instructions){
|
|
if (instruction.operand is FieldInfo field && field.Name.StartsWith("<j>"))
|
|
indexField = field;
|
|
|
|
if (tileProxyNullSequence.VerifyStage(instruction)) {
|
|
|
|
yield return instruction;
|
|
|
|
if (indexField != null) {
|
|
//DunGenPlusGenerator.PrintAddTileErrorQuick
|
|
var specialFunction = typeof(DunGenPlusGenerator).GetMethod("PrintAddTileErrorQuick", BindingFlags.Static | BindingFlags.Public);
|
|
|
|
yield return new CodeInstruction(OpCodes.Ldloc_1); // generator
|
|
yield return new CodeInstruction(OpCodes.Ldarg_0); // gets coroutine data
|
|
yield return new CodeInstruction(OpCodes.Ldfld, indexField); // gets index variable
|
|
|
|
yield return new CodeInstruction(OpCodes.Call, specialFunction);
|
|
}
|
|
else {
|
|
Plugin.logger.LogWarning("Failed to find current tile index field in the main path enumerator");
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
yield return instruction;
|
|
}
|
|
|
|
tileProxyNullSequence.ReportComplete();
|
|
}
|
|
|
|
|
|
public static TileProxy lastAttachTo;
|
|
public static IEnumerable<TileSet> lastUseableTileSets;
|
|
public static float lastNormalizedDepth;
|
|
public static TilePlacementParameters lastPlacementParms;
|
|
|
|
[HarmonyPrefix]
|
|
[HarmonyPatch(typeof(DungeonGenerator), "AddTile")]
|
|
public static void AddTileDebugPatch(TileProxy attachTo, IEnumerable<TileSet> useableTileSets, float normalizedDepth, TilePlacementParameters placementParams){
|
|
lastAttachTo = attachTo;
|
|
lastUseableTileSets = useableTileSets;
|
|
lastNormalizedDepth = normalizedDepth;
|
|
lastPlacementParms = placementParams;
|
|
}
|
|
|
|
}
|
|
}
|