SCI: QFG1VGA: Dagger Range script bug freezes game or reanimates the dead
|Quest for Glory 1
The dagger range has a script bug that can freeze the game or cause Brutus to kill you even after you've killed him. This is a bug in the original game. I believe that a script patch to prevent setting flag 324 will fix this.
What normally happens:
When spying on Brutus and Bruno when they meet at the dagger range (room 73), they talk and Bruno leaves and Brutus stays.
You can kill Brutus by throwing a dagger or a rock, or you can just leave. If you do neither then after 5 minutes he kills you with a throwing dagger.
You can't reach Brutus because you're spying behind bushes, you have to leave the room and re-enter from the south (room 80)
If you enter room 80 before 40 seconds have passed since Bruno left then Bruno is there and kills you.
If you return to room 73 from the east or west and haven't killed Brutus, Brutus kills you with a throwing dagger.
If you return to room 73 from the south and hadn't killed Brutus then you fight to the death.
Either way, once Brutus is dead, you search his body to get a key. The body will then be gone next time you enter room 73.
Where it goes wrong:
When Bruno leaves, a 300 tick countdown starts. If you kill Brutus or leave room 73 within those 300 ticks then the game is left in a broken state. For the rest of the game, if you ever return to the dagger range from the east or west during the first half of the day then the game will freeze or Brutus will come back to life and kill you, even if you already killed him.
Here are two ways to reproduce this, but there are many combos:
- Kill Brutus within 300 ticks
- Leave room 73
- Re-enter room 73 from east or west
- Brutus will still be lying dead but then launch into dagger throwing and kill you
- Leave the room within 300 ticks
- Re-enter from the south
- Fight and kill Brutus
- Search body to get key
- Re-enter from east or west (any time before sunset approaches)
- The game will freeze
The problems are in scripts brutusWaits and sEnterFromEast/sEnterFromWest.
brutusWaits starts as soon as Bruno leaves.
state 0: sets flag 324 and sets a countdown for 300 ticks before the next state
state 1: unsets flag 324 and sets a countdown for 5 minutes (minus the 300 ticks) before the next state
state 2: runs script brutusThrows which kills you with a dagger
When Brutus dies or you leave the room, the brutusWaits script stops. If that happens during state 0, flag 324 is never unset.
When entering the room from the side, sEnterFromEast and sEnterFromTheWest do this:
if local2 setScript brigsMeet else if (global119 < 4) && (local6 || isFlagSet(324)) setScript brutusThrows
global119 is time of day and can be 0 through 7. 4 is "sunset approaches". You spy on Bruno and Brutus at 2 ("midday").
local6 is true if Brutus is alone and alive and you entered from east or west.
Flag 324 is only true during the 300 tick window.
Flag 324 isn't read or written anywhere else. I don't know its purpose but in this case it overrides whether Brutus is present or alive.
The game freeze occurs if you have already searched the body. This causes Brutus' view (74) to not be loaded because he's no longer supposed to be here, but brutusThrows expects the view to have been loaded.
Since flag 324 isn't used anywhere else, and doesn't appear to have any effect except for this negative one, any patch that prevents it from being set should fix it. sEnterFromTheEast and sEnterFromTheWest work correctly when the flag isn't set.
Attached is a save game from right after Bruno leaves. The brutusWait script is at around 250 ticks so there's still time to throw a dagger or leave to cause the flag to stay set.