197 lines
7.4 KiB
Ucode
197 lines
7.4 KiB
Ucode
/**
|
|
* Author: dkanus
|
|
* Home repo: https://www.insultplayers.ru/git/AcediaFramework/AcediaCore
|
|
* License: GPL
|
|
* Copyright 2023 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
class ACommandSideEffects extends Command;
|
|
|
|
// Maps `UserID` to `ArrayList` with side effects listed for that player last time
|
|
var private HashTable displayedLists;
|
|
|
|
protected function Constructor() {
|
|
super.Constructor();
|
|
displayedLists = _.collections.EmptyHashTable();
|
|
}
|
|
|
|
protected function Finalizer() {
|
|
super.Finalizer();
|
|
_.memory.Free(displayedLists);
|
|
displayedLists = none;
|
|
}
|
|
|
|
protected function BuildData(CommandDataBuilder builder) {
|
|
builder.Group(P("debug"));
|
|
builder.Summary(P("Displays information about current side effects."));
|
|
builder.Describe(P("This command allows to display current side effects, optionally filtering"
|
|
@ "them by specified package names."));
|
|
builder.OptionalParams();
|
|
builder.ParamTextList(P("package_names"));
|
|
|
|
builder.SubCommand(P("show"));
|
|
builder.Describe(P("This sub-command is only usable after side effects have been shown"
|
|
@ "at least once. It takes an index from the last displayed list and displays a verbose"
|
|
@ "information about it."));
|
|
builder.ParamInteger(P("side_effect_number"));
|
|
|
|
builder.Option(P("verbose"));
|
|
builder.Describe(P("Display verbose information about each side effect."));
|
|
}
|
|
|
|
protected function Executed(
|
|
CallData arguments,
|
|
EPlayer instigator,
|
|
CommandPermissions permissions
|
|
) {
|
|
local UserID playerID;
|
|
local array<SideEffect> relevantSideEffects;
|
|
local ArrayList packagesList, storedSideEffectsList;
|
|
|
|
playerID = instigator.GetUserID();
|
|
if (arguments.subCommandName.IsEmpty()) {
|
|
relevantSideEffects = _.sideEffects.GetAll();
|
|
packagesList = arguments.parameters.GetArrayList(P("package_names"));
|
|
FilterSideEffects(/*out*/ relevantSideEffects, packagesList);
|
|
_.memory.Free(packagesList);
|
|
DisplaySideEffects(relevantSideEffects, arguments.options.HasKey(P("verbose")));
|
|
// Store new side effect list
|
|
storedSideEffectsList = _.collections.NewArrayList(relevantSideEffects);
|
|
displayedLists.SetItem(playerID, storedSideEffectsList);
|
|
_.memory.FreeMany(relevantSideEffects);
|
|
_.memory.Free(storedSideEffectsList);
|
|
} else {
|
|
ShowInfoFor(playerID, arguments.parameters.GetInt(P("side_effect_number")));
|
|
}
|
|
_.memory.Free(playerID);
|
|
}
|
|
|
|
private function FilterSideEffects(out array<SideEffect> sideEffects, ArrayList allowedPackages) {
|
|
local int i, j;
|
|
local int packagesLength;
|
|
local bool matchedPackage;
|
|
local Text nextSideEffectPackage, nextAllowedPackage;
|
|
|
|
if (allowedPackages == none) return;
|
|
if (allowedPackages.GetLength() <= 0) return;
|
|
|
|
packagesLength = allowedPackages.GetLength();
|
|
while (i < sideEffects.length) {
|
|
nextSideEffectPackage = sideEffects[i].GetPackage();
|
|
matchedPackage = false;
|
|
for (j = 0; j < packagesLength; j += 1) {
|
|
nextAllowedPackage = allowedPackages.GetText(j);
|
|
if (nextAllowedPackage.Compare(nextSideEffectPackage, SCASE_INSENSITIVE)) {
|
|
matchedPackage = true;
|
|
_.memory.Free(nextAllowedPackage);
|
|
break;
|
|
}
|
|
_.memory.Free(nextAllowedPackage);
|
|
}
|
|
if (!matchedPackage) {
|
|
sideEffects.Remove(i, 1);
|
|
} else {
|
|
i += 1;
|
|
}
|
|
_.memory.Free(nextSideEffectPackage);
|
|
}
|
|
}
|
|
|
|
private function DisplaySideEffects(array<SideEffect> toDisplay, bool verbose) {
|
|
local int i;
|
|
local MutableText nextPrefix;
|
|
|
|
if (toDisplay.length <= 0) {
|
|
callerConsole.Write(F("List of side effects is {$TextNeutral empty}."));
|
|
}
|
|
for (i = 0; i < toDisplay.length; i += 1) {
|
|
nextPrefix = _.text.FromIntM(i + 1);
|
|
nextPrefix.Append(P("."));
|
|
DisplaySideEffect(toDisplay[i], nextPrefix, verbose);
|
|
_.memory.Free(nextPrefix);
|
|
}
|
|
}
|
|
|
|
private function DisplaySideEffect(SideEffect toDisplay, BaseText prefix, bool verbose) {
|
|
local Text effectName, effectDescription, effectPackage, effectSource, effectStatus;
|
|
|
|
if (toDisplay == none) {
|
|
return;
|
|
}
|
|
if (prefix != none) {
|
|
callerConsole.Write(prefix);
|
|
callerConsole.Write(P(" "));
|
|
}
|
|
effectName = toDisplay.GetName();
|
|
effectPackage = toDisplay.GetPackage();
|
|
effectSource = toDisplay.GetSource();
|
|
effectStatus = toDisplay.GetStatus();
|
|
callerConsole.UseColor(_.color.TextEmphasis);
|
|
callerConsole.Write(P("["));
|
|
callerConsole.Write(effectPackage);
|
|
callerConsole.Write(P(" \\ "));
|
|
callerConsole.Write(effectSource);
|
|
callerConsole.Write(P("] "));
|
|
callerConsole.ResetColor();
|
|
callerConsole.Write(effectName);
|
|
callerConsole.Write(P(" {"));
|
|
callerConsole.Write(effectStatus);
|
|
callerConsole.WriteLine(P("}"));
|
|
if (verbose) {
|
|
effectDescription = toDisplay.GetDescription();
|
|
callerConsole.WriteBlock(effectDescription);
|
|
}
|
|
_.memory.Free5(effectName, effectDescription, effectPackage, effectSource, effectStatus);
|
|
}
|
|
|
|
private function ShowInfoFor(UserID playerID, int sideEffectIndex) {
|
|
local SideEffect toDisplay;
|
|
local ArrayList sideEffectList;
|
|
|
|
if (playerID == none) {
|
|
return;
|
|
}
|
|
if (sideEffectIndex <= 0) {
|
|
callerConsole.WriteLine(F("Specified side effect index {$TextNegative isn't positive}!"));
|
|
return;
|
|
}
|
|
sideEffectList = displayedLists.GetArrayList(playerID);
|
|
if (sideEffectList == none) {
|
|
callerConsole.WriteLine(F("{$TextNegative Cannot display} side effect by index without"
|
|
@ "first listing them. Call {$TextEmphasis sideeffects} command without"
|
|
@ "{$TextEmphasis show} subcommand first."));
|
|
return;
|
|
}
|
|
if (sideEffectIndex > sideEffectList.GetLength()) {
|
|
callerConsole.WriteLine(F("Specified side effect index is {$TextNegative out of bounds}."));
|
|
_.memory.Free(sideEffectList);
|
|
return;
|
|
}
|
|
// Above we checked that `sideEffectIndex` lies within `[0; sideEffectList.GetLength()]` segment
|
|
// This means that `sideEffectIndex - 1` points at non-`none` value
|
|
toDisplay = SideEffect(sideEffectList.GetItem(sideEffectIndex - 1));
|
|
if (!_.sideEffects.IsRegistered(toDisplay)) {
|
|
callerConsole.UseColorOnce(_.color.TextWarning);
|
|
callerConsole.WriteLine(P("Selected side effect is no longer active!"));
|
|
}
|
|
DisplaySideEffect(toDisplay, none, true);
|
|
_.memory.Free2(toDisplay, sideEffectList);
|
|
}
|
|
|
|
defaultproperties {
|
|
preferredName = "sideeffects"
|
|
} |