Opened 6 years ago
Closed 6 years ago
#10772 closed defect (fixed)
QFG4: Rations icon persists in toolbar after all are eaten
Reported by: | Vhati | Owned by: | Vhati |
---|---|---|---|
Priority: | low | Component: | Engine: SCI |
Version: | Keywords: | SCI32 original has-pull-request | |
Cc: | Game: | Quest for Glory 4 |
Description
ScummVM 2.1.0git3770-g15306581ab (Oct 18 2018 04:27:32)
Windows 7 64bit
QFG4 CD (English)
If rations were the last item you selected, the sandwich icon will remain in the toolbar after they've all been eaten and removed from inventory.
Just restore the attached savegame, rest an hour couple times, and check you inventory.
You can still use the item as if you had one (offer it to the Burgomeister, eat it yourself, etc). If you manually eat the lingering sandwich, it will disappear from the toolbar.
The original interpreter also does this.
File - 5kb MD5 - Full MD5
RESOURCE.000 - 263dce4aa34c49d3ad29bec889007b1c - 1364ba69e3c0abb68cc0170650a56692
RESOURCE.AUD - c39521bffb1d8b19a57394866184a0ca - 71098b9e97e20c8941c0e4812d5f906f
RESOURCE.MAP - aba367f2102e81782d961b14fbe3d630 - 801a04cc6aa5d437681a2dd0b6545248
RESOURCE.SFX - 3cf95e09dab8b11d675e0537e18b499a - 7c858d7253f86dab4cc6066013c5ecec
Attachments (2)
Change History (11)
by , 6 years ago
comment:1 by , 6 years ago
Occurs in the floppy edition under ScummVM, and its original interpreter, too.
ScummVM 2.1.0git3770-g15306581ab (Oct 18 2018 04:27:32)
Windows 7 64bit
QFG4 Floppy 1.1a + note patch (English)
File - 5kb MD5 - Full MD5
RESOURCE.000 - f64fd6aa3977939a86ff30783dd677e1 - ff42260a665995a85aeb277ad80aac8a
RESOURCE.MAP - d10a4cc177d2091d744e2ad8c049b0ae - 3695b1b0a1d15f3d324ea9f0cc325245
RESOURCE.SFX - 3cf95e09dab8b11d675e0537e18b499a - 7c858d7253f86dab4cc6066013c5ecec
comment:2 by , 6 years ago
- gloryInv (global9) is a collection of inventory items. "global9 at: 4" is theRations.
- "proc0_4(n)" - Tests the given plot flag.
- "proc0_2(n)", "proc0_3(n)" - Not clear on what they each do, but definitely setters.
script 7 - advanceTime::init() calls hero::eatMeal().
script 28 - hero::eatMeal()
(method (eatMeal &tmp temp0) (= temp0 0) (cond (global136 (-- global136) (= temp0 1)) (((global9 at: 4) amount?) ((global9 at: 4) amount: (- ((global9 at: 4) amount?) 1) ) (if (not ((global9 at: 4) amount?)) ((global9 at: 4) owner: 0) # More needs to be done here! ) (= temp0 1) ) ((proc0_4 3) (if (self useStamina: 8 0) (global91 say: 1 6 5 1 0 28) else (proc26_0 8 28 995 1) ) ) ((proc0_4 2) (proc0_2 3) (global91 say: 1 6 6 1 0 28)) (else (proc0_2 2) (global91 say: 1 6 4 1 0 28)) ) (if temp0 (cond ((proc0_4 3) (proc0_3 3)) ((proc0_4 2) (proc0_3 2)) ) ) )
script 16 has a procedure to cleanup mainIconBar (global69) when it sets amount to 0 on an item.
(procedure (localproc_00cc &tmp temp0) (global69 curInvIcon: 0 advanceCurIcon:) (global69 disableIcon: (global69 at: 6)) (= temp0 (ScriptID 36 1)) (temp0 signal: (| (temp0 signal?) $0008)) (DeleteScreenItem temp0) ) // ... (if (== (global69 curInvIcon?) theBerries) (localproc_00cc) ) (theBerries amount: 0)
Something like that should be happening.
comment:3 by , 6 years ago
script 28 - hero::use(itemId, amount) both decrements and removes items properly. A drop-in replacement for that part of the cond block.
(method (use param1 param2 &tmp temp0 temp1) (if (> (= temp1 (if (== argc 1) 1 else param2)) ((global9 at: param1) amount?) ) (= temp1 ((global9 at: param1) amount?)) ) (self get: param1 (- temp1)) (if (< ((global9 at: param1) amount?) 1) (global69 curInvIcon: 0 advanceCurIcon:) (= temp0 (ScriptID 36 1)) (temp0 signal: (| (temp0 signal?) $0008)) (DeleteScreenItem temp0) ) (return temp1) )
Hm. global69 is the verb bar (mainIconBar). hero::use() advances the verb icon, regardless of whether the doomed item was originally selected. So the player's cursor would unexpectedly change after a rest that included eating. Should be enough bytes freed to cache that...
comment:4 by , 6 years ago
Gah. hero::use() unconditionally clears the active inventory item, too. Centralization would've been nice, but this wrapper is too long to be worth it. Might as well write a copy of the localproc_00cc quote above, including its if.
comment:5 by , 6 years ago
"ScriptID 36 1" is invItem, a View that resides on mainIconBar and takes the appearance of whichever item is active.
It's a little odd that nearly all the code that hides invItem manipulates signal directly and calls DeleteScreenItem().
(= temp0 (ScriptID 36 1)) (temp0 signal: (| (temp0 signal?) $0008)) (DeleteScreenItem temp0)
There's already a method to do that.
script 64998 - View::hide()
(method (hide) (if (self isNotHidden:) (= signal (| signal $0008)) (DeleteScreenItem self) (= -info- (& -info- $ffef)) ) )
The one exception is when restarting.
script 0 - Glory::restart()
(not (& ((= temp2 (ScriptID 36 1)) signal?) $0008)) (temp2 hide:) )
Even that is redundant. The signal test is built into hide().
script 64998 - View::isNotHidden()
(method (isNotHidden) (return (not (& signal $0008))) )
I don't see that -info- is doing anything.
Nothing to avoid. Certainly not dangerous. It's show/hide!
Article: ScummVM Wiki - SCI Intro, Object segments
Info typically has one of the following values (although this does not appear to be relevant for SCI)
Whereas, all the code that shows invItem, always calls show().
script 64998 - View::show()
(method (show) (if (not (self isNotHidden:)) (= signal (& signal $fff7)) (AddScreenItem self) (= -info- (| -info- $0010)) ) )
Switching to hide() makes for a shorter patch.
comment:6 by , 6 years ago
script 28 - Patch pseudocode
(method (eatMeal &tmp temp0 temp1 temp2) (= temp0 0) # (cond 1) (if global136 (-- global136) (= temp0 1) # Eaten. [Skip the other conditions] # Patch begins. ) # (cond 2) # theRations (= temp1 (g9_gloryInv at: 4)) (= temp2 (theRations amount?)) (if temp2 (temp1 amount: (-- temp2)) (if (== temp2 0) (temp1 owner: 0) (if (== (g69_mainIconBar curInvIcon?) temp1) # theRations was the active inventory item. (g69_mainIconBar curInvIcon: 0 advanceCurIcon: disable: 6 ) # invItem ((ScriptID 36 1) hide:) ) ) (= temp0 1) [Skip the other conditions] ) # The following blocks are the same, except say() is a subroutine. # (cond 3, "hungry" flag) ((proc0_4 3) (if (self useStamina: 8 0) (mySub 5) # "You're starving." else (proc26_0 8 28 995 1) # hero dies. ) [Skip the other conditions] ) # (cond 4, "missed meal" flag) ((proc0_4 2) (proc0_2 3) (mySub 6) # "Really getting hungry." [Skip the other conditions] ) # (cond else) (else (proc0_2 2) (mysub 4) # "Get food soon." ) (subroutine (mySub param1) (g91_gloryMessager say: 1 6 param1 1 0 28) ) # Patch ends. (if temp0 (cond ((proc0_4 3) (proc0_3 3)) ((proc0_4 2) (proc0_3 2)) ) ) )
comment:7 by , 6 years ago
Keywords: | has-pull-request added |
---|
Pull Request: SCI32: Fix QFG4 rations icon removal after eating
comment:9 by , 6 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
SavedGame (CD) - Rest away rations