using System.Linq; using Content.Server.Administration; using Content.Server.Station.Systems; using Content.Shared.Administration; using Content.Shared.Roles; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Syntax; using Robust.Shared.Toolshed.TypeParsers; namespace Content.Server.Station.Commands; [ToolshedCommand, AdminCommand(AdminFlags.VarEdit)] public sealed class JobsCommand : ToolshedCommand { private StationJobsSystem? _jobs; [CommandImplementation("jobs")] public IEnumerable Jobs([PipedArgument] EntityUid station) { _jobs ??= GetSys(); foreach (var (job, _) in _jobs.GetJobs(station)) { yield return new JobSlotRef(job, station, _jobs, EntityManager); } } [CommandImplementation("jobs")] public IEnumerable Jobs([PipedArgument] IEnumerable stations) => stations.SelectMany(Jobs); [CommandImplementation("job")] public JobSlotRef Job([PipedArgument] EntityUid station, [CommandArgument] Prototype job) { _jobs ??= GetSys(); return new JobSlotRef(job.Value.ID, station, _jobs, EntityManager); } [CommandImplementation("job")] public IEnumerable Job([PipedArgument] IEnumerable stations, [CommandArgument] Prototype job) => stations.Select(x => Job(x, job)); [CommandImplementation("isinfinite")] public bool IsInfinite([PipedArgument] JobSlotRef job, [CommandInverted] bool inverted) => job.Infinite() ^ inverted; [CommandImplementation("isinfinite")] public IEnumerable IsInfinite([PipedArgument] IEnumerable jobs, [CommandInverted] bool inverted) => jobs.Select(x => IsInfinite(x, inverted)); [CommandImplementation("adjust")] public JobSlotRef Adjust( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] JobSlotRef @ref, [CommandArgument] ValueRef by ) { _jobs ??= GetSys(); _jobs.TryAdjustJobSlot(@ref.Station, @ref.Job, by.Evaluate(ctx), true, true); return @ref; } [CommandImplementation("adjust")] public IEnumerable Adjust( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] IEnumerable @ref, [CommandArgument] ValueRef by ) => @ref.Select(x => Adjust(ctx, x, by)); [CommandImplementation("set")] public JobSlotRef Set( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] JobSlotRef @ref, [CommandArgument] ValueRef by ) { _jobs ??= GetSys(); _jobs.TrySetJobSlot(@ref.Station, @ref.Job, by.Evaluate(ctx), true); return @ref; } [CommandImplementation("set")] public IEnumerable Set( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] IEnumerable @ref, [CommandArgument] ValueRef by ) => @ref.Select(x => Set(ctx, x, by)); [CommandImplementation("amount")] public int Amount( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] JobSlotRef @ref ) { _jobs ??= GetSys(); _jobs.TryGetJobSlot(@ref.Station, @ref.Job, out var slots); return (int)(slots ?? 0); } [CommandImplementation("amount")] public IEnumerable Amount( [CommandInvocationContext] IInvocationContext ctx, [PipedArgument] IEnumerable @ref ) => @ref.Select(x => Amount(ctx, x)); } // Used for Toolshed queries. public readonly record struct JobSlotRef(string Job, EntityUid Station, StationJobsSystem Jobs, IEntityManager EntityManager) { public override string ToString() { if (!Jobs.TryGetJobSlot(Station, Job, out var slot)) { return $"{EntityManager.ToPrettyString(Station)} job {Job} : (not a slot)"; } return $"{EntityManager.ToPrettyString(Station)} job {Job} : {slot?.ToString() ?? "infinite"}"; } public bool Infinite() { return Jobs.TryGetJobSlot(Station, Job, out var slot) && slot is null; } }