Defence towers: arrow (piercing), cannon (splash + knockback), magic (mana, slow, chain); 3 levels, repair by imps, heroes attack towers; torture/temple room tools prepared

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 07:47:50 +01:00
1 parent a1fe02ffa6
commit 903d6fb0f4
10 files changed
+708 -19

No files matched your search

+33 -3
View File
@@ -55,9 +55,11 @@ pub enum Tool {
Lightning,
Heal,
Summon,
Tower(TowerKind),
}
pub const TOOLS: [Tool; 12] = [
// New tools are appended so that existing key bindings ("tool<i>") keep their meaning
pub const TOOLS: [Tool; 17] = [
Tool::Dig,
Tool::Hand,
Tool::Room(0),
@@ -70,6 +72,11 @@ pub const TOOLS: [Tool; 12] = [
Tool::Lightning,
Tool::Heal,
Tool::Summon,
Tool::Room(5),
Tool::Room(6),
Tool::Tower(TowerKind::Arrow),
Tool::Tower(TowerKind::Cannon),
Tool::Tower(TowerKind::Magic),
];
@@ -88,7 +95,12 @@ pub fn tool_info(t: Tool) -> ToolInfo {
Tool::Room(1) => ("lair", T_LAIR, Some(1)),
Tool::Room(2) => ("farm", T_FARM, Some(2)),
Tool::Room(3) => ("training", T_TRAINING, Some(3)),
Tool::Room(_) => ("library", T_LIBRARY, Some(4)),
Tool::Room(4) => ("library", T_LIBRARY, Some(4)),
Tool::Room(5) => ("torture", T_TORTURE, Some(5)),
Tool::Room(_) => ("temple", T_TEMPLE, Some(6)),
Tool::Tower(TowerKind::Arrow) => ("arrow", I_ARROW, None),
Tool::Tower(TowerKind::Cannon) => ("cannon", I_CANNON, None),
Tool::Tower(TowerKind::Magic) => ("magic", I_MAGIC, None),
Tool::Sell => ("sell", I_SELL, None),
Tool::Flag => ("flag", I_FLAG, None),
Tool::Lightning => ("lightning", I_BOLT, None),
@@ -108,6 +120,14 @@ pub fn tool_cost(t: Tool, g: &Game) -> String {
Tool::Lightning => trf("cost.mana", &["50".into()]),
Tool::Heal => trf("cost.mana", &["60".into()]),
Tool::Summon => trf("cost.mana", &[(g.summon_cost() as i32).to_string()]),
Tool::Tower(k) => {
let s = tower_stats(k);
let mut c = trf("cost.tower", &[s.cost[0].to_string(), s.cost[1].to_string(), s.cost[2].to_string()]);
if s.mana > 0.0 {
c += &trf("cost.per_shot", &[(s.mana as i32).to_string()]);
}
c
}
_ => String::new(),
}
}
@@ -291,7 +311,7 @@ impl Ui {
gfx.window(0.0, tb_y, cols, tb_rows, S(), false, FRAME, BG);
self.rects.push(Rect::new(0.0, tb_y, sw, tb_rows as f32 * CH()));
self.tool_rects.clear();
let bw = 80.0 * K();
let bw = (80.0 * K()).min(((sw - CW() * 2.0 - 150.0) / TOOLS.len() as f32 - 4.0 * K()).max(48.0));
let mut hover_tool = None;
for (i, &t) in TOOLS.iter().enumerate() {
let bx = CW() + i as f32 * (bw + 4.0 * K());
@@ -638,6 +658,16 @@ pub fn hover_info(g: &Game, ent: Option<usize>, tile: Option<(i32, i32)>) -> Vec
out.push((tr("tile.portal"), MANA));
out.push((tr(if t.owner == Owner::Player { "portal.claimed" } else { "portal.neutral" }), DIM));
}
Kind::Tower => {
if let Some(tw) = g.tower_at(idx(x, y)) {
out.push((trf("info.tower", &[tr(tower_name(tw.kind)), tw.level.to_string()]), FRAME_HI));
out.push((trf("info.hp", &[(tw.hp as i32).to_string(), (tw.max_hp() as i32).to_string()]), GREEN));
out.push((trf("info.tower_stats", &[format!("{:.0}", tw.dmg()), format!("{:.1}", tw.range())]), TXT));
if tw.level < 3 {
out.push((trf("info.tower_upgrade", &[tower_stats(tw.kind).cost[tw.level as usize].to_string()]), GOLD));
}
}
}
Kind::Gate => {
out.push((tr("tile.gate"), BLUE));
out.push((trf("info.hp", &[(g.gate_hp as i32).to_string(), (GATE_HP as i32).to_string()]), BLUE));