1
SCI Syntax Help / Re: [SOLVED] SCI0 - Autosave
« on: January 05, 2021, 09:10:08 AM »
QfG3 had autosave, too... although they only used it like 2 or 3 times, if I recall right.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
(procedure (HandsOn)
;Enable ego control
(= isHandsOff FALSE)
(User canControl: TRUE canInput: TRUE)
(theGame setCursor: normalCursor (HaveMouse))
)
(procedure (HandsOff)
;Disable ego control
(= isHandsOff TRUE)
(User canControl: FALSE canInput: FALSE)
(theGame setCursor: waitCursor TRUE)
(ego setMotion: 0)
)
(instance music of Sound
(properties
number 26
priority 10
)
)
I think you probably have similar. Eric's Template stores that instance in a variable called theMusic. It appears QFG1EGA only calls it directly.
Would it be rude of me to implement just the death counter and type in my game similar to what you are doing here? I think it's a really cool idea.
;;; Sierra Script 1.0 - (do not remove this comment)
(script# 650)
(include system.sh) (include sci2.sh) (include game.sh)
(use Main)
(use _Inventory)
(use _System)
(use _Interface)
(public
theDeathSheet 0
)
(define SMALL_LINE_HEIGHT 9)
(procedure (DisplayDeathText death x y &tmp invQty [str 40])
(Display
651 (- death DIE_START)
p_at (+ x 5) y
p_mode teJustLeft
p_font smallFont
p_color (if (== death prevDeathNum) vLRED else vLBLUE)
)
;display name of death
)
(procedure (DisplayDeathHeader &tmp [str 40])
;Displays a different header depending on how many deaths we've had
;
(cond
((== deathCount 0)
(Display
650 0
p_at 10 8
p_mode teJustLeft
p_font 300
p_color vBLUE
)
;You haven't died at all. Don't be afraid to explore and try new things.
)
((== deathCount 1)
(Display
650 1
p_at 10 8
p_mode teJustLeft
p_font 300
p_color vBLUE
)
;You have died once.
)
((== deathCount deathCountUnique)
(Display
(Format @str 650 2 deathCount)
p_at 10 8
p_mode teJustLeft
p_font 300
p_color vBLUE
)
;You have died %u times.
)
(else
(Display
(Format @str 650 3 deathCount deathCountUnique)
p_at 10 8
p_mode teJustLeft
p_font 300
p_color vBLUE
)
;You have died %u times, in %u unique ways
)
)
)
(procedure (DisplayDeathPage pageStart offset &tmp i x y nextDeathStart)
(= i pageStart)
(= x 10)
(= y (+ 24 (* offset SMALL_LINE_HEIGHT)))
(= nextDeathStart 0)
(while (<= i DIE_END) ;there are currently 60 deaths. So that's how many we will show.
;if this is a true death, and it doesn't match the most recent death
(if (and (Btst i) (not (== i prevDeathNum)) )
(if (<= y 160)
;display the death text
(DisplayDeathText i x y)
else
;otherwise, make note of where to start the next page, and end this page.
(= nextDeathStart i)
(= i DIE_END)
)
;increment to the next line. If the next line is too far down, shift to the next column
(= y (+ y SMALL_LINE_HEIGHT))
(if (and (> y 160) (== x 10))
(= y 24)
(= x 170)
)
)
(++ i)
)
(return nextDeathStart)
)
(class DeathSheet of Object
(properties
nsTop 0
nsLeft 0
nsBottom southEdge
nsRight MAXRIGHT
theWindow NULL
state 0
register 0
more FALSE
startAt 0
)
(method (init &tmp i x y pageStart [str 40])
(super init:)
(self clearWindow:)
(self drawContents:)
)
(method (drawContents &tmp pageStart offset)
;decide what header to show
(DisplayDeathHeader)
;if there's a new death, we'll show that at the top row
(= offset 0)
(if prevDeathNum
(DisplayDeathText prevDeathNum 10 24)
(= offset 1)
)
;now we show the individual deaths.
(= pageStart (DisplayDeathPage (+ DIE_START startAt) offset))
(if (> pageStart DIE_START)
(= startAt pageStart)
(= more TRUE)
(Display 206 3 p_at 200 172 p_mode teJustRight p_font 300 p_color vBLUE p_width 100)
;(and more . . .)
else
(= more FALSE)
)
;now show the second page, then third page, etc. until we're done.
;clear any "Previous Death" flags.
(= prevDeathNum 0)
)
(method (clearWindow &tmp newWindow)
(= newWindow
(NewWindow nsTop nsLeft nsBottom nsRight {} nwNORMAL nwON_TOP vBLUE vWHITE)
)
(if theWindow
(DisposeWindow theWindow)
)
(= theWindow newWindow)
)
(method (doit &tmp newEvent evtType)
(= evtType nullEvt)
(while (not evtType)
(GlobalToLocal (= newEvent (Event new:)))
(cond
((not more)
(= evtType (newEvent type?))
)
((and (== keyDown (newEvent type?)) (== KEY_ESC (newEvent message?)) )
;there's more to see, but the user has clicked ESC
(= evtType (newEvent type?))
)
((not (== nullEvt (newEvent type?)))
;do anything else
(= evtType (newEvent type?))
;CI: TODO: Show a second page.
;(Print {Skip to next page})
;(self clearWindow:)
)
)
;(= evtType (newEvent type?))
(newEvent dispose:)
)
(self dispose:)
)
(method (dispose)
(DisposeWindow theWindow)
(super dispose:)
(DisposeScript 650)
)
)
(instance theDeathSheet of DeathSheet
(properties)
)
(enum
$500 infoM
invI
charI
divider501I
timeI
askI
lookI
divider502I
deathsI
)
I decided on CTRL-H for the DeatH List. I had also changed the Time/Day to line up with QFG2. (AddMenu
{ Information_}
{Inventory`^i:Char Sheet`^s:--!:Time/Day`^d:Ask about`^a:Look at`^l:--!:Deaths List`^h}
)
(method (handleEvent event &tmp [i 3] newVol [str 300] temp304)
(switch (super handleEvent: event)
(deathsI
;(Print {Not yet implemented.} #title {Deaths List})
(cond
((or (not (HaveMem 2000)) (== curRoomNum 95)) ;brigand dining hall (presumably, this room requires a lot of memory)
(HighPrint MENU 5)
;Sorry, there's not enough room to see that here.
)
((not isEgoLocked)
((ScriptID 650 0) init: doit:)
)
)
)
)
)
(EgoDead
0 28
#title {The surgeon general warns . . ._}
#icon (GetEgoViewNumber vEgoDeathScenes) 0 0
)
Specify the view, then the title, icon, etc.(EgoDead
DIE_NOFLAG
0 28
#title {The surgeon general warns . . ._}
#icon (GetEgoViewNumber vEgoDeathScenes) 0 0
)
(EgoDead
DIE_RETRY DIE_PICKNOSE
0 28
#title {The surgeon general warns . . ._}
#icon (GetEgoViewNumber vEgoDeathScenes) 0 0
)
(EgoDead DIE_RESTART
0 28
#title {The surgeon general warns . . ._}
#icon (GetEgoViewNumber vEgoDeathScenes) 0 0
)
;These are death flags. They're used to track which ways the user has died.
;They will be shown at the end of the game.
; unique deaths
(define DIE_RESTART -2) ;show Restore, Restart, Quit; (same as not specifying anything at all) instead of Retry, Restore, Quit)
(define DIE_RETRY -1) ;show a Retry, Restore, Quit
(define DIE_NOFLAG -1) ; a retry is shown, but nothing is flagged.
;explicitly define the starting number, ending number and death count, which will be used in the DeathSheet script.
(define DIE_START 450)
(define DIE_COUNT 79)
(define DIE_END 528)
;there are roughly 100 deaths, so we'll reserve flags 450-550 for them (with room for 50 more in expansion up to flag 600)
(enum 450
DIE_NOSTAMINA
DIE_PICKNOSE
DIE_ARRESTED
DIE_NIGHTGAUNT
)
(procedure (Bset bit)
(= [eventFlags (/ bit 16)]
(|
[eventFlags (/ bit 16)]
(>> $8000 (mod bit 16))
)
)
)
(procedure (Bclr bit)
(= [eventFlags (/ bit 16)]
(&
[eventFlags (/ bit 16)]
(~ (>> $8000 (mod bit 16)))
)
)
)
(procedure (Btst bit)
(return
(&
[eventFlags (/ bit 16)]
(>> $8000 (mod bit 16))
)
)
)
(enum 1
RESTORE
RESTART
QUIT
RETRY
)
(procedure (EgoDead what how &tmp printRet)
;stops all sounds, plays the death music, and gives the player a choice:
; Restore, Restart, Quit or
; Retry, Restore, Quit
;
; 'what' decides what we're doing: Restart or Retry.
; if 'what' == DIE_RETRY (-1), it's a Retry death;
; if 'what' == DIE_RESTART (-2), it's a Restart death (explicitly defined).
; any other values are assumed to be the original EgoDead function, for a Restart death (implicitly defined),
; and should be fully passed to the Print procedure.
;
; 'how' is this specific death's flag, to be set in the eventFlags variable, via the Bset function
;
; (CI: NOTE: This procedure is a recreation, based on Eric Oaklands's SCI01 template)
; https://github.com/EricOakford/SCI01-Template/blob/master/src/Main.sc
; it has been modified to more closely match the original asm, which is commented out but intact above,
; then has been further modified to support a Retry mode.
(HandsOff)
(Wait 100)
(theGame setCursor: normalCursor TRUE)
(sounds eachElementDo: #stop)
(if (!= deathMusic NULL)
(music number: deathMusic priority: 15 init: play:)
)
;if we're specifying a way the player died, then we'll set the flag for that death method.
(if (and (== what DIE_RETRY) (!= how DIE_NOFLAG))
(++ deathCount)
(= prevDeathNum how) ;we're going to flag out *every* time the hero dies.
(if (not (Btst how))
(Bset how)
(++ deathCountUnique)
)
)
(repeat
(= printRet
(cond
;1st priority: the new Retry dialog
((== what DIE_RETRY)
(Print &rest
#width 250
#button { Retry_} RETRY
#button {Restore} RESTORE
#button { Quit_} QUIT
)
)
;2nd priority: an explicit DIE_RESTART flag with no second parameter
((== what DIE_RESTART)
(Print how &rest
#width 250
#button {Restore} RESTORE
#button { Restart_} RESTART
#button { Quit_} QUIT
)
)
;finally, any original script EgoDeath scripts
((>= what 0)
(Print what how &rest
#width 250
#button {Restore} RESTORE
#button { Restart_} RESTART
#button { Quit_} QUIT
)
)
)
)
(switch printRet
(RESTORE ;restore
(theGame restore:)
)
(RESTART ;restart
(theGame restart:)
)
(QUIT ;quit
(= quit TRUE)
(break)
)
(RETRY ;retry
(if (!= deathMusic NULL)
(music stop:)
)
(HandsOn)
(break)
)
)
)
)
deathCount ;added by CI: the total number of times Ego has died (shown on the Death List)
deathCountUnique ;added by CI: the number of unique ways Ego has died (shown on the Death List)
prevDeathNum ;added by CI: Used to highlight the most recent death in the Death List.
Wouldn't you also need to store all status, inventory items, etc. right before ego enters the situation that kills him for the retry? Wouldn't that require modification at each danger point?That's exactly the sort of challenge I faced at the outset. Most of the time, if you die it's because of something you immediately did wrong. Like step on the wrong trap in the Brigand Fortress, or fall down a hole in the Graveyard, etc. Those are easy. Just back track to right before you did that one thing -- reposition ego, reset any views, undo any flags.
I also don't remember, but does the Mandrake plant grow back if you take it in the daytime?
Even if it does grow back, I think if you try to take it the day you get the Baba Yaga quest it won't be there for you at midnight, resulting in an unwinnable state. Probably just having it spawn at midnight would solve this problem.
Also, I love the death achievement log! I'm not sure how you are achieving that, but I would love to add something like that to my current project...but I guess it includes a huge overhaul of the entire save/restore system. Still, I really love it!
However, what about dead-ends? I guess you'll have to restore, and lose any unsaved death achievements?
Are there any dead-ends in QfG1?
SMF 2.0.14 |
SMF © 2017, Simple Machines
Simple Audio Video Embedder
Page created in 0.124 seconds with 22 queries.