Convenient Z-Levels (#421)
* clear ores and herbals frmo generation
* remake simple zlevels system
* GetMapOffset
* woohoo
* autolink between zlevels
* 5am
* somwthing sommetinh work
* Update CP14StationZLevelsSystem.cs
* fix biomespawner portal deletion
* some docs
* Revert "clear ores and herbals frmo generation"
This reverts commit 658d15a602.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
using Content.Server._CP14.BiomeSpawner.EntitySystems;
|
||||
using Content.Shared.Parallax.Biomes;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.BiomeSpawner.Components;
|
||||
@@ -19,4 +20,10 @@ public sealed partial class CP14BiomeSpawnerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public ProtoId<BiomeTemplatePrototype> Biome = "Grasslands";
|
||||
|
||||
/// <summary>
|
||||
/// entities that we don't remove.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntityWhitelist DeleteBlacklist = new();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Server._CP14.BiomeSpawner.Components;
|
||||
using Content.Server._CP14.RoundSeed;
|
||||
using Content.Server.Decals;
|
||||
using Content.Server.Parallax;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
@@ -26,6 +27,7 @@ public sealed class CP14BiomeSpawnerSystem : EntitySystem
|
||||
[Dependency] private readonly DecalSystem _decals = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly CP14RoundSeedSystem _roundSeed = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -79,11 +81,12 @@ public sealed class CP14BiomeSpawnerSystem : EntitySystem
|
||||
}
|
||||
|
||||
// Remove entities
|
||||
var oldEntities = _lookup.GetEntitiesInRange(spawnerTransform.Coordinates, 0.48f);
|
||||
var oldEntities = _lookup.GetEntitiesInRange(spawnerTransform.Coordinates, 0.48f, LookupFlags.Uncontained);
|
||||
// TODO: Replace this shit with GetEntitiesInBox2
|
||||
foreach (var entToRemove in oldEntities.Concat(new[] { ent.Owner })) // Do not remove self
|
||||
{
|
||||
QueueDel(entToRemove);
|
||||
if (!_whitelist.IsValid(ent.Comp.DeleteBlacklist, entToRemove))
|
||||
QueueDel(entToRemove);
|
||||
}
|
||||
|
||||
if (_biome.TryGetEntity(vec, biome.Layers, tile.Value, seed, map, out var entityProto))
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._CP14.StationDungeonMap;
|
||||
|
||||
/// <summary>
|
||||
/// Loads additional maps from the list at the start of the round.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14StationAdditionalMapSystem))]
|
||||
public sealed partial class CP14StationAdditionalMapComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// A map paths to load on a new map.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<ResPath> MapPaths = new();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using Content.Server.Parallax;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Teleportation.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.StationDungeonMap;
|
||||
|
||||
public sealed partial class CP14StationAdditionalMapSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly BiomeSystem _biome = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly LinkedEntitySystem _linkedEntity = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<CP14StationAdditionalMapComponent, StationPostInitEvent>(OnStationPostInit);
|
||||
}
|
||||
|
||||
private void OnStationPostInit(Entity<CP14StationAdditionalMapComponent> addMap, ref StationPostInitEvent args)
|
||||
{
|
||||
if (!TryComp(addMap, out StationDataComponent? dataComp))
|
||||
return;
|
||||
|
||||
foreach (var path in addMap.Comp.MapPaths)
|
||||
{
|
||||
var mapUid = _map.CreateMap(out var mapId);
|
||||
Log.Info($"Created map {mapId} for StationAdditionalMap system");
|
||||
var options = new MapLoadOptions { LoadMap = true };
|
||||
if (!_mapLoader.TryLoad(mapId, path.ToString(), out var roots, options))
|
||||
{
|
||||
Log.Error($"Failed to load map from {path}!");
|
||||
Del(mapUid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Content.Server._CP14.StationDungeonMap.EntitySystems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._CP14.StationDungeonMap.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the z-level system by creating a series of linked maps
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14StationZLevelsSystem))]
|
||||
public sealed partial class CP14StationZLevelsComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public int DefaultMapLevel = 0;
|
||||
|
||||
[DataField(required: true)]
|
||||
public Dictionary<int, CP14ZLevelEntry> Levels = new();
|
||||
|
||||
public bool Initialized = false;
|
||||
|
||||
public Dictionary<MapId, int> LevelEntities = new();
|
||||
}
|
||||
|
||||
[DataRecord, Serializable]
|
||||
public sealed class CP14ZLevelEntry
|
||||
{
|
||||
public ResPath? Path { get; set; } = null;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Server._CP14.StationDungeonMap.EntitySystems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.StationDungeonMap.Components;
|
||||
|
||||
/// <summary>
|
||||
/// automatically creates a linked portal at a different relative z-level, and then the component is removed
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14StationZLevelsSystem))]
|
||||
public sealed partial class CP14ZLevelAutoPortalComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// relative neighboring layer. Ideally, -1 is the neighboring bottom layer, +1 is the neighboring top layer
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public int ZLevelOffset = 0;
|
||||
|
||||
/// <summary>
|
||||
/// prototype of the portal being created on the other side
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntProtoId OtherSideProto = default!;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using Content.Server._CP14.StationDungeonMap.Components;
|
||||
using Content.Server.GameTicking.Events;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Station.Components;
|
||||
using Content.Shared.Teleportation.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.StationDungeonMap.EntitySystems;
|
||||
|
||||
public sealed partial class CP14StationZLevelsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly TileSystem _tile = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
[Dependency] private readonly LinkedEntitySystem _linkedEntity = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14ZLevelAutoPortalComponent, MapInitEvent>(OnPortalMapInit);
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||
SubscribeLocalEvent<CP14StationZLevelsComponent, StationPostInitEvent>(OnStationPostInit);
|
||||
}
|
||||
|
||||
private void OnRoundStart(RoundStartingEvent ev)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14ZLevelAutoPortalComponent>();
|
||||
while (query.MoveNext(out var uid, out var portal))
|
||||
{
|
||||
InitPortal((uid, portal));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStationPostInit(Entity<CP14StationZLevelsComponent> ent, ref StationPostInitEvent args)
|
||||
{
|
||||
if (ent.Comp.Initialized)
|
||||
return;
|
||||
|
||||
if (!TryComp(ent, out StationDataComponent? dataComp))
|
||||
{
|
||||
Log.Error($"Failed to init CP14StationZLevelsSystem: no StationData");
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultMap = _station.GetLargestGrid(dataComp);
|
||||
|
||||
if (defaultMap is null)
|
||||
{
|
||||
Log.Error($"Failed to init CP14StationZLevelsSystem: defaultMap is null");
|
||||
return;
|
||||
}
|
||||
|
||||
ent.Comp.LevelEntities.Add(Transform(defaultMap.Value).MapID, ent.Comp.DefaultMapLevel);
|
||||
|
||||
ent.Comp.Initialized = true;
|
||||
|
||||
foreach (var (map, level) in ent.Comp.Levels)
|
||||
{
|
||||
if (ent.Comp.LevelEntities.ContainsValue(map))
|
||||
{
|
||||
Log.Error($"Key duplication for CP14StationZLevelsSystem at level {map}!");
|
||||
continue;
|
||||
}
|
||||
|
||||
var path = level.Path.ToString();
|
||||
if (path is null)
|
||||
{
|
||||
Log.Error($"path {path} for CP14StationZLevelsSystem at level {map} don't exist!");
|
||||
continue;
|
||||
}
|
||||
|
||||
var mapUid = _map.CreateMap(out var mapId);
|
||||
var member = EnsureComp<StationMemberComponent>(mapUid);
|
||||
member.Station = ent;
|
||||
|
||||
Log.Info($"Created map {mapId} for CP14StationZLevelsSystem at level {map}");
|
||||
var options = new MapLoadOptions { LoadMap = true };
|
||||
|
||||
if (!_mapLoader.TryLoad(mapId, path, out var grids, options))
|
||||
{
|
||||
Log.Error($"Failed to load map for CP14StationZLevelsSystem at level {map}!");
|
||||
Del(mapUid);
|
||||
continue;
|
||||
}
|
||||
ent.Comp.LevelEntities.Add(mapId, map);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPortalMapInit(Entity<CP14ZLevelAutoPortalComponent> autoPortal, ref MapInitEvent args)
|
||||
{
|
||||
InitPortal(autoPortal);
|
||||
}
|
||||
|
||||
private void InitPortal(Entity<CP14ZLevelAutoPortalComponent> autoPortal)
|
||||
{
|
||||
var mapId = Transform(autoPortal).MapUid;
|
||||
if (mapId is null)
|
||||
return;
|
||||
|
||||
var offsetMap = GetMapOffset(mapId.Value, autoPortal.Comp.ZLevelOffset);
|
||||
|
||||
if (offsetMap is null)
|
||||
return;
|
||||
|
||||
var currentWorldPos = _transform.GetWorldPosition(autoPortal);
|
||||
var targetMapPos = new MapCoordinates(currentWorldPos, offsetMap.Value);
|
||||
|
||||
var otherSidePortal = Spawn(autoPortal.Comp.OtherSideProto, targetMapPos);
|
||||
|
||||
if (_linkedEntity.TryLink(autoPortal, otherSidePortal, true))
|
||||
RemComp<CP14ZLevelAutoPortalComponent>(autoPortal);
|
||||
}
|
||||
|
||||
public MapId? GetMapOffset(EntityUid mapUid, int offset)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14StationZLevelsComponent, StationDataComponent>();
|
||||
while (query.MoveNext(out var uid, out var zLevel, out _))
|
||||
{
|
||||
if (!zLevel.LevelEntities.TryGetValue(Transform(mapUid).MapID, out var currentLevel))
|
||||
continue;
|
||||
|
||||
var targetLevel = currentLevel + offset;
|
||||
|
||||
if (!zLevel.LevelEntities.ContainsValue(targetLevel))
|
||||
continue;
|
||||
|
||||
foreach (var (key, value) in zLevel.LevelEntities)
|
||||
{
|
||||
if (value == targetLevel && _map.MapExists(key))
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ entities:
|
||||
name: Map Entity
|
||||
- type: Transform
|
||||
- type: Map
|
||||
mapPaused: True
|
||||
- type: PhysicsMap
|
||||
- type: GridTree
|
||||
- type: MovedGrids
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
drawdepth: BelowFloor
|
||||
sprite: _CP14/Markers/biome.rsi
|
||||
- type: CP14BiomeSpawner
|
||||
deleteBlacklist:
|
||||
components:
|
||||
- Portal
|
||||
- MindContainer
|
||||
- CP14WorldBounding
|
||||
- type: PlacementReplacement
|
||||
key: CP14BiomeSpawner
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
- type: entity
|
||||
id: CP14DungeonEntrance
|
||||
name: dungeon entrance
|
||||
noSpawn: true
|
||||
description: The dark depths of the underworld are calling you.
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
@@ -31,12 +32,12 @@
|
||||
- type: Portal
|
||||
canTeleportToOtherMaps: true
|
||||
randomTeleport: false
|
||||
- type: CP14AutoLink
|
||||
|
||||
- type: entity
|
||||
parent: CP14DungeonEntrance
|
||||
id: CP14DungeonExit
|
||||
name: dungeon exit
|
||||
noSpawn: true
|
||||
description: A way out of the dark underworld into the overworld.
|
||||
components:
|
||||
- type: Sprite
|
||||
@@ -50,4 +51,19 @@
|
||||
radius: 3
|
||||
energy: 1
|
||||
netsync: false
|
||||
- type: CP14AutoLink
|
||||
|
||||
- type: entity
|
||||
parent: CP14DungeonEntrance
|
||||
id: CP14DungeonEntranceAutoLink
|
||||
components:
|
||||
- type: CP14ZLevelAutoPortal
|
||||
zLevelOffset: -1 # Go into deep
|
||||
otherSideProto: CP14DungeonExit
|
||||
|
||||
- type: entity
|
||||
parent: CP14DungeonExit
|
||||
id: CP14DungeonExitAutoLink
|
||||
components:
|
||||
- type: CP14ZLevelAutoPortal
|
||||
zLevelOffset: 1 # Go onto surface
|
||||
otherSideProto: CP14DungeonEntrance
|
||||
@@ -24,9 +24,11 @@
|
||||
AlchemyTest:
|
||||
stationProto: StandardStationArena
|
||||
components:
|
||||
- type: CP14StationAdditionalMap
|
||||
mapPaths:
|
||||
- /Maps/_CP14/alchemy_test_layer2.yml
|
||||
- type: CP14StationZLevels
|
||||
defaultMapLevel: 0
|
||||
levels:
|
||||
1:
|
||||
path: /Maps/_CP14/alchemy_test_layer2.yml
|
||||
- type: StationNameSetup
|
||||
mapNameTemplate: "Alchemy test"
|
||||
- type: StationJobs
|
||||
@@ -78,4 +80,11 @@
|
||||
CP14GuardCommander: [1, 1]
|
||||
CP14HouseKeeper: [1, 1]
|
||||
- type: CP14StationExpeditionTarget
|
||||
shuttlePath: /Maps/_CP14/Shuttles/test-ship.yml
|
||||
shuttlePath: /Maps/_CP14/Shuttles/test-ship.yml
|
||||
- type: CP14StationZLevels
|
||||
defaultMapLevel: 0
|
||||
levels:
|
||||
-1:
|
||||
path: /Maps/_CP14/alchemy_test_layer2.yml
|
||||
-2:
|
||||
path: /Maps/_CP14/battle_royale.yml
|
||||
@@ -27,3 +27,8 @@
|
||||
- type: StationJobs
|
||||
availableJobs:
|
||||
CP14Adventurer: [ -1, -1 ]
|
||||
- type: CP14StationZLevels
|
||||
defaultMapLevel: 0
|
||||
levels:
|
||||
-1:
|
||||
path: /Maps/_CP14/alchemy_test_layer2.yml
|
||||
|
||||
9
Resources/Prototypes/_CP14/Procedural/biome_markers.yml
Normal file
9
Resources/Prototypes/_CP14/Procedural/biome_markers.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
- type: biomeMarkerLayer
|
||||
id: CP14OreGold
|
||||
entityMask:
|
||||
CP14WallStone: CP14PlantPumpkinDeath
|
||||
maxCount: 30
|
||||
minGroupSize: 10
|
||||
maxGroupSize: 15
|
||||
radius: 4
|
||||
@@ -37,6 +37,10 @@ CP14WallStoneSilverOre: CP14WallStoneGoldOre
|
||||
CP14PloughedGround: CP14SeedbedWooden
|
||||
CP14SeedbedDefault: CP14SeedbedWooden
|
||||
|
||||
# 2024-08-24
|
||||
CP14DungeonEntrance: CP14DungeonEntranceAutoLink
|
||||
CP14DungeonExit: CP14DungeonExitAutoLink
|
||||
|
||||
# <---> CrystallPunk migration zone end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user