Verb agreement with object in message parameter substitution

Another day, another TADS3 question: what’s the proper way to force verb agreement with an object/Thing for message parameter substitution? Specifically in the case where the “bare” name of the object is used, instead of aName or theName.

The example:

#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>

startRoom:      Room 'Shop'
        "This is a featureless shop. "
;

alice: Actor 'shopkeeper' 'shopkeeper'
        "She looks like the first shopkeeper you'd turn to in a problem. "
        isHer = true
        location = startRoom
;
+ keys: Thing 'keys' 'keys'
        isPlural = true
        desc() {
                local holder, obj;

                obj = self;
                holder = self.getCarryingActor();
                gMessageParams(obj, holder);
                "{You obj/he} {is} hanging from {its holder/her} belt.\n ";
                "{Your holder/her} <<name>> {is} hanging from
                        {its holder/her} belt.\n ";
                "{Your holder/her} {you obj/he} {is} hanging from
                        {its holder/her} belt.\n ";
        }
;

me:     Actor
        location = startRoom
;

versionInfo:    GameID
        name = 'sample'
        byline = 'nobody'
        authorEmail = 'nobody <foo@bar.com>'
        desc = '[This space intentionally left blank]'
        version = '1.0'
        IFID = '12345'
;
gameMain:       GameMainDef
        initialPlayerChar = me
;

The only room is a shop of some sort, and the shopkeeper is carrying some keys. The problem:

>x keys
The keys are hanging from her belt.
The shopkeeper's keys is hanging from her belt.
The shopkeeper's the keys are hanging from her belt.

>

In the first phrase everything looks good: the {is} agrees with {You obj/he}. But in the second phrase {is} agrees with {Your holder/her} instead of the object. Presumably because it uses the <<>> form name instead of the {} parameter substitution syntax. Okay, fine. But what’s the correct message parameter substitution syntax for using just the name? In the third example the verb agreement is correct for {you obj/he}, but that uses the object’s theName instead of plain old name, which is what’s needed here.

Looking at the Message Parameter Substitutions documentation there doesn’t seem to be any way to use the name form.

To be clear: what I’m trying to work out is how to make something of the second/third form of the phrase work correctly, i.e. something like "{Your holder/her} {you obj/he} {is} hanging from {its holder/her} belt. " only without the extraneous “the” that this adds.

Clearly in this specific example it would be simple to just hardcode the strings, but I’m trying to figure out the syntax for this sort of situation in general.

Replying to myself with a really, really ugly kludge that works-ish.

There are a couple helper methods in adv3’s msg_neu.t for using variables in message parameter substitution, for example buildParam(). They look like the sort of thing I’m looking for above, but they require a “typeString” argument, which is a the stuff between the braces in a {}-style message parameter statement. And the problem is that there doesn’t seem to be one of those for the just-the-name form of an object’s name.

But this ugly mess kinda/sorta works:

fakeParam(str) {
        defaultReport('{It obj/he}');
        return(str);
}

…and then outputting a string using something like…

        desc() {
                local holder, obj;

                obj = self;
                holder = self.getCarryingActor();
                gMessageParams(obj, holder);
                "{Your holder/her} <<fakeParam(name)>> {is} hanging
                        from {its holder/her} belt.\n ";
        }

…which yeilds:

>x keys
The shopkeeper's keys are hanging from her belt.

>

This is pure sleazery: the variable substitution is just breaking the flow of the double-quoted output string, generating a bogus defaultReport() that’ll never be used (because we’re in the middle of outputting something else)…but that twiddles the message parameter substitution’s logic to use the object for verb agreement. So we get “are” in agreement with the object instead of “is” in agreement with the actor.

I’d still be delighted for a less kludgy way of doing this, just throwing it out there because it “works”.

The documentation is a bit unclear and I can’t test this right now, but I’m pretty sure you can override the object that verbs are made to agree with by writing something like {is obj}.

Good lord, thank you. I’d tried {is dobj/he} and {is dobj/him} but not {is dobj}, which is in fact correct. For completeness’ sake (and the benefit of anyone in the future finding this via search), this does the right thing:

        desc() {
                local holder;

                holder = self.getCarryingActor();
                gMessageParams(holder);
                "{Your holder/her} <<name>> {is dobj} hanging
                        from {its holder/her} belt.\n ";
        }

…namely…

>x keys
The shopkeeper's keys are hanging from her belt.

>

Thanks again.

1 Like