Here’s a pretty little problem. I have a dangerous throne, on the seat of which rests a cushion. The player may try to sit on the throne, which works as expected – the player will get zapped, and will leap up again. But instead, the player may try SIT ON CUSHION. When this happens, there seems to be an implicit action running in the background. Even though the dobjFor(SitOn) code in the cushion object does not permit the action to go forward, the player object ends up sitting on the throne anyhow.
Note that I’ve included postures.t, which is where the Chair class is defined.
EDIT: Found the solution (but I’ll keep the rest of the message, describing the problem, in case someone is wondering what the fuss is about). Here’s the solution:
dobjFor(SitOn) {
remap () { if (isIn(throne)) return throne; else return nil; }
verify() { if (!isIn(throne)) illogicalNow ('The cushion is not arrayed
in a manner that would be conducive to sitting. ');
}
}
Here’s the output that demonstrates the problem:
> sit on cushion
(first getting on the throne)
You step up to the throne, turn, and sit. ZAP!!! A powerful shooting pain stabs you from near the base of your spine straight up to the top of your head! You leap off the throne, breathing rapidly and trembling.
> l
Throne Room (sitting on the throne)
Remarkable for its grand splendor (a cynic might call it ostentation), the Throne Room is dominated by an enormous throne encrusted with gold and jewels. On the walls, gently billowing tapestries depict a variety of legendary events.
A broad stairway leads down to the east. Mounted in the south wall is a square hatch.
You are on the throne.
That shouldn’t happen. The player should not be on the throne.
Note also that if the player tries SIT ON THRONE first, it operates normally, but if the second command is then SIT ON CUSHION, the player object is automatically sent to the throne, even though the cushion object should not be allowing that.
Here’s the code:
-
+ throne: Chair, Fixture ‘throne; imposing splendid huge massive; chair’ "The throne from which your father once ruled Oz is huge and decorated with a stunning array of gold and jewels. Its back is high and its armrests are thick. A plump purple cushion provides comfort for the royal fundament. Your father’s royal sceptre is attached to the throne’s right-hand armrest. " isDangerous = true hasZapped = nil canStandInMe = nil canStandOnMe = nil canLieInMe = nil canLieOnMe = nil dobjFor(SitOn) { verify() {} check() { if (isDangerous && hasZapped) "Nothing would induce you to try that experiment again. "; } action() { if (isDangerous) { hasZapped = true; "You step up to the throne, turn, and sit. ZAP!!! A powerful shooting pain stabs you from your nether region up your spine to the top of your head! You leap off the throne, breathing rapidly and trembling. "; } else inherited; } } ; ++ purpleCushion: Thing ‘plump purple cushion’ "The cushion is decorated with gold tassels. " dobjFor(SitOn) { verify() { if (!(location == throne)) illogicalNow ('The cushion is not arrayed in a manner that would be conducive to sitting. '); } check() { if (throne.isDangerous && throne.hasZapped) "Nothing would induce you to try that experiment again. "; } action() { if (throne.isDangerous) { throne.hasZapped = true; "You step up to the throne, turn, and sit. ZAP!!! A powerful shooting pain stabs you from near the base of your spine straight up to the top of your head! You leap off the throne, breathing rapidly and trembling. "; exit; } else { "Testing. "; doInstead(SitOn, throne); } } } isListed = (!isIn(throne)) ;
I had originally tried simply redirecting SIT ON CUSHION to SIT ON THRONE using a doInstead(SitOn, throne) in the cushion’s action() block, but that didn’t work. That was why I tried just copying the code for the throne into the cushion object. That didn’t work either.
Running in the debugger to check the value of me.location suggests strongly that an implicit action is causing SIT ON CUSHION to be redirected somehow to SIT ON THRONE (silently, with no output) after the cushion’s SitOn verify() runs but before SitOn check() is evaluated. But neither the throne nor the cushion has a defined beforeAction, so I don’t see how this could happen.
I’m sure there’s probably a simple way to do what I have in mind, but I’m a bit baffled.