In this example, “put flowers in vase” gives the response “There are none at all available!” Why doesn’t this command work? Or maybe a better question would be, is there a straightforward way to make it work?
A flower is a kind of thing.
Lab is a room.
Five flowers are in Lab.
A vase is a container in Lab.
Test me with "put flowers in vase".
I think it has to do with implicit taking and plurals of a kind.
if you delete the “kind of thing” declaration, you can put the flowers in the vase without holding them.
Inform can handle explicit taking of “flowers.” Some clever person might have insight into implicit taking in this case, that’s Inform 6 stuff as far I can know.
Edit: actually, I don’t think you can handle kinds that way without an “understand” statement, so it’s probably more about confusion between flowers=kind and flowers=things.
Rule for deciding whether all includes a flower: it does.
That’s all you need.
Why you need it is a longer question, which I don’t have a complete answer to. It looks like the default answer for the “deciding whether all includes…” activity is different for the MULTIHELD and MULTIEXCEPT grammar tokens.
In the default template logic for the deciding whether all includes activity, there are the following lines:
if (context == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN && parent(j) ~= actor)
flag = 0;
These lines (in conjunction with some preceding lines) have the effect of enforcing that an object must be carried directly by the actor in order to be included in “all”. [EDIT: When processing certain types of tokens, that is, including the type used in this case.] By providing a rule applicable to flowers as zarf suggests, you’re overriding that default logic for them.
I believe that the purpose of the existing logic is to prevent >PUT ALL IN VASE from making the PC try to stuff every item within reach into the vase. Disabling those lines at the I6 level results in interaction like:
>I
You are carrying:
a basket
five flowers
>PUT ALL IN VASE
basket: Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
>GET BASKET
Taken.
>DROP IT
Dropped.
>PUT ALL IN VASE
basket: (first taking the basket)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
flower: (first taking the flower)
Done.
Note that for the second >PUT ALL IN VASE the flowers were already inside the vase. Also note that, per default behavior, the second >PUT ALL IN VASE results in a nothing to do error (i.e. “none at all available”).
There are several Standard Rules that override the default template logic when deciding whether all includes.
I have gotten good mileage out of using multiple action processing rules (see WWI 17.20 Multiple Action Processing) when trying to modify the general behavior.
This is an area where you want to make narrow changes. There’s a lot of ways for a fix over here to break “natural” library behavior over there. It’s very hard to test every possible combination of verbs and circumstances.
Note that all of them are about excluding items from “all”. E.g. the “exclude scenery from take all rule”, etc.
@bg: I agree with zarf; it’s very easy to break more than you fix when touching this logic. Can you be more specific about what kind of behavior you’re seeking when you say you want to “make it work”?
In further testing, I realized that this statement is subtly wrong… the following lines have the same effect (I think):
Rule for deciding whether all includes a flower: it does.
Rule for deciding whether all includes a flower: do nothing.
The default outcome of each rule is “it does”, the default outcome of the rulebook depends on the token being parsed. Or something like that.
A narrower change would be something like
Rule for deciding whether all includes a flower (called F) while inserting into:
if the holder of F is a room or the holder of F is the player:
it does;
else:
it does not.
If there’s not a reliable (i.e. unlikely to break anything) way to move the flowers to the vase when the player types “put flowers in vase,” then I think I mostly want a better response.
Right now it looks like a bug. “There are none at all available!” doesn’t make sense (from the player’s perspective) because the flowers are right there. So if the problem is that the player has to take them first, and if there’s not a good way to fix that, maybe I could just change the response to say “You’ll have to take them first.”
parser nothing error internal rule response (B): “[There] [adapt the verb are from the third person plural] none at all available!”
Is this an error that shows up only when the player needs to be carrying something first? I’m trying to figure out what replacement message I could use.
Ok, now I’m trying to write a rule along these lines, but it’s not compiling. I guess
when the player's command does not match the text "all"
is not allowed. What can I do instead?
Rule for printing a parser error when (the latest parser error is the nothing to do error) and (the player's command does not match the text "all"):
let wanted items be a text;
now the wanted items are "";
if the player's command matches the text "flowers":
if (the player does not enclose a flower) and (a flower is touchable):
now the wanted items are "flowers";
[more stuff here]
if the wanted items are not "":
say "There are none available. If you want to do something with the [wanted items], you could try taking them first.";
otherwise:
say "There are none available."
A flower is a kind of thing.
Lab is a room.
Five flowers are in Lab.
A vase is a container in Lab.
Test me with "put flowers in vase".
That does fix the match issue, but it prints both default and new. I’m not sure why that is, and there’s probably an easy fix I haven’t guessed. An alternative, just in case somebody finds this in a search, is to overwrite the response. I have no idea whether that’s smarter or not, it’s just something I’ve done in the past.
I had this code mostly available for a project, I didn’t just rewrite the sample on the spot.
say "There are none available. If you want to do something with the [wanted items], you could try taking them first.";
I think it’s because I incorporated most of the original message into the new one. I’m not sure of all the scenarios that might prompt this response, so I was trying to allow for the possibility that the “taking” suggestion might not be helpful. But trying to cover all possibilities might actually make it more confusing. So maybe I’ll leave out the “There are none available” part.
I realized that if I exclude commands that include “all,” it won’t catch “put all flowers in vase.” So I took out that condition.
Now I’ve got something along these lines:
Rule for printing a parser error when the latest parser error is the nothing to do error:
let wanted items be a text;
now the wanted items are "";
if the player's command matches the text "flowers":
if (the player does not enclose a flower) and (two flowers are visible):
now the wanted items are "flowers";
[more stuff here]
if the wanted items are not "": [i.e. if we have identified a likely set of items]
say "If you want to do something with the [wanted items], you could try taking them first.";
otherwise: [i.e. if we haven't identified a likely set of items]
say "There are none at all available."
Hopefully that will do the job.
Edit:
I end up changing this again to change just the “Parser nothing error internal rule response (B)” instead
Parser nothing error internal rule response (B) is "[Custom None At All Available Message]".
in case there are other responses resulting from the “nothing to do” error that I don’t want to override.
I’ve not used Inform for a couple of years now, sadly, but here’s something from an old project. No doubt I got ideas for it from this forum.
[This is to replace the message "There are none at all available!" when hamper is empty]
Rule for printing a parser error when the latest parser error is the nothing to do error and the player's command includes "from hamper":
if the hamper is empty:
say "The hamper is empty." instead.
[This is to replace the message "There are none at all available!" when "get all"]
Rule for printing a parser error when the latest parser error is the nothing to do error and the player's command includes "get all" or the player's command includes "take all":
say "There is nothing to take here." instead.