Difference between revisions of "Octorok (One Way)"
From TLoZ: ALTTP Hacking Resources
Line 1: | Line 1: | ||
{{subpage|Sprites}} | {{subpage|Sprites}} | ||
− | {{ | + | Sprite {{$|08}}: Octorok (One Way) |
− | | | + | == Octorok (One Way) == |
− | + | === Description === | |
− | + | An octorok who stops, fires only once, then begins moving again. | |
− | |||
− | |||
− | |||
− | == | + | === Combat Strategy === |
− | + | Very weak enemy. They fire and move only in lateral directions, so staying in their diagonal range is a safe way to approach them. | |
− | == | + | == Stats And Properties == |
− | + | See [[Sprite Properties]] | |
− | + | '''{{$|06B088}}''' | |
+ | {|{{Prettytable}} | ||
+ | !Bit(s) | ||
+ | !Info | ||
+ | !Value | ||
+ | |- | ||
+ | | {{Hex|7}} | ||
+ | | Harmless | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|6}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|5}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|4-0}} | ||
+ | | OAM Slots | ||
+ | | {{Hex|00010}} ({{$|02}}) | ||
+ | |} | ||
− | == | + | '''{{$|06B17B}}''' |
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7-0}} | ||
+ | | HP | ||
+ | | {{Hex|0000 0010}} ({{$|02}}) | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B26E}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7-4}} | ||
+ | | ? | ||
+ | | {{Hex|0000}} ({{$|00}}) | ||
+ | |- | ||
+ | | {{Hex|3-0}} | ||
+ | | [[Damage Types|Damage Type]] | ||
+ | | {{Hex|0001}} ({{$|01}}) | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B361}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7}} | ||
+ | | No Death Animation | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|6}} | ||
+ | | Invincible | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|5}} | ||
+ | | Adjust Child coordinates | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|4}} | ||
+ | | Draw Shadow | ||
+ | | {{Hex|1}} | ||
+ | |- | ||
+ | | {{Hex|3-1}} | ||
+ | | Palette | ||
+ | | {{Hex|110}} ({{$|06}}) | ||
+ | |- | ||
+ | | {{Hex|0}} | ||
+ | | ? | ||
+ | | {{Hex|1}} | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B454}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7}} | ||
+ | | Ignore Collision Settings | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|6}} | ||
+ | | Statis | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|5}} | ||
+ | | Persist | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|4-0}} | ||
+ | | Hit Box Dimensions | ||
+ | | {{Hex|00000}} ({{$|00}}) | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B547}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7-4}} | ||
+ | | Tile Interaction Hit Box | ||
+ | | {{Hex|0000}} ({{$|00}}) | ||
+ | |- | ||
+ | | {{Hex|3}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|2}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|1}} | ||
+ | | Dies Like A Boss | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|0}} | ||
+ | | Falls In Holes | ||
+ | | {{Hex|0}} | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B63A}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7}} | ||
+ | | Disable Tile Interactions | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|6}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|5}} | ||
+ | | Is shield Blockable | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|4}} | ||
+ | | Alternate Damage Sound | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|3-0}} | ||
+ | | Prize Pack | ||
+ | | {{Hex|0010}} ({{$|02}}) | ||
+ | |} | ||
+ | |||
+ | '''{{$|06B72D}}''' | ||
+ | {|{{Prettytable}} | ||
+ | ! Bit(s) | ||
+ | ! Info | ||
+ | ! Value | ||
+ | |- | ||
+ | | {{Hex|7}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|6}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|5}} | ||
+ | | Is Interactive | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|4}} | ||
+ | | Deflect Projectiles | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|3}} | ||
+ | | Collide With Less Tiles | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|2}} | ||
+ | | Impervious To Sword/Hammer | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|1}} | ||
+ | | Impervious To Arrows? | ||
+ | | {{Hex|0}} | ||
+ | |- | ||
+ | | {{Hex|0}} | ||
+ | | ? | ||
+ | | {{Hex|0}} | ||
+ | |} | ||
+ | |||
+ | == Code == | ||
+ | <Code> | ||
+ | ; $35363-$35376 DATA | ||
+ | pool Sprite_Octorock: | ||
+ | { | ||
+ | .next_direction | ||
+ | db 3, 2, 0, 1 | ||
+ | |||
+ | .x_speed | ||
+ | db 24, -24, 0, 0 | ||
+ | |||
+ | .y_speed | ||
+ | db 0, 0, 24, -24 | ||
+ | |||
+ | .unused | ||
+ | ; Unused? | ||
+ | db 1, 2, 4, 8 | ||
+ | |||
+ | .delays | ||
+ | ; Unused? | ||
+ | db 60, -128, -96, -128 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | !ai_state = $0D80 | ||
+ | !graphic = $0DC0 | ||
+ | !direction = $0DE0 | ||
+ | !type = $0E20 | ||
+ | !oam_4 = $0F50 | ||
+ | |||
+ | ; *$35377-$35450 JUMP LOCATION | ||
+ | Sprite_Octorock: | ||
+ | { | ||
+ | !force_hflip = $00 | ||
+ | !gfx_vert = $00 | ||
+ | |||
+ | ; ------------------------------ | ||
+ | |||
+ | ; Octorock Routine (Sprites 0x08 and 0x0A) | ||
+ | LDY !direction, X : PHY | ||
+ | |||
+ | LDA !timer_1, X : BEQ .timer_1_elapsed | ||
+ | |||
+ | LDA .next_direction, Y : STA !direction, X | ||
+ | |||
+ | .timer_1_elapsed | ||
+ | |||
+ | STZ $00 | ||
+ | |||
+ | LDA !graphic, X : CMP.b #$07 : BNE .no_forced_hflip | ||
+ | |||
+ | LDA.b #$40 : STA !force_hflip | ||
+ | |||
+ | .no_forced_hflip | ||
+ | |||
+ | LDA !oam_4, X : AND.b #$BF | ||
+ | |||
+ | ORA $D2AE, Y : ORA !force_hflip : STA !oam_4, X | ||
+ | |||
+ | JSR Octorock_Draw | ||
+ | |||
+ | PLA : STA !direction, X | ||
+ | |||
+ | JSR Sprite_CheckIfActive | ||
+ | JSR Sprite_CheckIfRecoiling | ||
+ | JSR Sprite_Move | ||
+ | JSR Sprite_CheckDamage | ||
+ | |||
+ | LDA !ai_state, X : AND.b #$01 : BNE .stop_and_spit_maybe | ||
+ | |||
+ | LDA !direction, X : AND.b #$02 : ASL A : STA !gfx_vert | ||
+ | |||
+ | INC $0E80, X | ||
+ | |||
+ | LDA $0E80, X : LSR #3 : AND.b #$03 : ORA !gfx_vert : STA !graphic, X | ||
+ | |||
+ | LDA !timer_0, X : BNE .wait_1 | ||
+ | |||
+ | ; Switch to the other main AI state. | ||
+ | INC !ai_state, X | ||
+ | |||
+ | LDY !type, X | ||
+ | |||
+ | LDA .delays-8, Y : STA !timer_0, X | ||
+ | |||
+ | RTS | ||
+ | |||
+ | .wait_1 | ||
+ | |||
+ | LDY !direction, X | ||
+ | |||
+ | ; Make this little bugger move. | ||
+ | LDA .x_speed, Y : STA $0D50, X | ||
+ | LDA .y_speed, Y : STA $0D40, X | ||
+ | |||
+ | JSR Sprite_CheckTileCollision | ||
+ | |||
+ | LDA $0E70, X : BEQ .epsilon | ||
+ | |||
+ | LDA !direction, X : EOR.b #$01 : STA !direction, X | ||
+ | |||
+ | BRA .return_2 | ||
+ | |||
+ | .epsilon | ||
+ | |||
+ | RTS | ||
+ | |||
+ | .stop_and_spit_maybe | ||
+ | |||
+ | JSR Sprite_Zero_XY_Velocity | ||
+ | |||
+ | LDA !timer_0, X : BNE .wait_2 | ||
+ | |||
+ | INC !ai_state, X | ||
+ | |||
+ | LDA !direction, X : PHA | ||
+ | |||
+ | ; Set a new countdown timer and direction slightly at random. | ||
+ | JSL GetRandomInt : AND.b #$3F : ADC.b #$30 : STA !timer_0, X | ||
+ | |||
+ | AND.b #$03 : STA !direction, X | ||
+ | |||
+ | ; Note this odd... certainty that both outcomes result in the same | ||
+ | ; branch location. | ||
+ | PLA : CMP !direction, X : BEQ .same_direction | ||
+ | EOR !direction, X : BNE .different_direction | ||
+ | |||
+ | ; Thus, this line of code is not reachable, as far as I can tell. | ||
+ | LDA.b #$08 : STA !timer_1, X | ||
+ | |||
+ | .same_direction | ||
+ | .different_direction | ||
+ | .return_2 | ||
+ | |||
+ | RTS | ||
+ | |||
+ | .wait_2 | ||
+ | |||
+ | LDA !type, X : SUB.b #$08 : REP #$30 : AND.w #$00FF : ASL A : TAY | ||
+ | |||
+ | ; Hidden Jump table, Argghghh! | ||
+ | LDA Octorock_AI_Table, Y : DEC A : PHA | ||
+ | |||
+ | SEP #$30 | ||
+ | |||
+ | RTS | ||
+ | |||
+ | .handlers | ||
+ | |||
+ | !nullptr = 0 | ||
+ | |||
+ | dw Octorock_Normal | ||
+ | dw !nullptr | ||
+ | dw Octorock_FourShooter | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $35451-$3546E DATA | ||
+ | pool Octorock_Normal: | ||
+ | { | ||
+ | |||
+ | .unknown | ||
+ | db 0, 2, 2, 2, 1, 1, 1, 0 | ||
+ | db 0, 0, 0, 0, 2, 2, 2, 2 | ||
+ | db 2, 1, 1 0 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $35465-$3546E DATA | ||
+ | pool Octorock_FourShooter: | ||
+ | { | ||
+ | |||
+ | .unknown | ||
+ | db 2, 2, 2, 2 2, 2, 2, 2, 1, 0 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $3546F-$35485 JUMP LOCATION (LOCAL) | ||
+ | Octorock_Normal: | ||
+ | { | ||
+ | LDA !timer_0, X : CMP.b #$1C : BNE .dont_spit_rock | ||
+ | |||
+ | PHA | ||
+ | |||
+ | JSR Octorock_SpitOutRock | ||
+ | |||
+ | PLA | ||
+ | |||
+ | .dont_spit_rock | ||
+ | |||
+ | LSR #3 : TAY | ||
+ | |||
+ | LDA .unknown, Y : STA $0DB0, X | ||
+ | |||
+ | RTS | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $35486-$35489 DATA | ||
+ | pool Octorock_FourShooter: | ||
+ | { | ||
+ | |||
+ | .next_direction | ||
+ | db 2, 3, 1, 0 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $3548A-$354B4 JUMP LOCATION (LOCAL) | ||
+ | Octorock_FourShooter: | ||
+ | { | ||
+ | LDA !timer_0, X : PHA | ||
+ | |||
+ | CMP.b #$80 : BCS .just_animate | ||
+ | AND.b #$0F : BNE .dont_rotate | ||
+ | |||
+ | PHA | ||
+ | |||
+ | LDY !direction, X | ||
+ | |||
+ | LDA .next_direction, Y : STA !direction, X | ||
+ | |||
+ | PLA | ||
+ | |||
+ | .dont_rotate | ||
+ | |||
+ | CMP.b #$08 : BNE .dont_shoot | ||
+ | |||
+ | JSR Octorock_SpitOutRock | ||
+ | |||
+ | .dont_shoot | ||
+ | .just_animate | ||
+ | |||
+ | PLA : LSR #4 : TAY | ||
+ | |||
+ | LDA .unknown, Y : STA $0DB0, X | ||
+ | |||
+ | RTS | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $354B5-$354CC DATA | ||
+ | pool Octorock_SpitOutRock: | ||
+ | { | ||
+ | |||
+ | ; \task Label these sublabels. | ||
+ | |||
+ | db 12, -12, 0, 0 | ||
+ | |||
+ | ; $354B9 | ||
+ | db 0, -1, 0, 0 | ||
+ | |||
+ | ; $354BD | ||
+ | db 4, 4, 12, -12 | ||
+ | |||
+ | ; $354C1 | ||
+ | db 0, 0, 0, -1 | ||
+ | |||
+ | ; $354C5 | ||
+ | db 44, -44, 0, 0 | ||
+ | |||
+ | ; $354C9 | ||
+ | db 0, 0, 44, -44 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $354CD-$35513 LOCAL | ||
+ | Octorock_SpitOutRock: | ||
+ | { | ||
+ | LDA.b #$07 : JSL Sound_SetSfx2PanLong | ||
+ | |||
+ | LDA.b #$0C | ||
+ | |||
+ | JSL Sprite_SpawnDynamically : BMI .spawn_failed | ||
+ | |||
+ | PHX | ||
+ | |||
+ | ; The position and velocity of the newly created rock depends on the | ||
+ | ; direction that the Octorok is currently facing. | ||
+ | LDA !direction, X : TAX | ||
+ | |||
+ | LDA $00 : ADD $D4B5, X : STA $0D10, Y | ||
+ | LDA $01 : ADC $D4B9, X : STA $0D30, Y | ||
+ | |||
+ | LDA $02 : ADD $D4BD, X : STA $0D00, Y | ||
+ | LDA $03 : ADC $D4C1, X : STA $0D20, Y | ||
+ | |||
+ | LDA !direction, Y : TAX | ||
+ | |||
+ | LDA $D4C5, X : STA $0D50, Y | ||
+ | LDA $D4C9, X : STA $0D40, Y | ||
+ | |||
+ | PLX | ||
+ | |||
+ | .spawn_failed | ||
+ | |||
+ | RTS | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; $35514-$35549 DATA | ||
+ | pool Octorock_Draw: | ||
+ | { | ||
+ | |||
+ | .x_offsets | ||
+ | dw 8, 0, 4, 8, 0, 4, 9, -1, 4 | ||
+ | |||
+ | .y_offsets | ||
+ | dw 6, 6, 9, 6, 6, 9, 6, 6, 9 | ||
+ | |||
+ | .chr | ||
+ | db $BB, $BB, $BA, $AB, $AB, $AA, $A9, $A9, $B9 | ||
+ | |||
+ | .properties | ||
+ | db $65, $25, $25, $65, $25, $25, $65, $25, $25 | ||
+ | } | ||
+ | |||
+ | ; ============================================================================== | ||
+ | |||
+ | ; *$3554A-$355B8 LOCAL | ||
+ | Octorock_Draw: | ||
+ | { | ||
+ | !top_x_bit_low = $0E | ||
+ | !top_x_bit_high = $0F | ||
+ | |||
+ | JSR Sprite_PrepOamCoord | ||
+ | |||
+ | ; perhaps this draws the octorock's snout? | ||
+ | LDA !direction, X : CMP.b #$03 : BEQ .dont_draw_this_part | ||
+ | |||
+ | ; $07 = [3 * $0DB0, X] + !direction | ||
+ | LDA $0DB0, X : ASL A : ADC $0DB0, X : ADC !direction, X : STA $07 | ||
+ | |||
+ | PHX : PHA | ||
+ | |||
+ | ASL A : TAX | ||
+ | |||
+ | REP #$20 | ||
+ | |||
+ | LDA $00 : ADD .x_offsets, X : STA ($90), Y | ||
+ | |||
+ | AND.w #$0100 : STA !top_x_bit_low | ||
+ | |||
+ | LDA $02 : ADD .y_offsets, X : INY : STA ($90), Y | ||
+ | |||
+ | ADD.w #$0010 : CMP.w #$0100 : SEP #$20 : BCC .not_off_screen | ||
+ | |||
+ | LDA.b #$F0 : STA ($90), Y | ||
+ | |||
+ | .not_off_screen | ||
+ | |||
+ | PLX | ||
+ | |||
+ | LDA .chr, X : INY : STA ($90), Y | ||
+ | |||
+ | LDA .properties, X : INY : ORA $05 : STA ($90), Y | ||
+ | |||
+ | LDA !top_x_bit_high : STA ($92) | ||
+ | |||
+ | PLX | ||
+ | |||
+ | .dont_draw_this_part | ||
+ | |||
+ | REP #$20 | ||
+ | |||
+ | LDA $90 : ADD.w #$0004 : STA $90 | ||
+ | |||
+ | INC $92 | ||
+ | |||
+ | SEP #$20 | ||
+ | |||
+ | DEC $0E40, X | ||
+ | |||
+ | LDY.b #$00 | ||
+ | |||
+ | JSR Sprite_PrepAndDrawSingleLarge.just_draw | ||
+ | |||
+ | INC $0E40, X | ||
+ | |||
+ | RTS | ||
+ | } | ||
+ | </Code> |
Latest revision as of 17:31, 19 December 2016
This is a subpage of Sprites
Sprite $08: Octorok (One Way)
Octorok (One Way)
Description
An octorok who stops, fires only once, then begins moving again.
Combat Strategy
Very weak enemy. They fire and move only in lateral directions, so staying in their diagonal range is a safe way to approach them.
Stats And Properties
$06B088
Bit(s) | Info | Value |
---|---|---|
7 | Harmless | 0 |
6 | ? | 0 |
5 | ? | 0 |
4-0 | OAM Slots | 00010 ($02) |
$06B17B
Bit(s) | Info | Value |
---|---|---|
7-0 | HP | 0000 0010 ($02) |
$06B26E
Bit(s) | Info | Value |
---|---|---|
7-4 | ? | 0000 ($00) |
3-0 | Damage Type | 0001 ($01) |
$06B361
Bit(s) | Info | Value |
---|---|---|
7 | No Death Animation | 0 |
6 | Invincible | 0 |
5 | Adjust Child coordinates | 0 |
4 | Draw Shadow | 1 |
3-1 | Palette | 110 ($06) |
0 | ? | 1 |
$06B454
Bit(s) | Info | Value |
---|---|---|
7 | Ignore Collision Settings | 0 |
6 | Statis | 0 |
5 | Persist | 0 |
4-0 | Hit Box Dimensions | 00000 ($00) |
$06B547
Bit(s) | Info | Value |
---|---|---|
7-4 | Tile Interaction Hit Box | 0000 ($00) |
3 | ? | 0 |
2 | ? | 0 |
1 | Dies Like A Boss | 0 |
0 | Falls In Holes | 0 |
$06B63A
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 | 0010 ($02) |
$06B72D
Bit(s) | Info | Value |
---|---|---|
7 | ? | 0 |
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 | ? | 0 |
Code
; $35363-$35376 DATA pool Sprite_Octorock: { .next_direction db 3, 2, 0, 1 .x_speed db 24, -24, 0, 0 .y_speed db 0, 0, 24, -24 .unused ; Unused? db 1, 2, 4, 8 .delays ; Unused? db 60, -128, -96, -128 }
- ==============================================================================
!ai_state = $0D80 !graphic = $0DC0 !direction = $0DE0 !type = $0E20 !oam_4 = $0F50 ; *$35377-$35450 JUMP LOCATION Sprite_Octorock: { !force_hflip = $00 !gfx_vert = $00 ; ------------------------------ ; Octorock Routine (Sprites 0x08 and 0x0A) LDY !direction, X : PHY LDA !timer_1, X : BEQ .timer_1_elapsed LDA .next_direction, Y : STA !direction, X .timer_1_elapsed STZ $00 LDA !graphic, X : CMP.b #$07 : BNE .no_forced_hflip LDA.b #$40 : STA !force_hflip .no_forced_hflip LDA !oam_4, X : AND.b #$BF ORA $D2AE, Y : ORA !force_hflip : STA !oam_4, X JSR Octorock_Draw PLA : STA !direction, X JSR Sprite_CheckIfActive JSR Sprite_CheckIfRecoiling JSR Sprite_Move JSR Sprite_CheckDamage LDA !ai_state, X : AND.b #$01 : BNE .stop_and_spit_maybe LDA !direction, X : AND.b #$02 : ASL A : STA !gfx_vert INC $0E80, X LDA $0E80, X : LSR #3 : AND.b #$03 : ORA !gfx_vert : STA !graphic, X LDA !timer_0, X : BNE .wait_1 ; Switch to the other main AI state. INC !ai_state, X LDY !type, X LDA .delays-8, Y : STA !timer_0, X RTS .wait_1 LDY !direction, X ; Make this little bugger move. LDA .x_speed, Y : STA $0D50, X LDA .y_speed, Y : STA $0D40, X JSR Sprite_CheckTileCollision LDA $0E70, X : BEQ .epsilon LDA !direction, X : EOR.b #$01 : STA !direction, X BRA .return_2 .epsilon RTS .stop_and_spit_maybe JSR Sprite_Zero_XY_Velocity LDA !timer_0, X : BNE .wait_2 INC !ai_state, X LDA !direction, X : PHA ; Set a new countdown timer and direction slightly at random. JSL GetRandomInt : AND.b #$3F : ADC.b #$30 : STA !timer_0, X AND.b #$03 : STA !direction, X ; Note this odd... certainty that both outcomes result in the same ; branch location. PLA : CMP !direction, X : BEQ .same_direction EOR !direction, X : BNE .different_direction ; Thus, this line of code is not reachable, as far as I can tell. LDA.b #$08 : STA !timer_1, X .same_direction .different_direction .return_2 RTS .wait_2 LDA !type, X : SUB.b #$08 : REP #$30 : AND.w #$00FF : ASL A : TAY ; Hidden Jump table, Argghghh! LDA Octorock_AI_Table, Y : DEC A : PHA SEP #$30 RTS .handlers !nullptr = 0 dw Octorock_Normal dw !nullptr dw Octorock_FourShooter }
- ==============================================================================
; $35451-$3546E DATA pool Octorock_Normal: { .unknown db 0, 2, 2, 2, 1, 1, 1, 0 db 0, 0, 0, 0, 2, 2, 2, 2 db 2, 1, 1 0 }
- ==============================================================================
; $35465-$3546E DATA pool Octorock_FourShooter: { .unknown db 2, 2, 2, 2 2, 2, 2, 2, 1, 0 }
- ==============================================================================
; $3546F-$35485 JUMP LOCATION (LOCAL) Octorock_Normal: { LDA !timer_0, X : CMP.b #$1C : BNE .dont_spit_rock PHA JSR Octorock_SpitOutRock PLA .dont_spit_rock LSR #3 : TAY LDA .unknown, Y : STA $0DB0, X RTS }
- ==============================================================================
; $35486-$35489 DATA pool Octorock_FourShooter: { .next_direction db 2, 3, 1, 0 }
- ==============================================================================
; $3548A-$354B4 JUMP LOCATION (LOCAL) Octorock_FourShooter: { LDA !timer_0, X : PHA CMP.b #$80 : BCS .just_animate AND.b #$0F : BNE .dont_rotate PHA LDY !direction, X LDA .next_direction, Y : STA !direction, X PLA .dont_rotate CMP.b #$08 : BNE .dont_shoot JSR Octorock_SpitOutRock .dont_shoot .just_animate PLA : LSR #4 : TAY LDA .unknown, Y : STA $0DB0, X RTS }
- ==============================================================================
; $354B5-$354CC DATA pool Octorock_SpitOutRock: { ; \task Label these sublabels. db 12, -12, 0, 0 ; $354B9 db 0, -1, 0, 0 ; $354BD db 4, 4, 12, -12 ; $354C1 db 0, 0, 0, -1 ; $354C5 db 44, -44, 0, 0 ; $354C9 db 0, 0, 44, -44 }
- ==============================================================================
; $354CD-$35513 LOCAL Octorock_SpitOutRock: { LDA.b #$07 : JSL Sound_SetSfx2PanLong LDA.b #$0C JSL Sprite_SpawnDynamically : BMI .spawn_failed PHX ; The position and velocity of the newly created rock depends on the ; direction that the Octorok is currently facing. LDA !direction, X : TAX LDA $00 : ADD $D4B5, X : STA $0D10, Y LDA $01 : ADC $D4B9, X : STA $0D30, Y LDA $02 : ADD $D4BD, X : STA $0D00, Y LDA $03 : ADC $D4C1, X : STA $0D20, Y LDA !direction, Y : TAX LDA $D4C5, X : STA $0D50, Y LDA $D4C9, X : STA $0D40, Y PLX .spawn_failed RTS }
- ==============================================================================
; $35514-$35549 DATA pool Octorock_Draw: { .x_offsets dw 8, 0, 4, 8, 0, 4, 9, -1, 4 .y_offsets dw 6, 6, 9, 6, 6, 9, 6, 6, 9 .chr db $BB, $BB, $BA, $AB, $AB, $AA, $A9, $A9, $B9 .properties db $65, $25, $25, $65, $25, $25, $65, $25, $25 }
- ==============================================================================
; *$3554A-$355B8 LOCAL Octorock_Draw: { !top_x_bit_low = $0E !top_x_bit_high = $0F JSR Sprite_PrepOamCoord ; perhaps this draws the octorock's snout? LDA !direction, X : CMP.b #$03 : BEQ .dont_draw_this_part ; $07 = [3 * $0DB0, X] + !direction LDA $0DB0, X : ASL A : ADC $0DB0, X : ADC !direction, X : STA $07 PHX : PHA ASL A : TAX REP #$20 LDA $00 : ADD .x_offsets, X : STA ($90), Y AND.w #$0100 : STA !top_x_bit_low LDA $02 : ADD .y_offsets, X : INY : STA ($90), Y ADD.w #$0010 : CMP.w #$0100 : SEP #$20 : BCC .not_off_screen LDA.b #$F0 : STA ($90), Y .not_off_screen PLX LDA .chr, X : INY : STA ($90), Y LDA .properties, X : INY : ORA $05 : STA ($90), Y LDA !top_x_bit_high : STA ($92) PLX .dont_draw_this_part REP #$20 LDA $90 : ADD.w #$0004 : STA $90 INC $92 SEP #$20 DEC $0E40, X LDY.b #$00 JSR Sprite_PrepAndDrawSingleLarge.just_draw INC $0E40, X RTS }