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:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 11:57:49 +01:00
1 parent 44b938f0e5
commit a0f2660eae
1 file changed
+53
+53
View File
@@ -864,6 +864,10 @@ impl Game {
self.gate_hp = (self.gate_hp + 8.0 * dt).min(GATE_HP); 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(); self.update_contested();
for i in 0..self.ents.len() { for i in 0..self.ents.len() {
if !self.ents[i].alive || self.ents[i].held { 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 // tiles within two of a fighting hero
fn update_contested(&mut self) { fn update_contested(&mut self) {
let n = self.map.t.len(); let n = self.map.t.len();
@@ -4178,6 +4213,24 @@ mod tests {
assert!(ok * 10 >= samples * 8); 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] #[test]
fn imps_reinforce_walls() { fn imps_reinforce_walls() {
let mut g = Game::new(3, 64, 64); let mut g = Game::new(3, 64, 64);