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

FTL coordinate disk command for admins: ftldisk #28075

Merged
merged 28 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b6be6b6
Add robo control comp, also de-reinforce a lot of walls.
IProduceWidgets May 13, 2024
5833521
Revert "Add robo control comp, also de-reinforce a lot of walls."
IProduceWidgets May 16, 2024
18528f9
FTLdiskburner command to make FTL disks.
IProduceWidgets May 16, 2024
f649ba9
Elegant failure on mistyped ID.
IProduceWidgets May 16, 2024
8fe95e2
even more more eleganter failures.
IProduceWidgets May 16, 2024
429d5ab
foo
IProduceWidgets May 16, 2024
4cce97f
bar
IProduceWidgets May 16, 2024
274a24f
Merge branch 'master' into FTLdiskburner
IProduceWidgets May 18, 2024
b3d9570
I have reached completion
IProduceWidgets Jun 23, 2024
ed843a9
prevent id confusion
IProduceWidgets Jun 23, 2024
0248a93
I'm givin' her all she's got captain!
IProduceWidgets Jul 1, 2024
0316bee
a bit more hug boxing for safe destinations.
IProduceWidgets Jul 1, 2024
9f5d0fa
comments for foo
IProduceWidgets Jul 1, 2024
12e6e48
extra thoughts.
IProduceWidgets Jul 1, 2024
27685ed
cleanup
IProduceWidgets Jul 1, 2024
7e42248
continuen't
IProduceWidgets Jul 1, 2024
526b48e
Improve feedback strings
IProduceWidgets Jul 1, 2024
b90e0d3
reviewer QOL
IProduceWidgets Jul 1, 2024
627de80
Reviewer QOL 2
IProduceWidgets Jul 1, 2024
6f0805b
handle easy reviews
IProduceWidgets Jul 1, 2024
8faf165
Add comments to clarify reviews
IProduceWidgets Jul 1, 2024
84cabc2
howdoicode to the rescue.
IProduceWidgets Jul 1, 2024
2575bda
ftldisk in hand
IProduceWidgets Oct 16, 2024
4d13849
ftl.ftl
IProduceWidgets Oct 16, 2024
106e7bb
Merge branch 'master' into FTLdiskburner
IProduceWidgets Oct 16, 2024
277827e
funny disk case
IProduceWidgets Oct 16, 2024
eacfcf1
loc
IProduceWidgets Oct 16, 2024
86a0d31
unusing
IProduceWidgets Oct 16, 2024
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
183 changes: 183 additions & 0 deletions Content.Server/Shuttles/Commands/FTLDiskCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using Content.Server.Administration;
using Content.Server.Labels;
using Content.Shared.Administration;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Shuttles.Components;
using Content.Shared.Storage;
using Content.Shared.Storage.EntitySystems;
using Robust.Shared.Console;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;

namespace Content.Server.Shuttles.Commands;

/// <summary>
/// Creates FTL disks, to maps, grids, or entities.
/// </summary>
[AdminCommand(AdminFlags.Fun)]

public sealed class FTLDiskCommand : LocalizedCommands
{
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IEntitySystemManager _entSystemManager = default!;

public override string Command => "ftldisk";

[ValidatePrototypeId<EntityPrototype>]
public const string CoordinatesDisk = "CoordinatesDisk";

[ValidatePrototypeId<EntityPrototype>]
public const string DiskCase = "DiskCase";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length == 0)
{
shell.WriteError(Loc.GetString("shell-need-minimum-one-argument"));
return;
}

var player = shell.Player;

if (player == null)
{
shell.WriteLine(Loc.GetString("shell-only-players-can-run-this-command"));
return;
}

if (player.AttachedEntity == null)
{
shell.WriteLine(Loc.GetString("shell-must-be-attached-to-entity"));
return;
}

EntityUid entity = player.AttachedEntity.Value;
var coords = _entManager.GetComponent<TransformComponent>(entity).Coordinates;

var handsSystem = _entSystemManager.GetEntitySystem<SharedHandsSystem>();
var labelSystem = _entSystemManager.GetEntitySystem<LabelSystem>();
var mapSystem = _entSystemManager.GetEntitySystem<SharedMapSystem>();
var storageSystem = _entSystemManager.GetEntitySystem<SharedStorageSystem>();

foreach (var destinations in args)
{
DebugTools.AssertNotNull(destinations);

// make sure destination is an id.
EntityUid dest;

if (_entManager.TryParseNetEntity(destinations, out var nullableDest))
{
DebugTools.AssertNotNull(nullableDest);

dest = (EntityUid) nullableDest;

// we need to go to a map, so check if the EntID is something else then try for its map
if (!_entManager.HasComponent<MapComponent>(dest))
{
if (!_entManager.TryGetComponent<TransformComponent>(dest, out var entTransform))
{
shell.WriteLine(Loc.GetString("cmd-ftldisk-no-transform", ("destination", destinations)));
continue;
}

if (!mapSystem.TryGetMap(entTransform.MapID, out var mapDest))
{
shell.WriteLine(Loc.GetString("cmd-ftldisk-no-map", ("destination", destinations)));
continue;
}

DebugTools.AssertNotNull(mapDest);
dest = mapDest!.Value; // explicit cast here should be fine since the previous if should catch it.
}

// find and verify the map is not somehow unusable.
if (!_entManager.TryGetComponent<MapComponent>(dest, out var mapComp)) // We have to check for a MapComponent here and above since we could have changed our dest entity.
{
shell.WriteLine(Loc.GetString("cmd-ftldisk-no-map-comp", ("destination", destinations), ("map", dest)));
continue;
}
if (mapComp.MapInitialized == false)
{
shell.WriteLine(Loc.GetString("cmd-ftldisk-map-not-init", ("destination", destinations), ("map", dest)));
continue;
}
if (mapComp.MapPaused == true)
{
shell.WriteLine(Loc.GetString("cmd-ftldisk-map-paused", ("destination", destinations), ("map", dest)));
continue;
}

// check if our destination works already, if not, make it.
if (!_entManager.TryGetComponent<FTLDestinationComponent>(dest, out var ftlDestComp))
{
FTLDestinationComponent ftlDest = _entManager.AddComponent<FTLDestinationComponent>(dest);
ftlDest.RequireCoordinateDisk = true;

if (_entManager.HasComponent<MapGridComponent>(dest))
{
ftlDest.BeaconsOnly = true;

shell.WriteLine(Loc.GetString("cmd-ftldisk-planet", ("destination", destinations), ("map", dest)));
}
}
else
{
// we don't do these automatically, since it isn't clear what the correct resolution is. Instead we provide feedback to the user and carry on like they know what theyre doing.
if (ftlDestComp.Enabled == false)
shell.WriteLine(Loc.GetString("cmd-ftldisk-already-dest-not-enabled", ("destination", destinations), ("map", dest)));

if (ftlDestComp.BeaconsOnly == true)
shell.WriteLine(Loc.GetString("cmd-ftldisk-requires-ftl-point", ("destination", destinations), ("map", dest)));
}

// create the FTL disk
EntityUid cdUid = _entManager.SpawnEntity(CoordinatesDisk, coords);
var cd = _entManager.EnsureComponent<ShuttleDestinationCoordinatesComponent>(cdUid);
cd.Destination = dest;
_entManager.Dirty(cdUid, cd);

// create disk case
EntityUid cdCaseUid = _entManager.SpawnEntity(DiskCase, coords);

// apply labels
if (_entManager.TryGetComponent<MetaDataComponent>(dest, out var meta) && meta != null && meta.EntityName != null)
{
labelSystem.Label(cdUid, meta.EntityName);
labelSystem.Label(cdCaseUid, meta.EntityName);
}

// if the case has a storage, try to place the disk in there and then the case inhand

if (_entManager.TryGetComponent<StorageComponent>(cdCaseUid, out var storage) && storageSystem.Insert(cdCaseUid, cdUid, out _, storageComp: storage, playSound: false))
{
if (_entManager.TryGetComponent<HandsComponent>(entity, out var handsComponent) && handsSystem.TryGetEmptyHand(entity, out var emptyHand, handsComponent))
{
handsSystem.TryPickup(entity, cdCaseUid, emptyHand, checkActionBlocker: false, handsComp: handsComponent);
}
}
else // the case was messed up, put disk inhand
{
_entManager.DeleteEntity(cdCaseUid); // something went wrong so just yeet the chaf

if (_entManager.TryGetComponent<HandsComponent>(entity, out var handsComponent) && handsSystem.TryGetEmptyHand(entity, out var emptyHand, handsComponent))
{
handsSystem.TryPickup(entity, cdUid, emptyHand, checkActionBlocker: false, handsComp: handsComponent);
}
}
}
else
{
shell.WriteLine(Loc.GetString("shell-invalid-entity-uid", ("uid", destinations)));
}
}
}

public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length >= 1)
return CompletionResult.FromHintOptions(CompletionHelper.MapUids(_entManager), Loc.GetString("cmd-ftldisk-hint"));
return CompletionResult.Empty;
}
}
14 changes: 14 additions & 0 deletions Resources/Locale/en-US/shuttles/commands.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# FTLdiskburner
cmd-ftldisk-desc = Creates an FTL coordinates disk to sail to the map the given EntityID is/on
cmd-ftldisk-help = ftldisk [EntityID]

cmd-ftldisk-no-transform = Entity {$destination} has no Transform Component!
cmd-ftldisk-no-map = Entity {$destination} has no map!
cmd-ftldisk-no-map-comp = Entity {$destination} is somehow on map {$map} with no map component.
cmd-ftldisk-map-not-init = Entity {$destination} is on map {$map} which is not initialized! Check it's safe to initialize, then initialize the map first or the players will be stuck in place!
cmd-ftldisk-map-paused = Entity {$desintation} is on map {$map} which is paused! Please unpause the map first or the players will be stuck in place.
cmd-ftldisk-planet = Entity {$desintation} is on planet map {$map} and will require an FTL point. It may already exist.
cmd-ftldisk-already-dest-not-enabled = Entity {$destination} is on map {$map} that already has an FTLDestinationComponent, but it is not Enabled! Set this manually for safety.
cmd-ftldisk-requires-ftl-point = Entity {$destination} is on map {$map} that requires a FTL point to travel to! It may already exist.

cmd-ftldisk-hint = Map netID
Loading