I am having a problem with Before and Carry out for multiple things. It seems that global variables are cleared (?!) between Before and Carry out. I want to treat many things as a group. I do this by converting the looping inherent in the multiple object list to a single iteration by truncating the multiple object list. Consider this code.
Before buying:
let L be the multiple object list;
let BulkQty be the number of entries in multiple object list;
if BulkQty is 0: [single item is 0 in multiple object list]
now BulkQty is 1;
truncate L to 1 entry;
alter the multiple object list to L;
let PricePer be ChrCostBuying for cost of noun;
now moneyAmt of bulkCost is PricePer * BulkQty;
say "Total cost for all [BulkQty] [noun][s] is [moneyAmt of bulkCost][line break]";
if the noun is in a showcase (called S) in the Emporium:
now CurrentCase is S;
Carry out buying:
say "BulkCost = [moneyAmt of BulkCost].[line break]";
decrease moneyAmt of cash by moneyAmt of BulkCost;
say "Starting [BulkQty] [noun][s] to inventory loop.[line break]";
repeat with N running from 1 to BulkQty:
say "Adding [BulkQty] [noun][s] to inventory.[line break]";
now player is carrying the noun;
I trigger this with say, BUY 3 ARROWS. However, BulkQty is 3 in the Before rule but 0 in the Carry out rule. Only 1 arrows is added to inventory.
Here is the setup code.
The block buying rule is not listed in any rulebook.
Understand "buy [something]" as buying. [This overrides the default rule.]
Understand "buy [things]" as buying.
The can't take what's already taken rule is not listed in any rulebook.
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.
CurrentCase is a showcase that varies.
BulkCost is money.
BulkQty is a number that varies. [total number of items to purchase]
Does the player mean buying something which is enclosed by a showcase:
it is very likely.
How is it that the global variable BulkQty is cleared to 0 after being 3 in the Before rule but BulkCost is not? Note that BulkCost is a thing but BulkQty is merely a variable.
I wouldn’t recommend this method in general. What happens if the player types BUY QUIVER AND THREE ARROWS AND SWORD? With this implementation, the parser will convert that into buying five quivers, because there are five items in the multiple object list and the first one is a quiver.
Reporting all the purchases individually is the much lesser evil imo.
Hmmm. But it is so easy assuming they all are the same noun. What if I checked the MOL to ensure that they were all the same, else print an error message to tell them to buy same kinds?
Checking whether everything is the same kind is tricky—there are ways to do it, but remember that things can have more than one kind. And “the noun” is only ever a single thing, not a kind of thing. If you leave the multiple object list intact, then it’ll run the carry out rule three times, ensuring that it’s a different arrow each time; if you delete the multiple object list, you’ll have to do all of that yourself.
As you can see, I perform the loop myself already. I am hung on the fact that a noun is not being moved to the player, which I think is not related to the MOL.
However, I get your point, I will revise to iterate over Carry Out activity.
The problem is, at any given time, “the noun” is a single, specific thing, not a broad category of things. So even if you “now player is carrying the noun” three times, it’ll just move the same arrow to the player’s inventory three times, not three different arrows.
Report is called multiple times. How do I stop repeating report messages? Or multiple Check messsages? Buying, for example, 24 arrows, would get annoying to the player.
After [buying some arrows]: [After stops the action before report phase]
say "You purchase arrows. You now have [number of arrows carried by the player]."
In general it is suggested to not deliver messages during Check rules unless the check stops the action or ends with Instead.
I have seen this page multiple times but never realized that. I think I misunderstand. After coding that, it turns out that ALL the activities: Before, Instead, Check, Carry out, After, and Report are in the MOL loop.
My code equivalent of your code gets called 3 times, just like Report does.
I suspect it was designed so After can be used as a last-minute detour out of standard Report rules for a unique message, or do do something special only in certain cases.
Report taking a clover:
say "You pick a three-leafed clover."
After taking a lucky clover:
say "You pick a lucky four-leaf clover!";
increase $luck by 1.
[After includes implicit stop the action so Report won’t re-report what happened in After]
I am trying to buy many things. I am using the generic Before, Carry Out, and Report activities (and now After activity) because I don’t have information about what specific thing is being bought.
You’re using the generic action “buying” for your rules. You can make rules more specific so you can sort them out and only apply multiple processing to certain kinds.
Before buying something: [something meaning 'the noun']
Before buying something (called merch): [called makes 'merch' a temporary variable you can refer to in that rule
Before buying an arrow:
Before buying arrows:
I believe you can make separate rules based on one item or multiples. Someone might need to check me on that though.
Understand "buy [something]" as buying.
Understand "buy [things]" as buying-multiply.
That way you can have two separate actions and only process multiples on the buying-multiply action.
"Shop"
The Shop is a room. A showcase is a kind of container.
A thing has a number called cost.
The weapons showcase is a showcase in the Shop.
A sword is a kind of thing. There are ten swords in the weapons showcase.
The cost of a sword is 4.
The armor showcase is a showcase in the Shop.
A shield is a kind of thing. There are ten shields in the armor showcase.
The cost of a shield is 6.
The not-for-sale showcase is a showcase in the Shop.
A jewel is a kind of thing. There are ten jewels in the not-for-sale showcase.
Understand "buy [things]" as buying.
The block buying rule is not listed in any rulebook.
Does the player mean buying something (called the prospective purchase):
if the prospective purchase is held by the player, it is very unlikely;
if the prospective purchase is not in a showcase, it is unlikely;
it is very likely.
[This is kind of a hack. We want to run exactly the same checks in two situations:
first, when printing items from the multiple object list;
second, when checking the actual buying action.
So we abstract those checks into this phrase.
]
To say check purchaseability of (item - a thing):
if the cost of the item is 0:
say "'Sorry, that's not for sale.'";
otherwise if the holder of the item is not a showcase:
say "You can only buy things in a showcase.".
Definition: a thing (called the item) is purchaseable if "[check purchaseability of the item]" is "".
The buying action has a list of objects called the list of things bought.
Setting action variables for buying:
now the list of things bought is the multiple object list;
if the list of things bought is empty:
add the noun to the list of things bought;
let the filtered list be filter to purchaseable things of the list of things bought;
now the list of things bought is the filtered list.
Check buying something:
if the noun is not purchaseable:
say check purchaseability of the noun instead.
This is the announce purchases from multiple object lists rule:
if the current item from the multiple object list is nothing:
do nothing;
otherwise if the current item from the multiple object list is purchaseable:
do nothing;
otherwise:
say "[current item from the multiple object list]: [run paragraph on]" (A).
The announce purchases from multiple object lists rule substitutes for the announce items from multiple object lists rule.
Temporary purchase storage is a container.
Carry out buying something:
now the noun is held by the player.
Report buying something:
if the noun is held by the player, move the noun to temporary purchase storage;
let N be the number of entries in the list of things bought;
if N is not 1, make no decision;
[Now we know we're on the last purchaseable item]
let the price be the total cost of things in temporary purchase storage;
say "You pay [price] gp for [the list of things in temporary purchase storage].";
now everything in temporary purchase storage is held by the player.
>buy sword
You pay 4 gp for the sword.
>undo
Shop
[Previous turn undone.]
>buy two swords
You pay 8 gp for the two swords.
>undo
Shop
[Previous turn undone.]
>buy two swords and three shields
You pay 26 gp for the three shields and the two swords.
>undo
Shop
[Previous turn undone.]
>buy sword and two shields and jewel
You pay 16 gp for the two shields and the sword.
“Sorry, that’s not for sale.”
>undo
Shop
[Previous turn undone.]
>buy shield and jewel and sword
“Sorry, that’s not for sale.”
You pay 10 gp for the sword and the shield.
The last two are supposed to say jewel: "Sorry, that's not for sale.", and I’m not sure why they don’t. Something is wrong with the “announce purchases from multiple object lists” rule. Similarly, it’s not preferring objects in showcases to objects held by the player, which is why I have to UNDO after each action to demonstrate it. But I don’t have the time to debug it further right now.