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. 253
      sources/Commands/ACommandInventory.uc
  2. 37
      sources/Tools/InventoryTool.uc
  3. 1
      sources/Tools/ReportTool.uc

253
sources/Commands/ACommandInventory.uc

@ -20,8 +20,17 @@
*/ */
class ACommandInventory extends Command; 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 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) protected function BuildData(CommandDataBuilder builder)
{ {
@ -43,14 +52,22 @@ protected function BuildData(CommandDataBuilder builder)
.Describe(P("This command removes items (based on listed templates)" .Describe(P("This command removes items (based on listed templates)"
@ "from the targeted player's inventory." @ "from the targeted player's inventory."
@ "Instead of templates item aliases can be specified.")); @ "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)) builder.Option(T(TEQUIP))
.Describe(F("Affect items currently equipped by the targeted player." .Describe(F("Affect items currently equipped by the targeted player."
@ "Releveant for a {$TextEmphasis remove} subcommand.")); @ "Releveant for a {$TextEmphasis remove} subcommand."));
builder.Option(T(TALL)) builder.Option(T(TLIST))
.Describe(F("This flag tells editing commands to affect all items." .Describe(P("Include weapons from specified group into the list."))
@ "When adding items it means \"all available weapons in the game\"" .ParamTextList(T(TLISTS_NAMES));
@ "and when removing it means \"all weapons in" builder.Option(T(TAMMO))
@ "the player's inventory\".")); .Describe(P("When adding weapons - signals that their"
@ "ammo / charge / whatever has to be filled after addition."));
builder.Option(T(TKEEP)) builder.Option(T(TKEEP))
.Describe(F("Removing items by default means simply destroying them." .Describe(F("Removing items by default means simply destroying them."
@ "This flag makes command to try and keep them in some form." @ "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" .Describe(P("Sometimes adding and removing items is impossible due to"
@ "the limitations imposed by the game. This option allows to" @ "the limitations imposed by the game. This option allows to"
@ "ignore some of those limitation.")); @ "ignore some of those limitation."));
builder.Option(T(TAMMO), P("A")) builder.Option(T(TALL), P("A"))
.Describe(P("When adding weapons - signals that their" .Describe(F("This flag is used when removing items. If user has"
@ "ammo / charge / whatever has to be filled after addition.")); @ "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( protected function ExecutedFor(
@ -76,121 +96,174 @@ protected function ExecutedFor(
CallData result, CallData result,
EPlayer callerPlayer) EPlayer callerPlayer)
{ {
local ConsoleWriter publicWriter;
local InventoryTool tool; local InventoryTool tool;
local DynamicArray itemsArray, specifiedLists;
LoadUserFlags(result.options);
tool = class'InventoryTool'.static.CreateFor(player); tool = class'InventoryTool'.static.CreateFor(player);
if (tool == none) { if (tool == none) {
return; return;
} }
if (result.subCommandName.IsEmpty()) itemsArray = result.parameters.GetDynamicArray(T(TITEMS));
{ specifiedLists = result.options.GetDynamicArrayBy(P("/list/lists names"));
tool.ReportInventory( callerPlayer.BorrowConsole(), if (result.subCommandName.IsEmpty()) {
result.options.HasKey(T(THIDDEN))); tool.ReportInventory(callerConsole, flagHidden);
} }
else if (result.subCommandName.Compare(T(TADD))) else if (result.subCommandName.Compare(T(TADD))) {
{ SubCommandAdd(tool, itemsArray, specifiedLists);
SubCommandAdd( tool, result.parameters.GetDynamicArray(T(TITEMS)), }
result.options.HasKey(T(TALL)), else if (result.subCommandName.Compare(T(TREMOVE))) {
result.options.HasKey(T(TFORCE)), SubCommandRemove(tool, itemsArray, specifiedLists);
result.options.HasKey(T(TAMMO)));
} }
else if (result.subCommandName.Compare(T(TREMOVE))) else if (result.subCommandName.Compare(T(TSET)))
{ {
SubCommandRemove( tool, tool.RemoveAllItems(flagKeep, flagForce, flagHidden);
result.parameters.GetDynamicArray(T(TITEMS)), SubCommandAdd(tool, itemsArray, specifiedLists);
result.options.HasKey(T(TALL)), }
result.options.HasKey(T(TFORCE)), tool.ReportChanges(callerPlayer, callerConsole, IRT_Caller);
result.options.HasKey(T(TKEEP)), tool.ReportChanges(callerPlayer, targetConsole, IRT_Target);
result.options.HasKey(T(TEQUIP)), tool.ReportChanges(callerPlayer, othersConsole, IRT_Others);
result.options.HasKey(T(THIDDEN)));
}
tool.ReportChanges(callerPlayer, player.BorrowConsole(), false);
publicWriter = _.console.ForAll().ButPlayer(callerPlayer);
tool.ReportChanges(callerPlayer, publicWriter, true);
_.memory.Free(tool); _.memory.Free(tool);
_.memory.Free(publicWriter);
} }
protected function SubCommandAdd( protected function SubCommandAdd(
InventoryTool tool, InventoryTool tool,
DynamicArray templateList, DynamicArray itemsArray,
bool flagAll, DynamicArray specifiedLists)
bool doForce,
bool doFillAmmo)
{ {
if (flagAll) { local int i, j;
AddAllItems(tool, doForce, doFillAmmo); 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 { // Add items from specified lists
AddGivenTemplates(tool, templateList, doForce, doFillAmmo); itemsFromLists = LoadAllItemsLists(specifiedLists);
for (i = 0; i < itemsFromLists.length; i += 1) {
tool.AddItem(itemsFromLists[j], flagForce, flagAmmo);
} }
_.memory.FreeMany(itemsFromLists);
} }
protected function SubCommandRemove( protected function SubCommandRemove(
InventoryTool tool, InventoryTool tool,
DynamicArray templateList, DynamicArray itemsArray,
bool flagAll, DynamicArray specifiedLists)
bool doForce,
bool doKeep,
bool flagEquip,
bool flagHidden)
{ {
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; return;
} }
// Remove due to "--equip" option
if (flagEquip) { if (flagEquip) {
tool.RemoveEquippedItems(doKeep, doForce, flagHidden); tool.RemoveEquippedItems(flagKeep, flagForce, flagHidden);
} }
RemoveGivenTemplates(tool, templateList, doForce, doKeep); // 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);
}
// 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( protected function LoadUserFlags(AssociativeArray options)
InventoryTool tool,
bool doForce,
bool doFillAmmo)
{ {
local int i; if (options == none)
local array<Text> allTempaltes; {
if (tool == none) { flagAll = false;
flagForce = false;
flagAmmo = false;
flagKeep = false;
flagEquip = false;
flagHidden = false;
flagGroups = false;
return; return;
} }
allTempaltes = _.kf.templates.GetItemList(T(TALL_WEAPONS)); flagAll = options.HasKey(T(TALL));
for (i = 0; i < allTempaltes.length; i += 1) { flagForce = options.HasKey(T(TFORCE));
tool.AddItem(allTempaltes[i], doForce, doFillAmmo); flagAmmo = options.HasKey(T(TAMMO));
} flagKeep = options.HasKey(T(TKEEP));
_.memory.FreeMany(allTempaltes); flagEquip = options.HasKey(T(TEQUIP));
flagHidden = options.HasKey(T(THIDDEN));
flagGroups = options.HasKey(T(TLIST));
} }
protected function AddGivenTemplates( protected function array<Text> LoadAllItemsLists(DynamicArray specifiedLists)
InventoryTool tool,
DynamicArray templateList,
bool doForce,
bool doFillAmmo)
{ {
local int i; local int i, j;
if (tool == none) return; local array<Text> result;
if (templateList == none) return; local array<Text> nextItemBatch;
local array<Text> availableLists;
for (i = 0; i < templateList.GetLength(); i += 1) { local ReportTool badLists;
tool.AddItem(templateList.GetText(i), doForce, doFillAmmo); 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( protected function array<Text> LoadItemsList(
InventoryTool tool, Text listName,
DynamicArray templateList, array<Text> availableLists,
bool doForce, ReportTool badLists)
bool doKeep)
{ {
local int i; local int i;
if (tool == none) return; local array<Text> emptyArray;
if (templateList == none) return; if (listName == none) {
return emptyArray;
for (i = 0; i < templateList.GetLength(); i += 1) { }
tool.RemoveItem(templateList.GetText(i), doKeep, doForce); // 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 defaultproperties
@ -215,6 +288,12 @@ defaultproperties
stringConstants(8) = "force" stringConstants(8) = "force"
TAMMO = 9 TAMMO = 9
stringConstants(9) = "ammo" stringConstants(9) = "ammo"
TALL_WEAPONS = 10 TLIST = 10
stringConstants(10) = "all weapons" 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}:"
} }

37
sources/Tools/InventoryTool.uc

@ -25,6 +25,13 @@
*/ */
class InventoryTool extends AcediaObject; 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 * Every instance of this class is created for a particular player and that
* player cannot be changed. It allows: * 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 TRESOLVED_INTO, TTILDE_QUOTE, TFAULTY_INVENTORY_IMPLEMENTATION;
var const int TITEM_MISSING, TITEM_NOT_REMOVABLE, TUNKNOWN, TVISIBLE; var const int TITEM_MISSING, TITEM_NOT_REMOVABLE, TUNKNOWN, TVISIBLE;
var const int TDISPLAYING_INVENTORY, THEADER_COLON, TDOT_SPACE, TCOLON_SPACE; 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() 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. * (or, at least, attempted to be preserved) and not simply destroyed.
* @param doForce Set to `true` if we must try to remove an item * @param doForce Set to `true` if we must try to remove an item
* even if it normally cannot be removed. * 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 bool itemWasMissing;
local Text realItemName, itemTemplate; 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 // Need to remember the name before removing the item
realItemName = storedItem.GetName(); realItemName = storedItem.GetName();
} }
if (targetInventory.RemoveTemplate(itemTemplate, doKeep, doForce)) if (targetInventory
.RemoveTemplate(itemTemplate, doKeep, doForce, doRemoveAll))
{ {
resolvedLine = MakeResolvedIntoLine(userProvidedName, itemTemplate); resolvedLine = MakeResolvedIntoLine(userProvidedName, itemTemplate);
itemsRemoved.Item(realItemName); itemsRemoved.Item(realItemName);
@ -460,9 +474,9 @@ public function RemoveEquippedItems(
* changes. * changes.
*/ */
public final function ReportChanges( public final function ReportChanges(
EPlayer blamedPlayer, EPlayer blamedPlayer,
ConsoleWriter writer, ConsoleWriter writer,
bool publicReport) InventoryReportTarget reportTarget)
{ {
local Text blamedName, targetName; local Text blamedName, targetName;
if (TargetPlayerIsInvalid()) { if (TargetPlayerIsInvalid()) {
@ -472,12 +486,17 @@ public final function ReportChanges(
if (blamedPlayer != none) { if (blamedPlayer != none) {
blamedName = blamedPlayer.GetName(); blamedName = blamedPlayer.GetName();
} }
if (publicReport) if (reportTarget == IRT_Others)
{ {
itemsAdded.Report(writer, blamedName, targetName); itemsAdded.Report(writer, blamedName, targetName);
itemsRemoved.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); itemsAddedPrivate.Report(writer, blamedName, targetName);
itemsRemovedPrivate.Report(writer, blamedName, targetName); itemsRemovedPrivate.Report(writer, blamedName, targetName);
@ -654,4 +673,6 @@ defaultproperties
stringConstants(20) = "{$TextSubHeader Hidden items:}" stringConstants(20) = "{$TextSubHeader Hidden items:}"
TDOLLAR = 21 TDOLLAR = 21
stringConstants(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`. * 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 writer `ConsoleWriter` to output report into.
* @param cause Player that caused the change this report is about. * @param cause Player that caused the change this report is about.

Loading…
Cancel
Save