Redid BranchLoop from tile prioritization to branch path prioritization

Added performance logs for the generation
Refactored how the DunGenExtenderProperties are structured
This commit is contained in:
LadyAliceMargatroid 2024-08-25 19:02:43 -07:00
parent 7b16fd6f37
commit 1407e39703
12 changed files with 536 additions and 241 deletions

View File

@ -24,142 +24,39 @@ namespace DunGenPlus.Collections {
} }
[Header("Main Path")] [Header("Main Path")]
[Tooltip("The number of main paths.\n\n1 means no additional main paths\n3 means two additional main paths\netc.")] public MainPathProperties MainPathProperties = new MainPathProperties();
[Range(1, 9)]
public int MainPathCount = 1;
[Tooltip("The Tile Prefab where the additional main paths will start from. Cannot be null if MainPathCount is more than 1.")]
public GameObject MainRoomTilePrefab;
[Tooltip("CopyFromMainPathPosition means that nodes will copy from the MainRoomTilePrefab's position in the main path.\n\nCopyFromNodeList means that nodes will copy from the MainRoomTilePrefab's location from the node list + 1.")]
public CopyNodeBehaviour MainPathCopyNodeBehaviour = CopyNodeBehaviour.CopyFromMainPathPosition;
//public bool MainPathCopyInjectionTiles;
[Header("Dungeon Bounds")] [Header("Dungeon Bounds")]
[Tooltip("If enabled, restricts the dungeon's generation to the bounds described below.\n\nThis will help in condensing the dungeon, but it will increase the chance of dungeon generation failure (potentially guarantees failure if the bounds is too small).")] public DungeonBoundsProperties DungeonBoundsProperties = new DungeonBoundsProperties();
public bool UseDungeonBounds = false;
[Tooltip("The base size of the bounds.")]
public Vector3 DungeonSizeBase = new Vector3(120f, 40f, 80f);
[Tooltip("The factor that's multiplied with the base size AND the dungeon's size. The resulting value is added to the base size of the bounds.\n\n0 means that the bound size is not influenced by the dungeon's size and is therefore a constant.")]
public Vector3 DungeonSizeFactor = new Vector3(1f, 0f, 1f);
[Tooltip("The base positional offset of the bounds.")]
public Vector3 DungeonPositionOffset = Vector3.zero;
[Tooltip("The pivot of the bounds.")]
public Vector3 DungeonPositionPivot = new Vector3(0.5f, 0f, 0.5f);
[Header("Archetypes on Normal Nodes")] [Header("Normal Nodes Archetypes")]
[Tooltip("If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths.")] public NormalNodeArchetypesProperties NormalNodeArchetypesProperties = new NormalNodeArchetypesProperties();
public bool AddArchetypesToNormalNodes = false;
public List<NodeArchetype> NormalNodeArchetypes = new List<NodeArchetype>();
internal Dictionary<string, NodeArchetype> _normalNodeArchetypesDictioanry;
internal NodeArchetype _defaultNodeArchetype;
[Header("Forced Tiles")] [Header("Forced Tiles")]
[Tooltip("If enabled, attempts to forcefully spawn tiles from ForcedTileSets after branching paths are generated.\n\nCan only be used if MainPathCount > 1.")] public ForcedTilesProperties ForcedTilesProperties = new ForcedTilesProperties();
public bool UseForcedTiles = false;
[Tooltip("The list of tiles that will be attempted to forcefully spawn. Each entry will spawn only one tile from it's list.\n\nIf the tile cannot be forcefully spawned, the dungeon generation will not restart.")]
public List<ForcedTileSetList> ForcedTileSets = new List<ForcedTileSetList>();
[Header("Branch Loop Boost")] [Header("Branch Path Multi Simulation")]
[Tooltip("If enabled, dungeon generation will prioritize branch tiles that connect to already generated tiles.\n\nThis increases the chance of circular/looping paths. Slows dungeon generation times a bit at the end.")] public BranchPathMultiSimulationProperties BranchPathMultiSimulationProperties = new BranchPathMultiSimulationProperties();
public bool UseBranchLoopBoost = false;
[Tooltip("The maximum amount of tiles the dungeon generation will consider before choosing the best tile.\nIncreasing this value gives the dungeon generation a higher chance of finding a good tile but impacts dungeon generation times. Decreasing this value gives the dungeon generation a lower chance of finding a good tile but also lessens the impact to dungeon generation times.")]
public int BranchLoopBoostTileSearch = 5;
[Tooltip("The tile weight scale added for each additional doorway connection if that tile was selected.")]
public float BranchLoopBoostTileScale = 0.25f;
[Header("Line Randomizer")] [Header("Line Randomizer")]
[Tooltip("If enabled, every archetype in LineRandomizerArchetypes will have the last LineRandomizerTakeCount tilesets replaced by a randomly selected set of tilesets from LineRandomizerTileSets. This applies for both archetype's TileSets and BranchCapTileSets.\n\nThis is designed for the scenario where dungeon generation takes a long time due to the combination of too many tiles and/or doorways in those tiles. This can reduce dungeon generation time while keeping some of the randomness of dungeon generation.\n\nAs stated previously, this WILL replace the last LineRandomizerTakeCount tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")] public LineRandomizerProperties LineRandomizerProperties = new LineRandomizerProperties();
public bool UseLineRandomizer = false;
[Tooltip("The archetypes whose tilesets will be replaced.\n\nThese archetypes should ideally used in the Lines section of DungeonFlow, but it's a free country.")]
public List<DungeonArchetype> LineRandomizerArchetypes = new List<DungeonArchetype>();
[Tooltip("The tilesets that will be used for replacement.")]
public List<TileSet> LineRandomizerTileSets = new List<TileSet>();
[Tooltip("The amount of tilesets that will be replaced from the archetypes, starting from the last element to the first element.\n\nAs stated previously, this WILL replace the tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")]
public int LineRandomizerTakeCount = 3;
[Header("Max Shadows Request")]
[Tooltip("If enabled, updates the MaxShadowsRequest to MaxShadowsRequestAmount when your dungeon loads.\n\nThis is designed for the scenario where your dungeon, for whatever reason, has too many lights nearby and causes the annoying 'Max shadow requests count reached' warning to spam the logs.")]
public bool UseMaxShadowsRequestUpdate = false;
[Tooltip("The amount of MaxShadowsRequest.\n\n4 is the game's default value. I find 8 to be more than acceptable.")]
public int MaxShadowsRequestAmount = 8;
[Header("Miscellaneous")] [Header("Miscellaneous")]
[Tooltip("If enabled, the DoorwaySisters component will become active.\n\nThe component prevents an intersecting doorway from generating if it's 'sister' doorway already generated and both doorways would lead to the same neighboring tile.\n\nThis is designed for the scenario where, two neighboring doorways would lead to the same tile, one doorway is a locked door and the other is an open doorway. This would defeat the purpose of the locked door, and such as, this feature exists if needed.\n\nThis feature slows down dungeon generation slightly when enabled.")] public MiscellaneousProperties MiscellaneousProperties = new MiscellaneousProperties();
public bool UseDoorwaySisters = false;
[Tooltip("If enabled, the RandomGuaranteedScrapSpawn component will be come active.\n\nThe component allows random scrap of a specified minimum value to always be spawned on a specific point.")]
public bool UseRandomGuaranteedScrapSpawn = false;
internal void SetupProperties(DungeonGenerator generator){ [Header("Asset Cache (FOR DEV DEBUG PURPOSES ONLY)")]
_normalNodeArchetypesDictioanry = new Dictionary<string, NodeArchetype>(); public List<GameObject> AssetCacheTileList = new List<GameObject>();
_defaultNodeArchetype = null; public List<TileSet> AssetCacheTileSetList = new List<TileSet>();
public List<DungeonArchetype> AssetCacheArchetypeList = new List<DungeonArchetype>();
foreach(var n in NormalNodeArchetypes) {
if (_normalNodeArchetypesDictioanry.ContainsKey(n.label)) {
Plugin.logger.LogError($"Label {n.label} already exists. Ignoring latest entry.");
continue;
}
_normalNodeArchetypesDictioanry.Add(n.label, n);
if (string.IsNullOrWhiteSpace(n.label)) {
_defaultNodeArchetype = n;
}
}
}
internal DungeonArchetype GetRandomArchetype(string label, RandomStream randomStream) {
NodeArchetype node;
if (!_normalNodeArchetypesDictioanry.TryGetValue(label, out node)) {
node = _defaultNodeArchetype;
}
if (node != null) {
var archetypes = node.archetypes;
var count = archetypes.Count;
if (count == 0) return null;
var index = randomStream.Next(0, count);
return archetypes[index];
}
return null;
}
internal Bounds GetDungeonBounds(float dungeonScale) {
var size = DungeonSizeBase + Vector3.Scale(DungeonSizeBase * (dungeonScale - 1), DungeonSizeFactor);
var offset = DungeonPositionOffset + Vector3.Scale(size, DungeonPositionPivot - Vector3.one * 0.5f);
return new Bounds(offset, size);
}
internal void CopyFrom(DunGenExtenderProperties props) { internal void CopyFrom(DunGenExtenderProperties props) {
MainPathCount = props.MainPathCount; MainPathProperties = props.MainPathProperties.Copy();
MainRoomTilePrefab = props.MainRoomTilePrefab; DungeonBoundsProperties = props.DungeonBoundsProperties.Copy();
MainPathCopyNodeBehaviour = props.MainPathCopyNodeBehaviour; NormalNodeArchetypesProperties = props.NormalNodeArchetypesProperties.Copy();
ForcedTilesProperties = props.ForcedTilesProperties.Copy();
UseDungeonBounds = props.UseDungeonBounds; BranchPathMultiSimulationProperties = props.BranchPathMultiSimulationProperties.Copy();
DungeonSizeBase = props.DungeonSizeBase; LineRandomizerProperties = props.LineRandomizerProperties.Copy();
DungeonSizeFactor = props.DungeonSizeFactor; MiscellaneousProperties = props.MiscellaneousProperties.Copy();
DungeonPositionOffset = props.DungeonPositionOffset;
DungeonPositionPivot = props.DungeonPositionPivot;
AddArchetypesToNormalNodes = props.AddArchetypesToNormalNodes;
NormalNodeArchetypes = props.NormalNodeArchetypes;
UseForcedTiles = props.UseForcedTiles;
ForcedTileSets = props.ForcedTileSets;
UseBranchLoopBoost = props.UseBranchLoopBoost;
BranchLoopBoostTileSearch = props.BranchLoopBoostTileSearch;
BranchLoopBoostTileScale = props.BranchLoopBoostTileScale;
UseLineRandomizer = props.UseLineRandomizer;
LineRandomizerTileSets = props.LineRandomizerTileSets;
LineRandomizerArchetypes = props.LineRandomizerArchetypes;
LineRandomizerTakeCount = props.LineRandomizerTakeCount;
UseMaxShadowsRequestUpdate = props.UseMaxShadowsRequestUpdate;
MaxShadowsRequestAmount = props.MaxShadowsRequestAmount;
UseDoorwaySisters = props.UseDoorwaySisters;
UseRandomGuaranteedScrapSpawn = props.UseRandomGuaranteedScrapSpawn;
} }
internal DunGenExtenderProperties Copy() { internal DunGenExtenderProperties Copy() {

View File

@ -0,0 +1,256 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static DunGenPlus.Collections.DunGenExtenderProperties;
using UnityEngine;
using DunGen;
namespace DunGenPlus.Collections {
[System.Serializable]
public class MainPathProperties {
[Tooltip("The number of main paths.\n\n1 means no additional main paths\n3 means two additional main paths\netc.")]
[Range(1, 9)]
public int MainPathCount = 1;
[Tooltip("The Tile Prefab where the additional main paths will start from. Cannot be null if MainPathCount is more than 1.")]
public GameObject MainRoomTilePrefab;
[Tooltip("CopyFromMainPathPosition means that nodes will copy from the MainRoomTilePrefab's position in the main path.\n\nCopyFromNodeList means that nodes will copy from the MainRoomTilePrefab's location from the node list + 1.")]
public CopyNodeBehaviour CopyNodeBehaviour = CopyNodeBehaviour.CopyFromMainPathPosition;
internal void CopyFrom(MainPathProperties props) {
MainPathCount = props.MainPathCount;
MainRoomTilePrefab = props.MainRoomTilePrefab;
CopyNodeBehaviour = props.CopyNodeBehaviour;
}
internal MainPathProperties Copy() {
var copy = new MainPathProperties();
copy.CopyFrom(this);
return copy;
}
}
[System.Serializable]
public class DungeonBoundsProperties {
[Tooltip("If enabled, restricts the dungeon's generation to the bounds described below.\n\nThis will help in condensing the dungeon, but it will increase the chance of dungeon generation failure (potentially guarantees failure if the bounds is too small).")]
public bool UseDungeonBounds = false;
[Tooltip("The base size of the bounds.")]
public Vector3 SizeBase = new Vector3(120f, 40f, 80f);
[Tooltip("The factor that's multiplied with the base size AND the dungeon's size. The resulting value is added to the base size of the bounds.\n\n0 means that the bound size is not influenced by the dungeon's size and is therefore a constant.")]
public Vector3 SizeFactor = new Vector3(1f, 0.5f, 1f);
[Tooltip("The base positional offset of the bounds.")]
public Vector3 PositionOffset = Vector3.zero;
[Tooltip("The pivot of the bounds.")]
public Vector3 PositionPivot = new Vector3(0.5f, 0.5f, 0.5f);
internal void CopyFrom(DungeonBoundsProperties props) {
UseDungeonBounds = props.UseDungeonBounds;
SizeBase = props.SizeBase;
SizeFactor = props.SizeFactor;
PositionOffset = props.PositionOffset;
PositionPivot = props.PositionPivot;
}
internal DungeonBoundsProperties Copy() {
var copy = new DungeonBoundsProperties();
copy.CopyFrom(this);
return copy;
}
internal Bounds GetDungeonBounds(float dungeonScale) {
var size = SizeBase + Vector3.Scale(SizeBase * (dungeonScale - 1), SizeFactor);
var offset = PositionOffset + Vector3.Scale(size, PositionPivot - Vector3.one * 0.5f);
return new Bounds(offset, size);
}
}
[System.Serializable]
public class NormalNodeArchetypesProperties {
[Tooltip("If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths.")]
public bool AddArchetypesToNormalNodes = false;
public List<NodeArchetype> NormalNodeArchetypes = new List<NodeArchetype>();
internal Dictionary<string, NodeArchetype> _normalNodeArchetypesDictioanry;
internal NodeArchetype _defaultNodeArchetype;
internal void CopyFrom(NormalNodeArchetypesProperties props)
{
AddArchetypesToNormalNodes = props.AddArchetypesToNormalNodes;
NormalNodeArchetypes = props.NormalNodeArchetypes;
}
internal NormalNodeArchetypesProperties Copy()
{
var copy = new NormalNodeArchetypesProperties();
copy.CopyFrom(this);
return copy;
}
internal void SetupProperties(DungeonGenerator generator)
{
_normalNodeArchetypesDictioanry = new Dictionary<string, NodeArchetype>();
_defaultNodeArchetype = null;
foreach (var n in NormalNodeArchetypes)
{
if (_normalNodeArchetypesDictioanry.ContainsKey(n.label))
{
Plugin.logger.LogError($"Label {n.label} already exists. Ignoring latest entry.");
continue;
}
_normalNodeArchetypesDictioanry.Add(n.label, n);
if (string.IsNullOrWhiteSpace(n.label))
{
_defaultNodeArchetype = n;
}
}
}
internal DungeonArchetype GetRandomArchetype(string label, RandomStream randomStream)
{
NodeArchetype node;
if (!_normalNodeArchetypesDictioanry.TryGetValue(label, out node))
{
node = _defaultNodeArchetype;
}
if (node != null)
{
var archetypes = node.archetypes;
var count = archetypes.Count;
if (count == 0) return null;
var index = randomStream.Next(0, count);
return archetypes[index];
}
return null;
}
}
[System.Serializable]
public class ForcedTilesProperties {
[Tooltip("If enabled, attempts to forcefully spawn tiles from ForcedTileSets after branching paths are generated.\n\nCan only be used if MainPathCount > 1.")]
public bool UseForcedTiles = false;
[Tooltip("The list of tiles that will be attempted to forcefully spawn. Each entry will spawn only one tile from it's list.\n\nIf the tile cannot be forcefully spawned, the dungeon generation will not restart.")]
public List<ForcedTileSetList> ForcedTileSets = new List<ForcedTileSetList>();
internal void CopyFrom(ForcedTilesProperties props) {
UseForcedTiles = props.UseForcedTiles;
ForcedTileSets = props.ForcedTileSets;
}
internal ForcedTilesProperties Copy() {
var copy = new ForcedTilesProperties();
copy.CopyFrom(this);
return copy;
}
}
[System.Serializable]
public class BranchPathMultiSimulationProperties {
[Tooltip("If enabled, dungeon generation will simulate a number of branch paths for each branch path, then choose the best branch path based on its weight. The weight is decided by the following criteria. Slows down Branch Path Times by a second or two.")]
public bool UseBranchPathMultiSim = false;
[Tooltip("The number pf simulations per branch path.\n\nIncreasing this value can increase your chances of finding your best path, but will increase Branch Path Times and vice versa.")]
public int SimulationCount = 5;
[Tooltip("The weight scale for the branch path's length. The length of the branch path is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize very long branch paths.")]
public float LengthWeightScale = 0.125f;
[Tooltip("The weight scale for the branch path's normalized length. The normalized length (0 -> 1) of the branch path (PathLength / MaxPathLength) is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who meet their maximum path length.")]
public float NormalizedLengthWeightScale = 1f;
[Tooltip("The weight scale for the branch path's number of connections to the same main path. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops in their main path in general.")]
public float SamePathBaseWeightScale = 0.125f;
[Tooltip("The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to their main paths")]
public float SamePathDepthWeightScale = 0.125f;
[Tooltip("The weight scale for the branch path's number of connections to the same main path. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to their main paths")]
public float SamePathNormalizedDepthWeightScale = 1f;
[Tooltip("The weight scale for the branch path's number of connections to other main paths. The number of possible connections is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make path loops to other main paths in general.")]
public float DiffPathBaseWeightScale = 0.25f;
[Tooltip("The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make deep path loops to other main paths.")]
public float DiffPathDepthWeightScale = 0.25f;
[Tooltip("The weight scale for the branch path's number of connections to other main paths. For each possible connection, the main path normalized depth difference is multiplied by the scale and is added to the branch path's weight.\n\nIncreasing this value will prioritize branch paths who make generally deep path loops to other main paths.")]
public float DiffPathNormalizedDepthWeightScale = 2f;
internal void CopyFrom(BranchPathMultiSimulationProperties props) {
UseBranchPathMultiSim = props.UseBranchPathMultiSim;
SimulationCount = props.SimulationCount;
LengthWeightScale = props.LengthWeightScale;
NormalizedLengthWeightScale = props.NormalizedLengthWeightScale;
SamePathBaseWeightScale = props.SamePathBaseWeightScale;
DiffPathBaseWeightScale = props.DiffPathBaseWeightScale;
SamePathDepthWeightScale = props.SamePathDepthWeightScale;
DiffPathDepthWeightScale = props.DiffPathDepthWeightScale;
SamePathNormalizedDepthWeightScale = props.SamePathNormalizedDepthWeightScale;
DiffPathNormalizedDepthWeightScale = props.DiffPathNormalizedDepthWeightScale;
}
internal BranchPathMultiSimulationProperties Copy() {
var copy = new BranchPathMultiSimulationProperties();
copy.CopyFrom(this);
return copy;
}
}
[System.Serializable]
public class LineRandomizerProperties {
[Tooltip("If enabled, every archetype in LineRandomizerArchetypes will have the last LineRandomizerTakeCount tilesets replaced by a randomly selected set of tilesets from LineRandomizerTileSets. This applies for both archetype's TileSets and BranchCapTileSets.\n\nThis is designed for the scenario where dungeon generation takes a long time due to the combination of too many tiles and/or doorways in those tiles. This can reduce dungeon generation time while keeping some of the randomness of dungeon generation.\n\nAs stated previously, this WILL replace the last LineRandomizerTakeCount tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")]
public bool UseLineRandomizer = false;
[Tooltip("The archetypes whose tilesets will be replaced.\n\nThese archetypes should ideally used in the Lines section of DungeonFlow, but it's a free country.")]
public List<DungeonArchetype> Archetypes = new List<DungeonArchetype>();
[Tooltip("The tilesets that will be used for replacement.")]
public List<TileSet> TileSets = new List<TileSet>();
[Tooltip("The amount of tilesets that will be replaced from the archetypes, starting from the last element to the first element.\n\nAs stated previously, this WILL replace the tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")]
public int TileSetsTakeCount = 3;
internal void CopyFrom(LineRandomizerProperties props) {
UseLineRandomizer = props.UseLineRandomizer;
Archetypes = props.Archetypes;
TileSets = props.TileSets;
}
internal LineRandomizerProperties Copy() {
var copy = new LineRandomizerProperties();
copy.CopyFrom(this);
return copy;
}
}
[System.Serializable]
public class MiscellaneousProperties {
[Tooltip("If enabled, updates the MaxShadowsRequest to MaxShadowsRequestAmount when your dungeon loads.\n\nThis is designed for the scenario where your dungeon, for whatever reason, has too many lights nearby and causes the annoying 'Max shadow requests count reached' warning to spam the logs.")]
public bool UseMaxShadowsRequestUpdate = false;
[Tooltip("The amount of MaxShadowsRequest.\n\n4 is the game's default value. I find 8 to be more than acceptable.")]
public int MaxShadowsRequestCount = 8;
[Tooltip("If enabled, the DoorwaySisters component will become active.\n\nThe component prevents an intersecting doorway from generating if it's 'sister' doorway already generated and both doorways would lead to the same neighboring tile.\n\nThis is designed for the scenario where, two neighboring doorways would lead to the same tile, one doorway is a locked door and the other is an open doorway. This would defeat the purpose of the locked door, and such as, this feature exists if needed.\n\nThis feature slows down dungeon generation slightly when enabled.")]
public bool UseDoorwaySisters = false;
[Tooltip("If enabled, the RandomGuaranteedScrapSpawn component will be come active.\n\nThe component allows random scrap of a specified minimum value to always be spawned on a specific point.")]
public bool UseRandomGuaranteedScrapSpawn = false;
internal void CopyFrom(MiscellaneousProperties props) {
UseMaxShadowsRequestUpdate = props.UseMaxShadowsRequestUpdate;
MaxShadowsRequestCount = props.MaxShadowsRequestCount;
UseDoorwaySisters = props.UseDoorwaySisters;
UseRandomGuaranteedScrapSpawn = props.UseRandomGuaranteedScrapSpawn;
}
internal MiscellaneousProperties Copy() {
var copy = new MiscellaneousProperties();
copy.CopyFrom(this);
return copy;
}
}
}

View File

@ -12,6 +12,7 @@ using LethalLevelLoader;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using DunGenPlus.DevTools.Panels; using DunGenPlus.DevTools.Panels;
using DunGenPlus.DevTools.UIElements; using DunGenPlus.DevTools.UIElements;
using DunGenPlus.Generation;
namespace DunGenPlus.DevTools { namespace DunGenPlus.DevTools {
internal partial class DevDebugManager : MonoBehaviour { internal partial class DevDebugManager : MonoBehaviour {
@ -101,6 +102,10 @@ namespace DunGenPlus.DevTools {
selectedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); selectedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate?.Invoke(fakeRoundManager);
DungeonManager.GlobalDungeonEvents?.onBeforeDungeonGenerate?.Invoke(fakeRoundManager); DungeonManager.GlobalDungeonEvents?.onBeforeDungeonGenerate?.Invoke(fakeRoundManager);
DunGenPlusGenerator.GenerateBranchBoostedPathsTime = 0f;
DunGenPlusGenerator.GetTileResultTime = 0f;
DunGenPlusGenerator.DoorwayPairTime = 0f;
DunGenPlusGenerator.CalculateWeightTime = 0f;
dungeon.Generate(); dungeon.Generate();
} }
@ -156,6 +161,12 @@ namespace DunGenPlus.DevTools {
textList.AppendLine($"Post Process Time: {stats.PostProcessTime:F2} ms"); textList.AppendLine($"Post Process Time: {stats.PostProcessTime:F2} ms");
textList.AppendLine($"Total Time: {stats.TotalTime:F2} ms"); textList.AppendLine($"Total Time: {stats.TotalTime:F2} ms");
textList.AppendLine("");
textList.AppendLine($"GenerateBranch Time: {DunGenPlusGenerator.GenerateBranchBoostedPathsTime:F2} ms");
textList.AppendLine($"GetTileResult Time: {DunGenPlusGenerator.GetTileResultTime:F2} ms");
textList.AppendLine($"DoorwayPair Time: {DunGenPlusGenerator.DoorwayPairTime:F2} ms");
textList.AppendLine($"CalculateWeight Time: {DunGenPlusGenerator.CalculateWeightTime:F2} ms");
statsTextMesh.text = textList.ToString(); statsTextMesh.text = textList.ToString();
} }

View File

@ -52,41 +52,40 @@ namespace DunGenPlus.DevTools.Panels.Collections {
} }
foreach(var t in extender.DungeonFlow.Nodes.SelectMany(n => n.TileSets)) { void AddTiles(IEnumerable<GameObject> tiles){
tileSetsHashSet.Add(t); foreach(var x in tiles) {
foreach(var x in t.TileWeights.Weights) { tilesHashSet.Add(x);
}
}
void AddTilesW(IEnumerable<GameObjectChance> tiles){
foreach(var x in tiles) {
tilesHashSet.Add(x.Value); tilesHashSet.Add(x.Value);
} }
} }
foreach(var a in extender.DungeonFlow.Lines.SelectMany(l => l.DungeonArchetypes)) {
archetypesHashSet.Add(a); void AddTileSets(IEnumerable<TileSet> tileSets){
foreach(var t in a.TileSets) { foreach(var x in tileSets){
tileSetsHashSet.Add(t); tileSetsHashSet.Add(x);
foreach(var x in t.TileWeights.Weights) { AddTilesW(x.TileWeights.Weights);
tilesHashSet.Add(x.Value);
}
} }
} }
foreach(var n in extender.Properties.NormalNodeArchetypes) { void AddArchetypes(IEnumerable<DungeonArchetype> archetypes){
foreach(var a in n.archetypes){ foreach(var x in archetypes){
archetypesHashSet.Add(a); archetypesHashSet.Add(x);
AddTileSets(x.TileSets);
foreach(var t in a.TileSets){
tileSetsHashSet.Add(t);
foreach(var x in t.TileWeights.Weights){
tilesHashSet.Add(x.Value);
}
}
} }
} }
foreach(var t in extender.Properties.ForcedTileSets.SelectMany(l => l.Tilesets)){ AddTileSets(extender.DungeonFlow.Nodes.SelectMany(n => n.TileSets));
tileSetsHashSet.Add(t); AddArchetypes(extender.DungeonFlow.Lines.SelectMany(l => l.DungeonArchetypes));
foreach(var x in t.TileWeights.Weights){ AddArchetypes(extender.Properties.NormalNodeArchetypesProperties.NormalNodeArchetypes.SelectMany(l => l.archetypes));
tilesHashSet.Add(x.Value); AddTileSets(extender.Properties.ForcedTilesProperties.ForcedTileSets.SelectMany(l => l.Tilesets));
}
} AddTiles(extender.Properties.AssetCacheTileList);
AddTileSets(extender.Properties.AssetCacheTileSetList);
AddArchetypes(extender.Properties.AssetCacheArchetypeList);
tileSets = new Collection<NullObject<TileSet>>(tileSetsHashSet.ToList()); tileSets = new Collection<NullObject<TileSet>>(tileSetsHashSet.ToList());
tiles = new Collection<NullObject<GameObject>>(tilesHashSet.ToList()); tiles = new Collection<NullObject<GameObject>>(tilesHashSet.ToList());

View File

@ -98,63 +98,73 @@ namespace DunGenPlus.DevTools.Panels {
var mainPathTransform = manager.CreateVerticalLayoutUIField(parentTransform); var mainPathTransform = manager.CreateVerticalLayoutUIField(parentTransform);
mainPathParentGameobject = mainPathTransform.gameObject; mainPathParentGameobject = mainPathTransform.gameObject;
manager.CreateHeaderUIField(parentTransform, "Main Path"); manager.CreateHeaderUIField(parentTransform, "Main Path");
manager.CreateIntSliderField(parentTransform, "Main Path Count", new IntParameter(properties.MainPathCount, 1, 10), SetMainPathCount); manager.CreateIntSliderField(parentTransform, "Main Path Count", new IntParameter(properties.MainPathProperties.MainPathCount, 1, 10), SetMainPathCount);
mainPathTransform.SetAsLastSibling(); mainPathTransform.SetAsLastSibling();
manager.CreateTileOptionsUIField(mainPathTransform, "Main Room Tile Prefab", selectedAssetCache.tiles.dictionary[properties.MainRoomTilePrefab], SetMainRoom); manager.CreateTileOptionsUIField(mainPathTransform, "Main Room Tile Prefab", selectedAssetCache.tiles.dictionary[properties.MainPathProperties.MainRoomTilePrefab], SetMainRoom);
manager.CreateCopyNodeBehaviourOptionsUIField(mainPathTransform, "Copy Node Behaviour", (int)properties.MainPathCopyNodeBehaviour, SetCopyNodeBehaviour); manager.CreateCopyNodeBehaviourOptionsUIField(mainPathTransform, "Copy Node Behaviour", (int)properties.MainPathProperties.CopyNodeBehaviour, SetCopyNodeBehaviour);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
var dungeonBoundsTransform = manager.CreateVerticalLayoutUIField(parentTransform); var dungeonBoundsTransform = manager.CreateVerticalLayoutUIField(parentTransform);
dungeonBoundsParentGameobject = dungeonBoundsTransform.gameObject; dungeonBoundsParentGameobject = dungeonBoundsTransform.gameObject;
manager.CreateHeaderUIField(parentTransform, "Dungeon Bounds"); manager.CreateHeaderUIField(parentTransform, "Dungeon Bounds");
manager.CreateBoolInputField(parentTransform, "Use Dungeon Bounds", properties.UseDungeonBounds, SetUseDungeonBounds); manager.CreateBoolInputField(parentTransform, "Use Dungeon Bounds", properties.DungeonBoundsProperties.UseDungeonBounds, SetUseDungeonBounds);
dungeonBoundsTransform.SetAsLastSibling(); dungeonBoundsTransform.SetAsLastSibling();
manager.CreateVector3InputField(dungeonBoundsTransform, "Size Base", properties.DungeonSizeBase, SetDungeonBoundsSizeBase); manager.CreateVector3InputField(dungeonBoundsTransform, "Size Base", properties.DungeonBoundsProperties.SizeBase, SetDungeonBoundsSizeBase);
manager.CreateVector3InputField(dungeonBoundsTransform, "Size Factor", properties.DungeonSizeFactor, SetDungeonBoundsSizeFactor); manager.CreateVector3InputField(dungeonBoundsTransform, "Size Factor", properties.DungeonBoundsProperties.SizeFactor, SetDungeonBoundsSizeFactor);
manager.CreateVector3InputField(dungeonBoundsTransform, "Position Offset", properties.DungeonPositionOffset, SetDungeonBoundsPosOffset); manager.CreateVector3InputField(dungeonBoundsTransform, "Position Offset", properties.DungeonBoundsProperties.PositionOffset, SetDungeonBoundsPosOffset);
manager.CreateVector3InputField(dungeonBoundsTransform, "Position Pivot", properties.DungeonPositionPivot, SetDungeonBoundsPosPivot); manager.CreateVector3InputField(dungeonBoundsTransform, "Position Pivot", properties.DungeonBoundsProperties.PositionPivot, SetDungeonBoundsPosPivot);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
var archetypesTransform = manager.CreateVerticalLayoutUIField(parentTransform); var archetypesTransform = manager.CreateVerticalLayoutUIField(parentTransform);
archetypesNodesParentGameobject = archetypesTransform.gameObject; archetypesNodesParentGameobject = archetypesTransform.gameObject;
manager.CreateHeaderUIField(parentTransform, "Archetypes Normal Nodes"); manager.CreateHeaderUIField(parentTransform, "Archetypes Normal Nodes");
manager.CreateBoolInputField(parentTransform, "Add Archetypes", properties.AddArchetypesToNormalNodes, SetAddArchetypes); manager.CreateBoolInputField(parentTransform, "Add Archetypes", properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes, SetAddArchetypes);
archetypesTransform.SetAsLastSibling(); archetypesTransform.SetAsLastSibling();
manager.CreateListUIField(archetypesTransform, "Normal Node Archetypes", properties.NormalNodeArchetypes); manager.CreateListUIField(archetypesTransform, "Normal Node Archetypes", properties.NormalNodeArchetypesProperties.NormalNodeArchetypes);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
var forcedTilesTransform = manager.CreateVerticalLayoutUIField(parentTransform); var forcedTilesTransform = manager.CreateVerticalLayoutUIField(parentTransform);
forcedTilesParentGameobject = forcedTilesTransform.gameObject; forcedTilesParentGameobject = forcedTilesTransform.gameObject;
manager.CreateHeaderUIField(parentTransform, "Forced Tiles"); manager.CreateHeaderUIField(parentTransform, "Forced Tiles");
manager.CreateBoolInputField(parentTransform, "Use Forced Tiles", properties.UseForcedTiles, SetUseForcedTiles); manager.CreateBoolInputField(parentTransform, "Use Forced Tiles", properties.ForcedTilesProperties.UseForcedTiles, SetUseForcedTiles);
forcedTilesTransform.SetAsLastSibling(); forcedTilesTransform.SetAsLastSibling();
manager.CreateListUIField(forcedTilesTransform, "Forced Tile Sets", properties.ForcedTileSets); manager.CreateListUIField(forcedTilesTransform, "Forced Tile Sets", properties.ForcedTilesProperties.ForcedTileSets);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
var branchLoopTransform = manager.CreateVerticalLayoutUIField(parentTransform); var branchLoopTransform = manager.CreateVerticalLayoutUIField(parentTransform);
branchLoopBoostParentGameobject = branchLoopTransform.gameObject; branchLoopBoostParentGameobject = branchLoopTransform.gameObject;
manager.CreateHeaderUIField(parentTransform, "Branch Loop Boost"); manager.CreateHeaderUIField(parentTransform, "Branch Path Multi Sim");
manager.CreateBoolInputField(parentTransform, "Use Branch Loop Boost", properties.UseBranchLoopBoost, SetUseBranchLoopBoost); manager.CreateBoolInputField(parentTransform, "Use Branch Path Multi Sim", properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim, SetUseBranchPathMultiSim);
branchLoopTransform.SetAsLastSibling(); branchLoopTransform.SetAsLastSibling();
manager.CreateIntInputField(branchLoopTransform, "Tile Search Count", new IntParameter(properties.BranchLoopBoostTileSearch, 1, 100, 1), SetTileBoostSearch); manager.CreateIntInputField(branchLoopTransform, "Simulation Count", new IntParameter(properties.BranchPathMultiSimulationProperties.SimulationCount, 1, 10, 1), SetSimulationCount);
manager.CreateFloatInputField(branchLoopTransform, "Tile Boost Search", new FloatParameter(properties.BranchLoopBoostTileScale, 0f, 2f, 0f), SetTileBoostScale); manager.CreateFloatInputField(branchLoopTransform, "Length Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.LengthWeightScale, 0f, 2f, 0f), SetLengthScale);
manager.CreateFloatInputField(branchLoopTransform, "Norm. Length Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.NormalizedLengthWeightScale, 0f, 2f, 0f), SetNormalizedLengthScale);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
var maxShadowsTransform = manager.CreateVerticalLayoutUIField(parentTransform); manager.CreateTextUIField(branchLoopTransform, "Same Path Connect");
maxShadowsParentGameobject = maxShadowsTransform.gameObject; manager.CreateFloatInputField(branchLoopTransform, "Base Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathBaseWeightScale, 0f, 2f, 0f), SamePathBaseConnectScale);
manager.CreateHeaderUIField(parentTransform, "Max Shadows Request"); manager.CreateFloatInputField(branchLoopTransform, "Depth Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathDepthWeightScale, 0f, 2f, 0f), SamePathConnectDepthScale);
manager.CreateBoolInputField(parentTransform, "Use Max Shadows Request", properties.UseMaxShadowsRequestUpdate, SetUseMaxShadows); manager.CreateFloatInputField(branchLoopTransform, "Norm. Depth Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.SamePathNormalizedDepthWeightScale, 0f, 2f, 0f), SamePathConnectNormalizedDepthScale);
maxShadowsTransform.SetAsLastSibling(); manager.CreateSpaceUIField(parentTransform);
manager.CreateIntInputField(maxShadowsTransform, "Shadows Request Amount", new IntParameter(properties.MaxShadowsRequestAmount, 4, 20, 4), SetMaxShadowsAmount);
manager.CreateTextUIField(branchLoopTransform, "Diff Path Connect");
manager.CreateFloatInputField(branchLoopTransform, "Base Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathBaseWeightScale, 0f, 2f, 0f), DiffPathBaseConnectScale);
manager.CreateFloatInputField(branchLoopTransform, "Depth Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathDepthWeightScale, 0f, 2f, 0f), DiffPathConnectDepthScale);
manager.CreateFloatInputField(branchLoopTransform, "Norm. Depth Weight Scale", new FloatParameter(properties.BranchPathMultiSimulationProperties.DiffPathNormalizedDepthWeightScale, 0f, 2f, 0f), DiffPathConnectNormalizedDepthScale);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
// miss
manager.CreateHeaderUIField(parentTransform, "Miscellaneous"); manager.CreateHeaderUIField(parentTransform, "Miscellaneous");
manager.CreateBoolInputField(parentTransform, "Use Doorway Sisters", properties.UseDoorwaySisters, SetUseDoorwaySisters); var maxShadowTransform = manager.CreateVerticalLayoutUIField(parentTransform);
manager.CreateBoolInputField(parentTransform, "Use Random Guaranteed Scrap", properties.UseRandomGuaranteedScrapSpawn, SetUseRandomGuaranteedScrap); maxShadowsParentGameobject = maxShadowTransform.gameObject;
manager.CreateBoolInputField(parentTransform, "Use Max Shadows Request", properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate, SetUseMaxShadows);
manager.CreateIntInputField(maxShadowTransform, "Shadows Request Amount", new IntParameter(properties.MiscellaneousProperties.MaxShadowsRequestCount, 4, 20, 4), SetMaxShadowsCount);
maxShadowTransform.SetAsLastSibling();
manager.CreateBoolInputField(parentTransform, "Use Doorway Sisters", properties.MiscellaneousProperties.UseDoorwaySisters, SetUseDoorwaySisters);
manager.CreateBoolInputField(parentTransform, "Use Random Guaranteed Scrap", properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn, SetUseRandomGuaranteedScrap);
manager.CreateSpaceUIField(parentTransform); manager.CreateSpaceUIField(parentTransform);
dungeonBoundsHelperGameObject.SetActive(selectedExtenderer.Properties.UseDungeonBounds); dungeonBoundsHelperGameObject.SetActive(selectedExtenderer.Properties.DungeonBoundsProperties.UseDungeonBounds);
UpdateDungeonBoundsHelper(); UpdateDungeonBoundsHelper();
} }
@ -167,20 +177,20 @@ namespace DunGenPlus.DevTools.Panels {
} }
public void SetMainPathCount(int value) { public void SetMainPathCount(int value) {
selectedExtenderer.Properties.MainPathCount = value; selectedExtenderer.Properties.MainPathProperties.MainPathCount = value;
mainPathParentGameobject.SetActive(value > 1); mainPathParentGameobject.SetActive(value > 1);
} }
public void SetMainRoom(GameObject value) { public void SetMainRoom(GameObject value) {
selectedExtenderer.Properties.MainRoomTilePrefab = value; selectedExtenderer.Properties.MainPathProperties.MainRoomTilePrefab = value;
} }
public void SetCopyNodeBehaviour(DunGenExtenderProperties.CopyNodeBehaviour value) { public void SetCopyNodeBehaviour(DunGenExtenderProperties.CopyNodeBehaviour value) {
selectedExtenderer.Properties.MainPathCopyNodeBehaviour = value; selectedExtenderer.Properties.MainPathProperties.CopyNodeBehaviour = value;
} }
public void SetUseDungeonBounds(bool state){ public void SetUseDungeonBounds(bool state){
selectedExtenderer.Properties.UseDungeonBounds = state; selectedExtenderer.Properties.DungeonBoundsProperties.UseDungeonBounds = state;
dungeonBoundsHelperGameObject.SetActive(state); dungeonBoundsHelperGameObject.SetActive(state);
dungeonBoundsParentGameobject.SetActive(state); dungeonBoundsParentGameobject.SetActive(state);
} }
@ -189,69 +199,98 @@ namespace DunGenPlus.DevTools.Panels {
if (selectedExtenderer == null) return; if (selectedExtenderer == null) return;
var t = dungeonBoundsHelperGameObject.transform; var t = dungeonBoundsHelperGameObject.transform;
var result = selectedExtenderer.Properties.GetDungeonBounds(dungeon.Generator.LengthMultiplier); var result = selectedExtenderer.Properties.DungeonBoundsProperties.GetDungeonBounds(dungeon.Generator.LengthMultiplier);
t.localPosition = result.center; t.localPosition = result.center;
t.localScale = result.size; t.localScale = result.size;
} }
public void SetDungeonBoundsSizeBase(Vector3 value) { public void SetDungeonBoundsSizeBase(Vector3 value) {
selectedExtenderer.Properties.DungeonSizeBase = value; selectedExtenderer.Properties.DungeonBoundsProperties.SizeBase = value;
UpdateDungeonBoundsHelper(); UpdateDungeonBoundsHelper();
} }
public void SetDungeonBoundsSizeFactor(Vector3 value) { public void SetDungeonBoundsSizeFactor(Vector3 value) {
selectedExtenderer.Properties.DungeonSizeFactor = value; selectedExtenderer.Properties.DungeonBoundsProperties.SizeFactor = value;
UpdateDungeonBoundsHelper(); UpdateDungeonBoundsHelper();
} }
public void SetDungeonBoundsPosOffset(Vector3 value) { public void SetDungeonBoundsPosOffset(Vector3 value) {
selectedExtenderer.Properties.DungeonPositionOffset = value; selectedExtenderer.Properties.DungeonBoundsProperties.PositionOffset = value;
UpdateDungeonBoundsHelper(); UpdateDungeonBoundsHelper();
} }
public void SetDungeonBoundsPosPivot(Vector3 value) { public void SetDungeonBoundsPosPivot(Vector3 value) {
selectedExtenderer.Properties.DungeonPositionPivot = value; selectedExtenderer.Properties.DungeonBoundsProperties.PositionPivot = value;
UpdateDungeonBoundsHelper(); UpdateDungeonBoundsHelper();
} }
public void SetAddArchetypes(bool state){ public void SetAddArchetypes(bool state){
selectedExtenderer.Properties.AddArchetypesToNormalNodes = state; selectedExtenderer.Properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes = state;
archetypesNodesParentGameobject.SetActive(state); archetypesNodesParentGameobject.SetActive(state);
} }
public void SetUseForcedTiles(bool state){ public void SetUseForcedTiles(bool state){
selectedExtenderer.Properties.UseForcedTiles = state; selectedExtenderer.Properties.ForcedTilesProperties.UseForcedTiles = state;
forcedTilesParentGameobject.SetActive(state); forcedTilesParentGameobject.SetActive(state);
} }
public void SetUseBranchLoopBoost(bool state){ public void SetUseBranchPathMultiSim(bool state){
selectedExtenderer.Properties.UseBranchLoopBoost = state; selectedExtenderer.Properties.BranchPathMultiSimulationProperties.UseBranchPathMultiSim = state;
branchLoopBoostParentGameobject.SetActive(state); branchLoopBoostParentGameobject.SetActive(state);
} }
public void SetTileBoostSearch(int value){ public void SetSimulationCount(int value){
selectedExtenderer.Properties.BranchLoopBoostTileSearch = value; selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SimulationCount = value;
} }
public void SetTileBoostScale(float value){ public void SetLengthScale(float value){
selectedExtenderer.Properties.BranchLoopBoostTileScale = value; selectedExtenderer.Properties.BranchPathMultiSimulationProperties.LengthWeightScale = value;
} }
public void SetNormalizedLengthScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.NormalizedLengthWeightScale = value;
}
public void SamePathBaseConnectScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathBaseWeightScale = value;
}
public void DiffPathBaseConnectScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathBaseWeightScale = value;
}
public void SamePathConnectDepthScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathDepthWeightScale = value;
}
public void DiffPathConnectDepthScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathDepthWeightScale = value;
}
public void SamePathConnectNormalizedDepthScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.SamePathNormalizedDepthWeightScale = value;
}
public void DiffPathConnectNormalizedDepthScale(float value){
selectedExtenderer.Properties.BranchPathMultiSimulationProperties.DiffPathNormalizedDepthWeightScale = value;
}
public void SetUseMaxShadows(bool state){ public void SetUseMaxShadows(bool state){
selectedExtenderer.Properties.UseMaxShadowsRequestUpdate = state; selectedExtenderer.Properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate = state;
maxShadowsParentGameobject.SetActive(state); maxShadowsParentGameobject.SetActive(state);
} }
public void SetMaxShadowsAmount(int value){ public void SetMaxShadowsCount(int value){
selectedExtenderer.Properties.MaxShadowsRequestAmount = value; selectedExtenderer.Properties.MiscellaneousProperties.MaxShadowsRequestCount = value;
} }
public void SetUseDoorwaySisters(bool state){ public void SetUseDoorwaySisters(bool state){
selectedExtenderer.Properties.UseDoorwaySisters = state; selectedExtenderer.Properties.MiscellaneousProperties.UseDoorwaySisters = state;
} }
public void SetUseRandomGuaranteedScrap(bool state){ public void SetUseRandomGuaranteedScrap(bool state){
selectedExtenderer.Properties.UseRandomGuaranteedScrapSpawn = state; selectedExtenderer.Properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn = state;
} }
public void RestoreOriginalState(){ public void RestoreOriginalState(){

View File

@ -130,6 +130,7 @@
<Compile Include="API.cs" /> <Compile Include="API.cs" />
<Compile Include="Assets.cs" /> <Compile Include="Assets.cs" />
<Compile Include="Collections\DunGenExtenderEvents.cs" /> <Compile Include="Collections\DunGenExtenderEvents.cs" />
<Compile Include="Collections\DunGenExtenderPropertiesCollection.cs" />
<Compile Include="Collections\ExtenderEvent.cs" /> <Compile Include="Collections\ExtenderEvent.cs" />
<Compile Include="Collections\ForcedTileSetList.cs" /> <Compile Include="Collections\ForcedTileSetList.cs" />
<Compile Include="Collections\NodeArchetype.cs" /> <Compile Include="Collections\NodeArchetype.cs" />

View File

@ -20,7 +20,7 @@ namespace DunGenPlus.Generation {
public static Dictionary<DoorwayProxy, Data> doorwayProxyDictionary; public static Dictionary<DoorwayProxy, Data> doorwayProxyDictionary;
public static void UpdateCache(IEnumerable<DoorwayProxy> list){ public static void UpdateCache(IEnumerable<DoorwayProxy> list){
if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.UseDoorwaySisters) return; if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) return;
Plugin.logger.LogDebug("Updating DoorwayProxy cache for DoorwaySistersRule"); Plugin.logger.LogDebug("Updating DoorwayProxy cache for DoorwaySistersRule");
doorwayDictionary = new Dictionary<Doorway, Data>(); doorwayDictionary = new Dictionary<Doorway, Data>();
@ -55,7 +55,7 @@ namespace DunGenPlus.Generation {
//Plugin.logger.LogInfo($"{tileA.Prefab.name} <-> {tileB.Prefab.name}: {(doorwayA.Position - doorwayB.Position).sqrMagnitude}"); //Plugin.logger.LogInfo($"{tileA.Prefab.name} <-> {tileB.Prefab.name}: {(doorwayA.Position - doorwayB.Position).sqrMagnitude}");
if (!result) return false; if (!result) return false;
if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.UseDoorwaySisters) return true; if (!DunGenPlusGenerator.Active || !DunGenPlusGenerator.Properties.MiscellaneousProperties.UseDoorwaySisters) return true;
var infoA = doorwayProxyDictionary[doorwayA].info; var infoA = doorwayProxyDictionary[doorwayA].info;
var infoB = doorwayProxyDictionary[doorwayB].info; var infoB = doorwayProxyDictionary[doorwayB].info;

View File

@ -22,6 +22,7 @@ namespace DunGenPlus.Generation {
internal partial class DunGenPlusGenerator { internal partial class DunGenPlusGenerator {
public static DunGenExtender Instance { get; internal set; } public static DunGenExtender Instance { get; internal set; }
public static DunGenExtenderProperties Properties { get; internal set; } public static DunGenExtenderProperties Properties { get; internal set; }
public static bool Active { get; internal set; } public static bool Active { get; internal set; }
public static bool ActiveAlternative { get; internal set; } public static bool ActiveAlternative { get; internal set; }
@ -36,25 +37,25 @@ namespace DunGenPlus.Generation {
var props = extender.Properties.Copy(); var props = extender.Properties.Copy();
var callback = new EventCallbackScenario(DevDebugManager.Instance); var callback = new EventCallbackScenario(DevDebugManager.Instance);
Instance.Events.OnModifyDunGenExtenderProperties.Invoke(props, callback); Instance.Events.OnModifyDunGenExtenderProperties.Invoke(props, callback);
props.SetupProperties(generator); props.NormalNodeArchetypesProperties.SetupProperties(generator);
Properties = props; Properties = props;
if (Properties.UseDungeonBounds) { if (Properties.DungeonBoundsProperties.UseDungeonBounds) {
generator.DebugRender = true; generator.DebugRender = true;
generator.RestrictDungeonToBounds = Properties.UseDungeonBounds; generator.RestrictDungeonToBounds = true;
var bounds = Properties.GetDungeonBounds(generator.LengthMultiplier); var bounds = Properties.DungeonBoundsProperties.GetDungeonBounds(generator.LengthMultiplier);
generator.TilePlacementBounds = bounds; generator.TilePlacementBounds = bounds;
Plugin.logger.LogDebug($"Dungeon Bounds: {bounds}"); Plugin.logger.LogDebug($"Dungeon Bounds: {bounds}");
} }
if (Properties.UseMaxShadowsRequestUpdate) { if (Properties.MiscellaneousProperties.UseMaxShadowsRequestUpdate) {
Plugin.logger.LogDebug($"Updating HDRP asset: setting max shadows request to {Properties.MaxShadowsRequestAmount}"); Plugin.logger.LogDebug($"Updating HDRP asset: setting max shadows request to {Properties.MiscellaneousProperties.MaxShadowsRequestCount}");
try { try {
previousHDRPAsset = QualitySettings.renderPipeline as HDRenderPipelineAsset; previousHDRPAsset = QualitySettings.renderPipeline as HDRenderPipelineAsset;
newHDRPAsset = ScriptableObject.Instantiate(previousHDRPAsset); newHDRPAsset = ScriptableObject.Instantiate(previousHDRPAsset);
var settings = newHDRPAsset.currentPlatformRenderPipelineSettings; var settings = newHDRPAsset.currentPlatformRenderPipelineSettings;
settings.hdShadowInitParams.maxScreenSpaceShadowSlots = Properties.MaxShadowsRequestAmount; settings.hdShadowInitParams.maxScreenSpaceShadowSlots = Properties.MiscellaneousProperties.MaxShadowsRequestCount;
newHDRPAsset.currentPlatformRenderPipelineSettings = settings; newHDRPAsset.currentPlatformRenderPipelineSettings = settings;
QualitySettings.renderPipeline = newHDRPAsset; QualitySettings.renderPipeline = newHDRPAsset;
@ -83,9 +84,27 @@ namespace DunGenPlus.Generation {
} }
} }
private static Dictionary<TileProxy, int> tileProxyMainPath = new Dictionary<TileProxy, int>();
public static int GetMainPathIndexFromTileProxy(TileProxy tileProxy){
return tileProxyMainPath[tileProxy];
}
private static void AddTileProxyToMainPathDictionary(IEnumerable<TileProxy> tileProxies, int index) {
var totalLength = (float)tileProxies.Last().Placement.PathDepth;
foreach(var t in tileProxies) {
tileProxyMainPath.Add(t, index);
t.Placement.NormalizedPathDepth = t.Placement.PathDepth / totalLength;
}
}
public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) { public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) {
var altCount = Properties.MainPathCount - 1; var altCount = Properties.MainPathProperties.MainPathCount - 1;
tileProxyMainPath.Clear();
var mainRoomTilePrefab = Properties.MainPathProperties.MainRoomTilePrefab;
var copyNodeBehaviour = Properties.MainPathProperties.CopyNodeBehaviour;
// default behaviour in case the multiple main paths are not considered // default behaviour in case the multiple main paths are not considered
if (!Active) { if (!Active) {
@ -103,7 +122,7 @@ namespace DunGenPlus.Generation {
yield break; yield break;
} }
if (Properties.MainRoomTilePrefab == null) { if (mainRoomTilePrefab == null) {
Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to MainRoomTilePrefab being null"); Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to MainRoomTilePrefab being null");
ActiveAlternative = false; ActiveAlternative = false;
yield return gen.Wait(gen.GenerateBranchPaths()); yield return gen.Wait(gen.GenerateBranchPaths());
@ -112,11 +131,13 @@ namespace DunGenPlus.Generation {
} }
var allMainPathTiles = new List<List<TileProxy>>(); var allMainPathTiles = new List<List<TileProxy>>();
allMainPathTiles.Add(gen.proxyDungeon.MainPathTiles.ToList()); var firstMainPathTiles = gen.proxyDungeon.MainPathTiles.ToList();
allMainPathTiles.Add(firstMainPathTiles);
AddTileProxyToMainPathDictionary(firstMainPathTiles, 0);
// main room is the true main room and not the fake room // main room is the true main room and not the fake room
// this MUST have multiple doorways as you can imagine // this MUST have multiple doorways as you can imagine
var mainRoom = gen.proxyDungeon.MainPathTiles.FirstOrDefault(t => t.Prefab == Properties.MainRoomTilePrefab); var mainRoom = gen.proxyDungeon.MainPathTiles.FirstOrDefault(t => t.Prefab == mainRoomTilePrefab);
if (mainRoom == null) { if (mainRoom == null) {
Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to MainRoomTilePrefab not spawning on the main path"); Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to MainRoomTilePrefab not spawning on the main path");
ActiveAlternative = false; ActiveAlternative = false;
@ -133,8 +154,8 @@ namespace DunGenPlus.Generation {
// nodes // nodes
var nodesSorted = gen.DungeonFlow.Nodes.OrderBy(n => n.Position).ToList(); var nodesSorted = gen.DungeonFlow.Nodes.OrderBy(n => n.Position).ToList();
var startingNodeIndexCache = -1; var startingNodeIndexCache = -1;
if (Properties.MainPathCopyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList) { if (copyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList) {
startingNodeIndexCache = nodesSorted.FindIndex(n => n.TileSets.SelectMany(t => t.TileWeights.Weights).Any(t => t.Value == Properties.MainRoomTilePrefab)); startingNodeIndexCache = nodesSorted.FindIndex(n => n.TileSets.SelectMany(t => t.TileWeights.Weights).Any(t => t.Value == mainRoomTilePrefab));
if (startingNodeIndexCache == -1) { if (startingNodeIndexCache == -1) {
Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to CopyNodeBehaviour being CopyFromNodeList AND MainRoomTilePrefab not existing in the Nodes' tilesets"); Plugin.logger.LogWarning($"Switching to default dungeon branch generation due to CopyNodeBehaviour being CopyFromNodeList AND MainRoomTilePrefab not existing in the Nodes' tilesets");
@ -158,16 +179,17 @@ namespace DunGenPlus.Generation {
var archetypes = new List<DungeonArchetype>(targetLength); var archetypes = new List<DungeonArchetype>(targetLength);
var newMainPathTiles = new List<TileProxy>(); var newMainPathTiles = new List<TileProxy>();
newMainPathTiles.Add(mainRoom); // this causes the main room to create three sets of branch paths
// newMainPathTiles.Add(mainRoom);
int startingNodeIndex; int startingNodeIndex;
if (Properties.MainPathCopyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromMainPathPosition) { if (copyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromMainPathPosition) {
var lineDepthRatio = Mathf.Clamp01(1f / (targetLength - 1)); var lineDepthRatio = Mathf.Clamp01(1f / (targetLength - 1));
startingNodeIndex = nodesSorted.FindIndex(n => n.Position >= lineDepthRatio); startingNodeIndex = nodesSorted.FindIndex(n => n.Position >= lineDepthRatio);
} else if (Properties.MainPathCopyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList) { } else if (copyNodeBehaviour == DunGenExtenderProperties.CopyNodeBehaviour.CopyFromNodeList) {
startingNodeIndex = startingNodeIndexCache; startingNodeIndex = startingNodeIndexCache;
} else { } else {
Plugin.logger.LogError($"{Properties.MainPathCopyNodeBehaviour} is not yet defined. How did this happen?"); Plugin.logger.LogError($"{copyNodeBehaviour} is not yet defined. How did this happen?");
startingNodeIndex = -1; startingNodeIndex = -1;
} }
@ -189,9 +211,6 @@ namespace DunGenPlus.Generation {
gen.previousLineSegment = lineAtDepth; gen.previousLineSegment = lineAtDepth;
} }
// terrible solution but FUCK it
// and yet it worked
// this is how my last node cannot be a target of pruning
GraphNode graphNode = null; GraphNode graphNode = null;
DungeonArchetype archetype = null; DungeonArchetype archetype = null;
foreach(var g in nodes) { foreach(var g in nodes) {
@ -256,8 +275,8 @@ namespace DunGenPlus.Generation {
if (gen.ShouldSkipFrame(true)) yield return gen.GetRoomPause(); if (gen.ShouldSkipFrame(true)) yield return gen.GetRoomPause();
} }
AddTileProxyToMainPathDictionary(newMainPathTiles, b + 1);
allMainPathTiles.Add(newMainPathTiles); allMainPathTiles.Add(newMainPathTiles);
} }
// okay lets fix the fakes // okay lets fix the fakes
@ -277,7 +296,13 @@ namespace DunGenPlus.Generation {
RandomizeLineArchetypes(gen, false); RandomizeLineArchetypes(gen, false);
gen.proxyDungeon.MainPathTiles = allMainPathTiles[b]; gen.proxyDungeon.MainPathTiles = allMainPathTiles[b];
if (Properties.UseBranchLoopBoost) yield return gen.Wait(GenerateBranchBoostedPaths(gen)); 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()); else yield return gen.Wait(gen.GenerateBranchPaths());
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
@ -9,8 +10,22 @@ namespace DunGenPlus.Generation
{ {
internal partial class DunGenPlusGenerator { internal partial class DunGenPlusGenerator {
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;
private class BranchPathProxy { private class BranchPathProxy {
public TileProxy attachTileProxy; public TileProxy mainPathTile;
public int mainPathIndex;
public List<TilePlacementResultProxy> list; public List<TilePlacementResultProxy> list;
public float weight; public float weight;
@ -18,7 +33,9 @@ namespace DunGenPlus.Generation
public List<InjectedTile> tilesPendingInjection; public List<InjectedTile> tilesPendingInjection;
public BranchPathProxy(DungeonGenerator gen, TileProxy attachTileProxy){ public BranchPathProxy(DungeonGenerator gen, TileProxy attachTileProxy){
this.attachTileProxy = attachTileProxy; mainPathTile = attachTileProxy;
mainPathIndex = GetMainPathIndexFromTileProxy(attachTileProxy);
list = new List<TilePlacementResultProxy>(); list = new List<TilePlacementResultProxy>();
weight = 0f; weight = 0f;
@ -27,21 +44,48 @@ namespace DunGenPlus.Generation
} }
public void CalculateWeight(DungeonGenerator gen){ public void CalculateWeight(DungeonGenerator gen){
weight = list.Count * 0.25f; var count = list.Count;
if (count == 0) return;
var lengthWeightScale = Properties.BranchPathMultiSimulationProperties.LengthWeightScale;
var normalizedWeightScale = Properties.BranchPathMultiSimulationProperties.NormalizedLengthWeightScale;
var samePathWeightScale = Properties.BranchPathMultiSimulationProperties.SamePathBaseWeightScale;
var diffPathWeightScale = Properties.BranchPathMultiSimulationProperties.DiffPathBaseWeightScale;
var samePathDepthWeightScale = Properties.BranchPathMultiSimulationProperties.SamePathDepthWeightScale;
var diffPathDepthWeightScale = Properties.BranchPathMultiSimulationProperties.DiffPathDepthWeightScale;
var samePathNormalizedDepthWeightScale = Properties.BranchPathMultiSimulationProperties.SamePathNormalizedDepthWeightScale;
var diffPathNormalizedDepthWeightScale = Properties.BranchPathMultiSimulationProperties.DiffPathNormalizedDepthWeightScale;
var lastNode = list[count - 1];
weight += lastNode.tileProxy.Placement.BranchDepth * lengthWeightScale;
weight += lastNode.tileProxy.Placement.NormalizedBranchDepth * normalizedWeightScale;
var allDungeonDoorways = gen.proxyDungeon.AllTiles.SelectMany(t => t.Doorways); var allDungeonDoorways = gen.proxyDungeon.AllTiles.SelectMany(t => t.Doorways);
foreach(var t in list) { foreach(var t in list) {
foreach(var d in allDungeonDoorways) { foreach(var d in allDungeonDoorways) {
if (d.TileProxy == mainPathTile) continue;
var dIndex = GetMainPathIndexFromTileProxy(d.TileProxy);
foreach(var l in t.tileProxy.doorways) { foreach(var l in t.tileProxy.doorways) {
if (d.TileProxy == t.previousDoorway.TileProxy || d.TileProxy == attachTileProxy) continue; if (d.TileProxy == t.previousDoorway.TileProxy) continue;
// favor paths that connect to other depths // favor paths that connect to other depths
if (gen.DungeonFlow.CanDoorwaysConnect(d.TileProxy.PrefabTile, l.TileProxy.PrefabTile, d.DoorwayComponent, l.DoorwayComponent) && Vector3.SqrMagnitude(d.Position - l.Position) < 1E-05){ if (gen.DungeonFlow.CanDoorwaysConnect(d.TileProxy.PrefabTile, l.TileProxy.PrefabTile, d.DoorwayComponent, l.DoorwayComponent) && Vector3.SqrMagnitude(d.Position - l.Position) < 1E-05){
var diff = Mathf.Abs(d.TileProxy.Placement.PathDepth - l.TileProxy.Placement.PathDepth); var diff = Mathf.Abs(d.TileProxy.Placement.PathDepth - l.TileProxy.Placement.PathDepth);
weight += diff; var normalDiff = Mathf.Abs(d.TileProxy.Placement.NormalizedPathDepth - l.TileProxy.Placement.NormalizedPathDepth);
var samePath = mainPathIndex == dIndex;
weight += samePath ? samePathWeightScale : diffPathWeightScale;
weight += diff * (samePath ? samePathDepthWeightScale : diffPathDepthWeightScale);
weight += normalDiff * (samePath ? samePathNormalizedDepthWeightScale : diffPathNormalizedDepthWeightScale);
} }
} }
} }
} }
//Plugin.logger.LogInfo($"Path({lastNode.tileProxy.Placement.NormalizedBranchDepth}): {weight}");
} }
} }
@ -68,7 +112,7 @@ namespace DunGenPlus.Generation
} }
public static IEnumerator GenerateBranchBoostedPaths(DungeonGenerator gen){ public static IEnumerator GenerateMultiBranchPaths(DungeonGenerator gen){
gen.ChangeStatus(GenerationStatus.Branching); gen.ChangeStatus(GenerationStatus.Branching);
var mainPathBranches = new int[gen.proxyDungeon.MainPathTiles.Count]; var mainPathBranches = new int[gen.proxyDungeon.MainPathTiles.Count];
BranchCountHelper.ComputeBranchCounts(gen.DungeonFlow, gen.RandomStream, gen.proxyDungeon, ref mainPathBranches); BranchCountHelper.ComputeBranchCounts(gen.DungeonFlow, gen.RandomStream, gen.proxyDungeon, ref mainPathBranches);
@ -88,7 +132,8 @@ namespace DunGenPlus.Generation
// create a bunch of proxy paths // create a bunch of proxy paths
// we evaulate later on the best one // we evaulate later on the best one
var pathProxys = new List<BranchPathProxy>(); var pathProxys = new List<BranchPathProxy>();
for(var x = 0; x < 5; ++x){ //Plugin.logger.LogInfo("New Path");
for(var x = 0; x < Properties.BranchPathMultiSimulationProperties.SimulationCount; ++x){
var currentPathProxy = new BranchPathProxy(gen, tile); var currentPathProxy = new BranchPathProxy(gen, tile);
var previousTile = tile; var previousTile = tile;
var branchDepth = tile.Placement.Archetype.BranchingDepth.GetRandom(gen.RandomStream); var branchDepth = tile.Placement.Archetype.BranchingDepth.GetRandom(gen.RandomStream);
@ -108,7 +153,13 @@ namespace DunGenPlus.Generation
// get potential tile to add // get potential tile to add
var normalizedDepth = (branchDepth <= 1) ? 1f : (float)depth / (branchDepth - 1); var normalizedDepth = (branchDepth <= 1) ? 1f : (float)depth / (branchDepth - 1);
GetTileResultStopwatch.Reset();
GetTileResultStopwatch.Start();
var tileResult = GetTileResult(gen, currentPathProxy, previousTile, useableTileSets, normalizedDepth, tile.Placement.Archetype); var tileResult = GetTileResult(gen, currentPathProxy, previousTile, useableTileSets, normalizedDepth, tile.Placement.Archetype);
GetTileResultStopwatch.Stop();
GetTileResultTime += (float)GetTileResultStopwatch.Elapsed.TotalMilliseconds;
var tileProxy = tileResult.tileProxy; var tileProxy = tileResult.tileProxy;
if (tileProxy == null) { if (tileProxy == null) {
// it's over, we done // it's over, we done
@ -126,13 +177,20 @@ namespace DunGenPlus.Generation
if (currentPathProxy.list.Count == 0) break; if (currentPathProxy.list.Count == 0) break;
// record path // record path
CalculateWeightStopwatch.Reset();
CalculateWeightStopwatch.Start();
currentPathProxy.CalculateWeight(gen); currentPathProxy.CalculateWeight(gen);
CalculateWeightStopwatch.Stop();
CalculateWeightTime += (float)CalculateWeightStopwatch.Elapsed.TotalMilliseconds;
pathProxys.Add(currentPathProxy); pathProxys.Add(currentPathProxy);
} }
// time to evaulate best path then add // time to evaulate best path then add
var bestPath = pathProxys.OrderByDescending(p => p.weight).FirstOrDefault(); var bestPath = pathProxys.OrderByDescending(p => p.weight).FirstOrDefault();
if (bestPath != null) { if (bestPath != null) {
//Plugin.logger.LogInfo($"Best path: {bestPath.weight}");
//Plugin.logger.LogInfo("");
foreach(var item in bestPath.list){ foreach(var item in bestPath.list){
MakeTileProxyConnection(gen, item); MakeTileProxyConnection(gen, item);
@ -143,6 +201,8 @@ namespace DunGenPlus.Generation
gen.injectedTiles = bestPath.injectedTiles; gen.injectedTiles = bestPath.injectedTiles;
gen.tilesPendingInjection = bestPath.tilesPendingInjection; gen.tilesPendingInjection = bestPath.tilesPendingInjection;
AddTileProxyToMainPathDictionary(bestPath.list.Select(x => x.tileProxy), bestPath.mainPathIndex);
if (gen.ShouldSkipFrame(true)){ if (gen.ShouldSkipFrame(true)){
yield return gen.GetRoomPause(); yield return gen.GetRoomPause();
} }
@ -225,7 +285,13 @@ namespace DunGenPlus.Generation
}; };
var maxCount = gen.UseMaximumPairingAttempts ? new int?(gen.MaxPairingAttempts) : null; var maxCount = gen.UseMaximumPairingAttempts ? new int?(gen.MaxPairingAttempts) : null;
DoorwayPairStopwatch.Reset();
DoorwayPairStopwatch.Start();
var doorwayPairs = doorwayPairFinder.GetDoorwayPairs(maxCount); var doorwayPairs = doorwayPairFinder.GetDoorwayPairs(maxCount);
DoorwayPairStopwatch.Stop();
DoorwayPairTime += (float)DoorwayPairStopwatch.Elapsed.TotalMilliseconds;
var tilePlacementResult = new TilePlacementResultProxy(TilePlacementResult.NoValidTile); var tilePlacementResult = new TilePlacementResultProxy(TilePlacementResult.NoValidTile);
while(doorwayPairs.Count > 0) { while(doorwayPairs.Count > 0) {
var pair = doorwayPairs.Dequeue(); var pair = doorwayPairs.Dequeue();
@ -270,6 +336,7 @@ namespace DunGenPlus.Generation
if (tile == null) return new TilePlacementResultProxy(TilePlacementResult.NewTileIsNull); if (tile == null) return new TilePlacementResultProxy(TilePlacementResult.NewTileIsNull);
tile.Placement.PathDepth = pair.PreviousTile.Placement.PathDepth; tile.Placement.PathDepth = pair.PreviousTile.Placement.PathDepth;
tile.Placement.NormalizedPathDepth = pair.PreviousTile.Placement.NormalizedPathDepth;
tile.Placement.BranchDepth = pair.PreviousTile.Placement.IsOnMainPath ? 0 : (pair.PreviousTile.Placement.BranchDepth + 1); tile.Placement.BranchDepth = pair.PreviousTile.Placement.IsOnMainPath ? 0 : (pair.PreviousTile.Placement.BranchDepth + 1);
return new TilePlacementResultProxy(TilePlacementResult.None, tile, previousDoorway, tile.Doorways[index]); return new TilePlacementResultProxy(TilePlacementResult.None, tile, previousDoorway, tile.Doorways[index]);

View File

@ -10,9 +10,9 @@ namespace DunGenPlus.Generation {
internal partial class DunGenPlusGenerator { internal partial class DunGenPlusGenerator {
public static void AddForcedTiles(DungeonGenerator gen){ public static void AddForcedTiles(DungeonGenerator gen){
if (!Properties.UseForcedTiles) return; if (!Properties.ForcedTilesProperties.UseForcedTiles) return;
var forcedTileSetLists = Properties.ForcedTileSets.ToList(); var forcedTileSetLists = Properties.ForcedTilesProperties.ForcedTileSets.ToList();
while(forcedTileSetLists.Count > 0){ while(forcedTileSetLists.Count > 0){
var item = forcedTileSetLists[forcedTileSetLists.Count - 1]; var item = forcedTileSetLists[forcedTileSetLists.Count - 1];
@ -48,16 +48,16 @@ namespace DunGenPlus.Generation {
} }
public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath){ public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath){
if (!Properties.UseLineRandomizer) return; if (!Properties.LineRandomizerProperties.UseLineRandomizer) return;
var flow = Instance.DungeonFlow; var flow = Instance.DungeonFlow;
var lines = flow.Lines; var lines = flow.Lines;
var tilesetsUsed = new Dictionary<TileSet, int>(); var tilesetsUsed = new Dictionary<TileSet, int>();
foreach(var t in Properties.LineRandomizerTileSets){ foreach(var t in Properties.LineRandomizerProperties.TileSets){
tilesetsUsed.Add(t, 0); tilesetsUsed.Add(t, 0);
} }
foreach(var a in Properties.LineRandomizerArchetypes) { foreach(var a in Properties.LineRandomizerProperties.Archetypes) {
var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets; var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets;
RandomizeArchetype(gen, tiles, tilesetsUsed); RandomizeArchetype(gen, tiles, tilesetsUsed);
} }
@ -65,9 +65,9 @@ namespace DunGenPlus.Generation {
public static void RandomizeArchetype(DungeonGenerator gen, List<TileSet> targetTileSet, Dictionary<TileSet, int> tilesetsUsed){ public static void RandomizeArchetype(DungeonGenerator gen, List<TileSet> targetTileSet, Dictionary<TileSet, int> tilesetsUsed){
// get 3 random // get 3 random
var newTiles = Properties.LineRandomizerTileSets var newTiles = Properties.LineRandomizerProperties.TileSets
.OrderBy(t => tilesetsUsed[t] + gen.RandomStream.NextDouble()) .OrderBy(t => tilesetsUsed[t] + gen.RandomStream.NextDouble())
.Take(Properties.LineRandomizerTakeCount); .Take(Properties.LineRandomizerProperties.TileSetsTakeCount);
var i = targetTileSet.Count - 1; var i = targetTileSet.Count - 1;
foreach(var n in newTiles){ foreach(var n in newTiles){
@ -81,8 +81,8 @@ namespace DunGenPlus.Generation {
public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node, RandomStream randomStream){ public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node, RandomStream randomStream){
if (!DunGenPlusGenerator.Active) return archetype; if (!DunGenPlusGenerator.Active) return archetype;
if (Properties.AddArchetypesToNormalNodes && node.NodeType == NodeType.Normal) { if (Properties.NormalNodeArchetypesProperties.AddArchetypesToNormalNodes && node.NodeType == NodeType.Normal) {
return Properties.GetRandomArchetype(node.Label, randomStream);; return Properties.NormalNodeArchetypesProperties.GetRandomArchetype(node.Label, randomStream);;
} }
return archetype; return archetype;
} }

View File

@ -24,7 +24,7 @@ namespace DunGenPlus.Patches {
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")] [HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")]
public static void waitForScrapToSpawnToSyncPatch (ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) { public static void waitForScrapToSpawnToSyncPatch (ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) {
if (DunGenPlusGenerator.Active && DunGenPlusGenerator.Properties.UseRandomGuaranteedScrapSpawn) { if (DunGenPlusGenerator.Active && DunGenPlusGenerator.Properties.MiscellaneousProperties.UseRandomGuaranteedScrapSpawn) {
var spawnedScrapList = spawnedScrap.ToList(); var spawnedScrapList = spawnedScrap.ToList();
var scrapValuesList = scrapValues.ToList(); var scrapValuesList = scrapValues.ToList();

View File

@ -46,8 +46,8 @@ namespace DunGenPlus.Patches {
if (validStartTileTargets.TryGetValue(t.name, out var paths)) { if (validStartTileTargets.TryGetValue(t.name, out var paths)) {
var extender = API.CreateDunGenExtender(d); var extender = API.CreateDunGenExtender(d);
var props = extender.Properties; var props = extender.Properties;
props.MainPathCount = paths; props.MainPathProperties.MainPathCount = paths;
props.MainRoomTilePrefab = t; props.MainPathProperties.MainRoomTilePrefab = t;
d.Length = new DunGen.IntRange(d.Length.Min / 2, d.Length.Max / 2); d.Length = new DunGen.IntRange(d.Length.Min / 2, d.Length.Max / 2);
Plugin.logger.LogInfo($"New length: {d.Length}"); Plugin.logger.LogInfo($"New length: {d.Length}");