diff --git a/src/game.rs b/src/game.rs index eeac51f..0fe0d2f 100644 --- a/src/game.rs +++ b/src/game.rs @@ -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);