Logo Pending


Hold up, let me try that again.

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.

Like
1
[ , , ]

Leave a Reply

Your email address will not be published. Required fields are marked *