Browse Source

Add `sideffects` command

pull/13/head
Anton Tarasenko 2 years ago
parent
commit
9187598252
  1. 193
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandSideEffects.uc
  2. 1
      sources/BaseAPI/API/Commands/Commands_Feature.uc

193
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandSideEffects.uc

@ -0,0 +1,193 @@
/**
* 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.Name(P("sideeffects"));
builder.Group(P("core"));
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) {
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 {
}

1
sources/BaseAPI/API/Commands/Commands_Feature.uc

@ -110,6 +110,7 @@ protected function OnEnabled() {
RegisterCommand(class'ACommandHelp'); RegisterCommand(class'ACommandHelp');
RegisterCommand(class'ACommandNotify'); RegisterCommand(class'ACommandNotify');
RegisterCommand(class'ACommandVote'); RegisterCommand(class'ACommandVote');
RegisterCommand(class'ACommandSideEffects');
if (_.environment.IsDebugging()) { if (_.environment.IsDebugging()) {
RegisterCommand(class'ACommandFakers'); RegisterCommand(class'ACommandFakers');
} }

Loading…
Cancel
Save