Silver, ruby and diamond veins; treasury shows its treasures; announced payday

- New veins (appended kinds): silver (common), ruby (rare), diamond (very rare, far from the core);
  treasure caves contain gems; each treasure is worth a different amount per strike and per vein
- Imps carry one kind of treasure at a time
- Treasury tiles hold up to 500 each and show gold coins, silver bars, rubies or diamonds;
  spending empties random treasury tiles, the soul core keeps what does not fit
- Training no longer drains gold continuously: it is billed on the next payday
- Payday is announced 20 s before (message with the cost); the HUD shows a payday countdown and
  the cost of the next payday in red next to the gold counter
- Tests for the treasury and the payday bill

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 10:43:33 +01:00
1 parent 75dc445d3b
commit 7e84cae910
7 files changed
+362 -31

No files matched your search

+15 -11
View File
@@ -14,7 +14,7 @@ pub const WALL_H: f32 = 0.95;
const CHUNK: i32 = 16;
pub const MAX_LIGHTS: usize = 24;
const ATLAS_W: f32 = 256.0;
const ATLAS_H: f32 = 128.0;
const ATLAS_H: f32 = 144.0;
const DISP_AMP: f32 = 0.11; // wall surface irregularity
// ------------------------------------------------------------------ camera
@@ -480,7 +480,7 @@ fn block_shell(mk: &mut MB, map: &Map, x: i32, z: i32, n: usize, fill: [u8; 4],
}
}
fn build_chunk(map: &Map, amb: &[f32], cx: i32, cz: i32, gold_fill: f32, atlas: &Texture2D, wall_sub: usize) -> [Option<Mesh>; 4] {
fn build_chunk(map: &Map, amb: &[f32], cx: i32, cz: i32, atlas: &Texture2D, wall_sub: usize) -> [Option<Mesh>; 4] {
let mut mb = MB::new();
let ov = MB::new(); // textured overlays (currently unused)
let mut ln = MB::new();
@@ -609,9 +609,12 @@ fn build_chunk(map: &Map, amb: &[f32], cx: i32, cz: i32, gold_fill: f32, atlas:
Kind::Library if z % 2 == 0 => mb.cross(xf + 0.5, zf + 0.5, 0.9, 0.85, D_SHELF, dc),
Kind::Torture if (x + z) % 2 == 1 => mb.cross(xf + 0.5, zf + 0.5, 0.8, 0.8, D_RACK, dc),
Kind::Temple if x % 3 == 1 && z % 3 == 1 => mb.cross(xf + 0.5, zf + 0.5, 0.8, 0.8, D_ALTAR, dc),
Kind::Treasury if gold_fill > 0.02 => {
let s = 0.35 + 0.55 * gold_fill;
mb.cross(xf + 0.5, zf + 0.5, s, s * 0.8, D_COINS, dc);
// each treasury tile shows what it holds (up to TREASURY_TILE)
Kind::Treasury if t.gold > 10 => {
let fill = (t.gold as f32 / TREASURY_TILE).clamp(0.0, 1.0);
let s = 0.35 + 0.55 * fill;
let sprite = [D_COINS, D_SILVER, D_RUBY, D_DIAMOND][(t.res & 3) as usize];
mb.cross(xf + 0.5, zf + 0.5, s, s * 0.8, sprite, dc);
}
_ => {}
}
@@ -763,7 +766,7 @@ fn rgba(u: u32) -> Color {
Color::from_rgba(u as u8, (u >> 8) as u8, (u >> 16) as u8, (u >> 24) as u8)
}
fn chunk_sig(map: &Map, cx: i32, cz: i32, fill_bucket: u8) -> u64 {
fn chunk_sig(map: &Map, cx: i32, cz: i32) -> u64 {
let mut h: u64 = 1469598103934665603;
for z in cz * CHUNK - 3..(cz + 1) * CHUNK + 3 {
for x in cx * CHUNK - 3..(cx + 1) * CHUNK + 3 {
@@ -771,7 +774,7 @@ fn chunk_sig(map: &Map, cx: i32, cz: i32, fill_bucket: u8) -> u64 {
Some(t) => {
let extra = match t.kind {
Kind::Farm => t.food as u64,
Kind::Treasury => fill_bucket as u64,
Kind::Treasury => (t.gold / 50) as u64 | (t.res as u64) << 5,
_ => 0,
};
(t.kind as u64) | (t.owner as u64) << 5 | (t.marked as u64) << 7 | (t.reinforced as u64) << 8 | extra << 9
@@ -817,19 +820,17 @@ impl R3d {
// Rebuilds visible chunks whose content changed (off-screen chunks are updated when they appear)
fn update_chunks(&mut self, g: &Game, gfx: &Gfx, m: &Mat4) {
self.ensure_chunks();
let fill = (g.gold / g.gold_cap()).clamp(0.0, 1.0);
let bucket = (fill * 6.0) as u8;
let mut amb: Option<Vec<f32>> = None;
for cz in 0..self.ncz {
for cx in 0..self.ncx {
if !Self::chunk_visible(m, cx, cz) {
continue;
}
let sig = chunk_sig(&g.map, cx, cz, bucket);
let sig = chunk_sig(&g.map, cx, cz);
let ch = &mut self.chunks[(cz * self.ncx + cx) as usize];
if ch.sig != sig {
let a = amb.get_or_insert_with(|| ambient_field(&g.map));
let [m, o, l, k] = build_chunk(&g.map, a, cx, cz, bucket as f32 / 6.0, &gfx.atlas, self.wall_sub);
let [m, o, l, k] = build_chunk(&g.map, a, cx, cz, &gfx.atlas, self.wall_sub);
ch.mesh = m;
ch.overlay = o;
ch.lines = l;
@@ -1525,6 +1526,9 @@ pub fn minimap_color(tile: &Tile) -> [u8; 4] {
Kind::Earth if tile.reinforced => [120, 70, 70, 255],
Kind::Earth => [86, 60, 40, 255],
Kind::Gold => [220, 180, 50, 255],
Kind::Silver => [190, 195, 210, 255],
Kind::Ruby => [220, 40, 70, 255],
Kind::Diamond => [170, 235, 255, 255],
Kind::Floor => match tile.owner {
Owner::Player => [140, 60, 80, 255],
Owner::Hero => [170, 175, 190, 255],