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)
}
}
|