unit: wip sub-tile movement
authorLukas Krickl <lukas@krickl.dev>
Tue, 24 Jun 2025 17:09:54 +0000 (19:09 +0200)
committerLukas Krickl <lukas@krickl.dev>
Tue, 24 Jun 2025 17:09:54 +0000 (19:09 +0200)
src/actortables.s
src/macros.inc
src/map.s
src/stats.s
src/unit.s

index 511da3df8f0be5062150465459f0aac3e23e022d..e92921d29a860adb46e024b688cb4a8445001309 100644 (file)
@@ -1,7 +1,7 @@
 #include "unit_demo.s"
 
 default_map_actor_table:
-.db 19 ; size
+.db 0 ; 19 ; size
 dw unit_demo_2
 dw unit_demo_3
 dw unit_demo_3
index 503f8895c4d6aaa8f86641227d65a4ee2718ed9a..5cde6d1cfff656a57303bbb4b4101e76a678aaf5 100644 (file)
@@ -72,7 +72,7 @@
   ; divides a regiser by 16 
   ; inputs:
   ;   $1: the register 
-#macro div8 
+#macro div16 
   srl $1 ; / 2
   srl $1 ; / 4
   srl $1 ; / 8
index d629f6b9020c3f515dee39044bfb098c2ef18728..975d758e7762fb898cd801ccef9d78cc0d6824b1 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -187,7 +187,9 @@ map_actors_load:
   ; de = actor table
   
   ; load actor count
-  ld a, [de] 
+  ld a, [de]
+  cp a, 0
+  jp z, @skip ; do not load if ptr is 0
   inc de ; de = first actor ptr
 
   ; load starting at slot 1
@@ -232,6 +234,7 @@ map_actors_load:
     dec a
   jr nz, @loop REL
 
+@skip:
   ; hand over control to a unit
   ld de, player_unit 
   call unit_wake_up 
index 4dd2f9b084161fe9562ddccf0476f8b476a7fa72..8f59cd61b953a201128ce433785c6401b7e1019c 100644 (file)
@@ -7,3 +7,13 @@
 stat_calc_str:
   ret
 
+  ; calculates the real speed state
+  ; inputs:
+  ;   de: actor
+  ; returns:
+  ;   a: speed stat
+stat_calc_speed:
+  ld hl, act_speed
+  add hl, de ; hl = speed stat
+  ld a, [hl]
+  ret
index c9618efd4aef6befca64ddefa8ae5a22060c7e16..407ce3f1b6be139dc56201ec740a149aea1b89f6 100644 (file)
@@ -306,6 +306,73 @@ unit_collides_with_any_other:
   ret
 #undefine scratch_loop_i
 
+#define TMP_MOVEMENT_SPEED scratch
+  ; calculates movement speed based un the current unit
+  ; inputs:
+  ;   de: unit
+  ; returns: 
+  ;   movement speed in sub-tiles in TMP_UNIT_MOVEMENT_SPEED
+unit_calc_movement_speed:
+  call stat_calc_speed
+  ; movement speed is simply speed / 16
+  div16 a
+  cp a, 0
+  jr nz, @not_zero_speed REL
+    inc a
+@not_zero_speed:
+  ld [TMP_MOVEMENT_SPEED], a
+  ret
+
+  ; performs a sub tile move
+  ; inputs:
+  ;   de: actor
+  ;   $1: swap a/nop
+  ;   $2: add/sub
+  ;   $3: mask to apply to move speed (0xF0 or 0x0F)
+  ; returns if sub-tile movement does not 
+  ; cause an over/underflow
+  ; preserves:
+  ;   hl
+#macro unit_sub_tile_move
+  push hl
+
+  push de
+  call unit_calc_movement_speed
+  pop de
+  
+  ld hl, act_rt_subtile_pos
+  add hl, de ; hl = subtile pos
+
+  ld a, [TMP_MOVEMENT_SPEED]
+  ld b, a ; b = movement speed
+
+  ld a, [hl] 
+  $1 ; swap 
+  and a, 0x0F ; mask bits we don't need
+  $2 a, b ; sub/add
+  ; test if overflow
+  ld c, a ; need value again in a bit
+  and a, 0xF0
+  ; z flag is set if no overflow
+  push af ; push flag on to stack for now
+
+  ld a, c ; now cut off value 
+  and a, 0x0F ; mask it out in case of overflow
+
+  $1 ; swap back
+  ld b, a ; b = new position
+  ld a, [hl] ; load value again
+  and a, $3 ; mask off 
+  or a, b 
+  ld [hl], a ; store new value
+
+  ; if we did not over/underflow 
+  ; exit now
+  pop af ; get back flag result
+  pop hl
+  ret nz
+#endmacro
+
   ; moves a unit up
   ; moves are aborted 
   ; if no more initiative is left
@@ -320,16 +387,23 @@ unit_try_move_up:
   ; y - 1
   unit_test_collision dec b, CF_COLLISION
 
+  push de
   ld hl, act_pos_y
   add hl, de
   ; hl = actor y
   ld a, [hl]
   cp a, 0 ; upper bound
+
+  pop de
   ret z
 
+  unit_sub_tile_move swap a, sub, 0xF0
+  
+  ld a, [hl]
   dec a
   ld [hl], a
 
+
   ret
 
 unit_try_move_down:
@@ -378,6 +452,8 @@ unit_try_move_right:
   ld [hl], a
   ret 
 
+#undefine TMP_MOVEMENT_SPEED
+
   ; centers the current scroll on the selected unit
   ; snaps to corners of the map
   ; inputs: