Scatter missed arrows instead of landing on a ring around towers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
730ad08d7a
commit
b4d834823b
2 files changed
+19
-7
No files matched your search
+6
-1
@@ -4886,7 +4886,12 @@ impl Game {
|
|||||||
TowerKind::Arrow => {
|
TowerKind::Arrow => {
|
||||||
// the arrow pierces up to two more heroes behind the target
|
// the arrow pierces up to two more heroes behind the target
|
||||||
let dir = norm(ex - px, ey - py);
|
let dir = norm(ex - px, ey - py);
|
||||||
let (endx, endy, wall) = self.arrow_end(px, py, dir.0, dir.1, t.range());
|
// what the eye sees: past the target the spent arrow comes down at a random
|
||||||
|
// distance (not all on a circle at the end of the range); the damage below
|
||||||
|
// still reaches along the whole range
|
||||||
|
let to_target = ((ex - px).powi(2) + (ey - py).powi(2)).sqrt();
|
||||||
|
let reach = to_target + 0.8 + self.vrng.f() * (t.range() + 1.5 - to_target - 0.8).max(0.5);
|
||||||
|
let (endx, endy, wall) = self.arrow_end(px, py, dir.0, dir.1, reach);
|
||||||
self.shot(mx, my, mh, endx, endy, 0.45, 0.3, 0xffd0e0f0);
|
self.shot(mx, my, mh, endx, endy, 0.45, 0.3, 0xffd0e0f0);
|
||||||
self.style_last_fx(if wall { crate::particles::ST_ARROW_WALL } else { crate::particles::ST_ARROW_FALL });
|
self.style_last_fx(if wall { crate::particles::ST_ARROW_WALL } else { crate::particles::ST_ARROW_FALL });
|
||||||
self.sfx(Sfx::Shoot, px, py);
|
self.sfx(Sfx::Shoot, px, py);
|
||||||
|
|||||||
+13
-6
@@ -332,12 +332,16 @@ impl Game {
|
|||||||
let spot = if f.style == ST_ARROW_FALL {
|
let spot = if f.style == ST_ARROW_FALL {
|
||||||
// spent at the end of its range: it sails on a little and comes down there
|
// spent at the end of its range: it sails on a little and comes down there
|
||||||
// (a wall in the way stops it in front of the wall)
|
// (a wall in the way stops it in front of the wall)
|
||||||
let reach = 0.35 + f.h2.max(0.0) * 1.5;
|
// where exactly varies: a little further or shorter, and off to the side
|
||||||
let (fx, fy) = (x + dx * reach, y + dy * reach);
|
let reach = 0.2 + f.h2.max(0.0) * 1.5 + self.vrng.f() * 1.4;
|
||||||
|
let side = (self.vrng.f() - 0.5) * 0.9;
|
||||||
|
let (fx, fy) = (x + dx * reach - dy * side, y + dy * reach + dx * side);
|
||||||
if self.map.get(fx as i32, fy as i32).map_or(true, |t| t.solid()) { (x, y) } else { (fx, fy) }
|
if self.map.get(fx as i32, fy as i32).map_or(true, |t| t.solid()) { (x, y) } else { (fx, fy) }
|
||||||
} else if self.vrng.f() < 0.35 {
|
} else if self.vrng.f() < 0.35 {
|
||||||
// a hit that glanced off: it comes down next to the target
|
// a hit that glanced off: it comes down next to the target
|
||||||
(x + self.vrng.f() * 0.7 - 0.35, y + self.vrng.f() * 0.7 - 0.35)
|
// (mostly on, a bit past the target)
|
||||||
|
let on = 0.1 + self.vrng.f() * 0.8;
|
||||||
|
(x + dx * on + self.vrng.f() * 1.0 - 0.5, y + dy * on + self.vrng.f() * 1.0 - 0.5)
|
||||||
} else {
|
} else {
|
||||||
return; // a hit: the arrow stays in the target
|
return; // a hit: the arrow stays in the target
|
||||||
};
|
};
|
||||||
@@ -493,10 +497,13 @@ mod tests {
|
|||||||
// a little lava and water east of the core
|
// a little lava and water east of the core
|
||||||
fn river_spot(g: &mut Game, kind: Kind) -> (f32, f32) {
|
fn river_spot(g: &mut Game, kind: Kind) -> (f32, f32) {
|
||||||
let (cx, cy) = g.map.core;
|
let (cx, cy) = g.map.core;
|
||||||
let (x, y) = (cx + 3, cy - 3);
|
let (x, y) = (cx + 4, cy - 4);
|
||||||
let t = &mut g.map.t[idx(x, y)];
|
// a 3x3 patch around (x, y)
|
||||||
|
for (dx, dy) in [(-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] {
|
||||||
|
let t = &mut g.map.t[idx(x + dx, y + dy)];
|
||||||
t.kind = kind;
|
t.kind = kind;
|
||||||
t.owner = Owner::None;
|
t.owner = Owner::None;
|
||||||
|
}
|
||||||
(x as f32 + 0.5, y as f32 + 0.5)
|
(x as f32 + 0.5, y as f32 + 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +512,7 @@ mod tests {
|
|||||||
let mut g = Game::new(3, 64, 64);
|
let mut g = Game::new(3, 64, 64);
|
||||||
let (lx, ly) = river_spot(&mut g, Kind::Lava);
|
let (lx, ly) = river_spot(&mut g, Kind::Lava);
|
||||||
// a spent tower arrow comes down in the lava: it drifts there, burning, then is gone
|
// a spent tower arrow comes down in the lava: it drifts there, burning, then is gone
|
||||||
g.shot(lx - 2.0, ly, 0.5, lx - 0.4, ly, 0.0, 0.3, 0xffffffff);
|
g.shot(lx - 2.0, ly, 0.5, lx - 1.2, ly, 0.0, 0.3, 0xffffffff);
|
||||||
g.style_last_fx(ST_ARROW_FALL);
|
g.style_last_fx(ST_ARROW_FALL);
|
||||||
for _ in 0..8 {
|
for _ in 0..8 {
|
||||||
g.update(0.05);
|
g.update(0.05);
|
||||||
|
|||||||
Reference in new issue
Block a user