/** * Command for changing nickname of the player. * Copyright 2021-2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * * Acedia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * (at your option) any later version. * * Acedia is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ class ACommandNick extends Command; var private bool foundErrors; var private MutableText newName; var private ACommandNick_Announcer announcer; protected function Finalizer() { _.memory.Free(announcer); _.memory.Free(newName); newName = none; super.Finalizer(); } protected function BuildData(CommandDataBuilder builder) { builder.Group(P("gameplay")); builder.Summary(P("Changes nickname.")); builder.RequireTarget(); builder.ParamRemainder(P("nick")); builder.Describe(P("Changes nickname of targeted players to .")); builder.Option(P("plain")); builder.Describe(P("Take nickname exactly as typed, without attempting to" @ "treat it like formatted string.")); builder.Option(P("fix"), P("f")); builder.Describe(P("In case of a nickname with erroroneous formatting or" @ "invalid default color (specified with `--color`)," @ "try to fix/ignore it instead of simply rejecting it.")); builder.Option(P("color")); builder.Describe(P("Color to use for the nickname. In case nickname is already" @ "colored, this flag will only affects uncolored parts.")); builder.ParamText(P("default_color")); announcer = ACommandNick_Announcer( _.memory.Allocate(class'ACommandNick_Announcer')); } protected function Executed( CallData arguments, EPlayer callerPlayer, CommandPermissions permissions ) { local Text givenName; local array errors; givenName = arguments.parameters.GetText(P("nick")); // `newName`'s reference persists between different command calls and // only deallocated when we need this variable for the next execution. // "Leaking" a single `Text` like that is insignificant. _.memory.Free(newName); newName = _.text.Empty(); if (arguments.options.HasKey(P("plain"))) { newName = givenName.MutableCopy(); } else { errors = class'FormattingStringParser'.static .ParseFormatted(givenName, newName, true); } foundErrors = false; if (arguments.options.HasKey(P("color"))) { foundErrors = !TryChangeDefaultColor( arguments.options.GetTextBy(P("/color/default_color"))); } foundErrors = foundErrors || (errors.length > 0); class'FormattingReportTool'.static.Report(callerConsole, errors); class'FormattingReportTool'.static.FreeErrors(errors); } protected function ExecutedFor( EPlayer target, CallData arguments, EPlayer instigator, CommandPermissions permissions ) { local Text alteredVersion; if (!foundErrors || arguments.options.HasKey(P("fix"))) { announcer.Setup(target, instigator, othersConsole); target.SetName(newName); alteredVersion = target.GetName(); if (newName.Compare(alteredVersion, SCASE_SENSITIVE, SFORM_SENSITIVE)) { announcer.AnnounceChangedNickname(newName); } else { announcer.AnnounceChangedAlteredNickname(newName, alteredVersion); } _.memory.Free(alteredVersion); } } protected function bool TryChangeDefaultColor(BaseText specifiedColor) { local Color defaultColor; if (newName == none) return false; if (specifiedColor == none) return false; if (_.color.Parse(specifiedColor, defaultColor)) { newName.ChangeDefaultColor(defaultColor); return true; } callerConsole .Write(F("Specified {$TextFailure invalid} color: ")) .WriteLine(specifiedColor); return false; } defaultproperties { preferredName = "nick" }