Catching actions before verify (TADS 3)

I’m looking for the equivalent of a beforeAction () capability that will run before verify().

The situation is that I have an object in a room, let’s call it a panama hat, that I don’t want the player to be able to refer yet as a panama hat, even though it quite obviously is one, and later he will be able to refer to it that way.

If I don’t put the adjective “panama” on the hat, then if the player refers to it as a panama hat, the game says, “You see no panama hat here,” when quite evidently he does see one.

I get most of what I want if I do the following:

    beforeAction () { //Runs between verify and check.
        if (gAction.getOrigText().find('panama')) {
            say ('[To be picky about it, you\'re actually not yet certain it is that specific kind of hat, but let\'s go ahead anyway.]\b ');
        }
    }

This will catch things like >examine panama hat or >throw foo at panama hat.

However, anything for which verify() creates a stopper isn’t treated the way I want. For example, >eat panama hat gets the default that the hat doesn’t appear to be edible.

The room’s roomBeforeAction() doesn’t catch this in time, nor does creating an actorAction method.

(By the way, the reason for all this pickiness is related to how the player learns spells in the game, which is too convoluted to explain here :smiley: )

Any ideas?

–Bob

Good question. I’ve never tried this, but I notice that the Action class has a preCond. By default it’s just an empty list. You could try modifying Action by creating a new precondition object using your

if (gAction.getOrigText().find(‘panama’))

somehow in the precondition, and then modify the Action class itself by adding your new precondition to the class’s preCond = [] list. Not sure that would work, but it’s worth a try.

Not sure I followed all this, but I’ll take a closer look.

Noticing that preCond runs before verify, I did try the following in the room’s definition, but that didn’t work either:

preCond () { if (gAction.getOrigText().find('panama')) { say ('[To be picky about it, you\'re actually not yet certain it is that specific kind of hat, but let\'s go ahead anyway.]\b '); } }
Putting a breakpoint on this code seems to indicate that the room’s preCond doesn’t get checked.

EDIT: I meant to add that somehow a dark room intercepts actions before verify(). (For example: >eat foo in a dark room doesn’t get the verify “inedible” message). I can’t unravel how the engine is doing that, but maybe it holds the key to my problem.

preCond is not a method, as in your sample code. Or rather, creating a method with that name won’t do anything. preCond is found within a dobjFor() or iobjFor() block, and contains a list of PreCondition objects. See p. 105 of “Learning T3” and the page “Custom Preconditions” in the Technical Manual. The thing I was referring to is that apparently there’s also such a list in the Action class itself – an empty list. After creating your own PreCondition object using the instructions on that page, you could try modifying the Action class to include your new PreCondition in its preCond = [] list.

If the word you’re looking for is something that you’re reasonably sure will not be used in any other context, the simplest approach is using a StringPreParser to check what the player typed:

StringPreParser doParsing(str, which) { if (str.find('panama')) { say ('[To be picky about it, you\'re actually not yet certain it is that specific kind of hat, but let\'s go ahead anyway.] '); } return str; } execBeforeMe = [commentPreParser] ;
This will run before the parser even starts to analyse the command, so you can’t use any information from the parser (like, say, what the action or the direct object of the command is) to narrow down whether the response is appropriate. But you can check things like “panamaHat.playerKnowsIsPanama”.

My answer is gonna be quite different: don’t do it :slight_smile:

If some players have played the game before and know about the hat, more power to them. Just have “panama” in the vocabulary for the hat without doing anything fancy. The game does not need to explain itself to someone who has already played it. Someone who hasn’t played it yet, will never type “panama”.

@Emerald: Thanks! That got me close enough to the target that I could get done what I wanted to.

@RealNC: Sound advice, but in this particular case, if I allowed the player to refer to the hat as a panama hat then by the rules of the game, he would learn a spell that I don’t want him to learn without solving a puzzle. He wouldn’t need to be on a replay, because by the very description of the hat, he would know instantly that it was a panama hat, and try to refer to it as such. (All this keeping in mind that we’re not really talking about a hat).

Such strange conversations we have!

@Jim: Thanks for your suggestions. Fortunately, Emerald’s approach worked for me so I didn’t have to dive into what (for me) are pretty deep waters! :smiley:

Cheers to all,

–Bob