Guard and attack markers (shields and swords, up to eight each, right click removes); the world and the interface are copied opaque so glows keep their brightness

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-06 07:47:21 +01:00
1 parent a1a53273cd
commit c9dafb1606
24 files changed
+470 -46

No files matched your search

+34 -2
View File
@@ -221,6 +221,7 @@ pub enum Job {
Spar(usize), // sparring in the arena
MendBridge(usize), // imp mends a worn bridge tile
RaiseWall(usize), // imp raises a planned wall on own floor
March(usize), // creature follows an attack marker (sword) at this tile
}
#[derive(Clone, Serialize, Deserialize)]
@@ -499,6 +500,8 @@ pub struct MasterState {
pub room_level: Vec<u8>,
pub gear_stock: Vec<u16>,
pub gear_work: f32,
pub guard_marks: Vec<usize>,
pub attack_marks: Vec<usize>,
pub springs: usize,
pub known: Vec<bool>,
pub researchable: Vec<bool>,
@@ -624,6 +627,12 @@ pub struct Game {
#[serde(default)]
pub happenings: Option<crate::events::Events>, // random events (free games and versus), see events.rs
#[serde(default)]
pub guard_marks: Vec<usize>, // guard markers (shields) of the master being processed (orders.rs)
#[serde(default)]
pub attack_marks: Vec<usize>, // attack markers (swords)
#[serde(default)]
pub marks_t: f32,
#[serde(default)]
pub stats: crate::stats::GameStats, // statistics of the master at this computer (see stats.rs)
#[serde(default)]
pub wall_plans: Vec<(usize, u8)>, // walls to raise: tile, master side (see walls.rs)
@@ -967,6 +976,9 @@ impl Game {
bridgework: Default::default(),
trading: Default::default(),
happenings: None,
guard_marks: Vec::new(),
attack_marks: Vec::new(),
marks_t: 0.0,
stats: Default::default(),
wall_plans: Vec::new(),
wood: crate::wood::WOOD_START,
@@ -1476,6 +1488,8 @@ impl Game {
room_level: self.room_level.clone(),
gear_stock: self.gear_stock.clone(),
gear_work: self.gear_work,
guard_marks: std::mem::take(&mut self.guard_marks),
attack_marks: std::mem::take(&mut self.attack_marks),
springs: self.springs,
known: std::mem::take(&mut self.known),
researchable: std::mem::take(&mut self.researchable),
@@ -1509,6 +1523,8 @@ impl Game {
self.room_level = m.room_level;
self.gear_stock = m.gear_stock;
self.gear_work = m.gear_work;
self.guard_marks = m.guard_marks;
self.attack_marks = m.attack_marks;
self.springs = m.springs;
self.known = m.known;
self.researchable = m.researchable;
@@ -1715,6 +1731,7 @@ impl Game {
}
self.update_forge(dt);
self.update_research();
self.update_marks(dt);
}
fn after_economy(&mut self, dt: f32) {
@@ -3776,7 +3793,7 @@ impl Game {
// a new creature builds its own bed in the lair soon after its arrival
let bed_kind = if flies(e.kind) { Kind::Aerie } else { Kind::Lair };
let beds = if flies(e.kind) { self.counts[7] } else { self.counts[1] };
if e.bed.is_none() && beds > 0 && !matches!(e.job, Job::Attack(_) | Job::Leave | Job::Rally) && self.rng.f() < 0.15 {
if e.bed.is_none() && beds > 0 && !matches!(e.job, Job::Attack(_) | Job::Leave | Job::Rally | Job::March(_)) && self.rng.f() < 0.15 {
let cur = e.tile();
let free = |i: usize| self.map.t[i].kind == bed_kind && self.map.t[i].bed == 0;
let found = if flies(e.kind) { self.map.search(cur, self.map.fly_cost(), free, true) } else { self.map.search(cur, self.map.walk_cost(), free, true) };
@@ -3797,7 +3814,7 @@ impl Game {
}
}
if !matches!(e.job, Job::Attack(_) | Job::Leave | Job::Rest(_) | Job::Brawl(_)) {
let radius = if e.job == Job::Rally { 8.5 } else if matches!(e.job, Job::Guard(_)) { 10.0 } else if flies(e.kind) { 9.0 } else { 7.0 };
let radius = if matches!(e.job, Job::Rally | Job::March(_)) { 8.5 } else if matches!(e.job, Job::Guard(_)) { 10.0 } else if flies(e.kind) { 9.0 } else { 7.0 };
if let Some(id) = self.nearest_enemy(e, radius) {
self.unreserve(me);
e.job = Job::Attack(id);
@@ -3893,6 +3910,15 @@ impl Game {
self.rally(e, dt);
return;
}
if let Job::March(f) = e.job {
if self.attack_marks.contains(&f) {
self.rally_to(e, f, dt);
} else {
e.job = Job::None;
e.path.clear();
}
return;
}
if self.step_path(e, dt) {
return;
}
@@ -4082,6 +4108,11 @@ impl Game {
e.path.clear();
return;
};
self.rally_to(e, f, dt);
}
// march to tile f and fight there (the attack flag, or an attack marker)
pub(crate) fn rally_to(&mut self, e: &mut Ent, f: usize, dt: f32) {
if e.hp < e.max_hp * 0.3 || e.energy < 0.1 || e.hunger > 2.2 {
// exhausted or badly hurt: retreat
e.job = Job::None;
@@ -5781,6 +5812,7 @@ pub fn job_name(e: &Ent) -> &'static str {
Job::Repair(_) => "job.repair",
Job::MendBridge(_) => "job.mend_bridge",
Job::RaiseWall(_) => "job.raise_wall",
Job::March(_) => "job.march",
Job::Carry(_) => "job.carry",
Job::Pray(_) => "job.pray",
Job::HealCore => "job.heal_core",