Anton Tarasenko
2 years ago
2 changed files with 194 additions and 0 deletions
@ -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 { |
||||||
|
} |
Loading…
Reference in new issue