← CE5F Bowling-ball behavior handler Map CFB1 → Bee behavior handler
CEB3: Hive behavior handler
Runs the hive each frame. It wanders sideways, homes on the bat's row and spawns bees above itself.
Input
IX the hive's sprite record, with its screen X,Y
IY the hive's logic record
C the hive's pool-slot index, passed to the overlap and offscreen helpers
update_hive CEB3 CALL inhabitant_react_state Reaction-state machine first; carry means skip this frame.
CEB6 RET C
CEB7 LD A,(IY+$0C) Play the burst while the hive spawns a bee.
CEBA CP $03
CEBC JR NZ,hive_idle
During the spawn, play the burst frames once. The animation step moves a frame every other call, so this spans 18 game frames. At anim frame 9 it returns to idle. Until then it returns without a move, so the hive holds still while the new bee spawns.
CEBE LD HL,anim_hive_burst Spawn-burst animation: one bitmap pointer per frame
CEC1 CALL advance_anim
CEC4 LD A,(IY+$0B) Hold until the burst completes.
CEC7 CP $09
CEC9 RET C
CECA LD (IY+$0B),$00 Burst done: reset the frame counter and return to idle.
CECE LD (IY+$0C),$00
CED2 RET
In the idle state the hive wanders and homes on the bat's row.
hive_idle CED3 LD HL,anim_hive_idle Idle animation
CED6 CALL advance_anim
CED9 LD A,(IY+$0B) Wrap the idle loop.
CEDC CP $09
CEDE JR C,hive_move
CEE0 LD (IY+$0B),$00
Pick a horizontal wander heading, right or left, then home vertically on the bat's row. The bat's row is the Y byte of its sprite record. While the hive runs right or left, its row is compared against the bat's. The comparison tilts the heading one step up or down. The horizontal run becomes a diagonal that closes on the bat's row.
hive_move CEE4 LD A,$03 Constrain the wander to a horizontal heading.
CEE6 CALL pick_wander_heading
CEE9 LD HL,bat_y The bat's row is the Y byte of its sprite record.
CEEC LD A,(IY+$00) Only steer while the heading is horizontal.
CEEF CP $02
CEF1 JR NZ,hive_steer_left
CEF3 LD A,(IX+$01) Run to the right: tilt the heading one step up when the bat is level with or above the hive.
CEF6 CP (HL)
CEF7 JR C,hive_nudge_a
CEF9 DEC (IY+$00)
CEFC JR hive_clamp_top
hive_nudge_a CEFE INC (IY+$00) The bat sits below, so tilt the other way.
CF01 JR hive_clamp_top
hive_steer_left CF03 CP $06 Run to the left: tilt the heading one step up when the bat is level with or above the hive.
CF05 JR NZ,hive_clamp_top
CF07 LD A,(IX+$01)
CF0A CP (HL)
CF0B JR C,hive_nudge_b
CF0D INC (IY+$00)
CF10 JR hive_clamp_top
hive_nudge_b CF12 DEC (IY+$00) The bat sits below, so tilt the other way.
Keep the hive out of the top strip. When the hive moves into the top strip of the play area, force the downward heading. That steers it back down.
hive_clamp_top CF15 LD A,(IX+$01) Too near the top of the screen: force the downward vertical heading.
CF18 CP $30
CF1A JR NC,hive_apply_move
CF1C LD A,$04
CF1E LD (IY+$00),A
hive_apply_move CF21 CALL object_avoid_walls Steer away from walls.
CF24 CALL move_object Advance one step along the heading.
CF27 CALL inhabitant_offscreen Despawn once off the far edge; carry means gone.
CF2A RET C
CF2B LD B,$0A Award 100 points if a ball hits it, banked into the pending score. Carry means killed.
CF2D CALL ball_kill
CF30 RET C
CF31 CALL overlap_sweep The sweep: non-zero means a hit.
CF34 OR A
CF35 JR Z,hive_try_spawn
CF37 LD (IY+$0B),$00 On a hit, restart the animation and die.
CF3B LD (IY+$0C),$02
CF3F RET
Spawn attempt, only on idle anim frame 0, so at most once per idle cycle. First scan the inhabitant records (inhabitant_records) for a bee already alive. A second bee is not spawned while one is. It is the only duplicate check a bee gets. The bee's entry in the singleton table (spawn_singleton_table) is clear, so the generic spawn process_wave_script_2 does not refuse a bee that a wave script places.
hive_try_spawn CF40 LD A,(IY+$0B) Spawn only on idle frame 0.
CF43 OR A
CF44 RET NZ
CF45 PUSH IY Set up to walk the inhabitant records.
CF47 LD IY,inhabitant_records
CF4B LD B,$05
hive_scan_bee CF4D LD A,(IY+$08) A live bee already exists?
CF50 CP $07
CF52 JR Z,hive_bee_exists
CF54 LD DE,$0010 Step to the next logic record and continue the scan.
CF57 ADD IY,DE
CF59 DJNZ hive_scan_bee
CF5B JR hive_spawn_roll No bee found in any slot, so a spawn is allowed.
hive_bee_exists CF5D POP IY Bee already alive: do not spawn.
CF5F RET
Roll the RNG and proceed only when its low nibble is 0. Then find a free pool slot: walk the inhabitant records and the parallel inhabitant entries of the sprite records for an empty type. With no free slot, give up this frame.
hive_spawn_roll CF60 POP IY Balance the scan's stack push.
CF62 CALL next_random Roll the RNG: 1-in-16 chance to spawn this frame.
CF65 AND $0F
CF67 RET NZ
CF68 PUSH IY Set up to scan the 5 records and object slots for a free one.
CF6A PUSH IX
CF6C LD IX,inhabitant_objects
CF70 LD IY,inhabitant_records
CF74 LD B,$05
hive_find_slot CF76 LD A,(IY+$08) A free slot?
CF79 OR A
CF7A JR Z,hive_emit_bee
CF7C LD DE,$0009 Step both records on and look again.
CF7F ADD IX,DE
CF81 LD DE,$0010
CF84 ADD IY,DE
CF86 DJNZ hive_find_slot
CF88 POP IX No free slot: give the saved registers back and drop the spawn.
CF8A POP IY
CF8C RET
Claim the free slot as a bee and place it at the hive's column, 14 pixels above the hive. The spawn initializer sets the bee's heading and timers. The hive then flashes the spawn burst.
hive_emit_bee CF8D LD (IY+$08),$07 Claim the slot for a bee.
CF91 POP HL Recover the hive's own sprite record.
CF92 LD A,(HL) Put the bee in the hive's column.
CF93 LD (IX+$00),A
CF96 INC HL
CF97 LD A,(HL) The bee spawns a fixed distance above the hive's row.
CF98 SUB $0E
CF9A LD (IX+$01),A
CF9D DEC HL
CF9E PUSH HL
CF9F LD B,$07 The new object is a bee.
CFA1 CALL spawn_object_init Initialize the new bee.
CFA4 POP IX
CFA6 POP IY
CFA8 LD (IY+$0C),$03 Switch the hive to its spawn burst.
CFAC LD (IY+$0B),$00
CFB0 RET
← CE5F Bowling-ball behavior handler Map CFB1 → Bee behavior handler
Fork me on GitHub