Dwarf caves in all modes: neutral dwarves guard a hoard and sometimes a rune chest; the rune forge tower; imps repair towers before claiming

- 1-4 cave slots by map size, 50% each (at least one); knight treasure caves only where a mission places them
- dwarves fight intruders near the cave, never chase far, heal at home, grow with distance and the player's army, never count for victory
- rune chest: one free rune forge tower (chain bolt to three more enemies), upgradeable for gold, sold once it comes back (next mission / free play at once), unbuilt ones carry over
- new tool (key N) shown in the tower menu while a rune tower can be built or upgraded

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 15:14:36 +01:00
1 parent d92b45a0b8
commit 9a9f04ae1f
17 files changed
+658 -32

No files matched your search

+6 -3
View File
@@ -60,13 +60,14 @@ pub enum Kind {
Aerie, // room for flying creatures (their beds)
Steel, // steel wall: hardly anyone gets through
ManaSpring, // crystal spring: once claimed, more mana and a higher mana maximum
RuneChest, // dwarven chest with the plans of a rune forge tower (claim it: one free build)
}
// options for the map generator (campaign missions)
#[derive(Clone, Debug)]
pub struct GenOpts {
pub portals: Option<usize>, // None: one per 64 x 64 tiles
pub treasures: Option<usize>, // guarded treasure caves; None: portals - 1
pub treasures: Option<usize>, // knight treasure caves; None: none (free play has dwarf caves instead)
pub gate: bool, // hero gate at the far side
pub core_y: Option<i32>, // row of the core (None: about the middle)
}
@@ -88,7 +89,7 @@ pub struct River {
}
// order matters for the packed savegame codec: only append new kinds
const KINDS: [Kind; 26] = [
const KINDS: [Kind; 27] = [
Kind::Rock,
Kind::Earth,
Kind::Gold,
@@ -115,6 +116,7 @@ const KINDS: [Kind; 26] = [
Kind::Aerie,
Kind::Steel,
Kind::ManaSpring,
Kind::RuneChest,
];
// treasures (veins, treasury content, imp loads): 0 gold, 1 silver, 2 ruby, 3 diamond
@@ -210,6 +212,7 @@ impl Tile {
| Kind::Shard
| Kind::Aerie
| Kind::ManaSpring
| Kind::RuneChest
)
}
// river tiles (open, but nobody can walk there)
@@ -349,7 +352,7 @@ impl Map {
let area = (w * h) as f32 / 4096.0;
let scale = |n: f32| (n * area).round() as i32;
let n_portals = opts.portals.unwrap_or((area.round() as usize).max(1));
let n_treasures = opts.treasures.unwrap_or(n_portals.saturating_sub(1));
let n_treasures = opts.treasures.unwrap_or(0);
let mut t = vec![Tile::new(Kind::Earth); w * h];
for (i, tile) in t.iter_mut().enumerate() {