SCI: Fix SQ4CD Cedric easter egg, bug #10920
This commit is contained in:
parent
e898ed379f
commit
43ab746a45
1 changed files with 146 additions and 0 deletions
|
@ -117,6 +117,8 @@ static const char *const selectorNameTable[] = {
|
|||
"modeless", // King's Quest 6 CD
|
||||
"cycler", // Space Quest 4 / system selector
|
||||
"addToPic", // Space Quest 4
|
||||
"stop", // Space Quest 4
|
||||
"canControl", // Space Quest 4
|
||||
"loop", // Laura Bow 1 Colonel's Bequest, QFG4
|
||||
"setLoop", // Laura Bow 1 Colonel's Bequest, QFG4
|
||||
"ignoreActors", // Laura Bow 1 Colonel's Bequest
|
||||
|
@ -213,6 +215,8 @@ enum ScriptPatcherSelectors {
|
|||
SELECTOR_modeless,
|
||||
SELECTOR_cycler,
|
||||
SELECTOR_addToPic,
|
||||
SELECTOR_stop,
|
||||
SELECTOR_canControl,
|
||||
SELECTOR_loop,
|
||||
SELECTOR_setLoop,
|
||||
SELECTOR_ignoreActors,
|
||||
|
@ -11256,6 +11260,145 @@ static const uint16 sq4PatchZeroGravityBlast[] = {
|
|||
PATCH_END
|
||||
};
|
||||
|
||||
// Cedric the owl from KQ5 appears in the CD version of Ms. Astro Chicken, but a
|
||||
// bug in this easter egg makes it a much rarer occurrence than intended.
|
||||
//
|
||||
// Every 50 ticks there's a 1 in 21 chance of Cedric appearing if there's no
|
||||
// rock on screen and he hasn't already been killed by colliding with the
|
||||
// player or getting shot by the farmer. The problem is that unless Cedric
|
||||
// appears before the farmer, which is very unlikely, then the farmer's first
|
||||
// bullet will kill Cedric off-screen due to incorrect collision testing.
|
||||
// buckShot:doit tests for collision by calling cedric:onMe, but Cedric isn't
|
||||
// initialized until he first appears, and View:onMe always returns true no
|
||||
// matter what coordinates are being tested if its rectangle isn't initialized.
|
||||
//
|
||||
// We fix this by initializing Cedric's actor-hidden signal flag on the heap.
|
||||
// This prevents View:onMe from returning true before Cedric is initialized.
|
||||
// The flag is later cleared by cedric:init when he is placed on screen.
|
||||
//
|
||||
// Applies to: English PC CD
|
||||
// Responsible method: Heap in script 290
|
||||
// Fixes bug #10920
|
||||
static const uint16 sq4CdSignatureCedricEasterEgg[] = {
|
||||
SIG_MAGICDWORD, // cedric
|
||||
SIG_UINT16(0x0110), // view = 272
|
||||
SIG_UINT16(0x0000), // loop = 0
|
||||
SIG_UINT16(0x0000), // cel = 0
|
||||
SIG_UINT16(0x000d), // priority = 13
|
||||
SIG_UINT16(0x0000), // underBits = 0
|
||||
SIG_UINT16(0x0810), // signal = $0810
|
||||
SIG_END
|
||||
};
|
||||
|
||||
static const uint16 sq4CdPatchCedricEasterEgg[] = {
|
||||
PATCH_ADDTOOFFSET(+10),
|
||||
PATCH_UINT16(0x0890), // signal = $0890 [ set actor-hidden flag ]
|
||||
PATCH_END
|
||||
};
|
||||
|
||||
// Colliding with Cedric in Ms. Astro Chicken after colliding with an obstacle
|
||||
// locks up the game. cedric:doit doesn't check if the player has been hit
|
||||
// before running killCedricScript. This interferes with the collision scripts'
|
||||
// animations and prevents them from continuing.
|
||||
//
|
||||
// We fix this by not running killCedricScript if the player has been hit.
|
||||
// Unfortunately there's no single property that can be tested as each
|
||||
// collision script does things differently, so this is a two-part patch.
|
||||
// First, ScrollActor:doChicken is patched to set User:canControl to 0, making
|
||||
// it consistent with the other collision scripts. Second, cedric:doit is
|
||||
// patched to test this value. To make room for this we replace testing
|
||||
// killCedricScript with testing the flag that killCedricScript sets.
|
||||
//
|
||||
// Applies to: English PC CD
|
||||
// Responsible methods: ScrollActor:doChicken, cedric:doit
|
||||
// Fixes bug #10920
|
||||
static const uint16 sq4CdSignatureCedricLockup1[] = {
|
||||
SIG_MAGICDWORD,
|
||||
0x18, // not
|
||||
0x30, SIG_UINT16(0x0049), // bnt 0049 [ end of method ]
|
||||
0x63, 0x84, // pToa deathLoop
|
||||
0x30, SIG_UINT16(0x0044), // bnt 0044 [ end of method ]
|
||||
0x38, SIG_SELECTOR16(stop), // pushi stop
|
||||
0x76, // push0
|
||||
0x81, 0x64, // lag 64
|
||||
0x4a, 0x04, // send 04 [ longSong2 stop: ]
|
||||
0x38, SIG_SELECTOR16(stop), // pushi stop
|
||||
0x76, // push0
|
||||
0x72, SIG_UINT16(0x0108), // lofsa eggSplatting
|
||||
0x4a, 0x04, // send 04 [ eggSplatting stop: ]
|
||||
0x39, SIG_SELECTOR8(number), // pushi number
|
||||
0x78, // push1
|
||||
0x67, 0x86, // pTos deathMusic
|
||||
0x39, SIG_SELECTOR8(loop), // pushi loop
|
||||
0x78, // push1
|
||||
0x78, // push1 [ unnecessary, loop is initialized to 1 on heap ]
|
||||
SIG_ADDTOOFFSET(+7),
|
||||
0x4a, 0x12, // send 12 [ theSound number: deathMusic loop: 1 play: self ]
|
||||
SIG_END
|
||||
};
|
||||
|
||||
static const uint16 sq4CdPatchCedricLockup1[] = {
|
||||
0x2f, 0x4b, // bt 4b [ end of method ]
|
||||
0x63, 0x84, // pToa deathLoop
|
||||
0x31, 0x47, // bnt 47 [ end of method ]
|
||||
0x38, PATCH_SELECTOR16(stop), // pushi stop
|
||||
0x3c, // dup
|
||||
0x76, // push0
|
||||
0x81, 0x64, // lag 64
|
||||
0x4a, 0x04, // send 04 [ longSong2 stop: ]
|
||||
0x76, // push0
|
||||
0x72, PATCH_UINT16(0x0108), // lofsa eggSplatting
|
||||
0x4a, 0x04, // send 04 [ eggSplatting stop: ]
|
||||
0x39, PATCH_SELECTOR8(number), // pushi number
|
||||
0x78, // push1
|
||||
0x67, 0x86, // pTos deathMusic
|
||||
0x38, PATCH_SELECTOR16(canControl), // pushi canControl
|
||||
0x78, // push1
|
||||
0x76, // push0
|
||||
0x81, 0x50, // lag 50
|
||||
0x4a, 0x06, // send 06 [ User canControl: 0 ]
|
||||
PATCH_ADDTOOFFSET(+7),
|
||||
0x4a, 0x0c, // send 0c [ theSound number: deathMusic play: self ]
|
||||
PATCH_END
|
||||
};
|
||||
|
||||
static const uint16 sq4CdSignatureCedricLockup2[] = {
|
||||
SIG_MAGICDWORD,
|
||||
0x31, 0x17, // bnt 17 [ end of method ]
|
||||
0x38, SIG_SELECTOR16(script), // pushi script
|
||||
0x76, // push0
|
||||
0x51, 0x9c, // class astroChicken
|
||||
0x4a, 0x04, // send 04 [ astroChicken script? ]
|
||||
0x18, // not [ acc = 1 if killCedricScript not running ]
|
||||
0x31, 0x0c, // bnt 0c [ end of method ]
|
||||
0x38, SIG_SELECTOR16(setScript), // pushi setScript
|
||||
0x78, // push1
|
||||
0x72, SIG_UINT16(0x0f7c), // lofsa killCedricScript
|
||||
0x36, // push
|
||||
0x51, 0x9c, // class astroChicken
|
||||
0x4a, 0x06, // send 06 [ astroChicken setScript: killCedricScript ]
|
||||
0x48, // ret
|
||||
0x48, // ret
|
||||
SIG_END
|
||||
};
|
||||
|
||||
static const uint16 sq4CdPatchCedricLockup2[] = {
|
||||
0x31, 0x18, // bnt 18 [ end of method ]
|
||||
0x38, PATCH_SELECTOR16(canControl), // pushi canControl
|
||||
0x76, // push0
|
||||
0x81, 0x50, // lag 50
|
||||
0x4a, 0x04, // send 04 [ User canControl? ]
|
||||
0x8b, 0x21, // lsl 21 [ local33 = 0 if cedric is alive, 1 if dead ]
|
||||
0x22, // lt? [ acc = 1 if cedric is alive and user has control ]
|
||||
0x31, 0x0b, // bnt 0b [ end of method ]
|
||||
0x38, PATCH_SELECTOR16(setScript), // pushi setScript
|
||||
0x78, // push1
|
||||
0x74, PATCH_UINT16(0x0f7c), // lofss killCedricScript
|
||||
0x51, 0x9c, // class astroChicken
|
||||
0x4a, 0x06, // send 06 [ astroChicken setScript: killCedricScript ]
|
||||
PATCH_END
|
||||
};
|
||||
|
||||
// The door to Sock's is immediately disposed of in the CD version, breaking its
|
||||
// Look message and preventing it from being drawn when restoring a saved game.
|
||||
// We remove the incorrect dispose call along with a redundant addToPic.
|
||||
|
@ -11380,6 +11523,9 @@ static const SciScriptPatcherEntry sq4Signatures[] = {
|
|||
{ true, 700, "Floppy: throw stuff at sequel police bug", 1, sq4FloppySignatureThrowStuffAtSequelPoliceBug, sq4FloppyPatchThrowStuffAtSequelPoliceBug },
|
||||
{ true, 35, "CD: sidewalk smell message fix", 1, sq4CdSignatureSidewalkSmellMessage, sq4CdPatchSidewalkSmellMessage },
|
||||
{ true, 45, "CD: walk in from below for room 45 fix", 1, sq4CdSignatureWalkInFromBelowRoom45, sq4CdPatchWalkInFromBelowRoom45 },
|
||||
{ true, 290, "CD: cedric easter egg fix", 1, sq4CdSignatureCedricEasterEgg, sq4CdPatchCedricEasterEgg },
|
||||
{ true, 290, "CD: cedric lockup fix (1/2)", 1, sq4CdSignatureCedricLockup1, sq4CdPatchCedricLockup1 },
|
||||
{ true, 290, "CD: cedric lockup fix (2/2)", 1, sq4CdSignatureCedricLockup2, sq4CdPatchCedricLockup2 },
|
||||
{ true, 370, "CD: sock's door restore and message fix", 1, sq4CdSignatureSocksDoor, sq4CdPatchSocksDoor },
|
||||
{ true, 391, "CD: missing Audio for universal remote control", 1, sq4CdSignatureMissingAudioUniversalRemote, sq4CdPatchMissingAudioUniversalRemote },
|
||||
{ true, 396, "CD: get points for changing back clothes fix", 1, sq4CdSignatureGetPointsForChangingBackClothes, sq4CdPatchGetPointsForChangingBackClothes },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue