The following is a little limited (the way I’ve written it, you can only buy one kind of thing at once), but it should let players buy mass numbers of things without having to deal with all of those repeating messages, since you seem to not be fond of them.
currentCase is an object that varies.
A thing has a number called cost.
A thing has a number called bulk-identifier.
A showcase is a kind of container.
A torch is a kind of thing. The cost of a torch is usually 1. The bulk-identifier of an torch is usually 1. There are 12 torches.
An arrow is a kind of thing. The cost of an arrow is usually 1. The bulk-identifier of an arrow is usually 2. There are 3 arrows.
Definition: a thing is locationShowcased if it is in a showcase in the location.
When play begins:
repeat with item running through torches:
now item is in the goods showcase;
repeat with item running through arrows:
now item is in the goods showcase;
The Emporium is a room. Ganon is a person in the Emporium. The goods showcase is a showcase in the emporium.
The Garden is south of the Emporium.
This is the my announce items from multiple object lists rule:
if the current action is not buying and the current item from the multiple object list is not nothing,
say "[current item from the multiple object list]: [run paragraph on]" (A).
The my announce items from multiple object lists rule is listed instead of the announce items from multiple object lists rule in the action-processing rules.
Understand "buy [things]" as buying.
Does the player mean buying a carried thing: it is unlikely.
The buying action has a number called goods quantity.
The buying action has a list of things called goods bought.
The buying action has a number called good type bought.
The buying action has a truth state called too many types.
Rule for setting action variables for buying (this is the bulk buying rule):
now good type bought is the bulk-identifier of the noun;
if the number of entries in the multiple object list is greater than 1:
let Count be 0;
repeat with item running through the multiple object list:
if the bulk-identifier of the item is the good type bought:
if the item is locationShowcased:
if Count is 0:
now the noun is the item; [We don't need the original noun for much, just in case it's carried. Let's make the noun something we ***know***.]
increment Count;
add item to goods bought;
else:
now too many types is true;
break;
now goods quantity is count;
if goods quantity is less than 2:
now goods quantity is 1;
alter the multiple object list to { };
The block buying rule is not listed in any rulebook.
First check buying something when location is emporium (this is the please simplify bulk buying rule):
if too many types is true:
say "Ganon briefly glances about for a pen and paper. Maybe you should stick to one kind of purchase at a time?";
stop the action;
Check buying:
if a showcase is not in the location:
say "There's nothing to buy out here.";
stop the action;
Check buying something when location is Emporium (this is the deny buying from an empty showcase rule):
if the noun is in a showcase (called S) in the Emporium: [Remember! We set a proper noun for bulk buying earlier.]
now the currentCase is S;
otherwise:
say "Ganon shakes his head and says, 'Sorry, I don't have any more. Perhaps I'll get some in later.'" instead;
Carry out buying when location is Emporium (this is the pay-less let player buy in the emporium rule):
if goods quantity is greater than 1:
repeat with item running through goods bought:
now the player is carrying item;
else:
now player is carrying the noun;
Report buying when location is Emporium (this is the report buying rule):
let C be (the cost of the noun * goods quantity);
say "Ganon takes your [C to 1 decimal places] gp, then removes [if goods quantity is less than 2]the [noun] from the [currentCase] and hands it to you[else][goods quantity in words] [printed plural name of the noun] from the [currentCase] and hands them to you[end if].[run paragraph on]";
say " '[one of]Excellent choice![run paragraph on][or]You've made a fine decision,[or]That should serve you well,'[at random][run paragraph on] he says.[line break][line break]";
rule succeeds;
Every turn:
now currentCase is nothing;
Emporium
You can see Ganon and a goods showcase (in which are three arrows and twelve torches) here.>buy arrow
Ganon takes your 1.0 gp, then removes the arrow from the goods showcase and hands it to you. "Excellent choice! he says.>buy arrow and torch
Ganon briefly glances about for a pen and paper. Maybe you should stick to one kind of purchase at a time?>buy 3 arrows
Ganon takes your 2.0 gp, then removes two arrows from the goods showcase and hands them to you. “That should serve you well,” he says.>buy arrows
Ganon shakes his head and says, “Sorry, I don’t have any more. Perhaps I’ll get some in later.”>buy three torches
Ganon takes your 3.0 gp, then removes three torches from the goods showcase and hands them to you. "Excellent choice! he says.>buy torches
Ganon takes your 9.0 gp, then removes nine torches from the goods showcase and hands them to you. "You’ve made a fine decision, he says.>inventory
You are carrying:
twelve torches
three arrows>s
Garden
>buy torches
There’s nothing to buy out here.
I’ve had to gut the mechanisms here a bit since I once again don’t have access to all of your variables and tables, but this should be a semi-scaleable skeleton which checks local showcases for contents matching the kind of noun (as classified by its bulk identifier) and buys all of the ones available.
If the player tries to buy more than one thing at once it tells the player to simplify things, though I can think of ways to get even that workable if you want to put the time in.
As a warning, since this is still technically part of multiple object processing you’ll need to get aggressive with some line breaks (note my own double line break at the bottom there) for your report rules. The automatic mechanisms choke up a little when you override them like this.
But yes! Hope this can help.
Edit: Apologies! Forgot to include my output, and made a slight edit to the response text.