using Content.Server.Decals;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Shuttles.Events;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Atmos;
using Content.Shared.Decals;
using Content.Shared.Gravity;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Noise;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Components;
+using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
[Dependency] private readonly AtmosphereSystem _atmos = default!;
[Dependency] private readonly DecalSystem _decals = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
+ [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly ShuttleSystem _shuttles = default!;
+ private EntityQuery<BiomeComponent> _biomeQuery;
+ private EntityQuery<FixturesComponent> _fixturesQuery;
private EntityQuery<TransformComponent> _xformQuery;
private readonly HashSet<EntityUid> _handledEntities = new();
{
base.Initialize();
Log.Level = LogLevel.Debug;
+ _biomeQuery = GetEntityQuery<BiomeComponent>();
+ _fixturesQuery = GetEntityQuery<FixturesComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
var query = AllEntityQuery<BiomeComponent>();
- while (query.MoveNext(out var biome))
+ while (query.MoveNext(out var uid, out var biome))
{
if (biome.Template == null || !reloads.Modified.TryGetValue(biome.Template, out var proto))
continue;
- SetTemplate(biome, (BiomeTemplatePrototype) proto);
+ SetTemplate(uid, biome, (BiomeTemplatePrototype) proto);
}
}
private void OnBiomeMapInit(EntityUid uid, BiomeComponent component, MapInitEvent args)
{
- if (component.Seed != -1)
- return;
+ if (component.Seed == -1)
+ {
+ SetSeed(uid, component, _random.Next());
+ }
+
+ var xform = Transform(uid);
+ var mapId = xform.MapID;
+
+ if (mapId != MapId.Nullspace && TryComp(uid, out MapGridComponent? mapGrid))
+ {
+ var setTiles = new List<(Vector2i Index, Tile tile)>();
- SetSeed(component, _random.Next());
+ foreach (var grid in _mapManager.GetAllMapGrids(mapId))
+ {
+ var gridUid = grid.Owner;
+
+ if (!_fixturesQuery.TryGetComponent(gridUid, out var fixtures))
+ continue;
+
+ // Don't want shuttles flying around now do we.
+ _shuttles.Disable(gridUid);
+ var pTransform = _physics.GetPhysicsTransform(gridUid);
+
+ foreach (var fixture in fixtures.Fixtures.Values)
+ {
+ for (var i = 0; i < fixture.Shape.ChildCount; i++)
+ {
+ var aabb = fixture.Shape.ComputeAABB(pTransform, i);
+
+ setTiles.Clear();
+ ReserveTiles(uid, aabb, setTiles);
+ }
+ }
+ }
+ }
}
- public void SetSeed(BiomeComponent component, int seed)
+ public void SetSeed(EntityUid uid, BiomeComponent component, int seed, bool dirty = true)
{
component.Seed = seed;
- Dirty(component);
+
+ if (dirty)
+ Dirty(uid, component);
}
- public void ClearTemplate(BiomeComponent component)
+ public void ClearTemplate(EntityUid uid, BiomeComponent component, bool dirty = true)
{
component.Layers.Clear();
component.Template = null;
- Dirty(component);
+
+ if (dirty)
+ Dirty(uid, component);
}
/// <summary>
/// Sets the <see cref="BiomeComponent.Template"/> and refreshes layers.
/// </summary>
- public void SetTemplate(BiomeComponent component, BiomeTemplatePrototype template)
+ public void SetTemplate(EntityUid uid, BiomeComponent component, BiomeTemplatePrototype template, bool dirty = true)
{
component.Layers.Clear();
component.Template = template.ID;
component.Layers.Add(layer);
}
- Dirty(component);
+ if (dirty)
+ Dirty(uid, component);
}
/// <summary>
/// Adds the specified layer at the specified marker if it exists.
/// </summary>
- public void AddLayer(BiomeComponent component, string id, IBiomeLayer addedLayer, int seedOffset = 0)
+ public void AddLayer(EntityUid uid, BiomeComponent component, string id, IBiomeLayer addedLayer, int seedOffset = 0)
{
for (var i = 0; i < component.Layers.Count; i++)
{
break;
}
- Dirty(component);
+ Dirty(uid, component);
}
- public void AddMarkerLayer(BiomeComponent component, string marker)
+ public void AddMarkerLayer(EntityUid uid, BiomeComponent component, string marker)
{
- if (!ProtoManager.HasIndex<BiomeMarkerLayerPrototype>(marker))
- {
- // TODO: Log when we get a sawmill
- return;
- }
-
component.MarkerLayers.Add(marker);
- Dirty(component);
+ Dirty(uid, component);
}
/// <summary>
/// Adds the specified template at the specified marker if it exists, withour overriding every layer.
/// </summary>
- public void AddTemplate(BiomeComponent component, string id, BiomeTemplatePrototype template, int seedOffset = 0)
+ public void AddTemplate(EntityUid uid, BiomeComponent component, string id, BiomeTemplatePrototype template, int seedOffset = 0)
{
for (var i = 0; i < component.Layers.Count; i++)
{
break;
}
- Dirty(component);
+ Dirty(uid, component);
}
private void OnFTLStarted(ref FTLStartedEvent ev)
foreach (var layer in markers)
{
- var proto = ProtoManager.Index<BiomeMarkerLayerPrototype>(layer);
+ var proto = ProtoManager.Index(layer);
var enumerator = new ChunkIndicesEnumerator(area, proto.Size);
while (enumerator.MoveNext(out var chunk))
public override void Update(float frameTime)
{
base.Update(frameTime);
- var biomeQuery = GetEntityQuery<BiomeComponent>();
- var xformQuery = GetEntityQuery<TransformComponent>();
var biomes = AllEntityQuery<BiomeComponent>();
while (biomes.MoveNext(out var biome))
// Get chunks in range
foreach (var pSession in Filter.GetAllPlayers(_playerManager))
{
-
- if (xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) &&
+ if (_xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) &&
_handledEntities.Add(pSession.AttachedEntity.Value) &&
- biomeQuery.TryGetComponent(xform.MapUid, out var biome))
+ _biomeQuery.TryGetComponent(xform.MapUid, out var biome))
{
- var worldPos = _transform.GetWorldPosition(xform, xformQuery);
+ var worldPos = _transform.GetWorldPosition(xform);
AddChunksInRange(biome, worldPos);
foreach (var layer in biome.MarkerLayers)
{
- var layerProto = ProtoManager.Index<BiomeMarkerLayerPrototype>(layer);
+ var layerProto = ProtoManager.Index(layer);
AddMarkerChunksInRange(biome, worldPos, layerProto);
}
}
foreach (var viewer in pSession.ViewSubscriptions)
{
if (!_handledEntities.Add(viewer) ||
- !xformQuery.TryGetComponent(viewer, out xform) ||
- !biomeQuery.TryGetComponent(xform.MapUid, out biome))
+ !_xformQuery.TryGetComponent(viewer, out xform) ||
+ !_biomeQuery.TryGetComponent(xform.MapUid, out biome))
{
continue;
}
- var worldPos = _transform.GetWorldPosition(xform, xformQuery);
+ var worldPos = _transform.GetWorldPosition(xform);
AddChunksInRange(biome, worldPos);
foreach (var layer in biome.MarkerLayers)
{
- var layerProto = ProtoManager.Index<BiomeMarkerLayerPrototype>(layer);
+ var layerProto = ProtoManager.Index(layer);
AddMarkerChunksInRange(biome, worldPos, layerProto);
}
}
while (loadBiomes.MoveNext(out var gridUid, out var biome, out var grid))
{
// Load new chunks
- LoadChunks(biome, gridUid, grid, biome.Seed, xformQuery);
+ LoadChunks(biome, gridUid, grid, biome.Seed, _xformQuery);
// Unload old chunks
UnloadChunks(biome, gridUid, grid, biome.Seed);
}
if (!Resolve(mapUid, ref metadata))
return;
- var biome = EnsureComp<BiomeComponent>(mapUid);
+ EnsureComp<MapGridComponent>(mapUid);
+ var biome = (BiomeComponent) EntityManager.ComponentFactory.GetComponent(typeof(BiomeComponent));
seed ??= _random.Next();
- SetSeed(biome, seed.Value);
- SetTemplate(biome, biomeTemplate);
+ SetSeed(mapUid, biome, seed.Value, false);
+ SetTemplate(mapUid, biome, biomeTemplate, false);
+ AddComp(mapUid, biome, true);
Dirty(mapUid, biome, metadata);
var gravity = EnsureComp<GravityComponent>(mapUid);
};
_atmos.SetMapAtmosphere(mapUid, false, mixture, atmos);
+ }
- EnsureComp<MapGridComponent>(mapUid);
+ /// <summary>
+ /// Sets the specified tiles as relevant and marks them as modified.
+ /// </summary>
+ public void ReserveTiles(EntityUid mapUid, Box2 bounds, List<(Vector2i Index, Tile Tile)> tiles, BiomeComponent? biome = null, MapGridComponent? mapGrid = null)
+ {
+ if (!Resolve(mapUid, ref biome, ref mapGrid, false))
+ return;
+
+ foreach (var tileSet in _mapSystem.GetLocalTilesIntersecting(mapUid, mapGrid, bounds, false))
+ {
+ Vector2i chunkOrigin;
+ HashSet<Vector2i> modified;
+
+ // Existing, ignore
+ if (_mapSystem.TryGetTileRef(mapUid, mapGrid, tileSet.GridIndices, out var existingRef) && !existingRef.Tile.IsEmpty)
+ {
+ chunkOrigin = SharedMapSystem.GetChunkIndices(tileSet.GridIndices, ChunkSize) * ChunkSize;
+ modified = biome.ModifiedTiles.GetOrNew(chunkOrigin);
+ modified.Add(tileSet.GridIndices);
+ continue;
+ }
+
+ if (!TryGetBiomeTile(tileSet.GridIndices, biome.Layers, biome.Seed, mapGrid, out var tile))
+ {
+ continue;
+ }
+
+ chunkOrigin = SharedMapSystem.GetChunkIndices(tileSet.GridIndices, ChunkSize) * ChunkSize;
+ modified = biome.ModifiedTiles.GetOrNew(chunkOrigin);
+ modified.Add(tileSet.GridIndices);
+ tiles.Add((tileSet.GridIndices, tile.Value));
+ }
+
+ _mapSystem.SetTiles(mapUid, mapGrid, tiles);
}
}
using Content.Server.Body.Systems;
using Content.Server.Doors.Systems;
+using Content.Server.Parallax;
using Content.Server.Shuttles.Components;
using Content.Server.Station.Systems;
using Content.Server.Stunnable;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
+ [Dependency] private readonly BiomeSystem _biomes = default!;
[Dependency] private readonly BodySystem _bobby = default!;
[Dependency] private readonly DockingSystem _dockSystem = default!;
[Dependency] private readonly DoorSystem _doors = default!;
[Dependency] private readonly MapLoaderSystem _loader = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
if (component.Enabled)
{
- Enable(uid, physicsComponent, component);
+ Enable(uid, component: physicsComponent, shuttle: component);
}
}
if (component.Enabled)
{
- Enable(uid, physicsComponent, component);
+ Enable(uid, component: physicsComponent, shuttle: component);
}
else
{
- Disable(uid, physicsComponent);
+ Disable(uid, component: physicsComponent);
}
}
- private void Enable(EntityUid uid, PhysicsComponent component, ShuttleComponent shuttle)
+ public void Enable(EntityUid uid, FixturesComponent? manager = null, PhysicsComponent? component = null, ShuttleComponent? shuttle = null)
{
- FixturesComponent? manager = null;
+ if (!Resolve(uid, ref manager, ref component, ref shuttle, false))
+ return;
_physics.SetBodyType(uid, BodyType.Dynamic, manager: manager, body: component);
_physics.SetBodyStatus(component, BodyStatus.InAir);
_physics.SetAngularDamping(component, shuttle.AngularDamping);
}
- private void Disable(EntityUid uid, PhysicsComponent component)
+ public void Disable(EntityUid uid, FixturesComponent? manager = null, PhysicsComponent? component = null)
{
- FixturesComponent? manager = null;
+ if (!Resolve(uid, ref manager, ref component, false))
+ return;
_physics.SetBodyType(uid, BodyType.Static, manager: manager, body: component);
_physics.SetBodyStatus(component, BodyStatus.OnGround);
if (EntityManager.GetComponent<MetaDataComponent>(uid).EntityLifeStage >= EntityLifeStage.Terminating)
return;
- if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
- {
- return;
- }
-
- Disable(uid, physicsComponent);
+ Disable(uid);
}
}