From f14864182c9db5c444bb3e297cfd9ded775058e8 Mon Sep 17 00:00:00 2001 From: codegirl-007 Date: Fri, 26 Jun 2026 17:43:58 -0700 Subject: [PATCH] splash damage --- game/projectile.odin | 59 +++++++++++++++++++++++++++++--------------- game/tower.odin | 6 ++++- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/game/projectile.odin b/game/projectile.odin index dbe134e..1dd21a3 100644 --- a/game/projectile.odin +++ b/game/projectile.odin @@ -3,13 +3,14 @@ package game import rl "vendor:raylib" Projectile :: struct { - active: bool, - position: Vec2, - target_slot: int, - damage: int, - speed: f32, - mode: Projectile_Mode, - direction: Vec2, + active: bool, + position: Vec2, + target_slot: int, + damage: int, + speed: f32, + mode: Projectile_Mode, + direction: Vec2, + splash_radius: f32, } Projectile_Mode :: enum { @@ -42,24 +43,26 @@ spawn_projectile :: proc(world: ^World, from: Vec2, target_slot: int, damage: in p.mode = .Homing p^ = Projectile { - active = true, - position = from, - target_slot = target_slot, - damage = damage, - speed = PROJECTILE_SPEED, + active = true, + position = from, + target_slot = target_slot, + damage = damage, + speed = PROJECTILE_SPEED, + splash_radius = 0, } } -spawn_ballistic :: proc(world: ^World, from, dir: Vec2, damage: int) { +spawn_ballistic :: proc(world: ^World, from, dir: Vec2, damage: int, splash: f32) { p := acquire_projectile(world) if p == nil do return p^ = Projectile { - active = true, - position = from, - direction = dir, - mode = .Ballistic, - damage = damage, - speed = CANNON_PROJECTILES_SPEED, + active = true, + position = from, + direction = dir, + mode = .Ballistic, + damage = damage, + speed = CANNON_PROJECTILES_SPEED, + splash_radius = splash, } } @@ -114,7 +117,7 @@ update_ballistic_projectile :: proc(world: ^World, p: ^Projectile, dt: f32) { p.position.x += p.direction.x * step p.position.y += p.direction.y * step - if hit_enemy_at(world, p.position, p.damage) { + if apply_splash_damage(world, p.position, p.damage, p.splash_radius) { p.active = false return } @@ -141,3 +144,19 @@ render_projectiles :: proc(world: ^World) { } } +apply_splash_damage :: proc(world: ^World, center: Vec2, damage: int, radius: f32) -> bool { + if radius <= 0 do return hit_enemy_at(world, center, damage) + + hit_any := false + for i in 0 ..< MAX_ENEMIES { + e := &world.enemies[i] + if !e.active do continue + if distance(center, e.position) <= radius { + apply_tower_hit(world, e, damage) + hit_any = true + } + } + + return hit_any +} + diff --git a/game/tower.odin b/game/tower.odin index e7fdcde..cb29d20 100644 --- a/game/tower.odin +++ b/game/tower.odin @@ -30,6 +30,7 @@ Tower_Archetype :: struct { upgrade_cost: int, damage_per_level: int, range_per_level: f32, + splash_radius: f32, } TOWER_ARCHETYPES: [Tower_Kind]Tower_Archetype = { @@ -45,6 +46,7 @@ TOWER_ARCHETYPES: [Tower_Kind]Tower_Archetype = { upgrade_cost = 40, damage_per_level = 3, range_per_level = 8, + splash_radius = 0, }, .Cannon = { kind = .Cannon, @@ -57,6 +59,7 @@ TOWER_ARCHETYPES: [Tower_Kind]Tower_Archetype = { upgrade_cost = 40, damage_per_level = 3, range_per_level = 8, + splash_radius = 60, }, .Ice = { kind = .Ice, @@ -69,6 +72,7 @@ TOWER_ARCHETYPES: [Tower_Kind]Tower_Archetype = { upgrade_cost = 40, damage_per_level = 3, range_per_level = 8, + splash_radius = 0, }, } @@ -238,7 +242,7 @@ update_towers :: proc(world: ^World, dt: f32) { (target.position.x - t.position.x) / len, (target.position.y - t.position.y) / len, } - spawn_ballistic(world, t.position, dir, damage) + spawn_ballistic(world, t.position, dir, damage, arch.splash_radius) } } case .Ice: