Port DeltaV Lavaland Initial
This commit is contained in:
76
Content.Server/DeltaV/Planet/PlanetSystem.cs
Normal file
76
Content.Server/DeltaV/Planet/PlanetSystem.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Parallax;
|
||||
using Content.Shared.DeltaV.Planet;
|
||||
using Content.Shared.Parallax.Biomes;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.DeltaV.Planet;
|
||||
|
||||
public sealed class PlanetSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmos = default!;
|
||||
[Dependency] private readonly BiomeSystem _biome = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
[Dependency] private readonly MetaDataSystem _meta = default!;
|
||||
|
||||
private readonly List<(Vector2i, Tile)> _setTiles = new();
|
||||
|
||||
/// <summary>
|
||||
/// Spawn a planet map from a planet prototype.
|
||||
/// </summary>
|
||||
public EntityUid SpawnPlanet(ProtoId<PlanetPrototype> id, bool runMapInit = true)
|
||||
{
|
||||
var planet = _proto.Index(id);
|
||||
|
||||
var map = _map.CreateMap(out _, runMapInit: runMapInit);
|
||||
_biome.EnsurePlanet(map, _proto.Index(planet.Biome), mapLight: planet.MapLight);
|
||||
|
||||
// add each marker layer
|
||||
var biome = Comp<BiomeComponent>(map);
|
||||
foreach (var layer in planet.BiomeMarkerLayers)
|
||||
{
|
||||
_biome.AddMarkerLayer(map, biome, layer);
|
||||
}
|
||||
|
||||
if (planet.AddedComponents is {} added)
|
||||
EntityManager.AddComponents(map, added);
|
||||
|
||||
_atmos.SetMapAtmosphere(map, false, planet.Atmosphere);
|
||||
|
||||
_meta.SetEntityName(map, Loc.GetString(planet.MapName));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns an initialized planet map from a planet prototype and loads a grid onto it.
|
||||
/// Returns the map entity if loading succeeded.
|
||||
/// </summary>
|
||||
public EntityUid? LoadPlanet(ProtoId<PlanetPrototype> id, string path)
|
||||
{
|
||||
var map = SpawnPlanet(id, runMapInit: false);
|
||||
var mapId = Comp<MapComponent>(map).MapId;
|
||||
if (!_mapLoader.TryLoad(mapId, path, out var grids))
|
||||
{
|
||||
Log.Error($"Failed to load planet grid {path} for planet {id}!");
|
||||
Del(map);
|
||||
return null;
|
||||
}
|
||||
|
||||
// don't want rocks spawning inside the base
|
||||
foreach (var gridUid in grids)
|
||||
{
|
||||
_setTiles.Clear();
|
||||
var aabb = Comp<MapGridComponent>(gridUid).LocalAABB;
|
||||
_biome.ReserveTiles(map, aabb.Enlarged(0.2f), _setTiles);
|
||||
}
|
||||
|
||||
_map.InitializeMap(map);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
164
Content.Server/DeltaV/Shuttles/Systems/DockingConsoleSystem.cs
Normal file
164
Content.Server/DeltaV/Shuttles/Systems/DockingConsoleSystem.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Shuttles.Events;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Shared.DeltaV.Shuttles;
|
||||
using Content.Shared.DeltaV.Shuttles.Components;
|
||||
using Content.Shared.DeltaV.Shuttles.Systems;
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Content.Shared.Shuttles.Systems;
|
||||
using Content.Shared.Timing;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
namespace Content.Server.DeltaV.Shuttles.Systems;
|
||||
|
||||
public sealed class DockingConsoleSystem : SharedDockingConsoleSystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly ShuttleSystem _shuttle = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DockEvent>(OnDock);
|
||||
SubscribeLocalEvent<UndockEvent>(OnUndock);
|
||||
|
||||
Subs.BuiEvents<DockingConsoleComponent>(DockingConsoleUiKey.Key, subs =>
|
||||
{
|
||||
subs.Event<BoundUIOpenedEvent>(OnOpened);
|
||||
subs.Event<DockingConsoleFTLMessage>(OnFTL);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnDock(DockEvent args)
|
||||
{
|
||||
UpdateConsoles(args.GridAUid, args.GridBUid);
|
||||
}
|
||||
|
||||
private void OnUndock(UndockEvent args)
|
||||
{
|
||||
UpdateConsoles(args.GridAUid, args.GridBUid);
|
||||
}
|
||||
|
||||
private void OnOpened(Entity<DockingConsoleComponent> ent, ref BoundUIOpenedEvent args)
|
||||
{
|
||||
if (TerminatingOrDeleted(ent.Comp.Shuttle))
|
||||
UpdateShuttle(ent);
|
||||
|
||||
UpdateUI(ent);
|
||||
}
|
||||
|
||||
private void UpdateConsoles(EntityUid gridA, EntityUid gridB)
|
||||
{
|
||||
UpdateConsolesUsing(gridA);
|
||||
UpdateConsolesUsing(gridB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI of every console that is using a certain shuttle.
|
||||
/// </summary>
|
||||
public void UpdateConsolesUsing(EntityUid shuttle)
|
||||
{
|
||||
if (!HasComp<DockingShuttleComponent>(shuttle))
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<DockingConsoleComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
if (comp.Shuttle == shuttle)
|
||||
UpdateUI((uid, comp));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateUI(Entity<DockingConsoleComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Shuttle is not {} shuttle)
|
||||
return;
|
||||
|
||||
var ftlState = FTLState.Available;
|
||||
StartEndTime ftlTime = default;
|
||||
List<DockingDestination> destinations = new();
|
||||
|
||||
if (TryComp<FTLComponent>(shuttle, out var ftl))
|
||||
{
|
||||
ftlState = ftl.State;
|
||||
ftlTime = _shuttle.GetStateTime(ftl);
|
||||
}
|
||||
|
||||
if (TryComp<DockingShuttleComponent>(shuttle, out var docking))
|
||||
{
|
||||
destinations = docking.Destinations;
|
||||
}
|
||||
|
||||
var state = new DockingConsoleState(ftlState, ftlTime, destinations);
|
||||
_ui.SetUiState(ent.Owner, DockingConsoleUiKey.Key, state);
|
||||
}
|
||||
|
||||
private void OnFTL(Entity<DockingConsoleComponent> ent, ref DockingConsoleFTLMessage args)
|
||||
{
|
||||
if (ent.Comp.Shuttle is not {} shuttle || !TryComp<DockingShuttleComponent>(shuttle, out var docking))
|
||||
return;
|
||||
|
||||
if (args.Index < 0 || args.Index > docking.Destinations.Count)
|
||||
return;
|
||||
|
||||
var dest = docking.Destinations[args.Index];
|
||||
var map = dest.Map;
|
||||
// can't FTL if its already there or somehow failed whitelist
|
||||
if (map == Transform(shuttle).MapID || !_shuttle.CanFTLTo(shuttle, map, ent))
|
||||
return;
|
||||
|
||||
if (FindLargestGrid(map) is not {} grid)
|
||||
return;
|
||||
|
||||
_shuttle.FTLToDock(shuttle, Comp<ShuttleComponent>(shuttle), grid, priorityTag: ent.Comp.DockTag);
|
||||
}
|
||||
|
||||
private EntityUid? FindLargestGrid(MapId map)
|
||||
{
|
||||
EntityUid? largestGrid = null;
|
||||
var largestSize = 0f;
|
||||
|
||||
var query = EntityQueryEnumerator<MapGridComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var gridUid, out var grid, out var xform))
|
||||
{
|
||||
if (xform.MapID != map)
|
||||
continue;
|
||||
|
||||
var size = grid.LocalAABB.Size.LengthSquared();
|
||||
if (size < largestSize)
|
||||
continue;
|
||||
|
||||
largestSize = size;
|
||||
largestGrid = gridUid;
|
||||
}
|
||||
|
||||
return largestGrid;
|
||||
}
|
||||
|
||||
private void UpdateShuttle(Entity<DockingConsoleComponent> ent)
|
||||
{
|
||||
var hadShuttle = ent.Comp.HasShuttle;
|
||||
// no error if it cant find one since it would fail every test as shuttle.grid_fill is false in dev
|
||||
ent.Comp.Shuttle = FindShuttle(ent.Comp.ShuttleWhitelist);
|
||||
ent.Comp.HasShuttle = ent.Comp.Shuttle != null;
|
||||
|
||||
if (ent.Comp.HasShuttle != hadShuttle)
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
private EntityUid? FindShuttle(EntityWhitelist whitelist)
|
||||
{
|
||||
var query = EntityQueryEnumerator<DockingShuttleComponent>();
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
{
|
||||
if (_whitelist.IsValid(whitelist, uid))
|
||||
return uid;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using Content.Server.Shuttles.Events;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.DeltaV.Shuttles.Components;
|
||||
using Content.Shared.DeltaV.Shuttles.Systems;
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Map.Components;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Server.DeltaV.Shuttles.Systems;
|
||||
|
||||
public sealed class DockingShuttleSystem : SharedDockingShuttleSystem
|
||||
{
|
||||
[Dependency] private readonly DockingConsoleSystem _console = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DockingShuttleComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<DockingShuttleComponent, FTLStartedEvent>(OnFTLStarted);
|
||||
SubscribeLocalEvent<DockingShuttleComponent, FTLCompletedEvent>(OnFTLCompleted);
|
||||
|
||||
SubscribeLocalEvent<StationGridAddedEvent>(OnStationGridAdded);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<DockingShuttleComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
// add any whitelisted destinations that it can FTL to
|
||||
// since it needs a whitelist, this excludes the station
|
||||
var query = EntityQueryEnumerator<FTLDestinationComponent, MapComponent>();
|
||||
while (query.MoveNext(out var mapUid, out var dest, out var map))
|
||||
{
|
||||
if (!dest.Enabled || _whitelist.IsWhitelistFailOrNull(dest.Whitelist, ent))
|
||||
continue;
|
||||
|
||||
ent.Comp.Destinations.Add(new DockingDestination()
|
||||
{
|
||||
Name = Name(mapUid),
|
||||
Map = map.MapId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFTLStarted(Entity<DockingShuttleComponent> ent, ref FTLStartedEvent args)
|
||||
{
|
||||
_console.UpdateConsolesUsing(ent);
|
||||
}
|
||||
|
||||
private void OnFTLCompleted(Entity<DockingShuttleComponent> ent, ref FTLCompletedEvent args)
|
||||
{
|
||||
_console.UpdateConsolesUsing(ent);
|
||||
}
|
||||
|
||||
private void OnStationGridAdded(StationGridAddedEvent args)
|
||||
{
|
||||
var uid = args.GridId;
|
||||
if (!TryComp<DockingShuttleComponent>(uid, out var comp))
|
||||
return;
|
||||
|
||||
// only add the destination once
|
||||
if (comp.Station != null)
|
||||
return;
|
||||
|
||||
if (_station.GetOwningStation(uid) is not {} station || !TryComp<StationDataComponent>(station, out var data))
|
||||
return;
|
||||
|
||||
// add the source station as a destination
|
||||
comp.Station = station;
|
||||
comp.Destinations.Add(new DockingDestination()
|
||||
{
|
||||
Name = Name(station),
|
||||
Map = Transform(data.Grids.First()).MapID
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Content.Server.DeltaV.Station.Systems;
|
||||
using Content.Shared.DeltaV.Planet;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.DeltaV.Station.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Loads a planet map on mapinit and spawns a grid on it (e.g. a mining base).
|
||||
/// The map can then be FTLd to by any shuttle matching its whitelist.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(StationPlanetSpawnerSystem))]
|
||||
public sealed partial class StationPlanetSpawnerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The planet to create.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<PlanetPrototype> Planet;
|
||||
|
||||
/// <summary>
|
||||
/// Path to the grid to load onto the map.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ResPath? GridPath;
|
||||
|
||||
/// <summary>
|
||||
/// The map that was loaded.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid? Map;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Content.Server.DeltaV.Planet;
|
||||
using Content.Server.DeltaV.Station.Components;
|
||||
|
||||
namespace Content.Server.DeltaV.Station.Systems;
|
||||
|
||||
public sealed class StationPlanetSpawnerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly PlanetSystem _planet = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<StationPlanetSpawnerComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<StationPlanetSpawnerComponent, ComponentShutdown>(OnShutdown);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<StationPlanetSpawnerComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
if (ent.Comp.GridPath is not {} path)
|
||||
return;
|
||||
|
||||
ent.Comp.Map = _planet.LoadPlanet(ent.Comp.Planet, path.ToString());
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<StationPlanetSpawnerComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
QueueDel(ent.Comp.Map);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user