72 lines
1.9 KiB
Odin
72 lines
1.9 KiB
Odin
package main
|
|
|
|
import math "core:math"
|
|
import rand "core:math/rand"
|
|
import rl "vendor:raylib"
|
|
|
|
EnemyKind :: enum {
|
|
Grunt,
|
|
Brute,
|
|
Scout,
|
|
}
|
|
|
|
Enemy :: struct {
|
|
using actor: Actor,
|
|
touch_dmg: i32,
|
|
kind: EnemyKind,
|
|
xp_reward: i32,
|
|
}
|
|
|
|
make_enemy :: proc(pos: rl.Vector2, kind: EnemyKind) -> Entity {
|
|
e: Enemy
|
|
switch kind {
|
|
case .Grunt:
|
|
e = Enemy{actor = Actor{hp = 45, max_hp = 45, speed = 55}, touch_dmg = 8, kind = .Grunt, xp_reward = 12}
|
|
e.base.gfx = {0 = GfxCircle{pos = {}, radius = 11, color = {220, 80, 80, 255}}}
|
|
case .Brute:
|
|
e = Enemy{actor = Actor{hp = 140, max_hp = 140, speed = 32}, touch_dmg = 20, kind = .Brute, xp_reward = 30}
|
|
e.base.gfx = {0 = GfxCircle{pos = {}, radius = 17, color = {160, 60, 220, 255}}}
|
|
case .Scout:
|
|
e = Enemy{actor = Actor{hp = 25, max_hp = 25, speed = 120}, touch_dmg = 5, kind = .Scout, xp_reward = 8}
|
|
e.base.gfx = {0 = GfxCircle{pos = {}, radius = 8, color = {240, 180, 60, 255}}}
|
|
}
|
|
e.base.pos = pos
|
|
e.base.col_size = 16
|
|
return Entity{v = e}
|
|
}
|
|
|
|
enemy_update :: proc(state: ^GameState, e: ^Enemy, h: Handle, dt: f32) {
|
|
pe := get_entity(state, state.player)
|
|
if pe != nil {
|
|
dir := get_base(pe).pos - e.pos
|
|
e.vel = rl.Vector2Normalize(dir) * e.speed
|
|
}
|
|
|
|
if e.hp <= 0 && !e.marked {
|
|
e.marked = true
|
|
enemy_give_rewards(e, state)
|
|
}
|
|
}
|
|
|
|
enemy_give_rewards :: proc(e: ^Enemy, state: ^GameState) {
|
|
_, p := get_player(state)
|
|
if p == nil do return
|
|
|
|
p.xp += e.xp_reward
|
|
add_log(state, "+%d XP", e.xp_reward)
|
|
check_level_up(state, p)
|
|
|
|
if rand.int_max(100) < 60 {
|
|
item := random_item(p.level)
|
|
spawn(state, make_ground_item(e.pos, item))
|
|
add_log(state, "Dropped: %s lvl %d", item.name, item.level)
|
|
}
|
|
|
|
if rand.int_max(100) < 45 {
|
|
ang := rand.float32() * 6.28
|
|
dist := 500 + rand.float32() * 300
|
|
pos := p.pos + rl.Vector2{math.cos_f32(ang), math.sin_f32(ang)} * dist
|
|
spawn(state, make_enemy(pos, EnemyKind(rand.int_max(3))))
|
|
}
|
|
}
|