aboutsummaryrefslogtreecommitdiff
path: root/src/enemy.odin
diff options
context:
space:
mode:
authoriamcheeseman <[email protected]>2026-03-04 16:12:25 -0500
committeriamcheeseman <[email protected]>2026-03-04 16:12:25 -0500
commit69bfcb3c5fec6957e00264d24990dd2f1263cd50 (patch)
treebab0896b254d9158b31cbe2ae1073562deef230e /src/enemy.odin
parentccd4b29cc358d89d231e602522ca7b35d178b120 (diff)
better muntik
Diffstat (limited to 'src/enemy.odin')
-rw-r--r--src/enemy.odin99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/enemy.odin b/src/enemy.odin
new file mode 100644
index 0000000..7da2635
--- /dev/null
+++ b/src/enemy.odin
@@ -0,0 +1,99 @@
+package demonchime
+
+import "base:intrinsics"
+
+import "core:math"
+import "core:log"
+import hm "core:container/handle_map"
+
+import "fw"
+import "phys"
+
+Enemy_Ai :: enum(u16) {
+ Muntik,
+}
+
+Enemy_Update_Callback :: #type proc(^Enemy, f32)
+
+update_funcs := [Enemy_Ai]Enemy_Update_Callback{
+ .Muntik = update_muntik,
+}
+
+Enemy_Stats :: struct {
+ iframes: f32,
+ max_health: i16,
+ defense: i16,
+}
+
+Enemy :: struct {
+ handle: int,
+
+ sprite: Sprite,
+ body: phys.Body_Handle,
+
+ stats: ^Enemy_Stats,
+
+ hit_timestamp: f32,
+
+ ai: Enemy_Ai,
+ health: i16,
+
+ variant: union {
+ ^Muntik,
+ },
+}
+
+make_enemy :: proc(
+ $T: typeid,
+ stats: ^Enemy_Stats,
+ sprite: Sprite,
+ body: phys.Body_Handle
+) -> ^T
+ where
+ intrinsics.type_has_field(T, "enemy"),
+ intrinsics.type_field_type(T, "enemy") == Enemy {
+ e := new(T)
+
+ e.enemy.stats = stats
+ e.enemy.sprite = sprite
+ e.enemy.body = body
+ e.enemy.health = stats.max_health
+ e.enemy.variant = e
+
+ e.enemy.handle = len(state.enemy_list)
+ append(&state.enemy_list, e)
+
+ return e
+}
+
+enemy_take_damage :: proc(e: ^Enemy, damage: i16, kb_dir: Vec2) {
+ current_time := f32(fw.get_time())
+ if current_time - e.hit_timestamp < e.stats.iframes {
+ return
+ }
+
+ e.hit_timestamp = current_time
+
+ total_damage := math.max(damage - e.stats.defense, 1)
+ e.health -= total_damage
+ e.health = math.max(e.health, 0)
+}
+
+update_enemies :: proc(dt: f32) {
+ for e in state.enemy_list {
+ update_funcs[e^.ai](e, dt)
+ }
+}
+
+draw_enemies :: proc() {
+ for e in state.enemy_list {
+ draw_sprite(e^.sprite)
+ }
+}
+
+clear_enemies :: proc() {
+ for e in state.enemy_list {
+ phys.remove_body(e^.body)
+ free(e)
+ }
+}