diff --git a/DunGenPlus/DunGenPlus/API.cs b/DunGenPlus/DunGenPlus/API.cs
index a2e198a..89aa1de 100644
--- a/DunGenPlus/DunGenPlus/API.cs
+++ b/DunGenPlus/DunGenPlus/API.cs
@@ -126,5 +126,13 @@ namespace DunGenPlus
return extender;
}
+ ///
+ /// DO NOT USE!
+ ///
+ ///
+ public static void AddTileToMainPathDictionary(Dictionary dictionary){
+ DunGenPlusGenerator.AddTileToMainPathDictionary(dictionary);
+ }
+
}
}
diff --git a/DunGenPlus/DunGenPlus/Collections/DunGenExtenderPropertiesCollection.cs b/DunGenPlus/DunGenPlus/Collections/DunGenExtenderPropertiesCollection.cs
index 7cc1ffc..6d4f127 100644
--- a/DunGenPlus/DunGenPlus/Collections/DunGenExtenderPropertiesCollection.cs
+++ b/DunGenPlus/DunGenPlus/Collections/DunGenExtenderPropertiesCollection.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using static DunGenPlus.Collections.DunGenExtenderProperties;
using UnityEngine;
using DunGen;
+using DunGen.Graph;
namespace DunGenPlus.Collections {
@@ -16,6 +17,7 @@ namespace DunGenPlus.Collections {
internal const string MainRoomTilePrefabTooltip = "The Tile prefab where the additional main paths will start from.\n\nCannot be null if MainPathCount is more than 1.";
internal const string CopyNodeBehaviourTooltip = "Defines how the nodes list is copied onto the additional main paths.\n\nCopyFromMainPathPosition: nodes will copy based on the MainRoomTilePrefab's position in the main path.\nCopyFromNodeList: nodes will copy based on the MainRoomTilePrefab's position in the node list + 1.";
internal const string MainPathDetailsTooltip = "Overrides certain DungeonFlow values during the main path generation.\n\nThe order of items in this list correspond to the order of the main paths being generated.\nThe first item in this list will activate for the first main path, the second item for the second main path, and so on. If there are more main paths than items in this list, the last item is used instead.";
+ 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.";
[Tooltip(MainPathCountTooltip)]
@@ -27,6 +29,8 @@ namespace DunGenPlus.Collections {
public CopyNodeBehaviour CopyNodeBehaviour = CopyNodeBehaviour.CopyFromMainPathPosition;
[Tooltip(MainPathDetailsTooltip)]
public List MainPathDetails = new List();
+ [Tooltip(LocalMainPathGlobalPropsTooltip)]
+ public List LocalMainPathGlobalProps = new List();
public MainPathExtender GetMainPathDetails(int index) {
var count = MainPathDetails.Count;
@@ -40,6 +44,7 @@ namespace DunGenPlus.Collections {
MainRoomTilePrefab = props.MainRoomTilePrefab;
CopyNodeBehaviour = props.CopyNodeBehaviour;
MainPathDetails = props.MainPathDetails;
+ LocalMainPathGlobalProps = props.LocalMainPathGlobalProps;
}
internal MainPathProperties Copy() {
diff --git a/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll b/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll
index d1c1d36..18fac0c 100644
Binary files a/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll and b/DunGenPlus/DunGenPlus/DunGenPlus/DunGenPlus.dll differ
diff --git a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGenerator.cs b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGenerator.cs
index 08ea045..404d9aa 100644
--- a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGenerator.cs
+++ b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGenerator.cs
@@ -87,19 +87,50 @@ namespace DunGenPlus.Generation {
}
private static Dictionary tileProxyMainPath = new Dictionary();
+ private static Dictionary tileMainPath = new Dictionary();
public static int GetMainPathIndexFromTileProxy(TileProxy tileProxy){
return tileProxyMainPath[tileProxy];
}
- private static void AddTileProxyToMainPathDictionary(IEnumerable tileProxies, int index) {
+ public static int GetMainPathIndexFromTile(Tile tile){
+ return tileMainPath[tile];
+ }
+
+ public static void AddTileProxy(TileProxy tileProxy, int index) {
+ //Plugin.logger.LogWarning($"Adding: {tileProxy.Prefab.name} ({tileProxy.Placement.IsOnMainPath}): {index}");
+ tileProxyMainPath.Add(tileProxy, index);
+ }
+
+ public static void AddMainPathTileProxies(IEnumerable tileProxies, int index){
var totalLength = (float)tileProxies.Last().Placement.PathDepth;
foreach(var t in tileProxies) {
- tileProxyMainPath.Add(t, index);
+ AddTileProxy(t, index);
t.Placement.NormalizedPathDepth = t.Placement.PathDepth / totalLength;
}
}
+ public static void BuildBranchPathTileProxiesDictionary(DungeonProxy dungeonProxy){
+ var lastIndex = 0;
+ foreach(var connection in dungeonProxy.Connections){
+ var aTileProxy = connection.A.TileProxy;
+ if (aTileProxy.Placement.IsOnMainPath) {
+ lastIndex = GetMainPathIndexFromTileProxy(aTileProxy);
+ }
+
+ var bTileProxy = connection.B.TileProxy;
+ if (!bTileProxy.Placement.IsOnMainPath){
+ AddTileProxy(bTileProxy, lastIndex);
+ }
+ }
+ }
+
+ public static void AddTileToMainPathDictionary(Dictionary dictionary){
+ foreach(var pair in dictionary){
+ tileMainPath.Add(pair.Value, GetMainPathIndexFromTileProxy(pair.Key));
+ }
+ }
+
public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) {
// default behaviour
@@ -112,6 +143,10 @@ namespace DunGenPlus.Generation {
var altCount = Properties.MainPathProperties.MainPathCount - 1;
tileProxyMainPath.Clear();
+ tileMainPath.Clear();
+
+ var firstMainPathTiles = gen.proxyDungeon.MainPathTiles.ToList();
+ AddMainPathTileProxies(firstMainPathTiles, 0);
var mainRoomTilePrefab = Properties.MainPathProperties.MainRoomTilePrefab;
var copyNodeBehaviour = Properties.MainPathProperties.CopyNodeBehaviour;
@@ -127,9 +162,7 @@ namespace DunGenPlus.Generation {
}
var allMainPathTiles = new List>();
- var firstMainPathTiles = gen.proxyDungeon.MainPathTiles.ToList();
allMainPathTiles.Add(firstMainPathTiles);
- AddTileProxyToMainPathDictionary(firstMainPathTiles, 0);
// main room is the true main room and not the fake room
// this MUST have multiple doorways as you can imagine
@@ -267,7 +300,7 @@ namespace DunGenPlus.Generation {
if (gen.ShouldSkipFrame(true)) yield return gen.GetRoomPause();
}
- AddTileProxyToMainPathDictionary(newMainPathTiles, b + 1);
+ AddMainPathTileProxies(newMainPathTiles, b + 1);
allMainPathTiles.Add(newMainPathTiles);
}
@@ -291,13 +324,17 @@ namespace DunGenPlus.Generation {
yield return gen.Wait(GenerateMultiBranchPaths(gen));
GenerateBranchBoostedPathsStopWatch.Stop();
GenerateBranchBoostedPathsTime += (float)GenerateBranchBoostedPathsStopWatch.Elapsed.TotalMilliseconds;
+ } else {
+ yield return gen.Wait(gen.GenerateBranchPaths());
}
- else yield return gen.Wait(gen.GenerateBranchPaths());
}
ActiveAlternative = true;
-
gen.proxyDungeon.MainPathTiles = allMainPathTiles[0];
+
+ if (!Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim){
+ BuildBranchPathTileProxiesDictionary(gen.proxyDungeon);
+ }
AddForcedTiles(gen);
}
@@ -312,6 +349,7 @@ namespace DunGenPlus.Generation {
yield return gen.Wait(gen.GenerateBranchPaths());
ActiveAlternative = true;
+ BuildBranchPathTileProxiesDictionary(gen.proxyDungeon);
AddForcedTiles(gen);
}
diff --git a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorBranchLoop.cs b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorBranchLoop.cs
index b1f4aa7..20bef46 100644
--- a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorBranchLoop.cs
+++ b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorBranchLoop.cs
@@ -191,7 +191,7 @@ namespace DunGenPlus.Generation
gen.injectedTiles = bestPath.injectedTiles;
gen.tilesPendingInjection = bestPath.tilesPendingInjection;
- AddTileProxyToMainPathDictionary(bestPath.list.Select(x => x.tileProxy), bestPath.mainPathIndex);
+ AddMainPathTileProxies(bestPath.list.Select(x => x.tileProxy), bestPath.mainPathIndex);
if (gen.ShouldSkipFrame(true)){
yield return gen.GetRoomPause();
diff --git a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorMiscellaneous.cs b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorMiscellaneous.cs
index d64a88f..f19fe34 100644
--- a/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorMiscellaneous.cs
+++ b/DunGenPlus/DunGenPlus/Generation/DunGenPlusGeneratorMiscellaneous.cs
@@ -2,10 +2,13 @@
using DunGen.Graph;
using DunGenPlus.DevTools;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UnityEngine;
+using static UnityEngine.Rendering.DebugUI;
namespace DunGenPlus.Generation {
internal partial class DunGenPlusGenerator {
@@ -33,6 +36,7 @@ namespace DunGenPlus.Generation {
var tileProxy = gen.AddTile(t, item.TileSets, t.Placement.NormalizedDepth, null, TilePlacementResult.None);
if (tileProxy == null) continue;
+ AddTileProxy(tileProxy, GetMainPathIndexFromTileProxy(t));
tileProxy.Placement.BranchDepth = t.Placement.BranchDepth;
tileProxy.Placement.NormalizedBranchDepth = t.Placement.NormalizedDepth;
tileProxy.Placement.GraphNode = t.Placement.GraphNode;
@@ -92,5 +96,133 @@ namespace DunGenPlus.Generation {
return defaultState || DevDebugManager.IsActive;
}
+ // Copied and pasted from DunGen
+ public static void ProcessGlobalPropsPerMainPath(DungeonGenerator dungeonGenerator){
+ var localIDs = Properties.MainPathProperties.LocalMainPathGlobalProps.Select(x => x.ID).ToHashSet();
+
+ // first parameter int is the GlobalProp ID
+ // second parameter is the List of GameObjectChanceTable indexed by the main path index
+ var localDictionary = new Dictionary>();
+
+ // default dictionary
+ var globalDictionary = new Dictionary();
+
+ foreach(var tile in dungeonGenerator.CurrentDungeon.AllTiles){
+ foreach(var globalProp in tile.GetComponentsInChildren()){
+ GameObjectChanceTable gameObjectChanceTable;
+ if (localIDs.Contains(globalProp.PropGroupID)){
+ if (!localDictionary.TryGetValue(globalProp.PropGroupID, out var dictionary)){
+ dictionary = new Dictionary();
+ localDictionary.Add(globalProp.PropGroupID, dictionary);
+ }
+
+ // The game will softlock if it can't find the tile
+ // THIS IS SCARY!!!
+ var mainPathIndex = GetMainPathIndexFromTile(tile);
+ if (!dictionary.TryGetValue(mainPathIndex, out gameObjectChanceTable)){
+ gameObjectChanceTable = new GameObjectChanceTable();
+ dictionary.Add(mainPathIndex, gameObjectChanceTable);
+ }
+ } else {
+ if (!globalDictionary.TryGetValue(globalProp.PropGroupID, out gameObjectChanceTable)){
+ gameObjectChanceTable = new GameObjectChanceTable();
+ globalDictionary.Add(globalProp.PropGroupID, gameObjectChanceTable);
+ }
+ }
+
+ var num = tile.Placement.IsOnMainPath ? globalProp.MainPathWeight : globalProp.BranchPathWeight;
+ num *= globalProp.DepthWeightScale.Evaluate(tile.Placement.NormalizedDepth);
+ gameObjectChanceTable.Weights.Add(new GameObjectChance(globalProp.gameObject, num, 0f, null));
+
+ }
+ }
+
+ foreach(var dictionary in localDictionary.Values){
+ foreach(var table2 in dictionary.Values){
+ foreach(var gameObjectChance in table2.Weights){
+ gameObjectChance.Value.SetActive(false);
+ }
+ }
+ }
+
+ foreach(var table2 in globalDictionary.Values){
+ foreach(var gameObjectChance in table2.Weights){
+ gameObjectChance.Value.SetActive(false);
+ }
+ }
+
+ var list = new List(localDictionary.Count + globalDictionary.Count);
+
+ int ProcessGlobalPropID(GameObjectChanceTable table, int localMax, int globalCount, int globalMax){
+ localMax = Mathf.Clamp(localMax, 0, table.Weights.Count);
+ var i = 0;
+ while(i < localMax && i + globalCount < globalMax){
+ var random = table.GetRandom(dungeonGenerator.RandomStream, true, 0f, null, true, true);
+ if (random != null && random.Value != null) {
+ random.Value.SetActive(true);
+ }
+ ++i;
+ }
+ return i;
+ }
+
+ using(var enumerator = globalDictionary.GetEnumerator()){
+ while(enumerator.MoveNext()){
+ var pair = enumerator.Current;
+ if (list.Contains(pair.Key)){
+ Plugin.logger.LogWarning("Dungeon Flow contains multiple entries for the global prop group ID: " + pair.Key.ToString() + ". Only the first entry will be used.");
+ } else {
+ //Plugin.logger.LogWarning($"{pair.Key}: Global");
+
+ var globalPropSettings = dungeonGenerator.DungeonFlow.GlobalProps
+ .Where(x => x.ID == pair.Key)
+ .FirstOrDefault();
+
+ if (globalPropSettings != null){
+ var tableClone = pair.Value.Clone();
+ var globalMax = globalPropSettings.Count.GetRandom(dungeonGenerator.RandomStream);
+
+ var spawned = ProcessGlobalPropID(tableClone, globalMax, 0, globalMax);
+ //Plugin.logger.LogError($"Spawned {spawned} ({spawned}/{globalMax})");
+ list.Add(pair.Key);
+ }
+ }
+ }
+ }
+
+ using(var enumerator = localDictionary.GetEnumerator()){
+ while(enumerator.MoveNext()){
+ var pair = enumerator.Current;
+ if (list.Contains(pair.Key)){
+ Plugin.logger.LogWarning("Dungeon Flow contains multiple entries for the global prop group ID: " + pair.Key.ToString() + ". Only the first entry will be used.");
+ } else {
+ //Plugin.logger.LogWarning($"{pair.Key}: Local");
+
+ var globalPropSettings = dungeonGenerator.DungeonFlow.GlobalProps
+ .Where(x => x.ID == pair.Key)
+ .FirstOrDefault();
+ var localPropSettings = Properties.MainPathProperties.LocalMainPathGlobalProps
+ .Where(x => x.ID == pair.Key)
+ .FirstOrDefault();
+
+ if (globalPropSettings != null && localPropSettings != null){
+ var globalCount = 0;
+ foreach(var path in pair.Value.Values){
+ var tableClone = path.Clone();
+ var globalMax = globalPropSettings.Count.GetRandom(dungeonGenerator.RandomStream);
+ var localMax = localPropSettings.Count.GetRandom(dungeonGenerator.RandomStream);
+
+ var spawned = ProcessGlobalPropID(tableClone, localMax, globalCount, globalMax);
+ globalCount += spawned;
+ //Plugin.logger.LogError($"Spawned {spawned} ({globalCount}/{globalMax})");
+ }
+ list.Add(pair.Key);
+ }
+ }
+ }
+ }
+
+ }
+
}
}
diff --git a/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs b/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs
index 9ffe323..694e6d4 100644
--- a/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs
+++ b/DunGenPlus/DunGenPlus/Patches/DungeonGeneratorPatch.cs
@@ -343,6 +343,49 @@ namespace DunGenPlus.Patches {
lastTilePlacementResult = result;
}
+ [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);
+
+ foreach(var instruction in instructions){
+ if (endSequence.VerifyStage(instruction)) {
+ yield return 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);
+
+ continue;
+ }
+ yield return instruction;
+ }
+
+ endSequence.ReportComplete();
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")]
+ public static bool ProcessGlobalPropsPatch(ref DungeonGenerator __instance){
+ if (DunGenPlusGenerator.Active){
+ var list = DunGenPlusGenerator.Properties.MainPathProperties.LocalMainPathGlobalProps;
+ if (list != null && list.Count > 0) {
+ Plugin.logger.LogDebug("Performing Local Global Props algorithm");
+ DunGenPlusGenerator.ProcessGlobalPropsPerMainPath(__instance);
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+
/*
[HarmonyTranspiler]
[HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)]
diff --git a/DunGenPlus/DunGenPlus/Utils/TranspilerUtilities.cs b/DunGenPlus/DunGenPlus/Utils/TranspilerUtilities.cs
index a0cc7ca..bb19449 100644
--- a/DunGenPlus/DunGenPlus/Utils/TranspilerUtilities.cs
+++ b/DunGenPlus/DunGenPlus/Utils/TranspilerUtilities.cs
@@ -255,11 +255,15 @@ namespace DunGenPlus.Utils {
public static void PrintInstructions(IEnumerable instructions) {
foreach(var i in instructions){
- var opString = i.opcode.ToString();
- var objString = i.operand != null ? i.operand.ToString() : "NULL";
- Plugin.logger.LogInfo($"{opString}: {objString}");
+ PrintInstruction(i);
}
}
+ public static void PrintInstruction(CodeInstruction inst) {
+ var opString = inst.opcode.ToString();
+ var objString = inst.operand != null ? inst.operand.ToString() : "NULL";
+ Plugin.logger.LogInfo($"{opString}: {objString}");
+ }
+
}
}
diff --git a/LoadstonePatch/LoadstoneNighty/Patch.cs b/LoadstonePatch/LoadstoneNighty/Patch.cs
index a006eed..a853d3d 100644
--- a/LoadstonePatch/LoadstoneNighty/Patch.cs
+++ b/LoadstonePatch/LoadstoneNighty/Patch.cs
@@ -7,6 +7,7 @@ using DunGen;
using DunGen.Graph;
using DunGenPlus;
using DunGenPlus.Collections;
+using HarmonyLib;
namespace LoadstoneNighty {
@@ -79,5 +80,11 @@ namespace LoadstoneNighty {
}
}
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(Loadstone.Patches.FromProxyPatches), "FromProxyEnd")]
+ public static void FromProxyEndPatch(Dictionary dictionary){
+ DunGenPlus.API.AddTileToMainPathDictionary(dictionary);
+ }
+
}
}
diff --git a/LoadstonePatch/LoadstoneNighty/Plugin.cs b/LoadstonePatch/LoadstoneNighty/Plugin.cs
index bdb5b78..927d11b 100644
--- a/LoadstonePatch/LoadstoneNighty/Plugin.cs
+++ b/LoadstonePatch/LoadstoneNighty/Plugin.cs
@@ -47,6 +47,13 @@ namespace LoadstoneNighty {
if (validVersion){
logger.LogInfo($"Plugin {modName} has been added!");
+
+ try {
+ harmony.PatchAll(typeof(Patch));
+ } catch {
+
+ }
+
Patch.Activate();
}
}