Toolshed part 2 (#18997)
* fixe * Save work. * Rune-aware parser. * oogh * pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests pass tests * Publicizes a lot of common generic commands, so custom toolshed envs can include them. * i think i might implode * Tests. * a * b * awa --------- Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
This commit is contained in:
@@ -13,8 +13,7 @@ public sealed class AdminTest : ToolshedTest
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(InvokeCommand("cmd:list where { acmd:perms isnull }", out var res));
|
||||
var list = ((IEnumerable<CommandSpec>) res).ToList();
|
||||
Assert.That(list, Is.Empty, "All commands must have admin permissions set up.");
|
||||
Assert.That((IEnumerable<CommandSpec>) res, Is.Empty, "All commands must have admin permissions set up.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Toolshed;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class CommandRunTest : ToolshedTest
|
||||
{
|
||||
[Test]
|
||||
public async Task SimpleCommandRun()
|
||||
{
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
ParseCommand("entities");
|
||||
ParseCommand("entities select 1");
|
||||
ParseCommand("entities with Item select 1");
|
||||
|
||||
ExpectError<OutOfInputError>();
|
||||
ParseCommand("entities with");
|
||||
|
||||
ExpectError<NoImplementationError>();
|
||||
ParseCommand("player:list with MetaData");
|
||||
|
||||
ExpectError<ExpressionOfWrongType>();
|
||||
ParseCommand("player:list", expectedType: typeof(IEnumerable<EntityUid>));
|
||||
|
||||
ParseCommand("entities not with MetaData");
|
||||
ParseCommand("with MetaData select 2 any", inputType: typeof(List<EntityUid>));
|
||||
|
||||
ParseCommand("entities not with MetaData => $myEntities");
|
||||
ParseCommand("=> $fooBar with MetaData", inputType: typeof(List<EntityUid>));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EntityUidTypeParser()
|
||||
{
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
ParseCommand("ent 1");
|
||||
ParseCommand("ent c1");
|
||||
|
||||
ExpectError<InvalidEntityUid>();
|
||||
ParseCommand("ent foodigity");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task QuantityTypeParser()
|
||||
{
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
ParseCommand("entities select 100");
|
||||
ParseCommand("entities select 50%");
|
||||
|
||||
ExpectError<InvalidQuantity>();
|
||||
ParseCommand("entities select -1");
|
||||
|
||||
ExpectError<InvalidQuantity>();
|
||||
ParseCommand("entities select 200%");
|
||||
|
||||
ExpectError<InvalidQuantity>();
|
||||
ParseCommand("entities select hotdog");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ComponentTypeParser()
|
||||
{
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
ParseCommand("entities with MetaData");
|
||||
|
||||
ExpectError<UnknownComponentError>();
|
||||
ParseCommand("entities with Foodiddy");
|
||||
|
||||
ExpectError<UnknownComponentError>();
|
||||
ParseCommand("entities with MetaDataComponent");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Toolshed;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Toolshed;
|
||||
|
||||
// this is an EXACT DUPLICATE of LocTest from robust. If you modify this, modify that too.
|
||||
// Anyone who fails to heed these instructions consents to being scrungled to death.
|
||||
[TestFixture]
|
||||
public sealed class LocTest : ToolshedTest
|
||||
{
|
||||
@@ -12,8 +16,10 @@ public sealed class LocTest : ToolshedTest
|
||||
{
|
||||
await Server.WaitAssertion(() =>
|
||||
{
|
||||
IoCManager.Resolve<ILocalizationManager>().LoadCulture(new CultureInfo("en-US"));
|
||||
|
||||
Assert.That(InvokeCommand("cmd:list where { cmd:descloc loc:tryloc isnull }", out var res));
|
||||
Assert.That((IEnumerable<CommandSpec>)res, Is.Empty, "All commands must have localized descriptions.");
|
||||
Assert.That((IEnumerable<CommandSpec>)res!, Is.Empty, "All commands must have localized descriptions.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,12 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
|
||||
protected RobustIntegrationTest.ServerIntegrationInstance Server = default!;
|
||||
protected RobustIntegrationTest.ClientIntegrationInstance? Client = null;
|
||||
protected ToolshedManager Toolshed = default!;
|
||||
public ToolshedManager Toolshed { get; private set; } = default!;
|
||||
public ToolshedEnvironment Environment => Toolshed.DefaultEnvironment;
|
||||
|
||||
protected IAdminManager AdminManager = default!;
|
||||
|
||||
protected IInvocationContext? Context = null;
|
||||
protected IInvocationContext? InvocationContext = null;
|
||||
|
||||
[TearDown]
|
||||
public async Task TearDownInternal()
|
||||
@@ -44,11 +46,11 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
public virtual async Task Setup()
|
||||
{
|
||||
PairTracker = await PoolManager.GetServerClient(new PoolSettings {Connected = Connected});
|
||||
Server = PairTracker.Pair.Server;
|
||||
Server = PairTracker.Server;
|
||||
|
||||
if (Connected)
|
||||
{
|
||||
Client = PairTracker.Pair.Client;
|
||||
Client = PairTracker.Client;
|
||||
await Client.WaitIdleAsync();
|
||||
}
|
||||
|
||||
@@ -63,10 +65,17 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
return Toolshed.InvokeCommand(this, command, null, out result);
|
||||
}
|
||||
|
||||
protected T InvokeCommand<T>(string command)
|
||||
{
|
||||
InvokeCommand(command, out var res);
|
||||
Assert.That(res, Is.AssignableTo<T>());
|
||||
return (T) res!;
|
||||
}
|
||||
|
||||
protected void ParseCommand(string command, Type? inputType = null, Type? expectedType = null, bool once = false)
|
||||
{
|
||||
var parser = new ForwardParser(command, Toolshed);
|
||||
var success = CommandRun.TryParse(false, false, parser, inputType, expectedType, once, out _, out _, out var error);
|
||||
var parser = new ParserContext(command, Toolshed);
|
||||
var success = CommandRun.TryParse(false, parser, inputType, expectedType, once, out _, out _, out var error);
|
||||
|
||||
if (error is not null)
|
||||
ReportError(error);
|
||||
@@ -77,9 +86,9 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
|
||||
public bool CheckInvokable(CommandSpec command, out IConError? error)
|
||||
{
|
||||
if (Context is not null)
|
||||
if (InvocationContext is not null)
|
||||
{
|
||||
return Context.CheckInvokable(command, out error);
|
||||
return InvocationContext.CheckInvokable(command, out error);
|
||||
}
|
||||
|
||||
error = null;
|
||||
@@ -92,9 +101,9 @@ public abstract class ToolshedTest : IInvocationContext
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context is not null)
|
||||
if (InvocationContext is not null)
|
||||
{
|
||||
return Context.Session;
|
||||
return InvocationContext.Session;
|
||||
}
|
||||
|
||||
return InvocationSession;
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using Content.Server.Polymorph.Components;
|
||||
using Content.Server.Polymorph.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Polymorph;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Administration.Commands;
|
||||
|
||||
[AdminCommand(AdminFlags.Fun)]
|
||||
public sealed class PolymorphCommand : IConsoleCommand
|
||||
{
|
||||
public string Command => "polymorph";
|
||||
|
||||
public string Description => Loc.GetString("polymorph-command-description");
|
||||
|
||||
public string Help => Loc.GetString("polymorph-command-help-text");
|
||||
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EntityUid.TryParse(args[0], out var entityUid))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
var protoManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
if (!protoManager.TryIndex<PolymorphPrototype>(args[1], out var polyproto))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("polymorph-not-valid-prototype-error"));
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var polySystem = entityManager.EntitySysManager.GetEntitySystem<PolymorphSystem>();
|
||||
|
||||
entityManager.EnsureComponent<PolymorphableComponent>(entityUid);
|
||||
polySystem.PolymorphEntity(entityUid, polyproto);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +203,7 @@ namespace Content.Server.Administration.Managers
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var spec in _toolshed.AllCommands())
|
||||
foreach (var spec in _toolshed.DefaultEnvironment.AllCommands())
|
||||
{
|
||||
var (isAvail, flagsReq) = GetRequiredFlag(spec.Cmd);
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Content.Server.Administration.Systems
|
||||
var player = actor.PlayerSession;
|
||||
|
||||
// Delete verb
|
||||
if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.GetCommand("delete"), null), player, out _) ?? false)
|
||||
if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.DefaultEnvironment.GetCommand("delete"), null), player, out _) ?? false)
|
||||
{
|
||||
Verb verb = new()
|
||||
{
|
||||
@@ -236,7 +236,7 @@ namespace Content.Server.Administration.Systems
|
||||
}
|
||||
|
||||
// Rejuvenate verb
|
||||
if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.GetCommand("rejuvenate"), null), player, out _) ?? false)
|
||||
if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.DefaultEnvironment.GetCommand("rejuvenate"), null), player, out _) ?? false)
|
||||
{
|
||||
Verb verb = new()
|
||||
{
|
||||
@@ -250,7 +250,7 @@ namespace Content.Server.Administration.Systems
|
||||
}
|
||||
|
||||
// Control mob verb
|
||||
if (_groupController.CanCommand(player, "controlmob") &&
|
||||
if (_toolshed.ActivePermissionController?.CheckInvokable(new CommandSpec(_toolshed.DefaultEnvironment.GetCommand("mind"), "control"), player, out _) ?? false &&
|
||||
args.User != args.Target)
|
||||
{
|
||||
Verb verb = new()
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using Content.Server.Administration.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
|
||||
namespace Content.Server.Administration.Toolshed;
|
||||
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Admin)]
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Debug)]
|
||||
public sealed class RejuvenateCommand : ToolshedCommand
|
||||
{
|
||||
private RejuvenateSystem? _rejuvenate;
|
||||
|
||||
[CommandImplementation]
|
||||
public IEnumerable<EntityUid> Rejuvenate([PipedArgument] IEnumerable<EntityUid> input)
|
||||
{
|
||||
@@ -19,4 +21,19 @@ public sealed class RejuvenateCommand : ToolshedCommand
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandImplementation]
|
||||
public void Rejuvenate([CommandInvocationContext] IInvocationContext ctx)
|
||||
{
|
||||
_rejuvenate ??= GetSys<RejuvenateSystem>();
|
||||
if (ExecutingEntity(ctx) is not { } ent)
|
||||
{
|
||||
if (ctx.Session is {} session)
|
||||
ctx.ReportError(new SessionHasNoEntityError(session));
|
||||
else
|
||||
ctx.ReportError(new NotForServerConsoleError());
|
||||
}
|
||||
else
|
||||
_rejuvenate.PerformRejuvenate(ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.Server.Administration.Toolshed;
|
||||
|
||||
@@ -38,6 +41,38 @@ public sealed class SolutionCommand : ToolshedCommand
|
||||
{
|
||||
return input.Select(x => Get(ctx, x, name)).Where(x => x is not null).Cast<SolutionRef>();
|
||||
}
|
||||
|
||||
[CommandImplementation("adjreagent")]
|
||||
public SolutionRef AdjReagent(
|
||||
[CommandInvocationContext] IInvocationContext ctx,
|
||||
[PipedArgument] SolutionRef input,
|
||||
[CommandArgument] Prototype<ReagentPrototype> name,
|
||||
[CommandArgument] ValueRef<FixedPoint2> amountRef
|
||||
)
|
||||
{
|
||||
_solutionContainer ??= GetSys<SolutionContainerSystem>();
|
||||
|
||||
var amount = amountRef.Evaluate(ctx);
|
||||
if (amount > 0)
|
||||
{
|
||||
_solutionContainer.TryAddReagent(input.Owner, input.Solution, name.Value.ID, amount, out _);
|
||||
}
|
||||
else if (amount < 0)
|
||||
{
|
||||
_solutionContainer.TryRemoveReagent(input.Owner, input.Solution, name.Value.ID, -amount);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
[CommandImplementation("adjreagent")]
|
||||
public IEnumerable<SolutionRef> AdjReagent(
|
||||
[CommandInvocationContext] IInvocationContext ctx,
|
||||
[PipedArgument] IEnumerable<SolutionRef> input,
|
||||
[CommandArgument] Prototype<ReagentPrototype> name,
|
||||
[CommandArgument] ValueRef<FixedPoint2> amountRef
|
||||
)
|
||||
=> input.Select(x => AdjReagent(ctx, x, name, amountRef));
|
||||
}
|
||||
|
||||
public readonly record struct SolutionRef(EntityUid Owner, Solution Solution)
|
||||
|
||||
@@ -11,7 +11,6 @@ using Content.Server.GhostKick;
|
||||
using Content.Server.Info;
|
||||
using Content.Server.Maps;
|
||||
using Content.Server.MoMMI;
|
||||
using Content.Server.NewCon;
|
||||
using Content.Server.NodeContainer.NodeGroups;
|
||||
using Content.Server.Objectives;
|
||||
using Content.Server.Objectives.Interfaces;
|
||||
@@ -24,7 +23,6 @@ using Content.Server.Worldgen.Tools;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.Kitchen;
|
||||
using Robust.Shared.Toolshed;
|
||||
|
||||
namespace Content.Server.IoC
|
||||
{
|
||||
|
||||
62
Content.Server/Mind/Toolshed/MindCommand.cs
Normal file
62
Content.Server/Mind/Toolshed/MindCommand.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.Players;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
|
||||
namespace Content.Server.Mind.Toolshed;
|
||||
|
||||
/// <summary>
|
||||
/// Contains various mind-manipulation commands like getting minds, controlling mobs, etc.
|
||||
/// </summary>
|
||||
[ToolshedCommand]
|
||||
public sealed class MindCommand : ToolshedCommand
|
||||
{
|
||||
private MindSystem? _mind;
|
||||
|
||||
[CommandImplementation("get")]
|
||||
public Mind? Get([PipedArgument] IPlayerSession session)
|
||||
{
|
||||
return session.ContentData()?.Mind;
|
||||
}
|
||||
|
||||
[CommandImplementation("get")]
|
||||
public Mind? Get([PipedArgument] EntityUid ent)
|
||||
{
|
||||
if (!TryComp<MindContainerComponent>(ent, out var container))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return container.Mind;
|
||||
}
|
||||
|
||||
[CommandImplementation("control")]
|
||||
public EntityUid Control(
|
||||
[CommandInvocationContext] IInvocationContext ctx,
|
||||
[PipedArgument] EntityUid target,
|
||||
[CommandArgument] ValueRef<IPlayerSession> playerRef)
|
||||
{
|
||||
_mind ??= GetSys<MindSystem>();
|
||||
|
||||
var player = playerRef.Evaluate(ctx);
|
||||
if (player is null)
|
||||
{
|
||||
ctx.ReportError(new NotForServerConsoleError());
|
||||
return target;
|
||||
}
|
||||
|
||||
var mind = player.ContentData()?.Mind;
|
||||
|
||||
if (mind is null)
|
||||
{
|
||||
ctx.ReportError(new SessionHasNoEntityError(player));
|
||||
return target;
|
||||
}
|
||||
|
||||
_mind.TransferTo(mind, target);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -248,22 +248,22 @@ namespace Content.Server.Polymorph.Systems
|
||||
/// </summary>
|
||||
/// <param name="uid">The entityuid of the entity being reverted</param>
|
||||
/// <param name="component"></param>
|
||||
public void Revert(EntityUid uid, PolymorphedEntityComponent? component = null)
|
||||
public EntityUid? Revert(EntityUid uid, PolymorphedEntityComponent? component = null)
|
||||
{
|
||||
if (Deleted(uid))
|
||||
return;
|
||||
return null;
|
||||
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
return null;
|
||||
|
||||
var parent = component.Parent;
|
||||
if (Deleted(parent))
|
||||
return;
|
||||
return null;
|
||||
|
||||
if (!_proto.TryIndex(component.Prototype, out PolymorphPrototype? proto))
|
||||
{
|
||||
_sawmill.Error($"{nameof(PolymorphSystem)} encountered an improperly initialized polymorph component while reverting. Entity {ToPrettyString(uid)}. Prototype: {component.Prototype}");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var uidXform = Transform(uid);
|
||||
@@ -317,6 +317,8 @@ namespace Content.Server.Polymorph.Systems
|
||||
("child", Identity.Entity(parent, EntityManager))),
|
||||
parent);
|
||||
QueueDel(uid);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
36
Content.Server/Polymorph/Toolshed/PolymorphCommand.cs
Normal file
36
Content.Server/Polymorph/Toolshed/PolymorphCommand.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Polymorph.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Polymorph;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.Server.Polymorph.Toolshed;
|
||||
|
||||
/// <summary>
|
||||
/// Polymorphs the given entity(s) into the target morph.
|
||||
/// </summary>
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Fun)]
|
||||
public sealed class PolymorphCommand : ToolshedCommand
|
||||
{
|
||||
private PolymorphSystem? _system;
|
||||
|
||||
[CommandImplementation]
|
||||
public EntityUid? Polymorph(
|
||||
[PipedArgument] EntityUid input,
|
||||
[CommandArgument] Prototype<PolymorphPrototype> prototype
|
||||
)
|
||||
{
|
||||
_system ??= GetSys<PolymorphSystem>();
|
||||
|
||||
return _system.PolymorphEntity(input, prototype.Value);
|
||||
}
|
||||
|
||||
[CommandImplementation]
|
||||
public IEnumerable<EntityUid> Polymorph(
|
||||
[PipedArgument] IEnumerable<EntityUid> input,
|
||||
[CommandArgument] Prototype<PolymorphPrototype> prototype
|
||||
)
|
||||
=> input.Select(x => Polymorph(x, prototype)).Where(x => x is not null).Select(x => (EntityUid)x!);
|
||||
}
|
||||
30
Content.Server/Polymorph/Toolshed/UnpolymorphCommand.cs
Normal file
30
Content.Server/Polymorph/Toolshed/UnpolymorphCommand.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Polymorph.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Polymorph;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.Server.Polymorph.Toolshed;
|
||||
|
||||
/// <summary>
|
||||
/// Undoes a polymorph, reverting the target to it's original form.
|
||||
/// </summary>
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Fun)]
|
||||
public sealed class UnpolymorphCommand : ToolshedCommand
|
||||
{
|
||||
private PolymorphSystem? _system;
|
||||
|
||||
[CommandImplementation]
|
||||
public EntityUid? Unpolymorph([PipedArgument] EntityUid input)
|
||||
{
|
||||
_system ??= GetSys<PolymorphSystem>();
|
||||
|
||||
return _system.Revert(input);
|
||||
}
|
||||
|
||||
[CommandImplementation]
|
||||
public IEnumerable<EntityUid> Unpolymorph([PipedArgument] IEnumerable<EntityUid> input)
|
||||
=> input.Select(Unpolymorph).Where(x => x is not null).Select(x => (EntityUid)x!);
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Robust.Server.Player;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
|
||||
namespace Content.Server.NewCon.Commands.AdminDebug;
|
||||
namespace Content.Server.Toolshed.Commands.AdminDebug;
|
||||
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Debug)]
|
||||
public sealed class ACmdCommand : ToolshedCommand
|
||||
@@ -6,7 +6,7 @@ using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
|
||||
namespace Content.Server.NewCon.Commands.Verbs;
|
||||
namespace Content.Server.Toolshed.Commands.Verbs;
|
||||
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Admin)]
|
||||
public sealed class RunVerbAsCommand : ToolshedCommand
|
||||
@@ -8,7 +8,7 @@ using Robust.Server.Player;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
|
||||
namespace Content.Server.NewCon.Commands;
|
||||
namespace Content.Server.Toolshed.Commands;
|
||||
|
||||
[ToolshedCommand, AdminCommand(AdminFlags.Admin)]
|
||||
public sealed class VisualizeCommand : ToolshedCommand
|
||||
@@ -58,5 +58,15 @@ command-description-tag-addmany =
|
||||
Adds a list of tags to the given entities.
|
||||
command-description-tag-rmmany =
|
||||
Removes a list of tags from the given entities.
|
||||
command-description-polymorph =
|
||||
Polymorphs the input entity with the given prototype.
|
||||
command-description-unpolymorph =
|
||||
Reverts a polymorph.
|
||||
command-description-solution-get =
|
||||
Returns a solution stored in an entity's solution container.
|
||||
Grabs the given solution off the given entity.
|
||||
command-description-solution-adjreagent =
|
||||
Adjusts the given reagent on the given solution.
|
||||
command-description-mind-get =
|
||||
Grabs the mind from the entity, if any.
|
||||
command-description-mind-control =
|
||||
Assumes control of an entity with the given player.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- Flags: QUERY
|
||||
- Flags: QUERY
|
||||
Commands:
|
||||
- entities
|
||||
- nearby
|
||||
@@ -7,6 +7,19 @@
|
||||
- player
|
||||
- splat
|
||||
- emplace
|
||||
- bin
|
||||
- extremes
|
||||
- reduce
|
||||
- sortby
|
||||
- sort
|
||||
- sortdownby
|
||||
- sortdown
|
||||
- sortmapby
|
||||
- sortmapdownby
|
||||
- iota
|
||||
- rep
|
||||
- to
|
||||
- iterate
|
||||
|
||||
- Flags: DEBUG
|
||||
Commands:
|
||||
@@ -23,7 +36,14 @@
|
||||
- types
|
||||
- ecscomp
|
||||
- actor
|
||||
- spawn
|
||||
- mappos
|
||||
- pos
|
||||
- tp
|
||||
- allcomps
|
||||
- replace
|
||||
- entitysystemupdateorder
|
||||
- mind
|
||||
|
||||
- Flags: HOST
|
||||
Commands:
|
||||
@@ -69,3 +89,95 @@
|
||||
- '>='
|
||||
- '=='
|
||||
- '!='
|
||||
- f
|
||||
- i
|
||||
- s
|
||||
- b
|
||||
- '+/'
|
||||
- '-/'
|
||||
- '*/'
|
||||
- '//'
|
||||
- join
|
||||
- append
|
||||
- '?'
|
||||
- 'or?'
|
||||
- '??'
|
||||
- rng
|
||||
- 'sum'
|
||||
- take
|
||||
- curtick
|
||||
- curtime
|
||||
- realtime
|
||||
- servertime
|
||||
- more
|
||||
- '%'
|
||||
- '%/'
|
||||
- '&~'
|
||||
- '|~'
|
||||
- '^~'
|
||||
- '~'
|
||||
- 'abs'
|
||||
- 'average'
|
||||
- 'bibytecount'
|
||||
- 'shortestbitlength'
|
||||
- 'countleadzeros'
|
||||
- 'counttrailingzeros'
|
||||
- 'fpi'
|
||||
- 'fe'
|
||||
- 'ftau'
|
||||
- 'fepsilon'
|
||||
- dpi
|
||||
- de
|
||||
- dtau
|
||||
- depsilon
|
||||
- hpi
|
||||
- he
|
||||
- htau
|
||||
- hepsilon
|
||||
- floor
|
||||
- ceil
|
||||
- round
|
||||
- trunc
|
||||
- round2frac
|
||||
- exponentbytecount
|
||||
- significandbytecount
|
||||
- significandbitcount
|
||||
- exponentshortestbitcount
|
||||
- stepnext
|
||||
- stepprev
|
||||
- checkedto
|
||||
- saturactedto
|
||||
- truncto
|
||||
- iscanonical
|
||||
- iscomplex
|
||||
- iseven
|
||||
- isodd
|
||||
- isfinite
|
||||
- isimaginary
|
||||
- isinfinite
|
||||
- isinteger
|
||||
- isnan
|
||||
- isnegative
|
||||
- ispositive
|
||||
- isreal
|
||||
- issubnormal
|
||||
- iszero
|
||||
- pow
|
||||
- sqrt
|
||||
- cbrt
|
||||
- root
|
||||
- hypot
|
||||
- sin
|
||||
- sinpi
|
||||
- asin
|
||||
- asinpi
|
||||
- cos
|
||||
- cospi
|
||||
- acos
|
||||
- acospi
|
||||
- tan
|
||||
- tanpi
|
||||
- atan
|
||||
- atanpi
|
||||
- pick
|
||||
- tee
|
||||
|
||||
@@ -645,6 +645,7 @@ public sealed class $CLASS$ : Shared$CLASS$ {
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ruinable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=saltern/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=sandboxing/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=satisfier/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Shrimple/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=singulo/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -694,6 +695,7 @@ public sealed class $CLASS$ : Shared$CLASS$ {
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xeno/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xenoarchaeology/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=xform/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xnor/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=yamls/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Zumos/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=652E0DBD3559BD4EA35305A83762B0C8/@KeyIndexDefined">True</s:Boolean>
|
||||
|
||||
Reference in New Issue
Block a user