Browse Source

Add more functionality to `ACommandInventory`

Add lists support and `set` subcommand. As well as general code
refactoring.
feature_improvement
Anton Tarasenko 2 years ago
parent
commit
82089ea9de
  1. 251
      sources/Commands/ACommandInventory.uc
  2. 33
      sources/Tools/InventoryTool.uc
  3. 1
      sources/Tools/ReportTool.uc

251
sources/Commands/ACommandInventory.uc

@ -20,8 +20,17 @@
*/
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, TALL_WEAPONS;
var protected const int THIDDEN, TFORCE, TAMMO, TLIST, TLISTS_NAMES, TSET;
var protected const int TLISTS_SKIPPED;
protected function BuildData(CommandDataBuilder builder)
{
@ -43,14 +52,22 @@ protected function BuildData(CommandDataBuilder builder)
.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(TALL))
.Describe(F("This flag tells editing commands to affect all items."
@ "When adding items it means \"all available weapons in the game\""
@ "and when removing it means \"all weapons in"
@ "the player's inventory\"."));
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."
@ -66,9 +83,12 @@ protected function BuildData(CommandDataBuilder builder)
.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(TAMMO), P("A"))
.Describe(P("When adding weapons - signals that their"
@ "ammo / charge / whatever has to be filled after addition."));
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(
@ -76,121 +96,174 @@ protected function ExecutedFor(
CallData result,
EPlayer callerPlayer)
{
local ConsoleWriter publicWriter;
local InventoryTool tool;
local DynamicArray itemsArray, specifiedLists;
LoadUserFlags(result.options);
tool = class'InventoryTool'.static.CreateFor(player);
if (tool == none) {
return;
}
if (result.subCommandName.IsEmpty())
{
tool.ReportInventory( callerPlayer.BorrowConsole(),
result.options.HasKey(T(THIDDEN)));
itemsArray = result.parameters.GetDynamicArray(T(TITEMS));
specifiedLists = result.options.GetDynamicArrayBy(P("/list/lists names"));
if (result.subCommandName.IsEmpty()) {
tool.ReportInventory(callerConsole, flagHidden);
}
else if (result.subCommandName.Compare(T(TADD)))
{
SubCommandAdd( tool, result.parameters.GetDynamicArray(T(TITEMS)),
result.options.HasKey(T(TALL)),
result.options.HasKey(T(TFORCE)),
result.options.HasKey(T(TAMMO)));
else if (result.subCommandName.Compare(T(TADD))) {
SubCommandAdd(tool, itemsArray, specifiedLists);
}
else if (result.subCommandName.Compare(T(TREMOVE))) {
SubCommandRemove(tool, itemsArray, specifiedLists);
}
else if (result.subCommandName.Compare(T(TREMOVE)))
else if (result.subCommandName.Compare(T(TSET)))
{
SubCommandRemove( tool,
result.parameters.GetDynamicArray(T(TITEMS)),
result.options.HasKey(T(TALL)),
result.options.HasKey(T(TFORCE)),
result.options.HasKey(T(TKEEP)),
result.options.HasKey(T(TEQUIP)),
result.options.HasKey(T(THIDDEN)));
}
tool.ReportChanges(callerPlayer, player.BorrowConsole(), false);
publicWriter = _.console.ForAll().ButPlayer(callerPlayer);
tool.ReportChanges(callerPlayer, publicWriter, true);
tool.RemoveAllItems(flagKeep, flagForce, flagHidden);
SubCommandAdd(tool, itemsArray, specifiedLists);
}
tool.ReportChanges(callerPlayer, callerConsole, IRT_Caller);
tool.ReportChanges(callerPlayer, targetConsole, IRT_Target);
tool.ReportChanges(callerPlayer, othersConsole, IRT_Others);
_.memory.Free(tool);
_.memory.Free(publicWriter);
}
protected function SubCommandAdd(
InventoryTool tool,
DynamicArray templateList,
bool flagAll,
bool doForce,
bool doFillAmmo)
DynamicArray itemsArray,
DynamicArray specifiedLists)
{
if (flagAll) {
AddAllItems(tool, doForce, doFillAmmo);
local int i, j;
local int itemsAmount;
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) {
tool.AddItem(itemsArray.GetText(i), flagForce, flagAmmo);
}
else {
AddGivenTemplates(tool, templateList, doForce, doFillAmmo);
// Add items from specified lists
itemsFromLists = LoadAllItemsLists(specifiedLists);
for (i = 0; i < itemsFromLists.length; i += 1) {
tool.AddItem(itemsFromLists[j], flagForce, flagAmmo);
}
_.memory.FreeMany(itemsFromLists);
}
protected function SubCommandRemove(
InventoryTool tool,
DynamicArray templateList,
bool flagAll,
bool doForce,
bool doKeep,
bool flagEquip,
bool flagHidden)
DynamicArray itemsArray,
DynamicArray specifiedLists)
{
if (flagAll)
local int i, j;
local int itemsAmount;
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(doKeep, doForce, flagHidden);
tool.RemoveAllItems(flagKeep, flagForce, flagHidden);
return;
}
// Remove due to "--equip" option
if (flagEquip) {
tool.RemoveEquippedItems(doKeep, doForce, flagHidden);
tool.RemoveEquippedItems(flagKeep, flagForce, flagHidden);
}
// Remove items user listed manually
// Use `itemsAmount` because `itemsArray` can be `none`
for (i = 0; i < itemsAmount; i += 1) {
tool.RemoveItem(itemsArray.GetText(i), flagKeep, flagForce, flagAll);
}
RemoveGivenTemplates(tool, templateList, doForce, doKeep);
// Remove items from specified lists
itemsFromLists = LoadAllItemsLists(specifiedLists);
for (i = 0; i < itemsFromLists.length; i += 1) {
tool.RemoveItem(itemsFromLists[j], flagKeep, flagForce, flagAll);
}
_.memory.FreeMany(itemsFromLists);
}
protected function AddAllItems(
InventoryTool tool,
bool doForce,
bool doFillAmmo)
protected function LoadUserFlags(AssociativeArray options)
{
local int i;
local array<Text> allTempaltes;
if (tool == none) {
if (options == none)
{
flagAll = false;
flagForce = false;
flagAmmo = false;
flagKeep = false;
flagEquip = false;
flagHidden = false;
flagGroups = false;
return;
}
allTempaltes = _.kf.templates.GetItemList(T(TALL_WEAPONS));
for (i = 0; i < allTempaltes.length; i += 1) {
tool.AddItem(allTempaltes[i], doForce, doFillAmmo);
}
_.memory.FreeMany(allTempaltes);
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 AddGivenTemplates(
InventoryTool tool,
DynamicArray templateList,
bool doForce,
bool doFillAmmo)
protected function array<Text> LoadAllItemsLists(DynamicArray specifiedLists)
{
local int i;
if (tool == none) return;
if (templateList == none) return;
for (i = 0; i < templateList.GetLength(); i += 1) {
tool.AddItem(templateList.GetText(i), doForce, doFillAmmo);
local int i, j;
local array<Text> result;
local array<Text> nextItemBatch;
local array<Text> availableLists;
local ReportTool badLists;
if (specifiedLists == none) {
return result;
}
badLists = ReportTool(_.memory.Allocate(class'ReportTool'));
badLists.Initialize(T(TLISTS_SKIPPED));
availableLists = _.kf.templates.GetAvailableLists();
for (i = 0; i < specifiedLists.Getlength(); i += 1)
{
nextItemBatch =
LoadItemsList(specifiedLists.GetText(i), availableLists, badLists);
for (j = 0; j < nextItemBatch.length; j += 1) {
result[result.length] = nextItemBatch[j];
}
}
badLists.Report(callerConsole);
_.memory.Free(badLists);
_.memory.FreeMany(availableLists);
return result;
}
protected function RemoveGivenTemplates(
InventoryTool tool,
DynamicArray templateList,
bool doForce,
bool doKeep)
protected function array<Text> LoadItemsList(
Text listName,
array<Text> availableLists,
ReportTool badLists)
{
local int i;
if (tool == none) return;
if (templateList == none) return;
for (i = 0; i < templateList.GetLength(); i += 1) {
tool.RemoveItem(templateList.GetText(i), doKeep, doForce);
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
@ -215,6 +288,12 @@ defaultproperties
stringConstants(8) = "force"
TAMMO = 9
stringConstants(9) = "ammo"
TALL_WEAPONS = 10
stringConstants(10) = "all weapons"
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}:"
}

33
sources/Tools/InventoryTool.uc

@ -25,6 +25,13 @@
*/
class InventoryTool extends AcediaObject;
enum InventoryReportTarget
{
IRT_Caller,
IRT_Target,
IRT_Others
};
/**
* Every instance of this class is created for a particular player and that
* player cannot be changed. It allows:
@ -62,7 +69,7 @@ var const int TITEMS_ADDITION_FAILED_MESSAGE, TITEMS_REMOVAL_FAILED_MESSAGE;
var const int TRESOLVED_INTO, TTILDE_QUOTE, TFAULTY_INVENTORY_IMPLEMENTATION;
var const int TITEM_MISSING, TITEM_NOT_REMOVABLE, TUNKNOWN, TVISIBLE;
var const int TDISPLAYING_INVENTORY, THEADER_COLON, TDOT_SPACE, TCOLON_SPACE;
var const int TCOMMA_SPACE, TSPACE, TOUT_OF, THIDDEN_ITEMS, TDOLLAR;
var const int TCOMMA_SPACE, TSPACE, TOUT_OF, THIDDEN_ITEMS, TDOLLAR, TYOU;
protected function Constructor()
{
@ -256,8 +263,14 @@ public function AddItem(Text userProvidedName, bool doForce, bool doFillAmmo)
* (or, at least, attempted to be preserved) and not simply destroyed.
* @param doForce Set to `true` if we must try to remove an item
* even if it normally cannot be removed.
* @param doRemoveAll Set to `true` to remove all instances of given
* template and `false` to only remove one.
*/
public function RemoveItem(Text userProvidedName, bool doKeep, bool doForce)
public function RemoveItem(
Text userProvidedName,
bool doKeep,
bool doForce,
bool doRemoveAll)
{
local bool itemWasMissing;
local Text realItemName, itemTemplate;
@ -287,7 +300,8 @@ public function RemoveItem(Text userProvidedName, bool doKeep, bool doForce)
// Need to remember the name before removing the item
realItemName = storedItem.GetName();
}
if (targetInventory.RemoveTemplate(itemTemplate, doKeep, doForce))
if (targetInventory
.RemoveTemplate(itemTemplate, doKeep, doForce, doRemoveAll))
{
resolvedLine = MakeResolvedIntoLine(userProvidedName, itemTemplate);
itemsRemoved.Item(realItemName);
@ -462,7 +476,7 @@ public function RemoveEquippedItems(
public final function ReportChanges(
EPlayer blamedPlayer,
ConsoleWriter writer,
bool publicReport)
InventoryReportTarget reportTarget)
{
local Text blamedName, targetName;
if (TargetPlayerIsInvalid()) {
@ -472,12 +486,17 @@ public final function ReportChanges(
if (blamedPlayer != none) {
blamedName = blamedPlayer.GetName();
}
if (publicReport)
if (reportTarget == IRT_Others)
{
itemsAdded.Report(writer, blamedName, targetName);
itemsRemoved.Report(writer, blamedName, targetName);
}
else
else if (reportTarget == IRT_Target)
{
itemsAdded.Report(writer, blamedName, T(TYOU));
itemsRemoved.Report(writer, blamedName, T(TYOU));
}
else if (reportTarget == IRT_Caller)
{
itemsAddedPrivate.Report(writer, blamedName, targetName);
itemsRemovedPrivate.Report(writer, blamedName, targetName);
@ -654,4 +673,6 @@ defaultproperties
stringConstants(20) = "{$TextSubHeader Hidden items:}"
TDOLLAR = 21
stringConstants(21) = "$"
TYOU = 22
stringConstants(22) = "you"
}

1
sources/Tools/ReportTool.uc

@ -134,6 +134,7 @@ public final function ReportTool Detail(Text detail)
/**
* Outputs report assembled thus far into the provided `ConsoleWriter`.
* Reports will be made only if at least one items was added (see `Item()`).
*
* @param writer `ConsoleWriter` to output report into.
* @param cause Player that caused the change this report is about.

Loading…
Cancel
Save