Moldorm (Boss)

From TLoZ: ALTTP Hacking Resources
Jump to: navigation, search
This is a subpage of Sprites

Sprite $09: Moldorm (Boss)

Moldorm (Boss)

Description

  • ooO:

Combat Strategy

Hit his tail, try not to fall down.

Stats And Properties

See Sprite Properties

$06B089

Bit(s) Info Value
7 Harmless 0
6  ? 0
5  ? 0
4-0 OAM Slots 01111 ($0F)

$06B17C

Bit(s) Info Value
7-0 HP 0000 1100 ($0C)

$06B26F

Bit(s) Info Value
7-4  ? 0001 ($01)
3-0 Damage Type 0011 ($03)

$06B362

Bit(s) Info Value
7 No Death Animation 0
6 Invincible 0
5 Adjust Child coordinates 0
4 Draw Shadow 0
3-1 Palette 000 ($06)
0  ? 1

$06B455

Bit(s) Info Value
7 Ignore Collision Settings 0
6 Statis 0
5 Persist 0
4-0 Hit Box Dimensions 00000 ($00)

$06B548

Bit(s) Info Value
7-4 Tile Interaction Hit Box 0000 ($00)
3  ? 1
2  ? 0
1 Dies Like A Boss 1
0 Falls In Holes 0

$06B63B

Bit(s) Info Value
7 Disable Tile Interactions 0
6  ? 0
5 Is shield Blockable 0
4 Alternate Damage Sound 0
3-0 Prize Pack 0000 ($00)

$06B72E

Bit(s) Info Value
7  ? 1
6  ? 0
5 Is Interactive 0
4 Deflect Projectiles 0
3 Collide With Less Tiles 0
2 Impervious To Sword/Hammer 0
1 Impervious To Arrows? 0
0  ? 1

Code

   ; *$ED6D1-$ED6F5 LONG
   Sprite_InitializedSegmented:
   {
       PHX : TXY
       
       LDX.b #$7F
   
   .init_segment_loop
   
       LDA $0D10, Y : STA $7FFC00, X
       LDA $0D30, Y : STA $7FFC80, X
       
       LDA $0D00, Y : STA $7FFD00, X
       LDA $0D20, Y : STA $7FFD80, X
       
       DEX : BPL .init_segment_loop
       
       PLX
       
       RTL
   }
==============================================================================
   ; *$ED6F6-$ED6FD LONG
   Sprite_GiantMoldormLong:
   {
       PHB : PHK : PLB
       
       JSR Sprite_GiantMoldorm
       
       PLB
       
       RTL
   }
==============================================================================
   ; $ED6FE-$ED74D DATA
   pool Sprite_GiantMoldorm:
   {
   
   .x_speeds
       db  24,  22,  17,   9,   0,   -9, -17, -22
       db -24, -22, -17,  -9,   0,    9,  17,  22
       db  36,  33,  25,  13,   0,  -13, -25, -33
       db -36, -33, -25, -13,   0,   13,  25,  33
   
   .y_speeds
       db   0,   9,  17,  22,  24,  22,  17,   9
       db   0,  -9, -17, -22, -24, -22, -17,  -9
       db   0,  13,  25,  33,  36,  33,  25,  13
       db   0, -13, -25, -33, -36, -33, -25, -13
   
   .direction
       db  8,  9, 10, 11, 12, 13, 14, 15
       db  0,  1,  2,  3,  4,  5,  6,  7
   }
==============================================================================
   ; *$ED74E-$ED7FD LOCAL
   Sprite_GiantMoldorm:
   {
       JSR GiantMoldorm_Draw
       JSR Sprite4_CheckIfActive
       
       LDA $0D80, X : CMP.b #$03 : BNE .not_scheduled_for_death
       
       JMP GiantMoldorm_AwaitDeath
   
   .not_scheduled_for_death
   
       JSL Sprite_CheckDamageFromPlayerLong
       
       LDA.b #$07
       
       LDY $0E50, X : CPY.b #$03 : BCS .not_desperate_yet
       
       INC $0E80, X
       
       LDA.b #$03
   
   .not_desperate_yet
   
       INC $0E80, X
       
       AND $1A : BNE .skip_sound_effect_this_frame
       
       LDA.b #$31 : JSL Sound_SetSfx3PanLong
   
   .skip_sound_effect_this_frame
   
       LDA $0EA0, X : BEQ .not_stunned_from_damage
       
       LDA.b #$40 : STA !timer_2, X
       
       LDA $1A : AND.b #$03 : BNE .stun_timer_delay
       
       DEC $0EA0, X
   
   .stun_timer_delay
   
       RTS
   
   .not_stunned_from_damage
   
       LDA $46 : BNE .dont_repulse_player
       
       JSL Sprite_CheckDamageToPlayerLong : BCC .dont_repulse_player
       
       JSL Player_HaltDashAttackLong
       
       LDA.b #$28 : JSL Sprite_ProjectSpeedTowardsPlayerLong
       
       LDA $00 : STA $27
       
       LDA $01 : STA $28
       
       LDA.b #$18 : STA $46
       
       LDA.b #$30 : STA !timer_1, X
       
       ; Wait... how does this work? This value gets overriden by the call...
       ; I think this may be a certified \bug
       LDA.b #$32 : JSL Sound_SetSfxPan : STA $012F
   
   .dont_repulse_player
   
       LDY $0DE0, X
       
       LDA $0E50, X : CMP.b #$03 : BCS .not_desperate_2
       
       TYA : ADD.b #$10 : TAY
   
   .not_desperate_2
   
       LDA .x_speeds, Y : STA $0D50, X
       
       LDA .y_speeds, Y : STA $0D40, X
       
       JSR Sprite4_Move
       
       JSR Sprite4_CheckTileCollision : BEQ .no_tile_collision
       
       LDY $0DE0, X
       
       LDA .directions, Y : STA $0DE0, X
       
       ; I guess... this is where the ticking sound comes from?
       LDA.b #$21 : JSL Sound_SetSfx2PanLong
   
   .no_tile_collision
   
       LDA $0D80, X
       
       JSL UseImplicitRegIndexedLocalJumpTable
       
       dw GiantMoldorm_StraightPath
       dw GiantMoldorm_SpinningMeander
       dw GiantMoldorm_LungeAtPlayer
   }
==============================================================================
   ; *$ED7FE-$ED82C JUMP LOCATION
   GiantMoldorm_StraightPath:
   {
       LDA !timer_0, X : BNE .wait
       
       LDA.b #$01
       
       INC $0ED0, X : LDY $0ED0, X : CPY.b #$03 : BNE .beta
       
       STZ $0ED0, X
       
       LDA.b #$02
   
   .beta
   
       STA $0D80, X
       
       ; \note Resultant value is either 1 or -1.
       JSL GetRandomInt : AND.b #$02 : DEC A : STA $0EB0, X
       
       JSL GetRandomInt : AND.b #$1F : ADC.b #$20 : STA !timer_0, X
   
   .wait
   
       RTS
   }
==============================================================================
   ; *$ED82D-$ED851 JUMP LOCATION
   GiantMoldorm_SpinningMeander:
   {
       LDA !timer_0, X : BNE .wait
       
       JSL GetRandomInt : AND.b #$0F : ADC.b #$08 : STA !timer_0, X
       
       STZ $0D80, X
       
       RTS
   
   .wait
   
       AND.b #$03 : BNE .dont_adjust_direction
       
       LDA $0DE0, X : ADD $0EB0, X : AND.b #$0F : STA $0DE0, X
   
   .dont_adjust_direction
   
       RTS
   }
==============================================================================
   ; *$ED852-$ED880 JUMP LOCATION
   GiantMoldorm_LungeAtPlayer:
   {
       TXA : EOR $1A : AND.b #$03 : BNE .frame_delay
       
       LDA.b #$1F : JSL Sprite_ApplySpeedTowardsPlayerLong
       
       JSL Sprite_ConvertVelocityToAngle
       
       CMP $0DE0, X : BNE .current_direction_doesnt_match
       
       STZ $0D80, X
       
       LDA.b #$30 : STA !timer_0, X
       
       RTS
   
   .current_direction_doesnt_match
   
       PHP : LDA $0DE0, X : PLP : BMI .rotate_one_way
       
       ; rotate the other way... don't know if it's clockwise or counter
       ; clockwise.
       INC #2
   
   .rotate_one_way
   
       DEC A : AND.b #$0F : STA $0DE0, X
   
   .frame_delay
   
       RTS
   }
==============================================================================
   ; *$ED881-$ED8F1 LOCAL
   GiantMoldorm_Draw:
   {
       JSR Sprite4_PrepOamCoord
       
       LDA.b #$0B : STA $0F50, X
       
       JSR GiantMoldorm_DrawEyeballs
       
       REP #$20
       
       LDA $90 : ADD.w #$0008 : STA $90
       
       INC $92 : INC $92
       
       SEP #$20
       
       PHX : TXY
       
       LDA $0E80, X : AND.b #$7F : TAX
       
       LDA $0D10, Y : STA $7FFC00, X
       LDA $0D00, Y : STA $7FFD00, X
       
       LDA $0D30, Y : STA $7FFC80, X
       LDA $0D20, Y : STA $7FFD80, X
       
       PLX
       
       JSR GiantMoldorm_DrawHead
       
       LDA $0DA0, X : CMP.b #$04 : BCS .dont_draw_segment
       
       JSR GiantMoldorm_DrawSegment_A
       
       LDA $0DA0, X : CMP.b #$03 : BCS .dont_draw_segment
       
       JSR GiantMoldorm_DrawSegment_B
       
       LDA $0DA0, X : CMP.b #$02 : BCS .dont_draw_segment
       
       JSR GiantMoldorm_DrawSegment_C
       
       LDA $0DA0, X : BNE .dont_draw_segment
       
       JSR GiantMoldorm_Tail
   
   .dont_draw_segment
   
       JSR GiantMoldorm_IncrementalSegmentExplosion
       JSL Sprite_Get_16_bit_CoordsLong
       
       RTS
   }
==============================================================================
   ; *$ED8F2-$ED912 LOCAL
   GiantMoldorm_IncrementalSegmentExplosion:
   {
       LDA $0DD0, X : CMP.b #$09 : BNE .alive_and_well
       
       LDA !timer_4, X : BEQ .delay_explosion
       CMP.b #$50      : BCS .delay_explosion
       
       AND.b #$0F : ORA $11 : ORA $0FC1 : BNE .delay_explosion
       
       ; Move on to the next segment.
       INC $0DA0, X
       
       JSL Sprite_MakeBossDeathExplosion
   
   .delay_explosion
   .alive_and_well
   
       RTS
   }
==============================================================================
   ; $ED913-$ED992 DATA
   pool GiantMoldorm_DrawHead:
   {
   
   .oam_groups
       dw -8, -8 : db $80, $00, $00, $02
       dw  8, -8 : db $82, $00, $00, $02
       dw -8,  8 : db $A0, $00, $00, $02
       dw  8,  8 : db $A2, $00, $00, $02
       
       dw -8, -8 : db $82, $40, $00, $02
       dw  8, -8 : db $80, $40, $00, $02
       dw -8,  8 : db $A2, $40, $00, $02
       dw  8,  8 : db $A0, $40, $00, $02
       
       dw -6, -6 : db $80, $00, $00, $02
       dw  6, -6 : db $82, $00, $00, $02
       dw -6,  6 : db $A0, $00, $00, $02
       dw  6,  6 : db $A2, $00, $00, $02
       
       dw -6, -6 : db $82, $40, $00, $02
       dw  6, -6 : db $80, $40, $00, $02
       dw -6,  6 : db $A2, $40, $00, $02
       dw  6,  6 : db $A0, $40, $00, $02
   }
==============================================================================
   ; *$ED993-$ED9B7 LOCAL
   GiantMoldorm_DrawHead:
   {
       LDA.b #$00 : XBA
       
       LDA !timer_1, X : AND.b #$02 : STA $00
       
       LDA $0E80, X : LSR A : AND.b #$01 : ORA $00
       
       REP #$20
       
       ASL #5 : ADC.w #.oam_groups : STA $08
       
       SEP #$20
       
       LDA.b #$04 : JMP Sprite4_DrawMultiple
   }
==============================================================================
   ; $ED9B8-$ED9F7 DATA
   pool GiantMoldorm_DrawSegment_A:
   {
   
   .oam_groups
       dw -8, -8 : db $84, $00, $00, $02
       dw  8, -8 : db $86, $00, $00, $02
       dw -8,  8 : db $A4, $00, $00, $02
       dw  8,  8 : db $A6, $00, $00, $02
       
       dw -8, -8 : db $86, $40, $00, $02
       dw  8, -8 : db $84, $40, $00, $02
       dw -8,  8 : db $A6, $40, $00, $02
       dw  8,  8 : db $A4, $40, $00, $02
   }
==============================================================================
   ; \note The segment nearest the head.
   ; *$ED9F8-$EDA4F LOCAL
   GiantMoldorm_DrawSegment_A:
   {
       TXY
       
       PHX
       
       LDA $0E80, X : SUB.b #$10
   
   ; *$EDA00 ALTERNATE ENTRY POINT
   shared GiantMoldorm_DrawLargeSegment:
   
       AND.b #$7F : TAX
       
       LDA $7FFC00, X : STA $0FD8
       LDA $7FFC80, X : STA $0FD9
       
       LDA $7FFD00, X : STA $0FDA
       LDA $7FFD80, X : STA $0FDB
       
       PLX
       
       LDA.b #$00 : XBA
       
       LDA $0E80, X : LSR A : AND.b #$01
       
       REP #$20
       
       ASL #5 : ADC.w #.oam_groups : STA $08
       
       REP #$20
       
       LDA $90 : ADD.w #$0010 : STA $90
       
       LDA $92 : ADD.w #$0004 : STA $92
       
       SEP #$20
       
       SEP #$20
       
       LDA.b #$04
       
       JMP Sprite4_DrawMultiple
   }
==============================================================================
   ; *$EDA50-$EDA5A LOCAL
   GiantMoldorm_DrawSegment_B:
   {
       TXY
       
       PHX
       
       LDA $0E80, X : SUB.b #$1C
       
       JMP GiantMoldorm_DrawLargeSegment
   }
==============================================================================
   ; $EDA5B-$EDA5E DATA
   pool GiantMoldorm_DrawSegment_C:
   {
   
   .vh_flip
       db $00, $40, $C0, $80
   }
==============================================================================
   ; *$EDA5F-$EDAB9 LOCAL
   GiantMoldorm_DrawSegment_C:
   {
       STZ $0DC0, X
       
       REP #$20
       
       LDA $90 : ADD.w #$0010 : STA $90
       
       LDA $92 : ADD.w #$0004 : STA $92
       
       SEP #$20
       
       TXY
       
       PHX
       
       LDA $0E80, X : SUB.b #$28
   
   ; *$EDA7E ALTERNATE ENTRY POINT
   shared GiantMoldorm_PrepAndDrawSingleLargeLong:
   
       AND.b #$7F : TAX
       
       LDA $7FFC00, X : STA $0FD8
       LDA $7FFC80, X : STA $0FD9
       
       LDA $7FFD00, X : STA $0FDA
       LDA $7FFD80, X : STA $0FDB
       
       PLX
       
       LDA $0E80, X : LSR A : AND.b #$03 : TAY
       
       LDA $0F50, X : PHA
       
       AND.b #$3F : ORA .vh_flip, Y : STA $0F50, X
       
       JSL Sprite_PrepAndDrawSingleLargeLong
       
       PLA : STA $0F50, X
       
       RTS
   }
==============================================================================
   ; *$EDABA-$EDB16 LOCAL
   GiantMoldorm_Tail:
   {
       JSR GiantMoldorm_DrawTail
       
       LDA !timer_2, X : BNE .temporarily_invulnerable
       
       LDA.b #$01 : STA $0D90, X
       
       STZ $0F60, X
       STZ $0CAA, X
       
       LDA $0D10, X : PHA
       LDA $0D30, X : PHA
       
       LDA $0D00, X : PHA
       LDA $0D20, X : PHA
       
       LDA $0FD8 : STA $0D10, X
       LDA $0FD9 : STA $0D30, X
       
       LDA $0FDA : STA $0D00, X
       LDA $0FDB : STA $0D20, X
       
       JSL Sprite_CheckDamageFromPlayerLong
       
       STZ $0D90, X
       
       LDA.b #$09 : STA $0F60, X
       LDA.b #$04 : STA $0CAA, X
       
       PLA : STA $0D20, X
       PLA : STA $0D00, X
       
       PLA : STA $0D30, X
       PLA : STA $0D10, X
   
   .temporarily_invulnerable
   
       RTS
   }
==============================================================================
   ; *$EDB17-$EDB3D LOCAL
   GiantMoldorm_DrawTail:
   {
       REP #$20
       
       LDA $90 : ADD.w #$0004 : STA $90
       
       LDA $92 : ADD.w #$0001 : STA $92
       
       SEP #$20
       
       INC $0DC0, X
       
       LDA.b #$0D : STA $0F50, X
       
       TXY
       PHX
       
       LDA $0E80, X : SUB.b #$30
       
       JMP GiantMoldorm_PrepAndDrawSingleLargeLong
   }
==============================================================================
   ; $EDB3E-$EDB9D DATA
   pool GiantMoldorm_DrawEyeballs:
   {
   
   .x_offsets
       dw  16,  15,  12,   6,   0,  -6, -12, -13
       dw -16, -13, -12,  -6,   0,   6,  12,  15
   
   .y_offsets
       dw   0,   6,  12,  15,  16,  15,  12,   6
       dw   0,  -6, -12, -13, -16, -13, -12,  -6
   
   .chr
       db $AA, $AA, $A8, $A8, $8A, $8A, $A8, $A8
       db $AA, $AA, $A8, $A8, $8A, $8A, $A8, $A8
   
   .vh_flip
       db $00, $00, $00, $00, $80, $80, $40, $40
       db $40, $40, $C0, $C0, $00, $00, $80, $80
   }
==============================================================================
   ; *$EDB9E-$EDC10 LOCAL
   GiantMoldorm_DrawEyeballs:
   {
       STZ $07
       
       LDA $0EA0, X : BEQ .dont_accelerate_eyerolling
       
       LDA $1A : STA $07
   
   .dont_accelerate_eyerolling
   
       LDA $0DE0, X : ADD.b #$FF : STA $06
       
       PHX
       
       LDX.b #$01
   
   .draw_eyes_loop
   
       LDA $06 : AND.b #$0F : ASL A : PHX : TAX
       
       REP #$20
       
       LDA $00 : ADD .x_offsets, X : STA ($90), Y
       
       AND.w #$0100 : STA $0E
       
       LDA $02 : ADD .y_offsets, X : INY : STA ($90), Y
       
       ADC.w #$0010 : CMP.w #$0100 : SEP #$20 : BCC .on_screen_y
       
       LDA.b #$F0 : STA ($90), Y
   
   .on_screen_y
   
       LDA $06 : ADD $07 : AND.b #$0F : TAX
       
       LDA .chr, X : INY : STA ($90), Y
       
       LDA .vh_flip, X : ORA $05 : INY : STA ($90), Y
       
       PHY : TYA : LSR #2 : TAY
       
       LDA $0F : ORA.b #$02 : STA ($92), Y
       
       LDA $06 : ADD.b #$02 : STA $06
       
       PLY : INY
       
       PLX : DEX : BPL .draw_eyes_loop
       
       PLX
       
       RTS
   }
==============================================================================
   ; *$EDC11-$EDC29 JUMP LOCATION
   GiantMoldorm_AwaitDeath:
   {
       LDA !timer_4, X : BNE .delay
   
   ; *$EDC16 ALTERNATE ENTRY POINT
   Sprite_ScheduleBossForDeath:
   
       LDA.b #$04 : STA $0DD0, X
       
       STZ $0D90, X
       
       LDA.b #$E0 : STA !timer_0, X
       
       RTS
   
   .delay
   
       ORA.b #$E0 : STA $0EF0, X
       
       RTS
   }
==============================================================================
   ; *$EDC2A-$EDC71 LONG
   Sprite_MakeBossDeathExplosion:
   {
       LDA.b #$0C : JSL Sound_SetSfx2PanLong
   
   ; *$EDC30 ALTERNATE ENTRY POINT
   .silent
   
       ; Spawn a.... raven? What? Oh it's just a dummy sprite that will be
       ; transmuted to an explosion.
       LDA.b #$00 : JSL Sprite_SpawnDynamically : BMI .spawn_failed
       
       LDA.b #$0B : STA $0AAA
       
       LDA.b #$04 : STA $0DD0, Y
       LDA.b #$03 : STA $0E40, Y
       LDA.b #$0C : STA $0F50, Y
       
       LDA $0FD8 : STA $0D10, Y
       LDA $0FD9 : STA $0D30, Y
       
       LDA $0FDA : STA $0D00, Y
       LDA $0FDB : STA $0D20, Y
       
       LDA.b #$1F : STA !timer_0, Y
                    STA $0D90, Y
       
       LDA.b #$02 : STA $0F20, Y
   
   .spawn_failed
   
       RTL
   }