Testing for a Topic (adv3lite)

I have a pair of NPCs, who are part of a CollectiveGroup. If the player tells them (as a group) about a certain thing, I want to customize the response. But this doesn’t work:

dobjFor(TellAbout) { verify() {} check() {} action() { // The parser seems to prefer the sign to the octopus, so we'll test for that too: if (gTopic && gTopic != ollie && gTopic != octopusSign) "The guards glance at one another, and {the ray} says, <q>You talk to her.</q><.p> "; doInstead (TellAbout, chuck, gTopic); } }
I want the sentence, “The guards glance at one another…” to print only if the player has NOT typed ‘tell guards about octopus’.

But the sentence always prints, even if that IS the topic. I’ve also tried gIobj rather than gTopic, but that doesn’t work either. How can I test whether that’s the topic? (I know the action is TellAbout, and I know the topic is as shown, because I used ‘debug actions’ to check it.)

I can’t immediately see what the problem is. Have you tried setting a break point on the line:

if (gTopic && gTopic != ollie && gTopic != octopusSign)

To check what the value of gTopic is at that point?

Okay I’ve now done this and I can see what the problem is: gTopic does not hold the current Topic object but rather the ResolvedTopic (just as it would, indeed, in adv3). Basically this is because the player’s input could match more than one Topic, and a ResolvedTopic is a wrapper for the list of possible Topics the player’s input could match. See the section on Topic Actions in the Adv3Lite Library Manual for a fuller explanation.

This means that your code needs to extract a Topic object from the ResolvedTopic that gTopic holds before trying to compare it with the Topics defined in your game; so you’d need something like:

dobjFor(TellAbout) {
        verify() {}
        check() {}
        action() {
            // The parser seems to prefer the sign to the octopus, so we'll test for that too:
            if (gTopic && gTopic.getBestMatch not in (ollie, octopusSign))
                "The guards glance at one another, and {the ray} says, <q>You talk to her.</q><.p> ";
            doInstead (TellAbout, chuck, gTopic.getBestMatch);
        }

When I try to replicate your experience, the debugger resolves gTopic to…

obj#fad4 (ResolvedTopic)

…which expands to (among other things)…

[code]gTopic

  • tokens [‘’,‘about’,‘’]
    • [1] ‘’
      [2] ‘about’
      [3] ‘’[/code]

So, if you want to know what topic was entered on the command line by the player, it would be if(gTopic.tokens[3] == ‘ollie’).

However, the breakpoint only hits if I entered the command as

If I enter it in shorthand…

…the breakpoint in dobjFor(TellAbout) does not get hit.

Also, if the command line entry contains other words, each word is a token. So, the Command tell group about ollie breaks down to three tokens, ‘group’, ‘about’, ‘ollie’ but if the command is entered as tell group about the guy named ollie, it would be six tokens: ‘group’, ‘about’, ‘the’, ‘guy’, ‘named’, ‘ollie’.

Jerry

Thanks, Eric – that solves the problem.

Fortunately, I don’t have to resort to Jerry’s parse-it-yourself approach, because there IS an octopus in the game. The topic is only a text entry until the player has visited the location where the octopus is to be seen.

This can turn into an issue if the player is replaying the game and carelessly expects to be able to use knowledge acquired in previous run-throughs. But trying to avoid that problem would be a nightmare.

The breakpoint in dobjFor(TellAbout) is only getting hit when the command entered on the command line is of the form tell about .

Any other entry…

…does not trigger the breakpoint, and therefore, presumably, would not display the alternate text nor invoke the doInstead() code.

Jerry