Hey, I have a question related to actor inventory, specifically the player’s. I’m trying to customize the way things are listed and formatted. After poking my head around inventory listers, I realize some of the coding is a little above my head, and I’d like some input on how to best approach this, please.
So, I’m aware that there are wide and tall inventory listings, and I like the look of tall inventory, but I’d also like worn items and carried items to be separated out and described like they are in wide listings (without “being worn”). Sort of like:
>inventory
You are wearing boots, a hat, and a coat.
You are carrying:
x1 hatchet
x5 sticks
Can this be done just by modifying either the wide or tall lister? Or is this more complex than I am realizing?
You can certainly do what you’re trying to do! Unfortunately, I’m not really available right away to whip up a code sample. I’ll check back soon if no one else has gotten to your question!
I second the question, sometimes I think that differentiating better than (which contains X, Y, and Z) the rucksack/pocket(s) contents when doing inventory can be a massive player’s QoL improvement…
Best regards from Italy,
dott. Piergiorgio.
ps. I have taken the liberty of editing the title and adding an appropriate tag
The subclass you want to override is actorInventoryLister, either overriding the showCombinedInventoryList method, or rewriting to use something different. I found it easier to manipulate the former, but really a personal choice. Definitely reference the stock implementation in msg_neu.t Note you can override under Actor, or the pc ‘me’ depending on your needs.
Here is what that might look like:
me : Actor
inventoryLister : actorInventoryLister
{
/*
* New routine to append vertical carrying list to standard worn listing
*/
showTallInventoryList(parent, carrying) {
// 'carried' is string of form '[a|an] [obj1.name],
// [a|an] [obj2.name],... and [a|an] [objN.name]
if (carrying == '') {
"<<buildSynthParam('The/he', parent)>> {is} carrying nothing. ";
} else {
// split carried string into components, then create lookup table of counts
// untested match string, test it!
local carriedList = carrying.split(R'(<Punct><Space>)?(and<Space>)?(a|an)<Space>');
local invLookup = new LookupTable();
carriedList.forEach(function(itm) {
local itmCount = 0;
parent.contents.forEach(function(inv) {
if (itm == inv.name) itmCount++;
});
invLookup[itm] = itmCount;
});
"<.p>You are carrying:\n";
invLookup.keysToList().forEach(function(inv) {
"\tx<<invLookup[inv]>> <<inv>>\n";
});
}
}
showCombinedInventoryList(parent, carrying, wearing) {
inherited(parent, '', wearing); // overkill, but using default with no carrying list
showTallInventoryList(parent, carrying); // add the vertical item list
}
showInventoryWearingOnly(parent, wearing) {
/* called by showCombined... inherited code. Tweaking it from original...
"<<buildSynthParam('The/he', parent)>> {is} carrying nothing,
and {is} wearing <<wearing>>. "; */
"<<buildSynthParam('The/he', parent)>> {is} wearing <<wearing>>. ";
}
showInventoryEmpty(parent) {
/* also mod this, as only refers to clothing now
"<<buildSynthParam('The/he', parent)>> {is} empty-handed. "; */
"<<buildSynthParam('The/he', parent)>> {is} nekkid! ";
}
}
This is untested code, so can’t promise no gotchas in there. Will test later when I have time, but maybe this gets you going?
Ha ha… didn’t know if anyone was going to pick this up so I just hashed something out.
Answering from phone, I’d think ListGroups would get the counting done…
Even better, it also provisions phraseSepPat = static new RexPattern(',(?! and )|;| and |<rparen>')
which is a much better pattern match than my off the cuff one above. As I think about it further, I do not have enough experience with multiple copied objects to have too much confidence in my split separator. Relying on existing stable code seems a better way to go about it.