In Leisure Suit Larry 6 – Shape Up or Slip Out, there are many ways to die, much like any other Larry game or indeed any Sierra game. Interestingly, this one has a “Try Again” button! How does that work?
Let’s work it out backwards. Starting from the script that handles the death message, we find it takes two parameters. One we can quickly determine to be the reason Larry died, the other we can tell is some sort of reference to a Script
instance. After all, at one point the procedure checks if it’s an object in the first place, and in another it tries to cue
the thing:
(while (not theAnswer) (Print font: gFont addTitle: @theTitle addText: @theMessage theMessageX theMessageY addIcon: frameIcon 0 0 2 0 addIcon: (deathIcon view: theView cel: 0 loop: theLoop yourself:) 0 0 theIconX theIconY ) (switch (= theAnswer (Print addButton: 1 2 0 3 1 (+ theMessageX 1) theButtonY scriptNumber addButton: 0 2 0 2 1 (- ((Print dialog?) nsRight?) 75) theButtonY scriptNumber init: ) ) (0 ; Try Again (gLarryWindow back: prevBackColor) (gLSL6 setCursor: oldCursor) (gSounds eachElementDo: #pause false) (if rewindScript (rewindScript cue:)) (= theAnswer -1) ) (1 ; Restore (= local19 0) (gLSL6 restore: hideControls: drawControls:) (= theAnswer 0) ) ) )
So there’s two things that can happen when you click “Try Again”. Either rewindScript
is valid and it gets cue
‘d before EgoDead
returns -1, or it merely returns -1.
Taking a step back, we’ll look at one point where it gets called. In my case, opening the door to the swimming pool:
(instance enterPoolScr of Script (method (changeState newState) (switchto (= state newState) ( (gGame handsOff:) (if (gMusic handle?) ; Pause whatever we're playing (gMusic pause:) ) (gEgo setSpeed: 8 view: 901 ; Grabbing the door loop: 6 cel: 0 setCycle: End self ) ) ( (sfx number: 518 loop: 1 play: ) (barDoor view: 5101 setCycle: End self ) (= ticks 10) ; Can you see the possible mistake here? ) ( (gEgo view: 5101 ; \o/ loop: 2 cel: 0) ) ( (= ticks 180) ) ( ; This is it. This is where we call the death routine. (EgoDead 13 self) ) ( ; "Try Again" was chosen, so we reset everything. (if (gMusic handle?) ; Unpause (gMusic pause: false) ) (gEgo normalize: 900 8 1 cel: 2 ) (barDoor view: 510 loop: 0 cel: 0 ) (gGame handsOn:) (self dispose:) ) ) ) )
So! You click the hand on the pool door, it animates a bit, calls EgoDead
with the correct reason. That in turn recognizes reason 13, picks out the little animation and window color, fetches the right text from its Message resource (noun 2, verb 0, condition 13, sequence 1 and 2 for the joke and title respectively), and displays the window. If you click “Restore”, it keeps looping until you actually do restore something. If you click “Try Again”, it cues the caller (enterPoolScr
in this case), which then sets it up like you never clicked the door in the first place.
And that’s how it works.