Claimed floors back to fitted flagstones in the masters' colours with damage; high-res floor decals

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-07 22:11:41 +01:00
1 parent 362f4e7670
commit ca8494aea0
51 files changed
+154 -39

No files matched your search

+36 -10
View File
@@ -347,19 +347,27 @@ const HD_TILES: [(u32, u32, &[u8], &[u8]); 2] = [
// Sets of five tiles that fit together in any order, so a floor or a wall shows no pattern:
// the ground kinds (all five tiles share one seamless border, their middles differ; see
// tools/make_tile.py --variants) and the masters' claimed floors (the same grey, worn-smooth
// castle flagstones for everybody, every tile with a polished inlay in its master's colour and
// an engraving of their own: the player a demon skull, Mossgrim a mushroom, Lady Nightwell a lily
// under the moon, Saffrax an alchemical sun; plain, cracked, chipped, broken, scratched). They go
// tools/make_tile.py --variants), the masters' claimed floors as well: fitted flagstones of
// different sizes, some cracked, chipped or broken, in the master's colour with faint carved
// symbols of their own (the player crimson with demonic runes, Mossgrim mossy green with
// mushrooms and mould, Lady Nightwell midnight blue with lilies and moons, Saffrax ochre with
// alchemical sigils). They go
// into cells of their own from T_HDSET on, five per set; a tile picks one by its position,
// weighted. (the kind's cells: first and count, the first own cell, 64x64 tiles side by side,
// 128x128 ones, weights)
pub const T_HDSET: u32 = 224;
// the floor decals (wear and tear laid over plain floors) in the high-res style: transparent
// pictures for their cells (cell, 64x64, 128x128)
const HD_DECALS: [(u32, &[u8], &[u8]); 2] = [
(D_RUBBLE, include_bytes!("../assets/textures/decal-rubble.png"), include_bytes!("../assets/textures/decal-rubble-128.png")),
(D_CRACK, include_bytes!("../assets/textures/decal-crack.png"), include_bytes!("../assets/textures/decal-crack-128.png")),
];
const HD_SETS: [(u32, u32, u32, &[u8], &[u8], [u32; 5]); 11] = [
(T_CLAIM, 4, T_HDSET, include_bytes!("../assets/textures/floor-player.png"), include_bytes!("../assets/textures/floor-player-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL1, 4, T_HDSET + 5, include_bytes!("../assets/textures/floor-mossgrim.png"), include_bytes!("../assets/textures/floor-mossgrim-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL2, 4, T_HDSET + 10, include_bytes!("../assets/textures/floor-nightwell.png"), include_bytes!("../assets/textures/floor-nightwell-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL3, 4, T_HDSET + 15, include_bytes!("../assets/textures/floor-saffrax.png"), include_bytes!("../assets/textures/floor-saffrax-128.png"), [4, 2, 2, 1, 3]),
(T_CLAIM, 4, T_HDSET, include_bytes!("../assets/textures/floor-player.png"), include_bytes!("../assets/textures/floor-player-128.png"), [1; 5]),
(T_RIVAL1, 4, T_HDSET + 5, include_bytes!("../assets/textures/floor-mossgrim.png"), include_bytes!("../assets/textures/floor-mossgrim-128.png"), [1; 5]),
(T_RIVAL2, 4, T_HDSET + 10, include_bytes!("../assets/textures/floor-nightwell.png"), include_bytes!("../assets/textures/floor-nightwell-128.png"), [1; 5]),
(T_RIVAL3, 4, T_HDSET + 15, include_bytes!("../assets/textures/floor-saffrax.png"), include_bytes!("../assets/textures/floor-saffrax-128.png"), [1; 5]),
(T_FLOOR, 4, T_HDSET + 20, include_bytes!("../assets/textures/floor-v64.png"), include_bytes!("../assets/textures/floor-v128.png"), [1; 5]),
(T_EARTH, 4, T_HDSET + 25, include_bytes!("../assets/textures/earth-v64.png"), include_bytes!("../assets/textures/earth-v128.png"), [1; 5]),
(T_ROCK, 4, T_HDSET + 30, include_bytes!("../assets/textures/rock-v64.png"), include_bytes!("../assets/textures/rock-v128.png"), [1; 5]),
@@ -425,6 +433,15 @@ fn gen_hd_atlas(tile: u32) -> Image {
}
}
}
for &(id, png, png2) in HD_DECALS.iter() {
let src = Image::from_file_with_format(if tile == HD_TILE2 { png2 } else { png }, Some(ImageFormat::Png)).expect("hd decal");
let (ox, oy) = ((id % ATLAS_COLS) * tile, (id / ATLAS_COLS) * tile);
for y in 0..tile {
for x in 0..tile {
img.set_pixel(ox + x, oy + y, src.get_pixel(x, y));
}
}
}
img
}
@@ -2783,7 +2800,16 @@ mod hd_atlas_tests {
}
}
}
// every slab of a floor shows up, the plain one most often
// the decals: transparent around their pictures
for &(id, _, _) in HD_DECALS.iter() {
for tile in [HD_TILE, HD_TILE2] {
let hd = gen_hd_atlas(tile);
let (ox, oy) = ((id % ATLAS_COLS) * tile, (id / ATLAS_COLS) * tile);
let clear = (0..tile * tile).filter(|i| hd.get_pixel(ox + i % tile, oy + i / tile).a < 0.5).count() as u32;
assert!(clear > tile * tile / 3 && clear < tile * tile, "decal {id} at {tile}: {clear} clear texels");
}
}
// every tile of a set shows up
let mut n = [0u32; 5];
for z in 0..60 {
for x in 0..60 {
@@ -2793,7 +2819,7 @@ mod hd_atlas_tests {
}
}
assert!(n.iter().all(|&k| k > 100), "{n:?}");
assert!(n[0] > n[3] * 2, "{n:?}");
assert!((T_HDSET + 15..T_HDSET + 20).contains(&hd_tile(T_RIVAL3 + 2, 3, 7)));
assert!((T_HDSET + 50..T_HDSET + 55).contains(&hd_tile(T_DIAMOND + 1, 8, 2)));
assert!((T_HDSET + 25..T_HDSET + 30).contains(&hd_tile(T_EARTH + 3, 5, 5)));