Creatures make their beds only in their own master's lair

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-06 09:50:31 +01:00
1 parent 568476ed1f
commit e1a8e2c49c
1 file changed
+36 -5
+36 -5
View File
@@ -2130,7 +2130,7 @@ impl Game {
if e.timer <= 0.0 {
let cur = e.tile();
let bed_kind = if flies(e.kind) { Kind::Aerie } else { Kind::Lair };
let free = |i: usize| self.map.t[i].kind == bed_kind && self.map.t[i].bed == 0;
let free = |i: usize| self.map.t[i].kind == bed_kind && self.map.t[i].bed == 0 && self.map.t[i].owner == self.me;
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) };
match found {
Some(p) => {
@@ -3405,7 +3405,7 @@ impl Game {
let me = self.me;
let target = e
.bed
.filter(|&b| self.map.t[b].kind == bed_kind)
.filter(|&b| self.map.t[b].kind == bed_kind && self.map.t[b].owner == me)
.or_else(|| self.map.search(cur, self.map.creature_cost(fly), |i| self.map.t[i].kind == bed_kind && self.map.t[i].owner == me, true).map(|p| p.last().copied().unwrap_or(cur)))
.or_else(|| self.map.search(cur, self.map.creature_cost(fly), |i| self.map.adj_core_of(i, me), true).map(|p| p.last().copied().unwrap_or(cur)));
let Some(b) = target else { return false };
@@ -3824,7 +3824,7 @@ impl Game {
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 | 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 free = |i: usize| self.map.t[i].kind == bed_kind && self.map.t[i].bed == 0 && self.map.t[i].owner == self.me;
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) };
if let Some(p) = found {
let b = p.last().copied().unwrap_or(cur);
@@ -4272,14 +4272,18 @@ impl Game {
let bed_kind = if flies(e.kind) { Kind::Aerie } else { Kind::Lair };
if let Some(b) = e.bed {
let t = &self.map.t[b];
if t.kind != bed_kind || t.bed != me {
// a bed in somebody else's lair (an ally's, or ground that changed hands) is given up
if t.kind != bed_kind || t.bed != me || t.owner != self.me {
if t.bed == me {
self.map.t[b].bed = 0;
}
e.bed = None;
}
}
if e.bed.is_none() {
let free = |i: usize| {
let t = &self.map.t[i];
t.kind == bed_kind && t.bed == 0
t.kind == bed_kind && t.bed == 0 && t.owner == self.me
};
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) };
if let Some(p) = found {
@@ -6857,6 +6861,33 @@ mod tests {
assert!(g.ents.iter().filter(|e| e.kind == EK::Chainbreaker).count() <= 1);
}
#[test]
fn creatures_never_make_their_bed_in_an_allys_lair() {
let mut g = Game::new(11, 96, 128);
g.coop = true;
assert!(g.start_masters(&[0, 2], 0));
let (cx, cy) = g.map.core;
for y in cy + 4..cy + 7 {
for x in cx - 1..cx + 4 {
let t = &mut g.map.t[idx(x, y)];
t.kind = Kind::Lair;
t.owner = Owner::Player;
}
}
g.recount();
let id = g.spawn(EK::Kobold, false, cx as f32 + 1.5, cy as f32 + 5.5, 1);
if let Some(e) = g.ents.iter_mut().find(|e| e.id == id) {
e.side = 2;
e.energy = 0.1;
}
for _ in 0..(40 * 20) {
g.update(0.05);
}
let e = g.ents.iter().find(|e| e.id == id).expect("still there");
assert!(e.bed.map_or(true, |b| g.map.t[b].owner != Owner::Player), "no bed in the ally's lair");
assert!(!g.map.t.iter().any(|t| t.kind == Kind::Lair && t.bed == id + 1));
}
#[test]
fn every_master_of_a_coop_mission_has_an_own_portal() {
let m = crate::campaign::coop_mission_indexes()[2];