From chat: Letting the player name things in I7

You can portably check that by testing ((verb_word->#dict_par1) & 1).

I suppose you should do that check before calling DictionaryWordToVerbNum(), if you want to be really careful. For non-verb-words, DictionaryWordToVerbNum() will return $FF (Z-code) or $FFFF (Glulx).

Now that I look, you’re checking the return value of DictionaryWordToVerbNum() against dictlen, which doesn’t make sense. That value isn’t a dictionary table index; it’s a grammar table index.

2 Likes

Thanks. It made sense at 2:13 in the morning. Not sure why, now.

Beyond identifying the verbs, I want to get all the directions and their aliases. When you hit ‘e’ in the dictionary, how does one tell that corresponds to a direction? It looks like the parser relies on NounDomain, and I’m hoping there’s a better way to do this than spoofing being in the middle of parsing.

1 Like

The parser calls NounDomain(compass), which boils down to checking all the direction objects contained in the compass object.

The game could customize this, but I think that is very rare. You normally adjust compass directions by moving them into and out of the compass, either when play begins or (if you’re doing something really fancy) during play.

1 Like

Changing the set of directions is also pretty rare in I7, so you could just take all the direction names from the Standard Rules and put them into the table by hand. Not as elegant as finding all the verbs in the dictionary table, but in 95% of cases you’d only have to do it once. Adding a new verb is a lot more common than adding a new direction!

I had gotten my stubborn on and really wanted to do the directions dynamically.

Use DICT_WORD_SIZE of 15.

To say again-word: (- Glulx_PrintAnything(AGAIN1__WD); -).
To say again-alias: (- Glulx_PrintAnything(AGAIN2__WD); -).
To say oops-word: (- Glulx_PrintAnything(OOPS1__WD); -).
To say oops-alias: (- Glulx_PrintAnything(OOPS2__WD); -).
To say undo-word: (- Glulx_PrintAnything(UNDO1__WD); -).

Include (-
[ PrintCommandWords j wd dictlen entrylen entry;
    dictlen = #dictionary_table-->0;
    entrylen = DICT_WORD_SIZE + 7;
        wd = #dictionary_table + WORDSIZE + entrylen*j; 
 if ((wd->#dict_par1) & 1)
            print (address) wd;
];
-)

To say dictionary command entry (n - a number): (- PrintCommandWords({n}); -)

To decide what number is the dictionary length: (- #dictionary_table-->0 -)

To decide what number is the number of dictionary words of/for (obj - object): (- ({obj}.#name)/WORDSIZE -)

To say dictionary word (n - a number) of/for (obj - object): (- print (address) ({obj}.&name)-->({n}-1); -)

To say command words: (- PrintCommandWords(); -)

The dictionary list is a list of texts variable.

To decide what text is the expanded (T - a text) (this is expanded-text): decide on the substituted form of T.

To build the dictionary list:
  if the dictionary list is empty begin;
    now the dictionary list is { "[again-word]", "[again-alias]", "[oops-word]", "[oops-alias]", "[undo-word]" };
   now dictionary list is expanded-text applied to dictionary list;
   repeat with dir running through the directions begin;
      repeat with i running from 1 to the number of dictionary words for dir begin;
        let t be "[dictionary word i of dir]";
        unless t matches the regular expression "^direction", add the substituted form of t to dictionary list;
      end repeat;
   end repeat;
   now dictionary list is expanded-text applied to dictionary list;
   let wordlist be the substituted form of "[command words]";
   repeat with i running from 1 to dictionary length begin;
      let d be "[dictionary command entry i]";
      unless d is "", add the substituted form of d to dictionary list;
   end repeat;
   sort the dictionary list;
  end if;

lab is a room.

when play begins: build the dictionary list; say the dictionary list
3 Likes

For a true pedant, there is sadly no alternative to dynamically parsing the topic for a match to a direction name, because it is always possible that the author has included some ‘Understand...’ phrase that works through a routine called by the parse_name property of a direction object rather than just looking at the names in its name property.

We don’t want to use NounDomain() like the parser does because if the player types something that matches the name of more than one direction (such as directions) we don’t want NounDomain to ask a disambiguation question. So we go a bit deeper into the weeds and call SearchScope() instead…

EDIT1: This works for 9.3/6M62 and 10.1 or 10.1.2 I didn’t find any problem from using #dictionary_table in any of these versions

EDIT2: This version will only work for Glulx: the dictionary table is structured slightly differently in the Z-machine

3 Likes

After all that, I think it was a simpler solution just to fix the parser’s unhelpful .noverb grammar behaviour, as in this previously-mentioned thread!

EDIT: although that woudn’t prevent the player foolishly or inadvertently naming their spell the same as a single-word command such as ‘jump’- in which case they would still have to use ‘cast jump’ rather than just ‘jump’ to get it to fire.

EDIT2: either way, the minor issue will remain with both approaches that typing a ‘verbless’ command in response to a disambiguation question will incorrectly not be recognised as a new command (rather than an answer to the disambiguation question), and so will fail- probably with the response ‘I did not understand that sentence’- see also here.

2 Likes

To make this all as completely bulletproof as possible, as well as dynamically parsing the suggested spell name for matching direction names, I guess one should also dynamically parse it for a match to the opening token of any other ‘verbless’ grammar lines and disallow a match to those too. This is left as an exercise for the reader :laughing:

EDIT: This would be chiefly a concern for someone wanting to make an extension- most authors would be well aware whether they had other verbless grammar or renamed directions in their story… unless it was unknowingly included in an extension they were using…

2 Likes

That’s weird. It had been identifying it, in particular, as a problem. I must have had a different error elsewhere confusing the compiler in exactly the “right” way that it thought there was something wrong with that instead.

1 Like