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:
1 parent
d92b45a0b8
commit
9a9f04ae1f
17 files changed
+658
-32
No files matched your search
+9
-2
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
// From which mission (0-based) on each tool is available (same order as ui::TOOLS):
|
||||
// dig, hand, treasury, lair, farm, training, library, sell, flag, lightning, heal, imp,
|
||||
// torture, temple, arrow tower, cannon tower, magic tower, bridge, aerie, steel
|
||||
pub const TOOL_UNLOCK: [usize; 20] = [0, 0, 0, 0, 0, 2, 5, 0, 0, 3, 5, 0, 8, 12, 3, 7, 12, 1, 8, 17];
|
||||
pub const TOOL_UNLOCK: [usize; 21] = [0, 0, 0, 0, 0, 2, 5, 0, 0, 3, 5, 0, 8, 12, 3, 7, 12, 1, 8, 17, 0];
|
||||
|
||||
pub struct FortDef {
|
||||
pub at: (f32, f32), // centre as a fraction of the map size
|
||||
@@ -79,6 +79,10 @@ fn cave(at: (f32, f32), chained: Option<(EK, u32)>, treasure: i32) -> CaveDef {
|
||||
pub struct Carry {
|
||||
pub creatures: Vec<(EK, u32, f32)>, // kind, level, experience
|
||||
pub gold: f32,
|
||||
#[serde(default)]
|
||||
pub rune_free: u32, // unbuilt rune forge towers from chests
|
||||
#[serde(default)]
|
||||
pub rune_final: u32, // unbuilt or sold rune forge towers that were already given back once
|
||||
}
|
||||
|
||||
pub const CARRY_CREATURES: usize = 5;
|
||||
@@ -499,6 +503,7 @@ pub fn start_mission(i: usize, carry: Option<&Carry>) -> Game {
|
||||
let y = ((ry * h as f32) as i32).clamp(10, h as i32 - 10);
|
||||
g.add_rival(side, x, y, diff);
|
||||
}
|
||||
g.place_dwarf_caves(d.seed);
|
||||
let heart = d.gate || d.forts.iter().any(|f| f.heart);
|
||||
if !heart {
|
||||
g.gate_hp = 0.0;
|
||||
@@ -524,6 +529,8 @@ pub fn start_mission(i: usize, carry: Option<&Carry>) -> Game {
|
||||
if let Some(c) = carry {
|
||||
joiners.extend(c.creatures.iter().copied());
|
||||
g.gold += c.gold;
|
||||
g.rune_free += c.rune_free;
|
||||
g.rune_final += c.rune_final;
|
||||
}
|
||||
for (k, &(kind, level, xp)) in joiners.iter().enumerate() {
|
||||
let a = k as f32 * 0.9;
|
||||
@@ -543,7 +550,7 @@ pub fn carry_from(g: &Game) -> Carry {
|
||||
let mut c: Vec<&Ent> = g.ents.iter().filter(|e| e.alive && e.creature()).collect();
|
||||
let power = |e: &Ent| e.max_hp * e.atk() / st(e.kind).interval;
|
||||
c.sort_by(|a, b| power(b).partial_cmp(&power(a)).unwrap_or(std::cmp::Ordering::Equal));
|
||||
Carry { creatures: c.iter().take(CARRY_CREATURES).map(|e| (e.kind, e.level, e.xp)).collect(), gold: (g.gold * CARRY_GOLD).floor() }
|
||||
Carry { creatures: c.iter().take(CARRY_CREATURES).map(|e| (e.kind, e.level, e.xp)).collect(), gold: (g.gold * CARRY_GOLD).floor(), rune_free: g.rune_free, rune_final: g.rune_final + g.rune_next }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in new issue
Block a user