Raise walls: plan them on own floor, imps build reinforced earth

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-05 22:11:51 +01:00
1 parent 398bb95681
commit ed3bc437e5
26 files changed
+347 -11

No files matched your search

+26 -4
View File
@@ -208,6 +208,7 @@ pub enum Job {
Guard(usize), // holds a guard post
Spar(usize), // sparring in the arena
MendBridge(usize), // imp mends a worn bridge tile
RaiseWall(usize), // imp raises a planned wall on own floor
}
#[derive(Clone, Serialize, Deserialize)]
@@ -587,6 +588,8 @@ pub struct Game {
#[serde(default)]
pub bridgework: crate::bridges::BridgeWork, // burning and worn bridges
#[serde(default)]
pub wall_plans: Vec<(usize, u8)>, // walls to raise: tile, master side (see walls.rs)
#[serde(default)]
pub wood: f32, // the second resource (see wood.rs)
#[serde(default)]
pub woodwork: crate::wood::WoodWork, // felled mushrooms growing back
@@ -765,7 +768,7 @@ pub fn room_index(k: Kind) -> Option<usize> {
ROOM_KINDS.iter().position(|&r| r == k)
}
fn adj4(a: usize, b: usize) -> bool {
pub(crate) fn adj4(a: usize, b: usize) -> bool {
let (ax, ay) = xy(a);
let (bx, by) = xy(b);
(ax - bx).abs() + (ay - by).abs() == 1
@@ -780,7 +783,7 @@ fn norm(x: f32, y: f32) -> (f32, f32) {
}
}
fn sgn(v: f32) -> f32 {
pub(crate) fn sgn(v: f32) -> f32 {
if v < 0.0 {
-1.0
} else {
@@ -909,6 +912,7 @@ impl Game {
vrng: crate::particles::vrng(),
dwarf_caves: Vec::new(),
bridgework: Default::default(),
wall_plans: Vec::new(),
wood: crate::wood::WOOD_START,
woodwork: Default::default(),
dwarf_t: 30.0,
@@ -1764,7 +1768,7 @@ impl Game {
}
// working speed at a tile: +25% per helper, at most 200% (five imps)
fn help_speed(&self, t: usize) -> f32 {
pub(crate) fn help_speed(&self, t: usize) -> f32 {
1.0 + 0.25 * self.helpers(t).min(HELPERS_MAX) as f32
}
@@ -2356,7 +2360,7 @@ impl Game {
Some((x as f32 + 0.5, y as f32 + 0.5))
};
let target = match e.job {
Job::Dig(t) | Job::Reinforce(t) | Job::Help(t) | Job::TearBridge(t) | Job::MendBridge(t) => tile(t),
Job::Dig(t) | Job::Reinforce(t) | Job::Help(t) | Job::TearBridge(t) | Job::MendBridge(t) | Job::RaiseWall(t) => tile(t),
Job::Attack(id) | Job::Torment(id) | Job::Carry(id) | Job::Brawl(id) => self.find(id).map(|j| (self.ents[j].x, self.ents[j].y)),
Job::Repair(id) | Job::AttackTower(id) => self.towers.iter().find(|t| t.id == id).map(|t| t.pos()),
_ => None,
@@ -3360,6 +3364,12 @@ impl Game {
self.sfx(Sfx::Reinforce, tx, ty);
}
}
Job::RaiseWall(w) => {
if !self.raise_wall_job(e, w, dt) {
self.unreserve(me);
e.job = Job::None;
}
}
Job::MendBridge(b) => {
let (bx, by) = xy(b);
let (tx, ty) = (bx as f32 + 0.5, by as f32 + 0.5);
@@ -3542,6 +3552,17 @@ impl Game {
return;
}
}
// planned walls are raised
if let Some(p) = self.map.search(cur, self.map.walk_cost(), |i| self.planned_wall_near(i, me).is_some(), true) {
let end = p.last().copied().unwrap_or(cur);
if let Some(w) = self.planned_wall_near(end, me) {
self.map.t[w].reserved = me;
e.path = p;
e.job = Job::RaiseWall(w);
e.timer = 0.0;
return;
}
}
// ... and so are bridges the knights worked on
if let Some(p) = self.map.search(cur, self.map.walk_cost(), |i| self.worn_bridge_near(i).is_some(), true) {
let end = p.last().copied().unwrap_or(cur);
@@ -5618,6 +5639,7 @@ pub fn job_name(e: &Ent) -> &'static str {
Job::Reinforce(_) => "job.reinforce",
Job::Repair(_) => "job.repair",
Job::MendBridge(_) => "job.mend_bridge",
Job::RaiseWall(_) => "job.raise_wall",
Job::Carry(_) => "job.carry",
Job::Pray(_) => "job.pray",
Job::HealCore => "job.heal_core",