Monster eye marks the camera on the minimap; middle double click resets the view angle; creatures by beds up to 100

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-06 10:06:51 +01:00
1 parent 0b2d327791
commit ac22351cdf
22 files changed
+147 -5

No files matched your search

+51 -1
View File
@@ -94,6 +94,7 @@ pub struct SfxEvent {
pub pos: Option<(f32, f32)>, // world position (for distance-based volume), None = UI
}
pub const MANA_MAX: f32 = 400.0;
pub const MAX_CREATURES: usize = 100; // creatures of one master (the beds decide below that)
pub const SPRING_MANA: f32 = 0.6; // mana per second of each claimed mana spring
pub const SPRING_MAX: f32 = 150.0; // more mana maximum per claimed spring
pub const CARRY_MAX: i32 = 300;
@@ -1925,7 +1926,14 @@ impl Game {
pub fn free_lair_aerie(&self) -> (usize, usize) {
let flyers = self.ents.iter().filter(|e| e.alive && e.creature() && flies(e.kind)).count();
let walkers = self.creature_count() - flyers;
(self.counts[1].min(30).saturating_sub(walkers), self.counts[7].min(20).saturating_sub(flyers))
// a bed per lair tile (aerie: per aerie tile), never more than MAX_CREATURES in all
let room = MAX_CREATURES.saturating_sub(walkers + flyers);
(self.counts[1].saturating_sub(walkers).min(room), self.counts[7].saturating_sub(flyers).min(room))
}
// how many creatures this master can house: his beds, at most MAX_CREATURES
pub fn creature_cap(&self) -> usize {
(self.counts[1] + self.counts[7]).min(MAX_CREATURES)
}
pub fn lair_factor(&self) -> f32 {
@@ -1955,6 +1963,10 @@ impl Game {
self.hint(1, "hint.no_farm");
return;
}
if self.creature_count() >= MAX_CREATURES {
self.hint(35, "hint.creature_max");
return;
}
let (free_lair, free_aerie) = self.free_lair_aerie();
if free_lair == 0 && free_aerie == 0 {
self.hint(2, "hint.lair_full");
@@ -6861,6 +6873,44 @@ mod tests {
assert!(g.ents.iter().filter(|e| e.kind == EK::Chainbreaker).count() <= 1);
}
#[test]
fn the_beds_decide_how_many_creatures_come_but_never_more_than_100() {
let mut g = Game::new(9, 96, 96);
let (cx, cy) = g.map.core;
// a lair of 40 beds: room for 40
let mut n = 0;
for y in cy + 4..cy + 20 {
for x in cx - 6..cx + 8 {
if n < 40 && inb(x, y) {
let t = &mut g.map.t[idx(x, y)];
t.kind = Kind::Lair;
t.owner = Owner::Player;
n += 1;
}
}
}
g.recount();
assert_eq!(g.creature_cap(), 40);
assert_eq!(g.free_lair_aerie().0, 40, "more than the old 30");
// a huge lair: the cap is 100
for y in cy + 4..cy + 20 {
for x in cx - 10..cx + 12 {
if inb(x, y) && g.map.t[idx(x, y)].kind != Kind::Core {
let t = &mut g.map.t[idx(x, y)];
t.kind = Kind::Lair;
t.owner = Owner::Player;
}
}
}
g.recount();
assert!(g.counts[1] > 100);
assert_eq!(g.creature_cap(), MAX_CREATURES);
for k in 0..100 {
g.spawn(EK::Kobold, false, cx as f32 + 0.5 + (k % 10) as f32, cy as f32 + 5.5 + (k / 10) as f32, 1);
}
assert_eq!(g.free_lair_aerie(), (0, 0), "no room for a 101st");
}
#[test]
fn creatures_never_make_their_bed_in_an_allys_lair() {
let mut g = Game::new(11, 96, 128);