The reason for this is boring: in Sonic 3, regardless of whether the player is Super or not, the HurtCharacter function is called, which uh, hurts the character. Meanwhile, Sonic & Knuckles added a check for invincibility (not Super!) that calls up a separate code path if the appropriate bit is set. This suggests the original behavior was just an oversight.
loc_510AE: loc_74664: move.w d0,$18(a0) move.w d0,$18(a0) move.w #-$600,$1A(a0) move.w #-$600,$1A(a0) move.w #$3F,$2E(a0) move.w #$3F,$2E(a0) btst #Status_Invincible,(Player_1+status_secondary).w bne.s loc_7468C movea.l a0,a2 movea.l a0,a2 lea (Player_1).w,a0 lea (Player_1).w,a0 jsr (HurtCharacter).l jsr (HurtCharacter).l movea.l a2,a0 movea.l a2,a0 rts rts loc_7468C: lea (Player_1).w,a1 clr.b $2E(a1) neg.w d0 move.w d0,$18(a1) move.w #-$400,$1A(a1) bset #1,$2A(a1) bclr #3,$2A(a1) clr.b $40(a1) clr.b $3D(a1) move.b #2,$20(a1) move.b #2,5(a1) moveq #-$4F,d0 jmp (Play_Sound_2).lThere's another, more interesting oversight with the Big Arm boss, which wasn't fixed in Sonic & Knuckles. It requires a second player, however in Sonic 3, the Tails object is deleted during the Egg Mobile ride, and in Sonic & Knuckles, only Knuckles fights the boss!
We can force the bug to occur in Sonic 3 by using the PAR code 05A8CC:6010, which prevents Tails from despawning at the end of Launch Base 2. Get the boss down to 1 HP, then let it grab you while having Tails deal the final hit.
When this happens, Sonic gets stuck in mid-air, at least until the ending sequence starts. The effects are more heinous in Sonic & Knuckles because a regular stage clear sequence was added to the level, which can't start because Sonic is not touching the floor.
What's interesting about this oversight is that both Sonic 3 and Sonic & Knuckles have code in place to prevent it. If the byte at offset $30 of Big Arm's SST is clear, then it calls the Restore_PlayerControl function, which clears the player's object_control flag and resets their animation:
loc_51D78: loc_7506E: tst.b $30(a0) tst.b $30(a0) bne.s loc_51D82 bne.s loc_7507A jsr Restore_PlayerControl(pc) jsr (Restore_PlayerControl).l loc_51D82: loc_7507A: jmp (SaveGame).l lea ChildObjDat_75186(pc),a2 jmp (CreateChild1_Normal).lProblem is, the byte at offset $30 is set when the boss is holding the player, which means the Restore_PlayerControl function is only called in the exact wrong situation: when the boss isn't holding the player.
This can be seen in both Sonic 3 and Sonic & Knuckles: upon dealing the final hit to the boss, the player's animation is reset, which results in them falling to the ground in their standing frame.
I see people think the first quirk is intentional because it's the final boss in S3A and not in S3K. I'm convinced it's an error because the spike balls in Icecap Zone - Act 1 hurt you in S3A but not S3K, likely because Knuckles has to face them in S3K. I imagine this is similar to the Sonic 1 spike bug, since the ICZ spike balls also hurt you when flashing, so now I want to extend the post-hit invulnerability timeframe to a minute or so and replace the debug mode S monitor with invincibility to test my hypotheses.
ReplyDeleteConsidering the above quote by Brainulator9, is there a reason why Big Arms can only be fought as Knuckles in S3K and skipped entirely by Sonic and Tails, compared to S3A where Sonic and Tails has to fight it? I can imagine some coding reasons are behind it, since the S3C hack patcher includes the ability to fight it in S3K, but what sort of coding is behind it?
ReplyDeleteDespite it being an oversight, i quite like how the Big Arm boss can knock you out of your Super form with the slam attack. Since it's the final boss for S3A, it oddly makes sense that it can knock you out of your most powerful form. Though fixing it for Knuckles in S3K was probably the right choice.
ReplyDelete