78 lines
1.7 KiB
Odin
78 lines
1.7 KiB
Odin
package game
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
Projectile :: struct {
|
|
active: bool,
|
|
position: Vec2,
|
|
target_slot: int,
|
|
damage: int,
|
|
speed: f32,
|
|
}
|
|
|
|
acquire_projectile :: proc(world: ^World) -> ^Projectile {
|
|
for i in 0 ..< MAX_PROJECTILES {
|
|
if !world.projectiles[i].active {
|
|
return &world.projectiles[i]
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
enemy_still_on_map :: proc(world: ^World, slot: int) -> (^Enemy, bool) {
|
|
if slot < 0 || slot >= MAX_ENEMIES do return nil, false
|
|
e := &world.enemies[slot]
|
|
if !e.active do return nil, false
|
|
if len(world.path) == 0 do return nil, false
|
|
if e.path_index >= len(world.path) do return nil, false
|
|
return e, true
|
|
}
|
|
|
|
spawn_projectile :: proc(world: ^World, from: Vec2, target_slot: int, damage: int) {
|
|
p := acquire_projectile(world)
|
|
if p == nil do return
|
|
|
|
p^ = Projectile {
|
|
active = true,
|
|
position = from,
|
|
target_slot = target_slot,
|
|
damage = damage,
|
|
speed = PROJECTILE_SPEED,
|
|
}
|
|
}
|
|
|
|
update_projectiles :: proc(world: ^World, dt: f32) {
|
|
for i in 0 ..< MAX_PROJECTILES {
|
|
p := &world.projectiles[i]
|
|
if !p.active do continue
|
|
|
|
target, ok := enemy_still_on_map(world, p.target_slot)
|
|
if !ok {
|
|
p.active = false
|
|
continue
|
|
}
|
|
|
|
move_toward(&p.position, target.position, p.speed, dt)
|
|
|
|
if distance(p.position, target.position) <= PROJECTILE_HIT_RADIUS {
|
|
target.health -= p.damage
|
|
p.active = false
|
|
|
|
if target.health <= 0 {
|
|
target.active = false
|
|
push_event(world, .Enemy_Killed, gold_reward = 5)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
render_projectiles :: proc(world: ^World) {
|
|
for i in 0 ..< MAX_PROJECTILES {
|
|
p := world.projectiles[i]
|
|
if !p.active do continue
|
|
rl.DrawCircle(i32(p.position.x), i32(p.position.y), 4, rl.GOLD)
|
|
}
|
|
}
|
|
|