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:
1 parent
568476ed1f
commit
e1a8e2c49c
1 file changed
+36
-5
+36
-5
@@ -2130,7 +2130,7 @@ impl Game {
|
|||||||
if e.timer <= 0.0 {
|
if e.timer <= 0.0 {
|
||||||
let cur = e.tile();
|
let cur = e.tile();
|
||||||
let bed_kind = if flies(e.kind) { Kind::Aerie } else { Kind::Lair };
|
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) };
|
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 {
|
match found {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
@@ -3405,7 +3405,7 @@ impl Game {
|
|||||||
let me = self.me;
|
let me = self.me;
|
||||||
let target = e
|
let target = e
|
||||||
.bed
|
.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.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)));
|
.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 };
|
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] };
|
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 {
|
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 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) };
|
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 {
|
if let Some(p) = found {
|
||||||
let b = p.last().copied().unwrap_or(cur);
|
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 };
|
let bed_kind = if flies(e.kind) { Kind::Aerie } else { Kind::Lair };
|
||||||
if let Some(b) = e.bed {
|
if let Some(b) = e.bed {
|
||||||
let t = &self.map.t[b];
|
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;
|
e.bed = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if e.bed.is_none() {
|
if e.bed.is_none() {
|
||||||
let free = |i: usize| {
|
let free = |i: usize| {
|
||||||
let t = &self.map.t[i];
|
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) };
|
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 {
|
if let Some(p) = found {
|
||||||
@@ -6857,6 +6861,33 @@ mod tests {
|
|||||||
assert!(g.ents.iter().filter(|e| e.kind == EK::Chainbreaker).count() <= 1);
|
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]
|
#[test]
|
||||||
fn every_master_of_a_coop_mission_has_an_own_portal() {
|
fn every_master_of_a_coop_mission_has_an_own_portal() {
|
||||||
let m = crate::campaign::coop_mission_indexes()[2];
|
let m = crate::campaign::coop_mission_indexes()[2];
|
||||||
|
|||||||
Reference in new issue
Block a user