dungenore wawa

This commit is contained in:
Ed
2025-05-29 22:14:14 +03:00
parent 7642f49b00
commit 5e6d1d0b3a
13 changed files with 264 additions and 57 deletions

View File

@@ -213,6 +213,11 @@ public sealed partial class DungeonJob : Job<List<Dungeon>>
switch (layer)
{
//CP14 zone
case CP14OreDunGen cp14OreDunGen:
await PostGen(cp14OreDunGen, dungeons, reservedTiles, random);
break;
//CP14 zone end
case AutoCablingDunGen cabling:
await PostGen(cabling, dungeons[^1], reservedTiles, random);
break;

View File

@@ -0,0 +1,159 @@
using System.Threading.Tasks;
using Content.Shared.Maps;
using Content.Shared.Procedural;
using Content.Shared.Procedural.Components;
using Content.Shared.Procedural.DungeonLayers;
using Robust.Shared.Collections;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Procedural.DungeonJob;
public sealed partial class DungeonJob
{
/// <summary>
/// <see cref="OreDunGen"/>
/// </summary>
private async Task PostGen(
CP14OreDunGen gen,
List<Dungeon> dungeons,
HashSet<Vector2i> reservedTiles,
Random random)
{
// Doesn't use dungeon data because layers and we don't need top-down support at the moment.
var replaceEntities = new Dictionary<Vector2i, EntityUid>();
var availableTiles = new List<Vector2i>();
var tiles = _maps.GetAllTilesEnumerator(_gridUid, _grid);
// WARNING:
// This DunGen handles not only the tiles of the passed dungeon, but ALL the tiles of the current grid
// So don't run it anywhere
while (tiles.MoveNext(out var tileRef))
{
var tile = tileRef.Value.GridIndices;
//Tile mask filtering
if (gen.TileMask is not null)
{
if (!gen.TileMask.Contains(((ContentTileDefinition) _tileDefManager[tileRef.Value.Tile.TypeId]).ID))
continue;
}
//Entity mask filtering
if (gen.EntityMask is not null)
{
var found = false;
var enumerator2 = _maps.GetAnchoredEntitiesEnumerator(_gridUid, _grid, tile);
while (enumerator2.MoveNext(out var uid))
{
var prototype = _entManager.GetComponent<MetaDataComponent>(uid.Value).EntityPrototype;
if (prototype?.ID is null)
continue;
if (!gen.EntityMask.Contains(prototype.ID))
continue;
replaceEntities[tile] = uid.Value;
found = true;
}
if (!found)
continue;
}
else
{
//If entity mask null - we ignore the tiles that have anything on them.
if (!_anchorable.TileFree(_grid, tile, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask))
continue;
}
// Add it to valid nodes.
availableTiles.Add(tile);
await SuspendDungeon();
if (!ValidateResume())
return;
}
var remapping = new Dictionary<EntProtoId, EntProtoId>();
// TODO: Move this to engine
if (_prototype.TryIndex(gen.Entity, out var proto) &&
proto.Components.TryGetComponent("EntityRemap", out var comps))
{
var remappingComp = (EntityRemapComponent) comps;
remapping = remappingComp.Mask;
}
var frontier = new ValueList<Vector2i>(32);
// Iterate the group counts and pathfind out each group.
for (var i = 0; i < gen.Count; i++)
{
await SuspendDungeon();
if (!ValidateResume())
return;
var groupSize = random.Next(gen.MinGroupSize, gen.MaxGroupSize + 1);
// While we have remaining tiles keep iterating
while (groupSize > 0 && availableTiles.Count > 0)
{
var startNode = random.PickAndTake(availableTiles);
frontier.Clear();
frontier.Add(startNode);
// This essentially may lead to a vein being split in multiple areas but the count matters more than position.
while (frontier.Count > 0 && groupSize > 0)
{
// Need to pick a random index so we don't just get straight lines of ores.
var frontierIndex = random.Next(frontier.Count);
var node = frontier[frontierIndex];
frontier.RemoveSwap(frontierIndex);
availableTiles.Remove(node);
// Add neighbors if they're valid, worst case we add no more and pick another random seed tile.
for (var x = -1; x <= 1; x++)
{
for (var y = -1; y <= 1; y++)
{
var neighbor = new Vector2i(node.X + x, node.Y + y);
if (frontier.Contains(neighbor) || !availableTiles.Contains(neighbor))
continue;
frontier.Add(neighbor);
}
}
var prototype = gen.Entity;
if (replaceEntities.TryGetValue(node, out var existingEnt))
{
var existingProto = _entManager.GetComponent<MetaDataComponent>(existingEnt).EntityPrototype;
_entManager.DeleteEntity(existingEnt);
if (existingProto != null && remapping.TryGetValue(existingProto.ID, out var remapped))
{
prototype = remapped;
}
}
// Tile valid salad so add it.
_entManager.SpawnAtPosition(prototype, _maps.GridTileToLocal(_gridUid, _grid, node));
groupSize--;
}
}
if (groupSize > 0)
{
_sawmill.Warning($"Found remaining group size for ore veins of {gen.Entity.Id ?? "null"}!");
}
}
}
}

View File

@@ -1,4 +1,3 @@
using Content.Shared.Maps;
using Robust.Shared.Prototypes;
namespace Content.Shared.Procedural.DungeonLayers;
@@ -13,16 +12,10 @@ namespace Content.Shared.Procedural.DungeonLayers;
public partial class OreDunGen : IDunGenLayer
{
/// <summary>
/// This vein can only be generated by replacing the specified entities.
/// If the vein generation should occur on top of existing entities what are we replacing.
/// </summary>
[DataField]
public HashSet<EntProtoId>? EntityMask;
/// <summary>
/// This vein can only be generated on the specified tiles
/// </summary>
[DataField]
public HashSet<ProtoId<ContentTileDefinition>>? TileMask;
public EntProtoId? Replacement;
/// <summary>
/// Entity to spawn.

View File

@@ -0,0 +1,50 @@
using Content.Shared.Maps;
using Robust.Shared.Prototypes;
namespace Content.Shared.Procedural.DungeonLayers;
/// <summary>
/// Generates veins inside of the specified dungeon.
/// </summary>
/// <remarks>
/// Generates on top of existing entities for sanity reasons moreso than performance.
/// </remarks>
[Virtual]
public partial class CP14OreDunGen : IDunGenLayer
{
/// <summary>
/// This vein can only be generated by replacing the specified entities.
/// </summary>
[DataField]
public HashSet<EntProtoId>? EntityMask;
/// <summary>
/// This vein can only be generated on the specified tiles
/// </summary>
[DataField]
public HashSet<ProtoId<ContentTileDefinition>>? TileMask;
/// <summary>
/// Entity to spawn.
/// </summary>
[DataField(required: true)]
public EntProtoId Entity;
/// <summary>
/// Maximum amount of group spawns
/// </summary>
[DataField]
public int Count = 10;
/// <summary>
/// Minimum entities to spawn in one group.
/// </summary>
[DataField]
public int MinGroupSize = 1;
/// <summary>
/// Maximum entities to spawn in one group.
/// </summary>
[DataField]
public int MaxGroupSize = 1;
}

View File

@@ -10,7 +10,7 @@
categories:
Danger: 0.25
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14Chasm
tileMask:
- CP14FloorBase
@@ -33,7 +33,7 @@
- CP14DemiplaneCold
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14FloorLava
tileMask:
- CP14FloorBase
@@ -53,7 +53,7 @@
categories:
Danger: 0.2
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: LandMineExplosive
count: 20
minGroupSize: 1
@@ -68,7 +68,7 @@
categories:
Danger: 0.25
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14AstralHaze
count: 10
minGroupSize: 1

View File

@@ -12,7 +12,7 @@
blacklistTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnMobUndeadZombieRandom
count: 4
minGroupSize: 3
@@ -30,7 +30,7 @@
- CP14DemiplaneOpenSky
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnMobDinoYumkaraptor
count: 5
minGroupSize: 1
@@ -49,7 +49,7 @@
blacklistTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnMobMonsterMosquito
count: 4
minGroupSize: 2
@@ -66,7 +66,7 @@
requiredTags:
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobDinoSmallHydra
count: 4
minGroupSize: 2
@@ -85,7 +85,7 @@
requiredTags:
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobMonsterMole
count: 6
minGroupSize: 1
@@ -104,7 +104,7 @@
blacklistTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobIceSpectre
count: 6
minGroupSize: 1
@@ -121,7 +121,7 @@
# requiredTags:
# - CP14DemiplaneUnderground
# layers:
# - !type:OreDunGen
# - !type:CP14OreDunGen
# entity: CP14MobMonsterInvisibleWhistler
# count: 2
# minGroupSize: 1
@@ -136,7 +136,7 @@
categories:
Danger: 0.35
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobSlimeElectric
count: 6
minGroupSize: 1
@@ -153,7 +153,7 @@
requiredTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobSlimeFire
count: 6
minGroupSize: 1
@@ -170,7 +170,7 @@
requiredTags:
- CP14DemiplaneCold
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobSlimeIce
count: 6
minGroupSize: 1
@@ -184,7 +184,7 @@
categories:
Danger: 0.25
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobSlimeBase
count: 6
minGroupSize: 1
@@ -203,7 +203,7 @@
blacklistTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobWatcherIce
count: 8
minGroupSize: 2
@@ -222,7 +222,7 @@
blacklistTags:
- CP14DemiplaneCold
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobWatcherMagma
count: 8
minGroupSize: 2

View File

@@ -11,7 +11,7 @@
- CP14DemiplaneHerbals
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -34,7 +34,7 @@
- CP14DemiplaneHerbals
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -56,12 +56,12 @@
requiredTags:
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14StatueStoneHeadHigh
count: 1
minGroupSize: 1
maxGroupSize: 1
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14StatueStoneHeadLow
count: 1
minGroupSize: 1

View File

@@ -9,7 +9,7 @@
categories:
GhostRoleDanger: 1
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnPointGhostDemiplaneSkeletonT1
count: 1
minGroupSize: 1
@@ -25,7 +25,7 @@
categories:
GhostRoleDanger: 1
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnPointGhostDemiplaneSkeletonT2
count: 1
minGroupSize: 2
@@ -41,7 +41,7 @@
categories:
GhostRoleDanger: 1
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: SpawnPointGhostDemiplaneLurker
count: 1
minGroupSize: 1

View File

@@ -13,7 +13,7 @@
- CP14DemiplaneOres
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneIronOre
@@ -34,7 +34,7 @@
- CP14DemiplaneOres
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneIronOre
@@ -55,7 +55,7 @@
- CP14DemiplaneOres
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneCopperOre
@@ -76,7 +76,7 @@
- CP14DemiplaneOres
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneCopperOre
@@ -99,7 +99,7 @@
- CP14DemiplaneOres
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneGoldOre
@@ -120,7 +120,7 @@
- CP14DemiplaneOres
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneGoldOre
@@ -141,7 +141,7 @@
- CP14DemiplaneOres
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneMithrilOre
@@ -162,7 +162,7 @@
- CP14DemiplaneOres
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14WallStone
entity: CP14WallStoneMithrilOre

View File

@@ -6,7 +6,7 @@
categories:
Reward: 0.15
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorBase
- CP14FloorIce

View File

@@ -12,7 +12,7 @@
- CP14DemiplaneHerbals
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -33,7 +33,7 @@
requiredTags:
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorBase
- CP14FloorGrass
@@ -55,7 +55,7 @@
requiredTags:
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -76,7 +76,7 @@
requiredTags:
- CP14DemiplaneHerbals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -98,7 +98,7 @@
- CP14DemiplaneHerbals
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -120,7 +120,7 @@
- CP14DemiplaneHerbals
- CP14DemiplaneWater
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entityMask:
- CP14FloorWater
- CP14FloorWaterLilies
@@ -142,7 +142,7 @@
requiredTags:
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight

View File

@@ -9,7 +9,7 @@
categories:
Reward: 0.15
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnerDemiplaneLootT1
count: 20
minGroupSize: 2
@@ -27,7 +27,7 @@
requiredTags:
- CP14DemiplanePeacefulAnimals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobRabbit
count: 3
minGroupSize: 2
@@ -45,7 +45,7 @@
requiredTags:
- CP14DemiplanePeacefulAnimals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobBoar
count: 3
minGroupSize: 2
@@ -62,7 +62,7 @@
requiredTags:
- CP14DemiplaneAnimalsSwamp
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
tileMask:
- CP14FloorGrass
- CP14FloorGrassLight
@@ -84,7 +84,7 @@
requiredTags:
- CP14DemiplanePeacefulAnimals
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14MobSheep
count: 1
minGroupSize: 4
@@ -100,7 +100,7 @@
Reward: 0.2
generationProb: 0.8
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14DemiplaneRuinsRoomSpawner
count: 8
minGroupSize: 1
@@ -117,7 +117,7 @@
categories:
Reward: 0.15
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14SpawnerDemiplaneLootT2
count: 20
minGroupSize: 2

View File

@@ -7,7 +7,7 @@
categories:
Reward: 0.15
layers:
- !type:OreDunGen
- !type:CP14OreDunGen
entity: CP14DemiplaneArtifactRoomSpawner
count: 1
minGroupSize: 1