| ← D47C | Map | D566 → |
D4E8: Dart behavior handler
|
Per-frame handler for the dart. It wanders the playfield and dies on the sweep. When the ball destroys it the player scores 500 and the global move-freeze is triggered. The freeze halts inhabitant movement and spawns for 512 frames, aged by the same inhabitant walk.
|
|||||||||||
|
|||||||||||
|
Animation is the 8-frame table, advanced by the animation step and wrapped at frame 8. The wander and the per-frame tests are the shared pattern with two exceptions. Its ball test is the 12-px overlap, narrower than the one the other inhabitants take through the ball-kill test. Its ball kill triggers the move-freeze and the 500-point award.
|
|||||||||||
| update_dart | D4E8 | CALL inhabitant_react_state | Reaction-state machine first; while a spawn or death animation plays it returns carry and skips the rest. | ||||||||
| D4EB | RET C | ||||||||||
| D4EC | LD HL,anim_dart | Advance and wrap the 8-frame animation. | |||||||||
| D4EF | CALL advance_anim | ||||||||||
| D4F2 | LD A,(IY+$0B) | ||||||||||
| D4F5 | CP $08 | ||||||||||
| D4F7 | JR C,dart_wander | ||||||||||
| D4F9 | LD (IY+$0B),$00 | ||||||||||
| dart_wander | D4FD | XOR A | Wander: re-pick the heading when the move timer expires, avoid walls, step, then despawn off the far edge. | ||||||||
| D4FE | CALL pick_wander_heading | ||||||||||
| D501 | CALL object_avoid_walls | ||||||||||
| D504 | CALL move_object | ||||||||||
| D507 | CALL inhabitant_offscreen | ||||||||||
| D50A | RET C | ||||||||||
| D50B | LD A,C | Test overlap with ball A through the first and second overlap operands. An overlap jumps to the ball-kill. | |||||||||
| D50C | LD (overlap_slot_1),A | ||||||||||
| D50F | LD A,$01 | ||||||||||
| D511 | LD (overlap_slot_2),A | ||||||||||
| D514 | CALL overlap_pair | ||||||||||
| D517 | OR A | ||||||||||
| D518 | JR NZ,dart_ball_kill | ||||||||||
| dart_test_ball2 | D51A | PUSH IX | No overlap with ball A: test ball B too, but only while its sprite pointer points at the ball sprite slot. An overlap jumps to the ball-kill. | ||||||||
| D51C | LD IX,obj2_object | ||||||||||
| D520 | LD L,(IX+$06) | ||||||||||
| D523 | LD H,(IX+$07) | ||||||||||
| D526 | POP IX | ||||||||||
| D528 | LD DE,slot_ball | ||||||||||
| D52B | XOR A | ||||||||||
| D52C | SBC HL,DE | ||||||||||
| D52E | JR NZ,dart_sweep | ||||||||||
| D530 | LD A,C | ||||||||||
| D531 | LD (overlap_slot_1),A | ||||||||||
| D534 | LD A,$02 | ||||||||||
| D536 | LD (overlap_slot_2),A | ||||||||||
| D539 | CALL overlap_pair | ||||||||||
| D53C | OR A | ||||||||||
| D53D | JR NZ,dart_ball_kill | ||||||||||
| dart_sweep | D53F | CALL overlap_sweep | No overlap with a ball: the sweep kills it; otherwise it survives the frame. | ||||||||
| D542 | OR A | ||||||||||
| D543 | RET Z | ||||||||||
| D544 | LD (IY+$0B),$00 | ||||||||||
| D548 | LD (IY+$0C),$02 | ||||||||||
| D54C | RET | ||||||||||
| dart_ball_kill | D54D | LD (IY+$0B),$00 | Ball-kill: reset the animation and enter the death reaction. Raise the global move-freeze flag and zero its expiry counter. Stage the 500-point award in the pending score. | ||||||||
| D551 | LD (IY+$0C),$02 | ||||||||||
| D555 | XOR A | ||||||||||
| D556 | LD (freeze_timer_lo),A | ||||||||||
| D559 | LD (freeze_timer_hi),A | ||||||||||
| D55C | INC A | ||||||||||
| D55D | LD (move_freeze),A | ||||||||||
| D560 | LD A,$32 | ||||||||||
| D562 | LD (pending_score),A | ||||||||||
| D565 | RET | ||||||||||
| ← D47C | Map | D566 → |
