General questions on remapping, pronouns and number formatting

Hello,
I have a few questions about TADS3 (adv) that I did not find answers to in the documentation, and I hope you can answer one or the other. I assume most of them are trivial for experienced authors,so I hope it is okay to ask you in the first place. Here we go:

1. How can I print “he/she/it” instead of “the boy/the girl/the baby” in a string?
I often use {the dobj/it} (or using G-TADS/german translation: {der dobj/er}), which generates an noutput like “The small bucket”. However, sometimes, when two such sentences follow each other, it would be nice to just say “it” (or the appropriate pronoun, whatsoever), so instead of

The small bucket is empty. The small bucket could be filled

rather

The small bucket is empty. It could be filled

2. How can I determine the container of an object, e.g. remap an action to the gDobj’s container
I handle the PourIntoAction on a Container, and if it gets called on the content (e.g. a Liquid or alike), I would like to remap the action to the container. I tried dobjFor(PourInto) remapTo(PourInto, gDobj.getConnectedContainers()[1], gIobj) but it leads to an

[Runtime error: nil object reference]

So what is the correct way to refer to the container in this specific case?
Also, yet another question regarding remap-like behaviour:
3. Say I would like to answer a dobjFor(FillAction) with the question “with what?”, how can I then remap to/invoke the FillInto Action with the dobj for the initial action plus the iObj defined by the player answer?
An example should make that a bit clearer:

Fill bucket
With what do you want to fill the small bucket?
water
// invoke “Fill bucket with water” (e.g. FillIntoAction(Dobj, ‘water’) or something)

Or, alternatively, just assume that we mean water, and add a String like “[with water]” before performing a regular remapTo, etc. You get the idea.

4. (differnt topic:) How can I format floating point numbers, e.g. round to 3 decimals?
The question is self-explanatory. While I generally try to avoid floating point numbers to prevent precision errors (that occur naturally in programming languages for known reasons), it would be nice to know how to round them, or at least format the output.

Finally, I wonder if for future questions you prefer one cummulated post like this, or split the questions into seperate topics (I guess the difference is “generating noise in the forum” vs “improve searchability for future readers” and thus preventing double posts)

I think it would be smarter to create seperate topics, but I did not want to generate too much noise before asking the moderators or well-known users how to handle the many questions that arise when starting with TADS3 from zero to hero :slight_smile: (Ah, is there a chat available that may be a better suit for many “trivial” questions?)

Best, and have a great week @ all!

2 Likes

I don’t know about the German version, but in English you can get automagic grammatical he/she/it message parameter substitution with {it dobj/she} and {it dobj/her}:

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

startRoom: Room 'Void' "This is a featureless void. ";
+me: Person;
+pebble: Thing 'small round pebble' 'pebble' "A small, round pebble. ";
+alice: Person 'Alice' 'Alice'
        "She looks like the first person you'd turn to in a problem. "
        isHer = true
        isProperName = true
;
+bob: Person 'Bob' 'Bob'
        "He looks like Robert, only shorter. "
        isHim = true
        isProperName = true
;

versionInfo: GameID;
gameMain: GameMainDef initialPlayerChar = me;

DefineTAction(Foozle);
VerbRule(Foozle) 'foozle' singleDobj: FoozleAction
        verbPhrase = 'foozle/foozling (what)';

modify Thing
        dobjFor(Foozle) {
                action() {
                        defaultReport('{You/He} foozle{s} {it dobj/her}. 
                                {It dobj/She} {is} now foozled. ');
                }
        }
;

This gives us a “game” with the new action >FOOZLE which takes a direct object. Transcript:

Void
This is a featureless void.

You see a pebble here.

Alice and Bob are standing here.

>foozle pebble
You foozle it.  It is now foozled.

>foozle alice
You foozle her.  She is now foozled.

>foozle bob
You foozle him.  He is now foozled.

Note that this requires that isHer and isHim be set on all in-game objects that need gendered pronouns.

For getting outermost containers, I use a method that works more or less the same way as getOutermostRoom only for Containers:

        getOutermostContainer() {
                local c;

                if((location != nil)
                        && (c = location.getOutermostContainer()) != nil)
                        return(c);

                return(self.ofKind(Container) ? self : nil);
        }

…on the object(s) you want to use it with. Full demo:

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

startRoom: Room 'Void' "This is a featureless void. ";
+me: Person;
+box: Container '(wooden) box' 'box' "A wooden box. ";
++vase: Container '(glass) vase' 'vase' "A glass vase. ";
+++pebble: Thing 'small round pebble' 'pebble' "A small, round pebble. ";

versionInfo: GameID;
gameMain: GameMainDef initialPlayerChar = me;

DefineTAction(Foozle);
VerbRule(Foozle) 'foozle' singleDobj: FoozleAction
        verbPhrase = 'foozle/foozling (what)';

modify Thing
        getOutermostContainer() {
                local c;

                if((location != nil)
                        && (c = location.getOutermostContainer()) != nil)
                        return(c);

                return(self.ofKind(Container) ? self : nil);
        }

        dobjFor(Foozle) {
                action() {
                        local o;

                        if((o = self.getOutermostContainer()) == nil) {
                                reportFailure('No outermost container found. ');
                                exit;
                        }
                        defaultReport('The outermost container for
                                {the dobj/him} is <q><<o.name>></q>. ');
                }
        }
;

This time around >FOOZLE [object] reports the object’s outermost container (with the idiosyncracy that a container is considered its own outermost container, a la the getOutermostRoom() logic—this could obviously be changed if it’s not what you want). That gets us:

Void
This is a featureless void.

You see a box (which contains a vase (which contains a pebble)) here.

>foozle pebble
The outermost container for the pebble is "box".

>foozle vase
The outermost container for the vase is "box".

>foozle box
The outermost container for the box is "box".

>foozle me
No outermost container found.

For rounding BigNumber values, use roundToDecimal(). If foo is a BigNumber and you want to round it to 3 decimal places, then you want something like foo = foo.roundToDecimal(3).

2 Likes

Oh, missed one.

In order to prompt for an iobj and then remap, use askForIobj():

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

startRoom: Room 'Void' "This is a featureless void. ";
+me: Person;
+bucket: Container '(wooden) bucket' 'bucket' "A wooden bucket. ";
+pebble: Thing 'small round pebble' 'pebble' "A small, round pebble. ";

versionInfo: GameID;
gameMain: GameMainDef initialPlayerChar = me;

DefineTIAction(FoozleWith);
VerbRule(FoozleWith)
        'foozle' singleDobj 'with' singleIobj: FoozleWithAction
        verbPhrase = 'foozle/foozling (what) (with what)'
;

DefineTAction(Foozle);
VerbRule(Foozle)
        'foozle' singleDobj: FoozleAction
        verbPhrase = 'foozle/foozling (what)'
;

modify Thing
        dobjFor(FoozleWith) {}
        iobjFor(FoozleWith) {
                action() {
                        defaultReport('{You/He} foozle{s} {the dobj/him}
                                with {the iobj/him}. ');
                }
        }
        dobjFor(Foozle) {
                action() { askForIobj(FoozleWith); }
        }
;

Now we have a >FOOZLE [dobj] action and a >FOOZLE [dobj] WITH [iobj] action:

Void
This is a featureless void.

You see a pebble and a bucket here.

>foozle bucket
What do you want to foozle it with?

>pebble
You foozle the bucket with the pebble.

>foozle 
What do you want to foozle?

>bucket
What do you want to foozle it with?

>pebble
You foozle the bucket with the pebble.

2 Likes

My opinions, I’m not a mod:

I would go with separate topics, for a couple of reasons. It’s generally easier to respond and comment on them that way, especially if the solution requires some back-and-forth between the OP and commenter(s).

Also, this message board does double-duty as a kind of knowledge base. Breaking them out one-by-one (theoretically) makes them easier to find, especially if the topic title is worded well.

TADS is, alas, a lower-traffic topic on the board (compared to Inform and Twine). Anything that boosts our stats is a boon!

There are a few official chat channels here. (On my interface, they can be found in the three-line “hamburger” menu at the top of the page.) However, the general feeling is to put technical and craft questions up for discussion here, and use the chat channels for more ethereal topics.

2 Likes