package demonchime import "core:math" import "core:math/linalg" import "core:math/rand" import "phys" import "fw" hugbug_stats := Enemy_Stats { max_health = 10, } Hugbug :: struct { using enemy: Enemy, saw_player: bool, spawn_position: Vec2, target_position: Vec2, patrol_timer: f32, } make_hugbug :: proc(pos: Vec2) -> (int, ^Hugbug) { sprite: Sprite init_sprite(&sprite, .Hugbug) sprite.offset = { f32(sprite.width / 2), f32(sprite.height / 2), } body := phys.make_body( phys.Rect{{-4, -4}, {10, 10}}, layers = {.Enemy}, mask = {.Player, .Hard}, ) phys.set_position(body, pos) hugbug := make_enemy( Hugbug, &hugbug_stats, sprite, body ) hugbug.ai = .Hugbug hugbug.spawn_position = pos hugbug.target_position = pos return hugbug.handle, hugbug } update_hugbug :: proc(e: ^Enemy, dt: f32) { hb, is_hugbug := e.variant.(^Hugbug) if !is_hugbug { return } pos := phys.get_position(hb.body) player_pos := phys.get_position(player.body) pursuing := false speed: f32 = HUGBUG_PATROL_SPEED distance := linalg.length2(player_pos - pos) if distance < HUGBUG_PURSUE_RANGE*HUGBUG_PURSUE_RANGE { hb.target_position = player_pos hb.patrol_timer = HUGBUG_PATROL_TIMEOUT_MAX speed = HUGBUG_PURSUE_SPEED pursuing = true } else { hb.patrol_timer -= dt if hb.patrol_timer < 0 { hb.patrol_timer = rand.float32_range( HUGBUG_PATROL_TIMEOUT_MIN, HUGBUG_PATROL_TIMEOUT_MAX, ) stay_idle := coin_flip() if stay_idle { hb.target_position = pos } else { hb.target_position = hb.spawn_position + Vec2{ rand.float32_range(-HUGBUG_PATROL_RANGE, HUGBUG_PATROL_RANGE), rand.float32_range(-HUGBUG_PATROL_RANGE, HUGBUG_PATROL_RANGE), } } } } accelerate_to_point(hb.body, hb.target_position, speed, HUGBUG_ACCEL) contact_damage(hb.body, HUGBUG_DAMAGE) hb.sprite.anim_speed = 1 if f32(fw.get_time()) - hb.hit_timestamp < 0.1 { set_sprite_active_tag(&hb.sprite, "hurt") } else { set_sprite_active_tag(&hb.sprite, "fly") if pursuing { hb.sprite.anim_speed = 2 } } vel := phys.get_velocity(hb.body) hb.sprite.scale.x = -1 if vel.x < 0 else 1 if math.abs(vel.x) < 5 { hb.sprite.scale.x = 1 } } object_spawner_hugbug :: proc(obj: Object_Resource) { make_hugbug(obj.pos) }