Something that >undo doesn't undo! (TADS3)

i have a quick check at the start of my game to see if the player types in a naughty word within the first 20 moves. Here is the code (with the naughty word replaced by “Obscene” for the sake of decorum here in the forum).

DefineIAction(Obscene) checkAction () { if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) { "(Well <i>that</i> didn't take you long!)\b"; me.obscenity_surprise = true; }
This works as expected, except that if the player types >undo, and the repeats the obscenity, the message doesn’t appear. I suspect this means that libGlobal.totalTurns isn’t behaving the way I expect it to.

This is not a big deal right now - it’s just a small joke. But if it later becomes important for libGlobal.totalTurns to work, does that mean that >undo will prevent it from doing so?

–Bob

Quick correction…

I actually have 2 versions of the obscenity test, one intransitive and one transitive. The code I posted for the intransitive version is working. It’s the intransitive version that isn’t working with >undo. Here is the code.

[code]DefineTAction(ObsceneObj);

VerbRule(ObsceneObj)
(‘xx’ | ‘yy’)
singleDobj
: TouchTAction, ObsceneObjAction
verbPhrase = ‘hump/humping (what)’
askDobjResponseProd = singleNoun
;

modify Thing
dobjFor(ObsceneObj)
{
verify() {
if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) {
“(Well that didn’t take you long!)\b”;
me.obscenity_surprise = true;
}
illogical('Sounds very painful. ');
}
}
;
[/code]
–Bob

What’s going on here … it took me a minute to test it and then notice the problem … is that you must never alter the state of the game in a verify() block. verify() is called several times while the parser is working out what the player’s command meant.

This works, I think:

modify Thing dobjFor(ObsceneObj) { verify() { if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) { logical; } else illogical('Sounds very painful. '); } action() { "(Well <i>that</i> didn't take you long!)\b"; me.obscenity_surprise = true; } } ;

This gets me most of the way there, but it leaves me only with the parenthetical response ("…didn’t take long…" and not the actual response ("…painful…").

So I added the actual response into the action() code, which works for Thing, but when I do the same for Person, I get two “…didn’t take long…” msgs, (probably because verify () is taking another pass because we’re dealing with a Person?).

I don’t know where to put the actual response in the Person code so that we only get one snarky comment from the game instead of two.

[code]modify Thing
dobjFor(ObsceneObj)
{
verify() {
if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) {
logical;
}
else illogical('Sounds very painful. ');
}
action() {
“(Well that didn’t take you long!)\b”;
if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) {
"Sounds extremely painful. ";
}
me.obscenity_surprise = true;
}
}
;

modify Person
dobjFor(ObsceneObj)
{
verify() {
if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) {
logical;
}
else illogical('Please try to control yourself. ');
}
action() {
“(Well that didn’t take you long!)\b”;
if ((libGlobal.totalTurns < 20) && !me.obscenity_surprise) {
"Good luck with that. ";
}
me.obscenity_surprise = true;
}
}
;
[/code]

Thanks, yet again!

–Bob

Not sure why you’d get the same response twice. I didn’t see that output. But I think the ordering of the lines of code needs a little more tweaking. I think this is what you’re aiming to do:

[code]modify Thing
dobjFor(ObsceneObj)
{
verify() {
if ((libGlobal.totalTurns < 5) && !me.obscenity_surprise) {
logical;
}
else illogical('Sounds very painful. ');
}
action() {
if ((libGlobal.totalTurns < 5) && !me.obscenity_surprise) {
me.obscenity_surprise = true;
“(Well that didn’t take you long!)\b”;
}
else "Sounds extremely painful. ";

    }
}

;

modify Person
dobjFor(ObsceneObj)
{
verify() {
if ((libGlobal.totalTurns < 5) && !me.obscenity_surprise) {
logical;
}
else illogical('Please try to control yourself. ');
}
action() {
if ((libGlobal.totalTurns < 5) && !me.obscenity_surprise) {
“(Well that didn’t take you long!)\b”;
me.obscenity_surprise = true;
}
else "Good luck with that. ";
}
}
;[/code]
In my brief test, this seems to produce only one output for any given command. (I reduced totalTurns to 5 for ease of testing.)

Oh, and by the way – if you end some quoted lines with a \b and don’t end others that way, T3 is going to give you inconsistent vertical spacing in the game text. I suggest always ending a line with a space, and skip the \b entirely.

Interesting – when I plug your code straight into my game, >Obscene foo gets only the snarky comment, and not the follow-on. But >Obscene person behaves properly, with both the snarky comment and the follow-on. I’m too tired to track this down tonight, but will check into it again tomorrow. --Bob

Just to wrap this up, I figured everything out. The double message was caused an earlier attempt to handle this in another part of the code. So all is good, and thanks for the help.