Earth corners between two reinforced walls are reinforced automatically
Imps cannot reach such corners (only diagonal to own floor); they are closed every two seconds. Knight fortress walls do not count; the floor condition keeps it from spreading. Test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
44b938f0e5
commit
a0f2660eae
1 file changed
+53
+53
@@ -864,6 +864,10 @@ impl Game {
|
||||
self.gate_hp = (self.gate_hp + 8.0 * dt).min(GATE_HP);
|
||||
}
|
||||
|
||||
// every two seconds: corners between reinforced walls are closed
|
||||
if (self.time / 2.0).floor() != ((self.time - dt) / 2.0).floor() {
|
||||
self.reinforce_corners();
|
||||
}
|
||||
self.update_contested();
|
||||
for i in 0..self.ents.len() {
|
||||
if !self.ents[i].alive || self.ents[i].held {
|
||||
@@ -1673,6 +1677,37 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
// An earth corner between two reinforced walls (and diagonal to own floor) cannot be
|
||||
// reached by the imps: it is reinforced together with the walls. The floor condition keeps
|
||||
// this from spreading into the earth behind the walls.
|
||||
pub fn reinforce_corners(&mut self) {
|
||||
let (w, h) = (mw() as i32, mh() as i32);
|
||||
let wall = |m: &Map, x: i32, y: i32| m.get(x, y).map_or(false, |n| n.kind == Kind::Earth && n.reinforced && n.owner != Owner::Hero);
|
||||
let floor = |m: &Map, x: i32, y: i32| m.get(x, y).map_or(false, |n| n.owner == Owner::Player && n.walkable());
|
||||
let mut add = Vec::new();
|
||||
for y in 1..h - 1 {
|
||||
for x in 1..w - 1 {
|
||||
let t = &self.map.t[idx(x, y)];
|
||||
if t.kind != Kind::Earth || t.reinforced || t.marked || t.owner == Owner::Hero {
|
||||
continue;
|
||||
}
|
||||
for (ax, by) in [(1, 1), (1, -1), (-1, 1), (-1, -1)] {
|
||||
if wall(&self.map, x + ax, y) && wall(&self.map, x, y + by) && floor(&self.map, x + ax, y + by) {
|
||||
add.push(idx(x, y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i in add {
|
||||
let t = &mut self.map.t[i];
|
||||
t.reinforced = true;
|
||||
t.hp = t.hp.max(12.0);
|
||||
let (x, y) = xy(i);
|
||||
self.fx(8, x as f32 + 0.5, y as f32 + 0.5, 0.0, 0.0, 0.5, 0xff4040e0);
|
||||
}
|
||||
}
|
||||
|
||||
// tiles within two of a fighting hero
|
||||
fn update_contested(&mut self) {
|
||||
let n = self.map.t.len();
|
||||
@@ -4178,6 +4213,24 @@ mod tests {
|
||||
assert!(ok * 10 >= samples * 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wall_corners_are_reinforced_too() {
|
||||
let mut g = Game::new(3, 64, 64);
|
||||
let (cx, cy) = g.map.core;
|
||||
// the start area spans cx-3..cx+5 / cy-3..cy+5: its walls are at cx-4 and cy-4
|
||||
let (x0, y0) = (cx - 4, cy - 4);
|
||||
for k in 1..4 {
|
||||
g.map.t[idx(x0 + k, y0)].reinforced = true;
|
||||
g.map.t[idx(x0, y0 + k)].reinforced = true;
|
||||
}
|
||||
assert!(g.map.t[idx(x0, y0)].kind == Kind::Earth && !g.map.t[idx(x0, y0)].reinforced);
|
||||
g.reinforce_corners();
|
||||
assert!(g.map.t[idx(x0, y0)].reinforced, "the corner is reinforced");
|
||||
// nothing spreads into the earth behind the walls
|
||||
g.reinforce_corners();
|
||||
assert!(!g.map.t[idx(x0 - 1, y0)].reinforced && !g.map.t[idx(x0, y0 - 1)].reinforced && !g.map.t[idx(x0 - 1, y0 - 1)].reinforced);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imps_reinforce_walls() {
|
||||
let mut g = Game::new(3, 64, 64);
|
||||
|
||||
Reference in new issue
Block a user