aboutsummaryrefslogtreecommitdiff
path: root/src/enemy.odin
blob: 7da263531798dcdd3fefc34ce2aaf678f1f9ce44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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)
  }
}