Ah yes. The skip button. You don’t see those often in most of the old Sierra adventure games, and to be honest I’m not interested enough in the later ones to check. Sue me. But how do they work?
As usual, let’s look at the scripts.
First, we have Leisure Suit Larry 5 – Passionate Patti does Pittsburgh, which shares its skip system with Freddy Pharkas Frontier Pharmacist. The only notable difference between the two is that, being an SCI11 game, the latter uses Messages instead of Text resources. This system has two dedicated parts to it, plus how the current scene reacts:
(instance icon5 of IconI ; ... (method (select) (return (if (and gFFRoom (super select: &rest)) ; That is, if we had a gFFRoom set and the usual response to a button click was true. (gIconBar hide:) (if (Print "Do you really want to skip ahead?" #title "Fast Forward" #button "Yes" 1 #button "Oops" 0) (if (== gFFRoom 1000) ; In this case, we want to cue something. (if (IsObject gFFScript) (gFFScript cue:) (SetFFRoom 0) else (Print "ERROR: Object passed to SetFFRoom isn't an object you silly person!") ) else ; In the *other* case, we just want to go somewhere. ; This option is good for larger cutscenes. (gRoom newRoom: gFFRoom) (= gFFRoom (+ gFFRoom 1000)) ; ... I'm... not entirely sure what that was for. ) ) else (return 0) ) ) ) ) (procedure (SetFFRoom room script) (if (not room) (= gFFRoom 0) (= gFFScript null) (gIconBar disable: 5) else (= gFFRoom room) (if (and (> argc 1) (== room 1000)) (= gFFScript script) ) (gIconBar enable: 5) ) )
Call SetFFRoom
with anything but 1000, and you set up a skip to another room. Call it with “room” 1000 and a cue-able object otherwise. Pretty simple, I don’t think I need to bother with a practical example.
Incidentally, this makes one of the examples of a non-standard procedure whose name is absolutely certain.
On to Leisure Suit Larry 6 – Shape Up or Slip Out. This is the low-res SCI11 version, but I sincerely doubt the SCI2 version is much different. It has only one shared part, the icon, without a setup procedure. Note that icon5
is exported as ScriptID 0 8
, hence the references throughout.
(instance icon5 of BarIconI ; ... (method (doit &tmp theTarget) (cond ((not gSkipTarget) ; Don't do anything if no skip was set up. 0 ) ((not (IsObject gSkipTarget)) ; Skip target is a number, so a room. (gButtonBar disable: (ScriptID 0 8)) ; icon5 that is. (= theTarget gSkipTarget) (= gSkipTarget null) (gRoom newRoom: theTarget) ) (else ; Skip target is something to cue. (gButtonBar disable: (ScriptID 0 8)) (= theTarget gSkipTarget) (= gSkipTarget null) (theTarget cue:) ) ) ) )
As an example, here’s the ladder-climbing sequence with Merrily:
(instance rm260 of LarryRoom (properties picture 260 horizon 11 ) (method (init) (super init: &rest) (= gSkipTarget gRoom) ((ScriptID 0 8) enable:) (self setScript: toTower) ; ... ) (method (cue) ; Called when we click the Fast Forward button. ((gRoom script?) setScript: forwardScript) ) ) (instance forwardScript of Script (properties) (method (changeState newState &tmp oldCursor) (switchto (= state newState) ( (= cycles 2) ) ( (= oldCursor gCursor) (gGame setCursor: 999) (SetCursor 225 87) (if (Print addTitle: "Just Not Into Rubber, Larry?" addText: "Do you really want to miss out on what promises to be a unique experience, Larry?" addButton: 0 "Oops" 0 35 addButton: 1 "Yes" 155 35 init: ) (self cue:) else (gGame setCursor: oldCursor) ; Reset the skip and get rid of this script. (= gSkipTarget gRoom) (self dispose:) ) ) ( ; We chose to skip. Change up our inventory... (gEgo get: 40 put: 35 put: 31 put: 20 put: 2) (= gSkipTarget null) ((ScriptID 0 8) disable:) (gGame handsOff: changeScore: 20 174 hideControls:) (= cycles 2) ) ( (SetPort 0) (SetPort 0 0 190 320 10 0) (Bset 8) (gSounds stop:) (DrawPic 98 dpOPEN_EDGECENTER) ; Black screen (gCast eachElementDo: #hide) (= cycles 2) ) ( (gRoom newRoom: 620) ; Go to your room ) ) ) )
And then there’s The Dating Pool. It has a simple skip system with a single global, like LSL6, but comes in two parts like LSL5 and FPFP.
(instance SkipIcon of cdIconItem (method (select) (if gSkip ; I *could* ask for confirmation here... (gIconBar hide:) (if (IsObject gSkip) (gSkip cue:) else (NewRoom gSkip) ) (return true) ) ) ) (procedure (SetSkip skip) (= gSkip (if argc skip else 0)) (if gSkip ; Unlike LSL6's ButtonBar, an IconBar's IconItem doesn't have enable or disable methods. (SkipIcon signal: (| icHIDEBAR icRELEASE icIMMEDIATE)) else ; I could let gIconBar enable or disable the icon but nyeh. (SkipIcon signal: (| icHIDEBAR icRELEASE icIMMEDIATE icDISABLED)) ) )
And an example:
(instance IntroScript of Script (method (changeState newState) (switchto (= state newState) ( (HandsOff) (SetSkip skipScript) ; ... ) ; ... ) ) ) (instance skipScript of Script (method (cue) (DrawPic 150 dpFADEOUT) ; Put us at place we'd be if we let the cutscene play out. (gEgo init: posn: 90 130 resetCycler: view: 0 loop: 2 ) (gRoom setScript: RoomScript) ) )
(Update: I’d changed the skip script in The Dating Pool to use cue
instead of doit
and allow gSkip
to be a room number. And then I forgot to update the example.)