Printing names for actions without "-ing"

I’d like to be able to print names for actions without the “-ing” ending. So instead of something like this:

Before doing something when the paralytic gas is in the location: say "You think of [the current action], but find you cannot move at all." instead.

we might be able to print:

Before doing something when the paralytic gas is in the location: say "You try to [infinitival form of the current action], but find you cannot move at all." instead.

Now if this were just a question of removing the “-ing” from an action name, this could be done tediously but relatively simply; I could just make a big table of action names with an infinitival form for each one (so that the infinitival form of the searching action was “search,” the infinitival form of the taking inventory was “take inventory,” etc.) But I can’t see that I would be able to do such a brute force method for entire stored actions, like “searching the closet” or “throwing the key at the door.” And I can’t even break down the message into parts such that I print the infinitival form of the action name, then the first noun if any, then the second noun if any, because I would get “throw it at the key the door.”

Is there any solution here? I suppose the solution is going to involve an enormous table with all the action names, with the participial form of the action in one column, and with the infinitival form of the action in another column, so that I can use indexed text to replace the pariticiple with the infinitival form. Oh dear. And is there an easy way to make it so that only the first occurrence of the matched text gets replaced, so that “throwing the throwing knife at the troll” doesn’t become “throw the throw knife at the troll”?

Since imperatives are identical in form to infinitives in English you might perhaps be able to use the player’s command? (Which will bring with it a whole bunch of new problems, though – like “You try to n, but find you cannot move at all.”)

– EDIT:
Wait! There is an I6 routine that does this (or something quite similar) I think. It’s called PrintCommand and is used when giving the “I only understood you as far as wanting to throw the key” kind of Parser Error messages. It also compensates for abbreviated commands such as “X” and “I”.

–EDIT 2:
Actually, there is even an I7 say phrase to call PrintCommand, to wit ‘say recap of command’ (as in “You try to [recap of command], but find you cannot move at all.”)

–EDIT 3:
It’s one of the “unindexed” I7 phrases, meaning that it’s uncertain to survive future revisions of the Standard Rules. However, even if it is at some time retracted from the Standard Rules, nothing prevents one from defining it in one’s own code, as long as the underlying I6 routine remains unchanged: To say recap of command: (- PrintCommand(); -).

Thank you!

Unfortunately, my actual use case comes when the commands are being tried by an NPC rather than as responses to the player’s command, so I don’t think this will work. Even PrintCommand can’t easily be hacked to refer to commands that the player hasn’t issued directly, can it?

I don’t think the infinite forms are stored anywhere. You might need to just remove the -ing and keep a separate table for exceptions.

Yeah, I thought probably.

I don’t feel up to that right now, so what I’m actually going to do is come up with a way of writing the messages I want to write that uses the participle rather than the infinitive.

PrintCommand() relies on internal parser state, so it can’t be used on a simple (stored) action.

The low-level DB_Action_Details() function has the table of participles. It can substitute object names – you call DB_Action_Details(actionname, noun, secondnoun) to get e.g. “putting the lamp on the table”. You could stuff that into indexed text and then use your table to remove “ing” from the first word.

You’ll need to fudge topic actions, in any event. (To print “asking Steve about the blue book”, the parser has to rely on the command buffer, because topics have no canonical printed form.)

Thanks zarf!

What would be the difference between using DB_Action_Details and using Ron Newcomb’s Editable Stored Actions? I can already get the putting the lamp on the table stored action by assembling it in Editable Stored Actions and then I suppose turn its name into indexed text.

In fact I see that Editable Stored Actions exposes the participle part of the action as an indexed text, which would make things much easier.

In my current WIP actions are just getting passed along from one turn to the next in a way that never alters the topic, so topic actions aren’t a problem. (In fact I want to just throw out the topic wherever there is one, and this thread has reminded me to do that, so thanks again!)

Would it be possible to temporarily change the current command to a stored action, then use the recap, then change it back? Something like this:

  • Set a global flag.
  • Try the stored action.
  • A “first check” rule with no associated action sees the flag and prints the recap, then stops the action.
  • Unset the flag again.

PrintCommand() relies on internal parser state. “try stored action” does not go through the parser, so it doesn’t set that state.

Hm. Would changing “the player’s command” followed by trying the stored action do it?

You would have to change it and then re-invoke the parser, which I don’t remember offhand how to do. There would be side effects. I’d say that this approach is the way of pain(TM Saruman).

As for Editable Stored Actions, I couldn’t say. (I preserve my limited hold on sanity by not trying to learn everything about I6 and I7 and all the I7 extensions…)

Then is it possible to access the table of verbs that the recap phrase uses?

Well, it seems to me that once you’ve started manipulating the indexed text, you might as well just work directly on the name of the stored action. And in fact those resources from Editable Stored Actions give the power to do this relatively painlessly. Below, the code (embedded in a minigame which is a Borges adaptation as well as a current movie tie-in):

[spoiler][code]“Kotsuke No Suke, The Insulting Etiquette Master”

Include Editable Stored Actions by Ron Newcomb.

Edo Castle is a room. Kotsuke No Suke is a man in Edo Castle. The description of Kotsuke No Suke is “For an etiquette master, he has been quite rude.”

The description of the player is “You are a put-upon daimyo preparing for the envoys of the Emperor.”

The player carries a sword. The description of the sword is “The sword that, as a daimyo, you must always carry with you[if the turn count is greater than 5]. It seems to be reminding you of its use[end if].”

To say infinitival form of (deed - a stored action):
say “[infinitival form of participle part of the deed][if the noun part of the deed is not nothing] [the noun part of the deed][end if][if the number of characters in the preposition part of the deed is greater than 0] [preposition part of the deed][end if][if the second noun part of the deed is not nothing] [the second noun part of the deed][end if]”.

Every turn:
say “Kotsuke No Suke says, 'Uncouth provincial, how dare you [infinitival form of the current action] so crudely in the presence of a member of the Emperor’s court!”;
if the current action is attacking Kotsuke No Suke or the current action is attacking Kotsuke No Suke with the sword:
say “Kotsuke No Suke runs away saying ‘You will pay for this assault!’”;
end the story saying “It was worth it”.

To say infinitival form of (participle - indexed text):
let T be indexed text;
now T is participle;
replace the regular expression “ing\b” in T with “”;
say T.

Attacking it with is an action applying to two things. Understand “attack [something] with [something]” as attacking it with.[/code][/spoiler]

Obviously to do this right I’d need the full table (this gives “examin” and “tak inventory”), as well as the fudges for topics and requests, but that seems like it should be doable but tedious.

Perhaps an action could be “e-terminated” or “not e-terminated”, and that property used instead of a table? I can’t think of an action that wouldn’t fit one of those two methods of conjugation.

EDIT: Also, you should probably detect “ing\b” instead of “ing” to avoid “r the doorbell”.

There’s participles that double up the final consonant like “dropping,” “cutting,” “rubbing,” and “setting.” I think that’s all of those in the standard actions. And there could be participles that form irregularly in other ways like “dying” which has to backform into “die.”

Already did the “ing\b” thing! I tested it with “swing sword.”

PS Editable Stored Actions is AWESOME. Faithful Companion would not remotely exist without it. I realize that doesn’t prove it’s awesome, but it’s awesome.

Okay, I think I have it figured out. These are the rules that I use:

  • Select only words ending in -ing to prevent the later rules from applying too broadly.
  • Cut final -ing from those words.
  • If the word ends with -VC, add final -e.
  • If the word ends with -VCC (with the two Cs being the same), cut the last character.

This works in theory, but I can’t find a good way to implement the last one. Is there a clever regular-expression way to make sure the two final consonants match before removing one?

Probably, but wouldn’t that turn “telling” into “tel”?

ETA: And adding an “e” to -VC is not unproblematic either; it seems like it’d have problems with “answering,” “throwing,” and “looking”; if you made it -CVC to take care of “looking” then you’d have problems with “squeezing.”

I really think that whatever person is going to undertake this is going to have to draw up a table of exceptions by hand.

Yes, I suppose it would.

Revised final rule: require the consonant to be an oral plosive or fricative.

Not sure if it could be helpful or not, but I do have this code lying around. It enumerates the (understood) verbs leading to a particular action:[code]Include (-
Global entry_index;
-) after “Definitions.i6t”.

Include (-
[ entry_index_limit;
#Ifdef TARGET_ZCODE;
return ((HDR_DICTIONARY–>0) + 5)–>0;
#Ifnot; ! GLULX
return #dictionary_table–>0;
#Endif;
];
[ entry_to_dictionary_word entry_index;
#Ifdef TARGET_ZCODE;
return VM_NumberToDictionaryAddress(entry_index);
#Ifnot; ! GLULX
return #dictionary_table + WORDSIZE + entry_index * (DICT_WORD_SIZE + 7);
#Endif;
];
[ dictionary_word_is_verb dictionary_word;
#Ifdef TARGET_ZCODE;
return DictionaryWordToVerbNum(dictionary_word) ~= $ff;
#Ifnot; ! GLULX
return DictionaryWordToVerbNum(dictionary_word) ~= $ffff;
#Endif;
];
[ dictionary_word_is_verb_for dictionary_word action
individual_table grammar_line_count grammar_line_index grammar_line_address candidate;
#Ifdef TARGET_ZCODE;
individual_table = (HDR_STATICMEMORY–>0)–>DictionaryWordToVerbNum(dictionary_word);
#Ifnot; ! GLULX
individual_table = (#grammar_table)–>(DictionaryWordToVerbNum(dictionary_word) + 1);
#Endif;
grammar_line_count = (individual_table->0) - 1;
grammar_line_address = individual_table + 1;
for (grammar_line_index = 0: grammar_line_index <= grammar_line_count: ++grammar_line_index) {
#Ifdef TARGET_ZCODE;
if (action == (256 * (grammar_line_address->0) + grammar_line_address->1) & $3ff) {
rtrue;
}
grammar_line_address–;
for (::slight_smile: {
grammar_line_address = grammar_line_address + 3;
if (grammar_line_address->0 == ENDIT_TOKEN) break;
}
#Ifnot; ! GLULX
@aloads grammar_line_address 0 candidate;
if (action == candidate) {
rtrue;
}
grammar_line_address = grammar_line_address - 2;
for (::slight_smile: {
grammar_line_address = grammar_line_address + 5;
if (grammar_line_address->0 == ENDIT_TOKEN) break;
}
#Endif;
grammar_line_address++;
}
rfalse;
];
-).

A dictionary word is a kind of value.
To say (W - a dictionary word): (- print (address) {W}; -).

To repeat with (I - a nonexisting dictionary word variable) running through verbs for (A - an action name) begin – end: (-
for (entry_index = entry_index_limit(): entry_index-- && ({I} = entry_to_dictionary_word(entry_index)):slight_smile:
if (dictionary_word_is_verb({I}) && dictionary_word_is_verb_for({I}, {A}))
-).

There is a room.
Before doing something:
repeat with the verb running through verbs for the action name part of the current action:
let the verb word be indexed text;
now the verb word is “[the verb]”;
say “[the verb word].”
[/code]