[On preview, I see zarf has already said a bunch of stuff I was saying. I’ll post anyway, though, in case my code is useful.]
There’s a bunch of actions like dropping, eating, and wearing, that won’t work if you aren’t holding the noun; that’s called a carrying requirement (and is governed by the carrying requirements rule, which I think is funky Inform 6 business). Many of these, like eating and wearing, generate implicit takes: If you try to eat or wear something that you aren’t holding, the game will have you try to take it first, and stop the action if you don’t succeed in taking it. But obviously we don’t want dropping to always generate implicit takes, because if the rock is on the floor and the player types “drop rock” it’s dumb to have the player pick up the rock and then drop it.
The hitch here is that if something is in a container that the player is holding, the game won’t recognize it as being held for the purposes of carrying requirements, but if you’re dropping it it won’t try to implicitly take it out of the container for you either. So what you’re looking for is a way to generate implicit takes for certain actions when and only when the noun is in a container the player is holding. Here’s a stab at it:
[code]Lab is a room. The player carries a box. A hat is a wearable thing in the box. The player carries a glass jar. A jellybean is in the glass jar. The glass jar is transparent and closed.
Dropping is action that needs an implicit take from a held container. [Add whatever other actions you want in this line]
Before action that needs an implicit take from a held container when the holder of the noun is a container that is held by the player:
say “(first taking [the noun] from [the holder of the noun])[command clarification break]”; [this prints the kind of thing you see]
silently try taking the noun; [because it’s silent, it won’t print “Taken,” but it will print any failure messages you get]
if the player does not hold the noun, stop the action. [this happens when the implicit take fails; otherwise, go on to perform the action]
Test me with “wear hat/put hat in box/drop hat/drop jellybean”.
Test nope with “drop box/drop hat”.[/code]
The first two actions show off the implicit actions that are already coded into the standard rules. Then the last two show how our new implicit actions work, when they succeed and when they fail. And the nope test shows that you really have to be holding the box for this to work.
“Action that needs an implicit take from a held container” is the name of a kind of action, and we can extend this machinery to more actions by adding more statements like that. (See section 7.15 of Writing with Inform.) Despite its stupidly long name, there isn’t any logical complexity to the name – the words “take,” “held,” and “container” don’t guarantee that this kind of action has anything to do with taking stuff from held containers, any more than the presence of the word “cat” in “scattergories” ensures that scattergories has something to do with cats. You could replace that whole thing with “foo” and it would work just the same. I gave it a name that shows what it does, but it’s that before rule that’s doing all the work.
This doesn’t cover things that are in nested held containers, and it probably needs a lot more testing, but hope it’s helpful.