Split up DunGenPlusGeneration code into separate partial files

This commit is contained in:
LadyAliceMargatroid 2024-08-24 16:24:04 -07:00
parent 101e2c3904
commit e215adc736
3 changed files with 224 additions and 199 deletions

View File

@ -15,12 +15,11 @@ using DunGenPlus.Managers;
using UnityEngine.Rendering; using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition; using UnityEngine.Rendering.HighDefinition;
using BepInEx.Logging; using BepInEx.Logging;
using static UnityEngine.Rendering.HighDefinition.ScalableSettingLevelParameter;
using DunGenPlus.DevTools; using DunGenPlus.DevTools;
[assembly: SecurityPermission( SecurityAction.RequestMinimum, SkipVerification = true )] [assembly: SecurityPermission( SecurityAction.RequestMinimum, SkipVerification = true )]
namespace DunGenPlus.Generation { namespace DunGenPlus.Generation {
internal 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; }
@ -287,203 +286,6 @@ namespace DunGenPlus.Generation {
AddForcedTiles(gen); AddForcedTiles(gen);
} }
public static void AddForcedTiles(DungeonGenerator gen){
if (!Properties.UseForcedTiles) return;
var forcedTileSetLists = Properties.ForcedTileSets.ToList();
while(forcedTileSetLists.Count > 0){
var item = forcedTileSetLists[forcedTileSetLists.Count - 1];
// we have to check ALL tiles
var allTiles = gen.proxyDungeon.AllTiles
.Select(t => {
var depthValue = item.DepthWeightScale.Evaluate(t.Placement.NormalizedDepth);
var weight = t.Placement.IsOnMainPath ? item.MainPathWeight : item.BranchPathWeight;
return (t, depthValue * weight * gen.RandomStream.NextDouble());
})
.Where(pair => pair.Item2 > 0f)
.OrderBy(pair => pair.Item2);
// try every tile, if we somehow fail than man that sucks
foreach(var pair in allTiles){
var t = pair.t;
var tileProxy = gen.AddTile(t, item.Tilesets, t.Placement.NormalizedDepth, null, TilePlacementResult.None);
if (tileProxy == null) continue;
tileProxy.Placement.BranchDepth = t.Placement.BranchDepth;
tileProxy.Placement.NormalizedBranchDepth = t.Placement.NormalizedDepth;
tileProxy.Placement.GraphNode = t.Placement.GraphNode;
tileProxy.Placement.GraphLine = t.Placement.GraphLine;
Plugin.logger.LogDebug($"Forcefully added tile {tileProxy.Prefab.name}");
break;
}
forcedTileSetLists.RemoveAt(forcedTileSetLists.Count - 1);
}
Plugin.logger.LogDebug($"Forcefully added all tiles");
}
public static (TilePlacementResult result, TileProxy tile) ProcessDoorwayPairs(DungeonGenerator gen, DungeonArchetype archetype, Queue<DoorwayPair> doorwayPairs) {
if (Properties != null && Properties.UseBranchLoopBoost && gen.Status == GenerationStatus.Branching) {
return EncourageBranchPathLoopEncouragement(gen, doorwayPairs);
}
while(doorwayPairs.Count > 0) {
var pair = doorwayPairs.Dequeue();
var result = gen.TryPlaceTile(pair, archetype, out var tileProxy);
if (result == TilePlacementResult.None) return (result, tileProxy);
gen.AddTilePlacementResult(result);
}
return (TilePlacementResult.NoValidTile, null);
}
public static (TilePlacementResult result, TileProxy tile) EncourageBranchPathLoopEncouragement(DungeonGenerator gen, Queue<DoorwayPair> doorwayPairs) {
// get list of 5 potential targets
var validTiles = new List<TilePlacementResultProxy>();
while(doorwayPairs.Count > 0) {
var pair = doorwayPairs.Dequeue();
var value = GetTileProxyOfDoorwayPair(gen, pair);
if (value.result == TilePlacementResult.None) {
validTiles.Add(value);
if (validTiles.Count >= Properties.BranchLoopBoostTileSearch) break;
}
}
if (validTiles.Count == 0) {
return (TilePlacementResult.NoValidTile, null);
}
// update their weight based on their potential doorway partners
var allDungeonDoorways = gen.proxyDungeon.AllTiles.SelectMany(t => t.Doorways);
//Plugin.logger.LogInfo("NEW TILES");
foreach(var t in validTiles) {
var doorwayCount = 0;
foreach(var d in allDungeonDoorways) {
foreach(var l in t.tile.doorways) {
if (d.TileProxy == t.previousDoorway.TileProxy) continue;
if (gen.DungeonFlow.CanDoorwaysConnect(d.TileProxy.PrefabTile, l.TileProxy.PrefabTile, d.DoorwayComponent, l.DoorwayComponent) && Vector3.SqrMagnitude(d.Position - l.Position) < 1E-05)
doorwayCount++;
}
}
if (doorwayCount > 0) {
//Plugin.logger.LogInfo($"{t.weight} -> {t.weight * (1f + doorwayCount * Properties.BranchLoopBoostTileScale)} ({doorwayCount})");
t.weight *= (1f + doorwayCount * Properties.BranchLoopBoostTileScale);
} else {
//Plugin.logger.LogInfo($"{t.weight}");
}
}
var bestChoice = validTiles.OrderByDescending(t => t.weight).FirstOrDefault();
//Plugin.logger.LogInfo($"Best: {bestChoice.weight}");
MakeTileProxyConnection(gen, bestChoice);
gen.AddTilePlacementResult(bestChoice.result);
return (bestChoice.result, bestChoice.tile);
}
private class TilePlacementResultProxy {
public TilePlacementResult result;
public TileProxy tile;
public DoorwayProxy previousDoorway;
public DoorwayProxy nextDoorway;
public float weight;
public TilePlacementResultProxy(TilePlacementResult result) {
this.result = result;
tile = null;
previousDoorway = null;
nextDoorway = null;
weight = 0f;
}
public TilePlacementResultProxy(TilePlacementResult result, TileProxy tile, DoorwayProxy previousDoorway, DoorwayProxy nextDoorway, float weight) {
this.result = result;
this.tile = tile;
this.previousDoorway = previousDoorway;
this.nextDoorway = nextDoorway;
this.weight = weight;
}
}
private static TilePlacementResultProxy GetTileProxyOfDoorwayPair(DungeonGenerator gen, DoorwayPair pair){
var nextTemplate = pair.NextTemplate;
var previousDoorway = pair.PreviousDoorway;
if (nextTemplate == null) return new TilePlacementResultProxy(TilePlacementResult.TemplateIsNull);
var index = pair.NextTemplate.Doorways.IndexOf(pair.NextDoorway);
var tile = new TileProxy(nextTemplate);
tile.Placement.isOnMainPath = false;
tile.Placement.TileSet = pair.NextTileSet;
if (previousDoorway != null) {
var myDoorway = tile.Doorways[index];
tile.PositionBySocket(myDoorway, previousDoorway);
var bounds = tile.Placement.Bounds;
if (gen.RestrictDungeonToBounds && !gen.TilePlacementBounds.Contains(bounds)) return new TilePlacementResultProxy(TilePlacementResult.OutOfBounds);
if (gen.IsCollidingWithAnyTile(tile, previousDoorway.TileProxy)) return new TilePlacementResultProxy(TilePlacementResult.TileIsColliding);
}
if (tile == null) return new TilePlacementResultProxy(TilePlacementResult.NewTileIsNull);
tile.Placement.PathDepth = pair.PreviousTile.Placement.PathDepth;
tile.Placement.BranchDepth = pair.PreviousTile.Placement.IsOnMainPath ? 0 : (pair.PreviousTile.Placement.BranchDepth + 1);
return new TilePlacementResultProxy(TilePlacementResult.None, tile, previousDoorway, tile.Doorways[index], pair.TileWeight);
}
private static void MakeTileProxyConnection(DungeonGenerator gen, TilePlacementResultProxy proxy) {
if (proxy.previousDoorway != null) {
gen.proxyDungeon.MakeConnection(proxy.previousDoorway, proxy.nextDoorway);
}
gen.proxyDungeon.AddTile(proxy.tile);
}
public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath){
if (!Properties.UseLineRandomizer) return;
var flow = Instance.DungeonFlow;
var lines = flow.Lines;
var tilesetsUsed = new Dictionary<TileSet, int>();
foreach(var t in Properties.LineRandomizerTileSets){
tilesetsUsed.Add(t, 0);
}
foreach(var a in Properties.LineRandomizerArchetypes) {
var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets;
RandomizeArchetype(gen, tiles, tilesetsUsed);
}
}
public static void RandomizeArchetype(DungeonGenerator gen, List<TileSet> targetTileSet, Dictionary<TileSet, int> tilesetsUsed){
// get 3 random
var newTiles = Properties.LineRandomizerTileSets
.OrderBy(t => tilesetsUsed[t] + gen.RandomStream.NextDouble())
.Take(Properties.LineRandomizerTakeCount);
var i = targetTileSet.Count - 1;
foreach(var n in newTiles){
targetTileSet[i] = n;
--i;
tilesetsUsed[n] += 1;
}
}
public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node, RandomStream randomStream){
if (!DunGenPlusGenerator.Active) return archetype;
if (Properties.AddArchetypesToNormalNodes && node.NodeType == NodeType.Normal) {
return Properties.GetRandomArchetype(node.Label, randomStream);;
}
return archetype;
}
public static void FixDoorwaysToAllFloors(TileProxy mainRoom, MainRoomDoorwayGroups doorwayGroups) { public static void FixDoorwaysToAllFloors(TileProxy mainRoom, MainRoomDoorwayGroups doorwayGroups) {
var first = doorwayGroups.doorwayListFirst; var first = doorwayGroups.doorwayListFirst;
if (first == null) return; if (first == null) return;

View File

@ -0,0 +1,132 @@
using DunGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace DunGenPlus.Generation {
internal partial class DunGenPlusGenerator {
public static (TilePlacementResult result, TileProxy tile) ProcessDoorwayPairs(DungeonGenerator gen, DungeonArchetype archetype, Queue<DoorwayPair> doorwayPairs) {
if (Properties != null && Properties.UseBranchLoopBoost && gen.Status == GenerationStatus.Branching) {
return EncourageBranchPathLoopEncouragement(gen, doorwayPairs);
}
while(doorwayPairs.Count > 0) {
var pair = doorwayPairs.Dequeue();
var result = gen.TryPlaceTile(pair, archetype, out var tileProxy);
if (result == TilePlacementResult.None) return (result, tileProxy);
gen.AddTilePlacementResult(result);
}
return (TilePlacementResult.NoValidTile, null);
}
public static (TilePlacementResult result, TileProxy tile) EncourageBranchPathLoopEncouragement(DungeonGenerator gen, Queue<DoorwayPair> doorwayPairs) {
// get list of 5 potential targets
var validTiles = new List<TilePlacementResultProxy>();
while(doorwayPairs.Count > 0) {
var pair = doorwayPairs.Dequeue();
var value = GetTileProxyOfDoorwayPair(gen, pair);
if (value.result == TilePlacementResult.None) {
validTiles.Add(value);
if (validTiles.Count >= Properties.BranchLoopBoostTileSearch) break;
}
}
if (validTiles.Count == 0) {
return (TilePlacementResult.NoValidTile, null);
}
// update their weight based on their potential doorway partners
var allDungeonDoorways = gen.proxyDungeon.AllTiles.SelectMany(t => t.Doorways);
//Plugin.logger.LogInfo("NEW TILES");
foreach(var t in validTiles) {
var doorwayCount = 0;
foreach(var d in allDungeonDoorways) {
foreach(var l in t.tile.doorways) {
if (d.TileProxy == t.previousDoorway.TileProxy) continue;
if (gen.DungeonFlow.CanDoorwaysConnect(d.TileProxy.PrefabTile, l.TileProxy.PrefabTile, d.DoorwayComponent, l.DoorwayComponent) && Vector3.SqrMagnitude(d.Position - l.Position) < 1E-05)
doorwayCount++;
}
}
if (doorwayCount > 0) {
//Plugin.logger.LogInfo($"{t.weight} -> {t.weight * (1f + doorwayCount * Properties.BranchLoopBoostTileScale)} ({doorwayCount})");
t.weight *= (1f + doorwayCount * Properties.BranchLoopBoostTileScale);
} else {
//Plugin.logger.LogInfo($"{t.weight}");
}
}
var bestChoice = validTiles.OrderByDescending(t => t.weight).FirstOrDefault();
//Plugin.logger.LogInfo($"Best: {bestChoice.weight}");
MakeTileProxyConnection(gen, bestChoice);
gen.AddTilePlacementResult(bestChoice.result);
return (bestChoice.result, bestChoice.tile);
}
private class TilePlacementResultProxy {
public TilePlacementResult result;
public TileProxy tile;
public DoorwayProxy previousDoorway;
public DoorwayProxy nextDoorway;
public float weight;
public TilePlacementResultProxy(TilePlacementResult result) {
this.result = result;
tile = null;
previousDoorway = null;
nextDoorway = null;
weight = 0f;
}
public TilePlacementResultProxy(TilePlacementResult result, TileProxy tile, DoorwayProxy previousDoorway, DoorwayProxy nextDoorway, float weight) {
this.result = result;
this.tile = tile;
this.previousDoorway = previousDoorway;
this.nextDoorway = nextDoorway;
this.weight = weight;
}
}
private static TilePlacementResultProxy GetTileProxyOfDoorwayPair(DungeonGenerator gen, DoorwayPair pair){
var nextTemplate = pair.NextTemplate;
var previousDoorway = pair.PreviousDoorway;
if (nextTemplate == null) return new TilePlacementResultProxy(TilePlacementResult.TemplateIsNull);
var index = pair.NextTemplate.Doorways.IndexOf(pair.NextDoorway);
var tile = new TileProxy(nextTemplate);
tile.Placement.isOnMainPath = false;
tile.Placement.TileSet = pair.NextTileSet;
if (previousDoorway != null) {
var myDoorway = tile.Doorways[index];
tile.PositionBySocket(myDoorway, previousDoorway);
var bounds = tile.Placement.Bounds;
if (gen.RestrictDungeonToBounds && !gen.TilePlacementBounds.Contains(bounds)) return new TilePlacementResultProxy(TilePlacementResult.OutOfBounds);
if (gen.IsCollidingWithAnyTile(tile, previousDoorway.TileProxy)) return new TilePlacementResultProxy(TilePlacementResult.TileIsColliding);
}
if (tile == null) return new TilePlacementResultProxy(TilePlacementResult.NewTileIsNull);
tile.Placement.PathDepth = pair.PreviousTile.Placement.PathDepth;
tile.Placement.BranchDepth = pair.PreviousTile.Placement.IsOnMainPath ? 0 : (pair.PreviousTile.Placement.BranchDepth + 1);
return new TilePlacementResultProxy(TilePlacementResult.None, tile, previousDoorway, tile.Doorways[index], pair.TileWeight);
}
private static void MakeTileProxyConnection(DungeonGenerator gen, TilePlacementResultProxy proxy) {
if (proxy.previousDoorway != null) {
gen.proxyDungeon.MakeConnection(proxy.previousDoorway, proxy.nextDoorway);
}
gen.proxyDungeon.AddTile(proxy.tile);
}
}
}

View File

@ -0,0 +1,91 @@
using DunGen;
using DunGen.Graph;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DunGenPlus.Generation {
internal partial class DunGenPlusGenerator {
public static void AddForcedTiles(DungeonGenerator gen){
if (!Properties.UseForcedTiles) return;
var forcedTileSetLists = Properties.ForcedTileSets.ToList();
while(forcedTileSetLists.Count > 0){
var item = forcedTileSetLists[forcedTileSetLists.Count - 1];
// we have to check ALL tiles
var allTiles = gen.proxyDungeon.AllTiles
.Select(t => {
var depthValue = item.DepthWeightScale.Evaluate(t.Placement.NormalizedDepth);
var weight = t.Placement.IsOnMainPath ? item.MainPathWeight : item.BranchPathWeight;
return (t, depthValue * weight * gen.RandomStream.NextDouble());
})
.Where(pair => pair.Item2 > 0f)
.OrderBy(pair => pair.Item2);
// try every tile, if we somehow fail than man that sucks
foreach(var pair in allTiles){
var t = pair.t;
var tileProxy = gen.AddTile(t, item.Tilesets, t.Placement.NormalizedDepth, null, TilePlacementResult.None);
if (tileProxy == null) continue;
tileProxy.Placement.BranchDepth = t.Placement.BranchDepth;
tileProxy.Placement.NormalizedBranchDepth = t.Placement.NormalizedDepth;
tileProxy.Placement.GraphNode = t.Placement.GraphNode;
tileProxy.Placement.GraphLine = t.Placement.GraphLine;
Plugin.logger.LogDebug($"Forcefully added tile {tileProxy.Prefab.name}");
break;
}
forcedTileSetLists.RemoveAt(forcedTileSetLists.Count - 1);
}
Plugin.logger.LogDebug($"Forcefully added all tiles");
}
public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath){
if (!Properties.UseLineRandomizer) return;
var flow = Instance.DungeonFlow;
var lines = flow.Lines;
var tilesetsUsed = new Dictionary<TileSet, int>();
foreach(var t in Properties.LineRandomizerTileSets){
tilesetsUsed.Add(t, 0);
}
foreach(var a in Properties.LineRandomizerArchetypes) {
var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets;
RandomizeArchetype(gen, tiles, tilesetsUsed);
}
}
public static void RandomizeArchetype(DungeonGenerator gen, List<TileSet> targetTileSet, Dictionary<TileSet, int> tilesetsUsed){
// get 3 random
var newTiles = Properties.LineRandomizerTileSets
.OrderBy(t => tilesetsUsed[t] + gen.RandomStream.NextDouble())
.Take(Properties.LineRandomizerTakeCount);
var i = targetTileSet.Count - 1;
foreach(var n in newTiles){
targetTileSet[i] = n;
--i;
tilesetsUsed[n] += 1;
}
}
public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node, RandomStream randomStream){
if (!DunGenPlusGenerator.Active) return archetype;
if (Properties.AddArchetypesToNormalNodes && node.NodeType == NodeType.Normal) {
return Properties.GetRandomArchetype(node.Label, randomStream);;
}
return archetype;
}
}
}