+
+ ; attempts to spawna a new actor
+ ; by searching for a free slot of type 0
+ ; returns:
+ ; hl: free actor ptr
+ ; hl: NULL if no slot is available
+ ; note: memory is not cleared
+ ; the caller will have to initialize the actor
+actor_try_add:
+ ld b, ACTS_MAX
+ ld hl, actors
+ ld de, act_size
+@loop:
+ ld a, [hl] ; check type
+ cp a, 0
+ ret z ; if 0 type -> match! return now
+ ; go to next ptr
+ add hl, de
+ dec b
+ jr nz, @loop REL
+
+ ; nothing found
+ ld hl, NULL
+ ret
+
+
; draws a single object
; for an actor accounting for scroll
; inputs:
dw act_nop
dw player_update_and_draw
dw act_guard_update_and_draw
+
+ ; called when an actor is spawned
+ ; via a map object
+actor_init_table:
+ dw act_nop
+ dw act_nop
+ dw act_guard_init
actor_collision_res_table:
dw act_nop
dw player_col_res
dw act_guard_col_res
+ ; inits an actors
+ ; inputs:
+ ; de: actor
+actor_init:
+ ld a, [de]
+ add a, a ; * 2 for offset
+ ld hl, actor_init_table
+ ld b, 0
+ ld c, a
+ add hl, bc
+
+ ld a, [hl+]
+ ld b, a
+ ld a, [hl]
+ ld h, a
+ ld l, b
+ call_hl
+
+ ret
+
; calls update for all actors
; and draws them
actor_update_all:
jr nz, @loop REL
ret
- ; spawns a test guard
- ; inputs:
- ; $1: actor offset
- ; $2: y
- ; $3: x
-#macro actor_spawn_test_guard
- ld de, act_enemy_guard
- ld hl, actors+act_size * $1
- ld bc, act_size
- call memcpy
-
- ; set a test position
- ld a, $2
- ld [actors+ act_size * $1 + act_pos_y], a
- ld a, $3
- ld [actors+ act_size * $1 + act_pos_x], a
-#endmacro
-
-
- ; loads a test actor
-actor_load_test:
- actor_spawn_test_guard 0, 30, 30
- actor_spawn_test_guard 1, 20, 40
- actor_spawn_test_guard 2, 20, 50
- actor_spawn_test_guard 3, 20, 60
- actor_spawn_test_guard 4, 20, 70
- actor_spawn_test_guard 5, 20, 80
- actor_spawn_test_guard 6, 30, 80
- ret
-
; despawns an actor
; inputs:
; de: actor ptr
l1_objs:
modef MOT_SET_PAT, 0, 8, pat_center_empty_wall
+ modef2 MOT_ACTOR_SPAWNER, 0, 8, ACT_T_GUARD, 0x40
; rectangle at y/x 0/0 with height 32 width 64
modef MOT_RECT, 0, 8, 0x0804
modef MOT_SET_PAT, 0, 18, pat_center_empty_wall
modef MOT_RECT, 0, 18, 0x080F
+ modef2 MOT_ACTOR_SPAWNER, 0, 18, ACT_T_GUARD, 0x40
modef MOT_SET_PAT, 0, 0x1E, pat_empty
modef MOT_DISABLE_SCROLL, 0, 0x20, 0
ret
; spawns an actor spawner
+ ; dat1: actor type
+ ; dat2 nnnn0000: x offset to spawn at / 8
; inputs:
; de: map object ptr
mo_actor_spawner:
+ ld hl, mo_dat
+ add hl, de
+
+ push hl
+ call actor_try_add
+ pop de
+ ld a, h
+ or a, l
+ ret z ; bail if hl is NULL
+
+ ; we have a ptr!
+ ld a, [de]
+ inc de ; go to dat2
+
+ push hl
+ ; set type
+ ld [hl+], a
+
+ ; clear flags
+ xor a, a
+ ld [hl+], a
+
+ ; y position is always the same
+ ld a, -16 & 0xFF
+ ld [hl+], a
+
+ ; TODO:
+ ; x position is based on dat2
+ ld a, [de]
+ and a, 0xF0
+ swap a
+ add a, a ; * 2
+ add a, a ; * 4
+ add a, a ; * 8
+ ld [hl+], a
+
+ ; clear p0 and state
+ xor a, a
+ ld [hl+], a
+ ld [hl+], a
+
+ ; TODO: run some init code based on type
+ pop de
+ ; de = actor base
+ call actor_init
+
ret