1
0

DungeonJob.PostGenSplineDungeonConnector.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using System.Numerics;
  2. using System.Threading.Tasks;
  3. using Content.Server.NPC.Pathfinding;
  4. using Content.Shared.Procedural;
  5. using Content.Shared.Procedural.PostGeneration;
  6. using Robust.Shared.Map;
  7. using Robust.Shared.Random;
  8. namespace Content.Server.Procedural.DungeonJob;
  9. public sealed partial class DungeonJob
  10. {
  11. /// <summary>
  12. /// <see cref="SplineDungeonConnectorDunGen"/>
  13. /// </summary>
  14. private async Task<Dungeon> PostGen(
  15. SplineDungeonConnectorDunGen gen,
  16. DungeonData data,
  17. List<Dungeon> dungeons,
  18. HashSet<Vector2i> reservedTiles,
  19. Random random)
  20. {
  21. // TODO: The path itself use the tile
  22. // Widen it randomly (probably for each tile offset it by some changing amount).
  23. // NOOP
  24. if (dungeons.Count <= 1)
  25. return Dungeon.Empty;
  26. if (!data.Tiles.TryGetValue(DungeonDataKey.FallbackTile, out var fallback) ||
  27. !data.Tiles.TryGetValue(DungeonDataKey.WidenTile, out var widen))
  28. {
  29. LogDataError(typeof(SplineDungeonConnectorDunGen));
  30. return Dungeon.Empty;
  31. }
  32. var nodes = new List<Vector2i>();
  33. foreach (var dungeon in dungeons)
  34. {
  35. foreach (var room in dungeon.Rooms)
  36. {
  37. if (room.Entrances.Count == 0)
  38. continue;
  39. nodes.Add(room.Entrances[0]);
  40. break;
  41. }
  42. }
  43. var tree = _dungeon.MinimumSpanningTree(nodes, random);
  44. await SuspendDungeon();
  45. if (!ValidateResume())
  46. return Dungeon.Empty;
  47. var tiles = new List<(Vector2i Index, Tile Tile)>();
  48. var pathfinding = _entManager.System<PathfindingSystem>();
  49. var allTiles = new HashSet<Vector2i>();
  50. var fallbackTile = new Tile(_prototype.Index(fallback).TileId);
  51. foreach (var pair in tree)
  52. {
  53. var path = pathfinding.GetSplinePath(new PathfindingSystem.SplinePathArgs()
  54. {
  55. Distance = gen.DivisionDistance,
  56. MaxRatio = gen.VarianceMax,
  57. Args = new PathfindingSystem.SimplePathArgs()
  58. {
  59. Start = pair.Start,
  60. End = pair.End,
  61. TileCost = node =>
  62. {
  63. // We want these to get prioritised internally and into space if it's a space dungeon.
  64. if (_maps.TryGetTile(_grid, node, out var tile) && !tile.IsEmpty)
  65. return 1f;
  66. return 5f;
  67. }
  68. },
  69. },
  70. random);
  71. // Welp
  72. if (path.Path.Count == 0)
  73. {
  74. _sawmill.Error($"Unable to connect spline dungeon path for {_entManager.ToPrettyString(_gridUid)} between {pair.Start} and {pair.End}");
  75. continue;
  76. }
  77. await SuspendDungeon();
  78. if (!ValidateResume())
  79. return Dungeon.Empty;
  80. var wide = pathfinding.GetWiden(new PathfindingSystem.WidenArgs()
  81. {
  82. Path = path.Path,
  83. },
  84. random);
  85. tiles.Clear();
  86. allTiles.EnsureCapacity(allTiles.Count + wide.Count);
  87. foreach (var node in wide)
  88. {
  89. if (reservedTiles.Contains(node))
  90. continue;
  91. allTiles.Add(node);
  92. Tile tile;
  93. if (random.Prob(0.9f))
  94. {
  95. tile = new Tile(_prototype.Index(widen).TileId);
  96. }
  97. else
  98. {
  99. tile = _tileDefManager.GetVariantTile(widen, random);
  100. }
  101. tiles.Add((node, tile));
  102. }
  103. _maps.SetTiles(_gridUid, _grid, tiles);
  104. tiles.Clear();
  105. allTiles.EnsureCapacity(allTiles.Count + path.Path.Count);
  106. foreach (var node in path.Path)
  107. {
  108. if (reservedTiles.Contains(node))
  109. continue;
  110. allTiles.Add(node);
  111. tiles.Add((node, fallbackTile));
  112. }
  113. _maps.SetTiles(_gridUid, _grid, tiles);
  114. }
  115. var dungy = new Dungeon();
  116. var dungyRoom = new DungeonRoom(allTiles, Vector2.Zero, Box2i.Empty, new HashSet<Vector2i>());
  117. dungy.AddRoom(dungyRoom);
  118. return dungy;
  119. }
  120. }