New Verb Conundrum (adv3Lite)

Here’s an odd little design problem. In order to implement a particular puzzle, I need a HoldIn action.

The required action is holding a hand mirror in a beam of sunlight so as to reflect the beam somewhere else.

For other, quite different purposes, I’ve defined a Hold action, which is usually (except in one particular situation) handled asDobjFor(Take). Now, the library quite properly understands that in the input ‘take the candle in the drawer’, the dobj is the candle and “in the drawer” points to the location of the candle. The library only attempts to read ‘candle in the drawer’ as a single dobj if there isn’t any candle in the drawer.

The problem that arises is this: If I haven’t defined HoldIn, ‘hold the candle in the drawer’ correctly and sensibly causes the Take action. But once I define HoldIn with a default check() telling the player that’s not a sensible action, the default check() runs in response to ‘hold the candle in the drawer’, because now the library thinks the candle is the dobj and the drawer is the iobj of a HoldIn action.

So the problem is, how do I keep the HoldIn action from stepping on the Hold action?

Experiment with gCommand.originalAction as a condition in your check command for Take.

I have not tried anything based on your description of what you are trying to accomplish, but I have used gCommand.originalAction in a somewhat similar circumstance.

In my case, if the player says “eat food” but is not holding it, the game first does a Take. I want the game to do different things in each case, though, so I have an if condition in dobjFor(Take) that says if(gCommand.originalAction == Eat) do something else.

You might be able to leverage this behavior to achieve your own desired results.


Maybe I’m not fully understanding you, but it seems to me that if you have defined an action matching the grammar HOLD X IN Y then it’s reasonable for the parser to interpret a command of that form as the HoldIn action.

If the player then types HOLD THE CANDLE IN THE DRAWER then this command is at best ambiguous. It could mean either “Apply the Hold action to the candle that is in the drawer” or “Apply the HoldIn action with the candle as direct object and the drawer as indirect object”. The parser has to plump for one interpretation or the other, and the latter interpretation is hardly an unreasonable one.

As an alternative to Jerry’s suggestion, you might want to experiment with using a Doer to make HOLD CANDLE IN DRAWER mean “Take the candle that is in the drawer” when the candle is in the drawer. Something like this:

Doer 'hold Thing in Container' execAction(c) { if(gDobj.isIn(gIobj)) doInstead(Take, gDobj); else inherited(c); } ;

What this does is to intercept a HoldIn action where for which the direct object is inside the indirect object and redirect it to a Take action on the direct object. Since this should happen before HoldIn gets to run its check routine, this should bypass the problem you’re seeing (whether it’ll make the parser behave consistently from the perspective of the player is another matter, but it may serve your purpose well enough).

Once again, I’m not at home so I can’t test this right now.