diff --git a/Sprites/Bosses/manhandla.asm b/Sprites/Bosses/manhandla.asm index 9e5a75e..013efc0 100644 --- a/Sprites/Bosses/manhandla.asm +++ b/Sprites/Bosses/manhandla.asm @@ -72,22 +72,313 @@ Sprite_Manhandla_Prep: RTL } +; If both the heads are dead, it's okay for this sprite to "die" +; Then we transition to the chuchu phase. +Sprite_Manhandla_CheckForNextPhaseOrDeath: +{ + LDA Offspring1_Id : TAY + LDA.w SprState, Y : BEQ .offspring1_dead + JMP .not_dead + .offspring1_dead + + LDA Offspring2_Id : TAY + LDA.w SprState, Y : BEQ .offspring2_dead + JMP .not_dead + .offspring2_dead + + LDA.w SprMiscD, X : BNE .phase2 + LDA.w SprHealth, X : CMP.b #$08 : BCS .not_dead + + LDA.b #$01 : STA.w SprMiscD, X + LDA.b #$20 : STA.w SprHealth, X + LDA.b #$08 : STA.w SprNbrOAM, X + + .not_dead + RTS + .phase2 + LDA.w SprMiscD, X : CMP.b #$02 : BEQ + + + LDA.w SprHealth, X : CMP.b #$08 : BCS .phase2_not_dead + LDA.b #$20 : STA.w SprTimerA, X + LDA.b #$05 : STA.w SprAction, X + LDA.b #$13 : STA $012C + LDA.b #$02 : STA.w SprMiscD, X + + .phase2_not_dead + + + + RTS +} ; ========================================================= +macro SetLeftHeadPos() + REP #$20 + LDA SprCachedX : SEC : SBC.w #$0016 + SEP #$20 + STA.w SprX, Y : XBA : STA.w SprXH, Y + + REP #$20 + LDA SprCachedY : SEC : SBC.w #$000F + SEP #$20 + STA.w SprY, Y : XBA : STA.w SprYH, Y +endmacro + +macro SetRightHeadPos() + REP #$20 + LDA SprCachedX : CLC : ADC.w #$0016 + SEP #$20 + STA.w SprX, Y : XBA : STA.w SprXH, Y + + REP #$20 + LDA SprCachedY : SEC : SBC.w #$000F + SEP #$20 + STA.w SprY, Y : XBA : STA.w SprYH, Y +endmacro + Sprite_Manhandla_Main: { LDA.w SprAction, X JSL UseImplicitRegIndexedLocalJumpTable - dw Manhandla_Intro + dw Manhandla_Intro + dw Manhandla_FrontHead + dw Manhandla_LeftHead + dw Manhandla_RightHead + dw BigChuchu_Main + dw BigChuChu_Dead Manhandla_Intro: { - + LDA.w SprSubtype, X : BNE .not_main + LDA.w SprX : SEC : SBC.b #$04 : STA.w SprX + JSR ApplyManhandlaGraphics + JSR ApplyManhandlaPalette + JSR SpawnLeftManhandlaHead + JSR SpawnRightManhandlaHead + INC.w SprAction, X + RTS + .not_main + LDA.w SprSubtype, X : STA.w SprAction, X + RTS + } + + Manhandla_FrontHead: + { + %PlayAnimation(0,1,16) + + JSL GetRandomInt : AND.b #$7F : BNE + + JSR Mothula_SpawnBeams + + + + JSR Sprite_Manhandla_Move + JSL Sprite_DamageFlash_Long + + JSL Sprite_CheckDamageFromPlayerLong + %DoDamageToPlayerSameLayerOnContact() + + PHX + LDY.w Offspring1_Id + LDA.w SprType, Y : CMP.b #$88 : BNE .not_head + LDA.w SprState, Y : BEQ .offspring1_dead + %SetLeftHeadPos() + .offspring1_dead + .not_head + LDY.w Offspring2_Id + LDA.w SprType, Y : CMP.b #$88 : BNE .not_head2 + LDA.w SprState, Y : BEQ .offspring2_dead + %SetRightHeadPos() + .offspring2_dead + .not_head2 + PLX RTS } + + Manhandla_LeftHead: + { + %StartOnFrame(2) + %PlayAnimation(2,3,16) + + JSL Sprite_Move + JSL Sprite_DamageFlash_Long + + JSL Sprite_CheckDamageFromPlayerLong + %DoDamageToPlayerSameLayerOnContact() + + RTS + } + + Manhandla_RightHead: + { + %StartOnFrame(4) + %PlayAnimation(4,5,16) + + PHX + JSL Sprite_Move + JSL Sprite_DamageFlash_Long + + JSL Sprite_CheckDamageFromPlayerLong + %DoDamageToPlayerSameLayerOnContact() + PLX + + RTS + } + + BigChuchu_Main: + { + %PlayAnimation(0,2,16) + + PHX + JSR Sprite_Manhandla_Move + JSL Sprite_DamageFlash_Long + + JSL Sprite_CheckDamageFromPlayerLong + %DoDamageToPlayerSameLayerOnContact() + PLX + + RTS + } + + BigChuChu_Dead: + { + LDA $1C : ORA.b #$01 : STA $1C ;turn on BG2 (Body) + ; Flicker the body every other frame using the timer + LDA SprTimerA, X : AND.b #$01 : BEQ .flicker + LDA $1C : AND.b #$FE : STA $1C ;turn off BG2 (Body) + .flicker + + LDA SprTimerA, X : BNE .continue + STZ.w $0422 + STZ.w $0424 + LDA $1C : AND.b #$FE : STA $1C ;turn off BG2 (Body) + LDA.b #$04 : STA.w SprState, X + STZ.w SprHealth, X + + .continue + RTS + } +} + +Sprite_Manhandla_Move: +{ + LDA.w SprMiscC, X + JSL UseImplicitRegIndexedLocalJumpTable + + dw StageControl + dw MoveXandY + dw MoveXorY + dw KeepWalking + + StageControl: + { + STZ.w SprYSpeed : STZ.w SprXSpeed ;set velocitys to 0 + JSL MoveBody + JSR Manhandla_StopIfOutOfBounds + LDA SprTimerA, X : BNE .continue + INC.w SprMiscC, X + .continue + RTS + } + + MoveXandY: + { + LDA $36 + JSL Sprite_ApplySpeedTowardsPlayer + JSR Manhandla_StopIfOutOfBounds + JSL MoveBody + + INC.w SprMiscC, X + RTS + } + + MoveXorY: + { + LDA $36 : STA $00 + JSL NewSprite_ApplySpeedTowardsPlayerXOrY + JSR Manhandla_StopIfOutOfBounds + JSL MoveBody + + INC.w SprMiscC, X + RTS + } + + KeepWalking: + { + PHX + REP #$20 + + ; Use a range of + 0x05 because being exact equal didnt trigger consistently + LDA $20 : SBC SprCachedY : CMP.w #$FFFB : BCC .notEqualY + SEP #$20 + LDA.b #$02 : STA.w SprMiscC, X + + BRA .notEqualX + .notEqualY + + ; Use a range of + 0x05 because being exact equal didnt trigger consistently + LDA $22 : SBC SprCachedX : CMP.w #$FFFB : BCC .notEqualX + SEP #$20 + LDA.b #$02 : STA.w SprMiscC, X + .notEqualX + + SEP #$20 + JSR Manhandla_StopIfOutOfBounds + + ;if both velocities are 0 go back to the Stalk_Player_XORY to re-set the course + LDA.w SprYSpeed : BNE .notZero + LDA.w SprXSpeed : BNE .notZero + LDA.b #$03 : STA.w SprMiscC, X + .notZero + + JSL MoveBody + + PLX ;restores X + RTS + } +} + +Manhandla_StopIfOutOfBounds: +{ + ; Set A to 00 if outside of certain bounds + REP #$20 + LDA SprCachedX : CMP.w #$1528 : BCS .not_out_of_bounds_Left + SEP #$20 + LDA.w SprXSpeed : CMP.b #$7F : BCC .not_out_of_bounds_Left + LDA.b #-10 : STA.w SprXSpeed : STA SprXRound + + .not_out_of_bounds_Left + SEP #$20 + + REP #$20 + LDA SprCachedX : CMP.w #$15C8 : BCC .not_out_of_bounds_Right + SEP #$20 + LDA.w SprXSpeed : CMP.b #$80 : BCS .not_out_of_bounds_Right + LDA.b #$00 : STA.w SprXSpeed : STA SprXRound + + .not_out_of_bounds_Right + SEP #$20 + + ; Upper bound + REP #$20 + LDA SprCachedY : CMP.w #$0B30 : BCS .not_out_of_bounds_Up + SEP #$20 + LDA.w SprYSpeed : CMP.b #$7F : BCC .not_out_of_bounds_Up + LDA.b #$00 : STA.w SprYSpeed : STA SprYRound + + .not_out_of_bounds_Up + SEP #$20 + + REP #$20 + LDA SprCachedY : CMP.w #$0BC0 : BCC .not_out_of_bounds_Down + SEP #$20 + LDA.w SprYSpeed : CMP.b #$80 : BCS .not_out_of_bounds_Down + LDA.b #-10 : STA.w SprYSpeed : STA SprYRound ; Reverse the direction + + .not_out_of_bounds_Down + SEP #$20 + + RTS } ; ========================================================= @@ -99,7 +390,7 @@ Sprite_Manhandla_Draw: LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame LDA .start_index, Y : STA $06 - + LDA.w SprMiscA, X : STA $08 PHX LDX .nbr_of_tiles, Y ;amount of tiles -1 @@ -132,7 +423,7 @@ Sprite_Manhandla_Draw: INY LDA .chr, X : STA ($90), Y INY - LDA .properties, X : STA ($90), Y + LDA .properties, X : ORA $08 : STA ($90), Y PHY @@ -152,32 +443,241 @@ Sprite_Manhandla_Draw: ; ========================================================= .start_index - db $00, $02, $04, $08 + db $00, $02, $04, $08, $0C, $10, $14, $17, $1A .nbr_of_tiles - db 1, 1, 3, 3 + db 1, 1, 3, 3, 3, 3, 2, 2, 2 .x_offsets dw 0, 0 dw 0, 0 - dw -4, -4, 12, 12 - dw -4, 4, -4, 12 + dw 0, 8, 8, 0 + dw 0, 8, 0, 8 + dw 0, -8, -8, 0 + dw 0, -8, 0, -8 + dw -12, -4, 12 + dw -12, -4, 12 + dw 12, 4, -12 .y_offsets dw -8, 8 - dw -4, 12 - dw -8, 8, -8, 8 - dw -8, -8, 8, 8 + dw 0, 16 + dw -4, -4, 12, 12 + dw -4, -4, 12, 12 + dw -4, -4, 12, 12 + dw -4, -4, 12, 12 + dw 0, 0, 0 + dw 0, 0, 0 + dw 0, 0, 0 .chr - db $C0, $E0 - db $C2, $E2 - db $C4, $E4, $C6, $E6 - db $C8, $C9, $E8, $EA + db $00, $20 + db $02, $22 + db $04, $05, $25, $24 + db $07, $08, $27, $28 + db $04, $05, $25, $24 + db $07, $08, $27, $28 + db $40, $41, $40 + db $43, $44, $46 + db $43, $44, $46 .properties db $33, $33 db $33, $33 db $33, $33, $33, $33 db $33, $33, $33, $33 + db $73, $73, $73, $73 + db $73, $73, $73, $73 + db $33, $33, $73 + db $33, $33, $73 + db $73, $73, $33 .sizes db $02, $02 db $02, $02 db $02, $02, $02, $02 db $02, $02, $02, $02 -} \ No newline at end of file + db $02, $02, $02, $02 + db $02, $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 +} + +Sprite_BigChuchu_Draw: +{ + JSL Sprite_PrepOamCoord + JSL Sprite_OAM_AllocateDeferToPlayer + + LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame + LDA .start_index, Y : STA $06 + LDA.w SprMiscA, X : STA $08 + + PHX + LDX .nbr_of_tiles, Y ;amount of tiles -1 + LDY.b #$00 + .nextTile + + PHX ; Save current Tile Index? + + TXA : CLC : ADC $06 ; Add Animation Index Offset + + PHA ; Keep the value with animation index offset? + + ASL A : TAX + + REP #$20 + + LDA $00 : CLC : ADC .x_offsets, X : STA ($90), Y + AND.w #$0100 : STA $0E + INY + LDA $02 : CLC : ADC .y_offsets, X : STA ($90), Y + CLC : ADC #$0010 : CMP.w #$0100 + SEP #$20 + BCC .on_screen_y + + LDA.b #$F0 : STA ($90), Y ;Put the sprite out of the way + STA $0E + .on_screen_y + + PLX ; Pullback Animation Index Offset (without the *2 not 16bit anymore) + INY + LDA .chr, X : STA ($90), Y + INY + LDA .properties, X : ORA $08 : STA ($90), Y + + PHY + + TYA : LSR #2 : TAY + + LDA .sizes, X : ORA $0F : STA ($92), Y ; store size in oam buffer + + PLY : INY + + PLX : DEX : BPL .nextTile + + PLX + + RTS + + ; ======================================================= + .start_index + db $00, $09, $12 + .nbr_of_tiles + db 8, 8, 8 + .x_offsets + dw -12, 4, 20, -12, 4, 12, -12, 4, 12 + dw -12, 4, 20, -12, 4, 12, -12, 4, 12 + dw -12, 4, 20, -12, 4, 12, -8, 8, 16 + .y_offsets + dw 8, 8, 8, 16, 16, 16, 32, 32, 32 + dw 8, 8, 8, 16, 16, 16, 32, 32, 32 + dw 8, 8, 8, 16, 16, 16, 32, 32, 32 + .chr + db $80, $82, $84, $90, $92, $93, $B0, $B2, $B3 + db $80, $82, $84, $90, $92, $93, $D0, $D2, $D3 + db $80, $82, $84, $90, $92, $93, $D6, $D8, $D9 + .properties + db $33, $33, $33, $33, $33, $33, $33, $33, $33 + db $33, $33, $33, $33, $33, $33, $33, $33, $33 + db $33, $33, $33, $33, $33, $33, $33, $33, $33 + .sizes + db $02, $02, $02, $02, $02, $02, $02, $02, $02 + db $02, $02, $02, $02, $02, $02, $02, $02, $02 + db $02, $02, $02, $02, $02, $02, $02, $02, $02 +} + + +Mothula_SpawnBeams: +{ + LDA.b #$36 ; SFX3.36 + JSL $0DBB8A ; SpriteSFX_QueueSFX3WithPan + + LDA.b #$02 + STA.w $0FB5 + + .next_spawn + LDA.b #$89 ; SPRITE 89 + JSL Sprite_SpawnDynamically + BMI .no_space + + JSL Sprite_SetSpawnedCoordinates + + LDA.b $02 : SEC : SBC.b $04 + + CLC : ADC.b #$03 : STA.w $0D00,Y + + LDA.b #$10 : STA.w $0DF0,Y : STA.w $0BA0,Y + + PHX + + LDX.w $0FB5 + + LDA.b $00 : CLC : ADC.w .speed_and_offset_x,X + STA.w $0D10,Y + + LDA.w .speed_and_offset_x,X : STA.w $0D50,Y + + LDA.w .speed_y,X + STA.w $0D40,Y + + LDA.b #$00 + STA.w $0F70,Y + + PLX + + .no_space + DEC.w $0FB5 + BPL .next_spawn + + RTS + .speed_and_offset_x + db -16, 0, 16 + + .speed_y + db 24, 32, 24 +} + +SpawnLeftManhandlaHead: +{ + LDA #$88 + JSL Sprite_SpawnDynamically : BMI .return + TYA : STA Offspring1_Id + + PHX + + %SetLeftHeadPos() + ; store the sub-type + LDA.b #$03 : STA.w $0E30, Y + STA.w SprSubtype, Y + LDA.b #$10 : STA.w SprHealth, Y + LDA.b #$90 : STA.w SprTileDie, Y + + TYX + + STZ.w SprYRound, X + STZ.w SprXRound, X + PLX + + .return + RTS +} + + +SpawnRightManhandlaHead: +{ + LDA #$88 + JSL Sprite_SpawnDynamically : BMI .return + TYA : STA Offspring2_Id + + PHX + %SetRightHeadPos() + + LDA.b #$02 : STA $0E30, Y + STA.w SprSubtype, Y + LDA.b #$10 : STA.w SprHealth, Y + LDA.b #$90 : STA.w SprTileDie, Y + + TYX + + STZ.w SprYRound, X + STZ.w SprXRound, X + PLX + .return + RTS +} +