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

Admeme Language Commands (Attempt 2) #565

Merged
Show file tree
Hide file tree
Changes from all 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
75 changes: 75 additions & 0 deletions Content.Server/Language/Commands/AdminLanguageCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Language;
using Content.Shared.Language.Components;
using Content.Shared.Language.Systems;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Syntax;
using Robust.Shared.Toolshed.TypeParsers;

namespace Content.Server.Language.Commands;

[ToolshedCommand(Name = "language"), AdminCommand(AdminFlags.Admin)]
public sealed class AdminLanguageCommand : ToolshedCommand
{
private LanguageSystem? _languagesField;
private LanguageSystem Languages => _languagesField ??= GetSys<LanguageSystem>();

[CommandImplementation("add")]
public EntityUid AddLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref,
[CommandArgument] bool canSpeak = true,
[CommandArgument] bool canUnderstand = true
)
{
var language = @ref.Evaluate(ctx)!;
Mnemotechnician marked this conversation as resolved.
Show resolved Hide resolved

if (language == SharedLanguageSystem.UniversalPrototype)
{
EnsureComp<UniversalLanguageSpeakerComponent>(input);
Languages.UpdateEntityLanguages(input);
}
else
{
EnsureComp<LanguageSpeakerComponent>(input);
Languages.AddLanguage(input, language, canSpeak, canUnderstand);
}

return input;
}

[CommandImplementation("rm")]
public EntityUid RemoveLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref,
[CommandArgument] bool removeSpeak = true,
[CommandArgument] bool removeUnderstand = true
)
{
var language = @ref.Evaluate(ctx)!;
if (language == SharedLanguageSystem.UniversalPrototype && HasComp<UniversalLanguageSpeakerComponent>(input))
{
RemComp<UniversalLanguageSpeakerComponent>(input);
EnsureComp<LanguageSpeakerComponent>(input);
}
// We execute this branch even in case of universal so that it gets removed if it was added manually to the LanguageKnowledge
Languages.RemoveLanguage(input, language, removeSpeak, removeUnderstand);

return input;
}

[CommandImplementation("lsspoken")]
public IEnumerable<string> ListSpoken([PipedArgument] EntityUid input)
{
return Languages.GetSpokenLanguages(input);
}

[CommandImplementation("lsunderstood")]
public IEnumerable<string> ListUnderstood([PipedArgument] EntityUid input)
{
return Languages.GetUnderstoodLanguages(input);
}
}
155 changes: 155 additions & 0 deletions Content.Server/Language/Commands/AdminTranslatorCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Language;
using Content.Shared.Language.Components;
using Content.Shared.Language.Components.Translators;
using Content.Shared.Language.Systems;
using Robust.Server.Containers;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Syntax;
using Robust.Shared.Toolshed.TypeParsers;

namespace Content.Server.Language.Commands;

[ToolshedCommand(Name = "translator"), AdminCommand(AdminFlags.Admin)]
public sealed class AdminTranslatorCommand : ToolshedCommand
{
private LanguageSystem? _languagesField;
private ContainerSystem? _containersField;

private ContainerSystem Containers => _containersField ??= GetSys<ContainerSystem>();
private LanguageSystem Languages => _languagesField ??= GetSys<LanguageSystem>();

[CommandImplementation("addlang")]
public EntityUid AddLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref,
[CommandArgument] bool addSpeak = true,
[CommandArgument] bool addUnderstand = true
)
{
var language = @ref.Evaluate(ctx)!;
// noob trap - needs a universallanguagespeakercomponent
if (language == SharedLanguageSystem.UniversalPrototype)
throw new ArgumentException(Loc.GetString("command-language-error-this-will-not-work"));

if (!TryGetTranslatorComp(input, out var translator))
throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input)));

if (addSpeak && !translator.SpokenLanguages.Contains(language))
translator.SpokenLanguages.Add(language);
if (addUnderstand && !translator.UnderstoodLanguages.Contains(language))
translator.UnderstoodLanguages.Add(language);

UpdateTranslatorHolder(input);

return input;
}

[CommandImplementation("rmlang")]
public EntityUid RemoveLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref,
[CommandArgument] bool removeSpeak = true,
[CommandArgument] bool removeUnderstand = true
)
{
var language = @ref.Evaluate(ctx)!;
if (!TryGetTranslatorComp(input, out var translator))
throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input)));

if (removeSpeak)
translator.SpokenLanguages.Remove(language);
if (removeUnderstand)
translator.UnderstoodLanguages.Remove(language);

UpdateTranslatorHolder(input);

return input;
}

[CommandImplementation("addrequired")]
public EntityUid AddRequiredLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref)
{
var language = @ref.Evaluate(ctx)!;
if (!TryGetTranslatorComp(input, out var translator))
throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input)));

if (!translator.RequiredLanguages.Contains(language))
{
translator.RequiredLanguages.Add(language);
UpdateTranslatorHolder(input);
}

return input;
}

[CommandImplementation("rmrequired")]
public EntityUid RemoveRequiredLanguage(
[CommandInvocationContext] IInvocationContext ctx,
[PipedArgument] EntityUid input,
[CommandArgument] ValueRef<string, Prototype<LanguagePrototype>> @ref)
{
var language = @ref.Evaluate(ctx)!;
if (!TryGetTranslatorComp(input, out var translator))
throw new ArgumentException(Loc.GetString("command-language-error-not-a-translator", ("entity", input)));

if (translator.RequiredLanguages.Remove(language))
UpdateTranslatorHolder(input);

return input;
}

[CommandImplementation("lsspoken")]
public IEnumerable<string> ListSpoken([PipedArgument] EntityUid input)
{
if (!TryGetTranslatorComp(input, out var translator))
return [];
return translator.SpokenLanguages;
}

[CommandImplementation("lsunderstood")]
public IEnumerable<string> ListUnderstood([PipedArgument] EntityUid input)
{
if (!TryGetTranslatorComp(input, out var translator))
return [];
return translator.UnderstoodLanguages;
}

[CommandImplementation("lsrequired")]
public IEnumerable<string> ListRequired([PipedArgument] EntityUid input)
{
if (!TryGetTranslatorComp(input, out var translator))
return [];
return translator.RequiredLanguages;
}

private bool TryGetTranslatorComp(EntityUid uid, [NotNullWhen(true)] out BaseTranslatorComponent? translator)
{
if (TryComp<HandheldTranslatorComponent>(uid, out var handheld))
translator = handheld;
else if (TryComp<TranslatorImplantComponent>(uid, out var implant))
translator = implant;
else if (TryComp<IntrinsicTranslatorComponent>(uid, out var intrinsic))
translator = intrinsic;
else
translator = null;

return translator != null;
}

private void UpdateTranslatorHolder(EntityUid translator)
{
if (!Containers.TryGetContainingContainer(translator, out var cont)
|| cont.Owner is not { Valid: true } holder)
return;

Languages.UpdateEntityLanguages(holder);
}
}
18 changes: 18 additions & 0 deletions Resources/Locale/en-US/language/commands.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,21 @@ command-language-entry = {$id}. {$language} - {$name}

command-language-invalid-number = The language number must be between 0 and {$total}. Alternatively, use the language name.
command-language-invalid-language = The language {$id} does not exist or you cannot speak it.

# toolshed

command-description-language-add = Adds a new language to the piped entity. The two last arguments indicate whether it should be spoken/understood. Example: 'self language:add "Canilunzt" true true'
command-description-language-rm = Removes a language from the piped entity. Works similarly to language:add. Example: 'self language:rm "GalacticCommon" true true'.
command-description-language-lsspoken = Lists all languages the entity can speak. Example: 'self language:lsspoken'
command-description-language-lsunderstood = Lists all languages the entity can understand. Example: 'self language:lssunderstood'

command-description-translator-addlang = Adds a new target language to the piped translator entity. See language:add for details.
command-description-translator-rmlang = Removes a target language from the piped translator entity. See language:rm for details.
command-description-translator-addrequired = Adds a new required language to the piped translator entity. Example: 'ent 1234 translator:addrequired "GalacticCommon"'
command-description-translator-rmrequired = Removes a required language from the piped translator entity. Example: 'ent 1234 translator:rmrequired "GalacticCommon"'
command-description-translator-lsspoken = Lists all spoken languages for the piped translator entity. Example: 'ent 1234 translator:lsspoken'
command-description-translator-lsunderstood = Lists all understood languages for the piped translator entity. Example: 'ent 1234 translator:lssunderstood'
command-description-translator-lsrequired = Lists all required languages for the piped translator entity. Example: 'ent 1234 translator:lsrequired'

command-language-error-this-will-not-work = This will not work.
command-language-error-not-a-translator = Entity {$entity} is not a translator.
Loading