Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Shuttle Purchasing/Selling system #61

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ private bool IsBlocked(CargoShuttleComponent component)
return FoundOrganics(component.Owner, mobQuery, xformQuery);
}

private bool FoundOrganics(EntityUid uid, EntityQuery<MobStateComponent> mobQuery, EntityQuery<TransformComponent> xformQuery)
public bool FoundOrganics(EntityUid uid, EntityQuery<MobStateComponent> mobQuery, EntityQuery<TransformComponent> xformQuery)
{
var xform = xformQuery.GetComponent(uid);
var childEnumerator = xform.ChildEnumerator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ public void CallEmergencyShuttle()
_commsConsole.UpdateCommsConsoleInterface();
}

private List<DockingComponent> GetDocks(EntityUid uid)
public List<DockingComponent> GetDocks(EntityUid uid)
{
var result = new List<DockingComponent>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Content.Server.Administration;
using Content.Server.Maps;
using Content.Server.Shipyard.Systems;
using Content.Shared.Administration;
using Robust.Shared.Console;

namespace Content.Server.Shipyard.Commands;

/// <summary>
/// Purchases a shuttle and docks it to a station.
/// </summary>
[AdminCommand(AdminFlags.Fun)]
public sealed class PurchaseShuttleCommand : IConsoleCommand
{
[Dependency] private readonly IEntitySystemManager _entityManager = default!;
public string Command => "purchaseshuttle";
public string Description => "Spawns and docks a specified shuttle from a grid file";
public string Help => $"{Command} <station ID> <gridfile path>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (!int.TryParse(args[0], out var stationId))
{
shell.WriteError($"{args[0]} is not a valid integer.");
return;
}

var shuttlePath = args[1];
var system = _entityManager.GetEntitySystem<ShipyardSystem>();
var station = new EntityUid(stationId);
system.PurchaseShuttle(station, shuttlePath);
}

public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
switch (args.Length)
{
case 1:
return CompletionResult.FromHint(Loc.GetString("station-id"));
case 2:
var opts = CompletionHelper.PrototypeIDs<GameMapPrototype>();
return CompletionResult.FromHintOptions(opts, Loc.GetString("cmd-hint-savemap-path"));
}

return CompletionResult.Empty;
}
}
49 changes: 49 additions & 0 deletions Content.Server/_Citadel/Shipyard/Commands/SellShuttleCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Content.Server.Administration;
using Content.Server.Shipyard.Systems;
using Content.Shared.Administration;
using Robust.Shared.Console;

namespace Content.Server.Shipyard.Commands;

/// <summary>
/// Sells a shuttle docked to a station.
/// </summary>
[AdminCommand(AdminFlags.Fun)]
public sealed class SellShuttleCommand : IConsoleCommand
{
[Dependency] private readonly IEntitySystemManager _entityManager = default!;

public string Command => "sellshuttle";
public string Description => "Appraises and sells a selected grid connected to selected station";
public string Help => $"{Command} <station ID> <shuttle ID>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (!EntityUid.TryParse(args[0], out var stationId))
{
shell.WriteError($"{args[0]} is not a valid entity uid.");
return;
}

if (!EntityUid.TryParse(args[1], out var shuttleId))
{
shell.WriteError($"{args[0]} is not a valid entity uid.");
return;
};

var system = _entityManager.GetEntitySystem<ShipyardSystem>();
system.SellShuttle(stationId, shuttleId);
}

public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
switch (args.Length)
{
case 1:
return CompletionResult.FromHint(Loc.GetString("station-id"));
case 2:
return CompletionResult.FromHint(Loc.GetString("shuttle-id"));
}

return CompletionResult.Empty;
}
}
177 changes: 177 additions & 0 deletions Content.Server/_Citadel/Shipyard/Systems/ShipyardSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using System;
using Content.Server.Shuttles.Systems;
using Content.Server.Shuttles.Components;
using Content.Server.Station.Components;
using Content.Server.Cargo.Systems;
using Content.Server.Station.Systems;
using Content.Shared.MobState.Components;
using Content.Shared.GameTicking;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Map;
using Robust.Shared.GameObjects;
using static Content.Server.Power.Pow3r.PowerState;

namespace Content.Server.Shipyard.Systems
{

public sealed partial class ShipyardSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly CargoSystem _cargo = default!;
[Dependency] private readonly MapLoaderSystem _map = default!;
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved

public MapId? ShipyardMap { get; private set; }
private float _shuttleIndex;
private const float ShuttleSpawnBuffer = 1f;
private ISawmill _sawmill = default!;

public override void Initialize()
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved
{
_sawmill = Logger.GetSawmill("shipyard");
SubscribeLocalEvent<BecomesStationComponent, ComponentStartup>(OnShipyardStartup);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
}

private void OnShipyardStartup(EntityUid uid, BecomesStationComponent component, ComponentStartup args)
{
SetupShipyard();
}

private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
CleanupShipyard();
}

/// <summary>
/// Adds a ship to the shipyard, calculates its price, and attempts to ftl-dock it to the given station
/// </summary>
/// <param name="Station ID"></param>
/// <param name="Shuttle Path"></param>
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved
public void PurchaseShuttle(EntityUid? stationUid, string shuttlePath)
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved
{
if (!TryComp<StationDataComponent>(stationUid, out var stationData) || !TryComp<ShuttleComponent>(AddShuttle(shuttlePath), out var shuttle))
return;

var targetGrid = _station.GetLargestGrid(stationData);

if (targetGrid == null)
return;

var price = _pricing.AppraiseGrid(shuttle.Owner, null);

//can do FTLTravel later instead if we want to open that door
_shuttle.TryFTLDock(shuttle, targetGrid.Value);

_sawmill.Info($"Shuttle {shuttlePath} was purchased at {targetGrid} for {price} spacebucks");
}

/// <summary>
/// Loads a paused shuttle into the ShipyardMap from a file path
/// </summary>
/// <param name="Shuttle Path"></param>
/// <returns></returns>
private EntityUid? AddShuttle(string shuttlePath)
{
if (ShipyardMap == null)
return null;

//only dealing with a single grid at a time for now

var loadOptions = new MapLoadOptions()
{
Offset = (500f + _shuttleIndex, 0f)
};

var shuttle = _map.LoadGrid(ShipyardMap.Value, shuttlePath.ToString(), loadOptions);
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved

if (shuttle == null)
{
_sawmill.Error($"Unable to spawn shuttle {shuttlePath}");
return null;
}

_shuttleIndex += _mapManager.GetGrid(shuttle.Value).LocalAABB.Width + ShuttleSpawnBuffer;

return shuttle.Value;
}

/// <summary>
/// Checks a shuttle to make sure that it is docked to the given station, and that there are no lifeforms aboard. Then it appraises the grid, outputs to the server log, and deletes the grid
/// </summary>
/// <param name="Station ID"></param>
/// <param name="Shuttle ID"></param>
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved
public void SellShuttle(EntityUid stationUid, EntityUid shuttleUid)
Cheackraze marked this conversation as resolved.
Show resolved Hide resolved
{
if (!TryComp<StationDataComponent>(stationUid, out var stationGrid) || !HasComp<ShuttleComponent>(shuttleUid) || !TryComp<TransformComponent>(shuttleUid, out var xform) || ShipyardMap == null)
return;

var targetGrid = _station.GetLargestGrid(stationGrid);

if (targetGrid == null)
return;

var gridDocks = _shuttle.GetDocks((EntityUid) targetGrid);
var shuttleDocks = _shuttle.GetDocks(shuttleUid);
var isDocked = false;

foreach (var shuttleDock in shuttleDocks)
{
foreach (var gridDock in gridDocks)
{
if (shuttleDock.DockedWith == gridDock.Owner)
{
isDocked = true;
break;
};
};
if (isDocked)
break;
};

if (!isDocked)
{
_sawmill.Warning($"shuttle is not docked to that station");
return;
};

var mobQuery = GetEntityQuery<MobStateComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();

if (_cargo.FoundOrganics(shuttleUid, mobQuery, xformQuery) == true)
{
_sawmill.Warning($"organics on board");
return;
};

//just yeet and delete for now. Might want to split it into another function later to send back to the shipyard map first to pause for something
var price = _pricing.AppraiseGrid(shuttleUid);
_mapManager.DeleteGrid(shuttleUid);
_sawmill.Info($"Sold shuttle {shuttleUid} for {price}");
}

private void CleanupShipyard()
{
if (ShipyardMap == null || !_mapManager.MapExists(ShipyardMap.Value))
{
ShipyardMap = null;
return;
}

_mapManager.DeleteMap(ShipyardMap.Value);
}

private void SetupShipyard()
{
if (ShipyardMap != null && _mapManager.MapExists(ShipyardMap.Value))
return;

ShipyardMap = _mapManager.CreateMap();

_mapManager.SetMapPaused(ShipyardMap.Value, true);
}
}
}