Administration tools: commands and non gameplay server configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

317 lines
12 KiB

/**
* Command for managing (displaying + adding and removing to/items from it)
* player's inventory.
* 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 <https://www.gnu.org/licenses/>.
*/
class ACommandInventory extends Command;
// Load user-specified options into the boolean flags during'
// `ExecutedFor()` and use them in auxiliary methods.
// This is might be a questionable way of doing things, but it allows to
// avoid passing flags in copious amounts to auxiliary methods and
// does not overcomplicate logic
var private bool flagAll, flagForce, flagAmmo, flagKeep;
var private bool flagEquip, flagHidden, flagGroups;
var protected const int TINVENTORY, TADD, TREMOVE, TITEMS, TEQUIP, TALL, TKEEP;
var protected const int THIDDEN, TFORCE, TAMMO, TLIST, TLISTS_NAMES, TSET;
var protected const int TLISTS_SKIPPED;
protected function BuildData(CommandDataBuilder builder)
{
builder.Name(T(TINVENTORY)).Group(P("gameplay"))
.Summary(P("Manages player's inventory."))
.Describe(P("Command for displaying and editing players' inventories."
@ "If called without specifying subcommand - simply displays"
@ "targeted player's inventory."));
builder.RequireTarget();
builder.SubCommand(T(TADD))
.OptionalParams()
.ParamTextList(T(TITEMS))
.Describe(P("This command adds items (based on listed templates) to"
@ "the targeted player's inventory."
@ "Instead of templates item aliases can be specified."));
builder.SubCommand(T(TREMOVE))
.OptionalParams()
.ParamTextList(T(TITEMS))
.Describe(P("This command removes items (based on listed templates)"
@ "from the targeted player's inventory."
@ "Instead of templates item aliases can be specified."));
builder.SubCommand(T(TSET))
.OptionalParams()
.ParamTextList(T(TITEMS))
.Describe(P("This command acts like combination of two commands -"
@ "first removing all items from the player's current inventory and"
@ "then adding specified items. first clears inventory"
@ "(based on specified options) and then "));
builder.Option(T(TEQUIP))
.Describe(F("Affect items currently equipped by the targeted player."
@ "Releveant for a {$TextEmphasis remove} subcommand."));
builder.Option(T(TLIST))
.Describe(P("Include weapons from specified group into the list."))
.ParamTextList(T(TLISTS_NAMES));
builder.Option(T(TAMMO))
.Describe(P("When adding weapons - signals that their"
@ "ammo / charge / whatever has to be filled after addition."));
builder.Option(T(TKEEP))
.Describe(F("Removing items by default means simply destroying them."
@ "This flag makes command to try and keep them in some form."
@ "Success for all items is not guaranteed."));
builder.Option(T(THIDDEN))
.Describe(F("Some of the items in the inventory are"
@ "{$TextEmphasis hidden} and are not supposed to be seem by"
@ "the player. To avoid weird behavior, {$TextEmphasis inventory}"
@ "command by default ignores them when affecting groups of items"
@ "(like when removing all items) unless they're directly"
@ "specified. This flag tells it to also affect hidden items."));
builder.Option(T(TFORCE))
.Describe(P("Sometimes adding and removing items is impossible due to"
@ "the limitations imposed by the game. This option allows to"
@ "ignore some of those limitation."));
builder.Option(T(TALL), P("A"))
.Describe(F("This flag is used when removing items. If user has"
@ "specified any weapon templates - it means"
@ "\"remove all items with these tempaltes from inventory\","
@ "but if user has not specified any templated it simply means"
@ "\"remove all items from the inventory\"."));
}
protected function ExecutedFor(
EPlayer target,
CallData arguments,
EPlayer instigator)
{
local InventoryTool tool;
local ArrayList itemsArray, specifiedLists;
LoadUserFlags(arguments.options);
tool = class'InventoryTool'.static.CreateFor(target);
if (tool == none) {
return;
}
itemsArray = arguments.parameters.GetArrayList(T(TITEMS));
specifiedLists = arguments.options.GetArrayListBy(P("/list/lists names"));
if (arguments.subCommandName.IsEmpty()) {
tool.ReportInventory(callerConsole, flagHidden);
}
else if (arguments.subCommandName.Compare(T(TADD))) {
SubCommandAdd(tool, itemsArray, specifiedLists);
}
else if (arguments.subCommandName.Compare(T(TREMOVE))) {
SubCommandRemove(tool, itemsArray, specifiedLists);
}
else if (arguments.subCommandName.Compare(T(TSET)))
{
tool.RemoveAllItems(flagKeep, flagForce, flagHidden);
SubCommandAdd(tool, itemsArray, specifiedLists);
}
tool.SetupReportInstigator(instigator);
if (!instigator.SameAs(target)) {
tool.ReportChanges(instigator, targetConsole, IRT_Target);
}
tool.ReportChanges(instigator, callerConsole, IRT_Instigator);
tool.ReportChanges(instigator, othersConsole, IRT_Others);
_.memory.Free(tool);
_.memory.Free(itemsArray);
_.memory.Free(specifiedLists);
}
protected function SubCommandAdd(
InventoryTool tool,
ArrayList itemsArray,
ArrayList specifiedLists)
{
local int i;
local int itemsAmount;
local Text nextItem;
local array<Text> itemsFromLists;
if (tool == none) {
return;
}
if (itemsArray != none) {
itemsAmount = itemsArray.GetLength();
}
// Add items user listed manually
// Use `itemsAmount` because `itemsArray` can be `none`
for (i = 0; i < itemsAmount; i += 1)
{
nextItem = itemsArray.GetText(i);
tool.AddItem(nextItem, flagForce, flagAmmo);
_.memory.Free(nextItem);
}
// Add items from specified lists
itemsFromLists = LoadAllItemsLists(specifiedLists);
for (i = 0; i < itemsFromLists.length; i += 1) {
tool.AddItem(itemsFromLists[i], flagForce, flagAmmo);
}
_.memory.FreeMany(itemsFromLists);
}
protected function SubCommandRemove(
InventoryTool tool,
ArrayList itemsArray,
ArrayList specifiedLists)
{
local int i;
local int itemsAmount;
local Text nextItem;
local array<Text> itemsFromLists;
if (tool == none) {
return;
}
if (itemsArray != none) {
itemsAmount = itemsArray.GetLength();
}
// Remove due to "--all" option
if (flagAll && itemsAmount <= 0)
{
tool.RemoveAllItems(flagKeep, flagForce, flagHidden);
return;
}
// Remove due to "--equip" option
if (flagEquip) {
tool.RemoveEquippedItems(flagKeep, flagForce, flagHidden);
}
// Remove items user listed manually
// Use `itemsAmount` because `itemsArray` can be `none`
for (i = 0; i < itemsAmount; i += 1)
{
nextItem = itemsArray.GetText(i);
tool.RemoveItem(nextItem, flagKeep, flagForce, flagAll);
_.memory.Free(nextItem);
}
// Remove items from specified lists
itemsFromLists = LoadAllItemsLists(specifiedLists);
for (i = 0; i < itemsFromLists.length; i += 1) {
tool.RemoveItem(itemsFromLists[i], flagKeep, flagForce, flagAll);
}
_.memory.FreeMany(itemsFromLists);
}
protected function LoadUserFlags(HashTable options)
{
if (options == none)
{
flagAll = false;
flagForce = false;
flagAmmo = false;
flagKeep = false;
flagEquip = false;
flagHidden = false;
flagGroups = false;
return;
}
flagAll = options.HasKey(T(TALL));
flagForce = options.HasKey(T(TFORCE));
flagAmmo = options.HasKey(T(TAMMO));
flagKeep = options.HasKey(T(TKEEP));
flagEquip = options.HasKey(T(TEQUIP));
flagHidden = options.HasKey(T(THIDDEN));
flagGroups = options.HasKey(T(TLIST));
}
protected function array<Text> LoadAllItemsLists(ArrayList specifiedLists)
{
local int i, j;
local Text nextList;
local array<Text> result;
local array<Text> nextItemBatch;
local array<Text> availableLists;
local ListBuilder badLists;
local MutableText badListsAsText;
if (specifiedLists == none) {
return result;
}
badLists = ListBuilder(_.memory.Allocate(class'ListBuilder'));
callerConsole.Write(T(TLISTS_SKIPPED));
availableLists = _.kf.templates.GetAvailableLists();
for (i = 0; i < specifiedLists.GetLength(); i += 1)
{
nextList = specifiedLists.GetText(i);
nextItemBatch = LoadItemsList(nextList, availableLists, badLists);
_.memory.Free(nextList);
for (j = 0; j < nextItemBatch.length; j += 1) {
result[result.length] = nextItemBatch[j];
}
}
badListsAsText = badLists.IntoMutableText();
callerConsole.WriteLine(badListsAsText);
_.memory.Free(badListsAsText);
_.memory.FreeMany(availableLists);
return result;
}
protected function array<Text> LoadItemsList(
BaseText listName,
array<BaseText> availableLists,
ListBuilder badLists)
{
local int i;
local array<Text> emptyArray;
if (listName == none) {
return emptyArray;
}
// Try exact matching first
for (i = 0; i < availableLists.length; i += 1)
{
if (availableLists[i].Compare(listName, SCASE_INSENSITIVE)) {
return _.kf.templates.GetItemList(availableLists[i]);
}
}
// Prefix matching otherwise
for (i = 0; i < availableLists.length; i += 1)
{
if (availableLists[i].StartsWith(listName, SCASE_INSENSITIVE)) {
return _.kf.templates.GetItemList(availableLists[i]);
}
}
badLists.Item(listName);
return emptyArray;
}
defaultproperties
{
TINVENTORY = 0
stringConstants(0) = "inventory"
TADD = 1
stringConstants(1) = "add"
TREMOVE = 2
stringConstants(2) = "remove"
TITEMS = 3
stringConstants(3) = "items"
TEQUIP = 4
stringConstants(4) = "equip"
TALL = 5
stringConstants(5) = "all"
TKEEP = 6
stringConstants(6) = "keep"
THIDDEN = 7
stringConstants(7) = "hidden"
TFORCE = 8
stringConstants(8) = "force"
TAMMO = 9
stringConstants(9) = "ammo"
TLIST = 10
stringConstants(10) = "list"
TLISTS_NAMES = 11
stringConstants(11) = "lists names"
TSET = 12
stringConstants(12) = "set"
TLISTS_SKIPPED = 13
stringConstants(13) = "Following lists could not have been found and will be {$TextFailure skipped}:"
}