Buildings textured by material (stone, iron, wood, cloth); the heart in crystal facets
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d951c16902
commit
d87f862199
10 files changed
+119
-64
No files matched your search
@@ -58,6 +58,15 @@ The spine of one old leather-bound book standing upright, filling the whole imag
|
|||||||
An open page of an old spellbook filling the whole image: yellowed parchment with many lines of dark handwritten script, a small drawn magic circle and a red initial letter, in light neutral tones.
|
An open page of an old spellbook filling the whole image: yellowed parchment with many lines of dark handwritten script, a small drawn magic circle and a red initial letter, in light neutral tones.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## crystal
|
||||||
|
|
||||||
|
```text
|
||||||
|
A cut gemstone surface seen close: many sharp triangular and kite-shaped facets with bright edges and darker faces, a few internal glints, in light neutral grey tones.
|
||||||
|
```
|
||||||
|
|
||||||
|
The soul core's heart (its lobes) and the buildings use the materials too: `props::auto_cube`
|
||||||
|
picks one for every box of the buildings by its colour and shape.
|
||||||
|
|
||||||
## Processing
|
## Processing
|
||||||
|
|
||||||
`tools/make_material.py` crops (stone and the book lay on white), turns the picture into grey
|
`tools/make_material.py` crops (stone and the book lay on white), turns the picture into grey
|
||||||
@@ -74,6 +83,7 @@ python3 $T straw-raw.png straw --crop 0.05,0.05,0.95,0.95
|
|||||||
python3 $T fur-raw.png fur
|
python3 $T fur-raw.png fur
|
||||||
python3 $T book-raw.png book --trim --mean 0.75
|
python3 $T book-raw.png book --trim --mean 0.75
|
||||||
python3 $T paper-raw.png paper --color --crop 0.04,0.04,0.96,0.96 --mean 0.8
|
python3 $T paper-raw.png paper --color --crop 0.04,0.04,0.96,0.96 --mean 0.8
|
||||||
|
python3 $T crystal-raw.png crystal --crop 0.1,0.1,0.9,0.9 --mean 0.75
|
||||||
```
|
```
|
||||||
|
|
||||||
Copied to `assets/textures/mat/`.
|
Copied to `assets/textures/mat/`.
|
||||||
@@ -11,6 +11,7 @@ MATS = {
|
|||||||
"fur": "Thick shaggy animal fur with tufts and strands, in light neutral beige-grey tones.",
|
"fur": "Thick shaggy animal fur with tufts and strands, in light neutral beige-grey tones.",
|
||||||
"book": "The spine of one old leather-bound book standing upright, filling the whole image: two raised bands near the top and the bottom, "
|
"book": "The spine of one old leather-bound book standing upright, filling the whole image: two raised bands near the top and the bottom, "
|
||||||
"a gilded frame and a short line of golden title letters in the middle, worn leather, in light neutral tones.",
|
"a gilded frame and a short line of golden title letters in the middle, worn leather, in light neutral tones.",
|
||||||
|
"crystal": "A cut gemstone surface seen close: many sharp triangular and kite-shaped facets with bright edges and darker faces, a few internal glints, in light neutral grey tones.",
|
||||||
"paper": "An open page of an old spellbook filling the whole image: yellowed parchment with many lines of dark handwritten script, "
|
"paper": "An open page of an old spellbook filling the whole image: yellowed parchment with many lines of dark handwritten script, "
|
||||||
"a small drawn magic circle and a red initial letter, in light neutral tones.",
|
"a small drawn magic circle and a red initial letter, in light neutral tones.",
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 451 B |
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 451 B |
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
+4
-3
@@ -106,8 +106,8 @@ pub struct Gfx {
|
|||||||
pub gear: Texture2D, // their gear parts (see GEAR_HELMET etc.)
|
pub gear: Texture2D, // their gear parts (see GEAR_HELMET etc.)
|
||||||
pub atlas_hd: Texture2D, // the tile atlas of the high-res style, 64x64 tiles (see HD_TILES)
|
pub atlas_hd: Texture2D, // the tile atlas of the high-res style, 64x64 tiles (see HD_TILES)
|
||||||
pub atlas_hd2: Texture2D, // the same with 128x128 tiles (close up)
|
pub atlas_hd2: Texture2D, // the same with 128x128 tiles (close up)
|
||||||
pub materials: [Texture2D; 8], // furniture materials, high-res (see crate::props::Mat)
|
pub materials: [Texture2D; 9], // furniture materials, high-res (see crate::props::Mat)
|
||||||
pub materials_px: [Texture2D; 8], // the same for the pixel-art style (16x16)
|
pub materials_px: [Texture2D; 9], // the same for the pixel-art style (16x16)
|
||||||
pub cursors: Texture2D, // mouse pointer frames, 16x16 each (see CURSOR_*)
|
pub cursors: Texture2D, // mouse pointer frames, 16x16 each (see CURSOR_*)
|
||||||
pub badges: Texture2D, // achievement badges, 32x32 each (see badges.rs)
|
pub badges: Texture2D, // achievement badges, 32x32 each (see badges.rs)
|
||||||
pub font: Texture2D, // Dinowyde (glyphs of 6x8 px ordered by Unicode, see font_slot) and DINOBYTE
|
pub font: Texture2D, // Dinowyde (glyphs of 6x8 px ordered by Unicode, see font_slot) and DINOBYTE
|
||||||
@@ -354,7 +354,7 @@ macro_rules! material {
|
|||||||
(include_bytes!(concat!("../assets/textures/mat/", $name, "-64.png")) as &[u8], include_bytes!(concat!("../assets/textures/mat/", $name, "-16.png")) as &[u8])
|
(include_bytes!(concat!("../assets/textures/mat/", $name, "-64.png")) as &[u8], include_bytes!(concat!("../assets/textures/mat/", $name, "-16.png")) as &[u8])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const MATERIALS: [(&[u8], &[u8]); 8] = [
|
const MATERIALS: [(&[u8], &[u8]); 9] = [
|
||||||
material!("wood"),
|
material!("wood"),
|
||||||
material!("stone"),
|
material!("stone"),
|
||||||
material!("iron"),
|
material!("iron"),
|
||||||
@@ -363,6 +363,7 @@ const MATERIALS: [(&[u8], &[u8]); 8] = [
|
|||||||
material!("fur"),
|
material!("fur"),
|
||||||
material!("book"),
|
material!("book"),
|
||||||
material!("paper"),
|
material!("paper"),
|
||||||
|
material!("crystal"),
|
||||||
];
|
];
|
||||||
|
|
||||||
// ---- high-res tiles
|
// ---- high-res tiles
|
||||||
|
|||||||
+42
-2
@@ -49,17 +49,57 @@ pub enum Mat {
|
|||||||
Fur,
|
Fur,
|
||||||
Book,
|
Book,
|
||||||
Paper,
|
Paper,
|
||||||
|
Crystal,
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
// the material textures of the current graphics style (set every frame, see set_materials)
|
// the material textures of the current graphics style (set every frame, see set_materials)
|
||||||
static MATS: std::cell::RefCell<Option<[Texture2D; 8]>> = std::cell::RefCell::new(None);
|
static MATS: std::cell::RefCell<Option<[Texture2D; 9]>> = std::cell::RefCell::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_materials(m: &[Texture2D; 8]) {
|
pub fn set_materials(m: &[Texture2D; 9]) {
|
||||||
MATS.with(|t| *t.borrow_mut() = Some(m.clone()));
|
MATS.with(|t| *t.borrow_mut() = Some(m.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the texture of a material in the current style
|
||||||
|
pub fn material(m: Mat) -> Option<Texture2D> {
|
||||||
|
MATS.with(|t| t.borrow().as_ref().map(|a| a[m as usize].clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// the material of a box of the buildings (render3d: towers, the soul core's throne, gates,
|
||||||
|
// portals, traps) by its colour and shape: dark and grey blocks are stone (thin ones iron),
|
||||||
|
// brown is wood, gold and brass are metal, strong colours are cloth; translucent and bright
|
||||||
|
// glowing parts stay plain
|
||||||
|
fn auto_mat(s: Vec3, c: Color) -> Option<Mat> {
|
||||||
|
if c.a < 0.99 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let (mx, mn) = (c.r.max(c.g).max(c.b), c.r.min(c.g).min(c.b));
|
||||||
|
let sat = if mx > 0.0 { (mx - mn) / mx } else { 0.0 };
|
||||||
|
let thin = s.x.min(s.y).min(s.z) < 0.07;
|
||||||
|
if mx > 0.85 && sat > 0.45 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if mx < 0.22 || sat < 0.2 {
|
||||||
|
return Some(if thin { Mat::Iron } else { Mat::Stone });
|
||||||
|
}
|
||||||
|
if c.r > 0.6 && c.g > 0.45 && c.b < c.g * 0.6 {
|
||||||
|
return Some(Mat::Iron);
|
||||||
|
}
|
||||||
|
if c.r >= c.g && c.g >= c.b && mx < 0.8 {
|
||||||
|
return Some(Mat::Wood);
|
||||||
|
}
|
||||||
|
Some(Mat::Cloth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// a box of a building, textured by its material (see auto_mat)
|
||||||
|
pub fn auto_cube(p: Vec3, s: Vec3, c: Color) {
|
||||||
|
match auto_mat(s, c) {
|
||||||
|
Some(m) => mc(m, p, s, c),
|
||||||
|
None => draw_cube(p, s, None, c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// a box of a material; the detail is a little darker than white, the colour makes up for it
|
// a box of a material; the detail is a little darker than white, the colour makes up for it
|
||||||
fn mc(m: Mat, p: Vec3, s: Vec3, c: Color) {
|
fn mc(m: Mat, p: Vec3, s: Vec3, c: Color) {
|
||||||
let k = GROW.with(|g| g.get()).map_or(1.0, |g| g.1);
|
let k = GROW.with(|g| g.get()).map_or(1.0, |g| g.1);
|
||||||
|
|||||||
+62
-59
@@ -2167,7 +2167,7 @@ fn draw_dark_tower(tw: &Tower) {
|
|||||||
let iron = shade_c(58, 56, 64, f);
|
let iron = shade_c(58, 56, 64, f);
|
||||||
let bone = shade_c(214, 204, 178, f);
|
let bone = shade_c(214, 204, 178, f);
|
||||||
let blood = shade_c(128, 18, 26, f);
|
let blood = shade_c(128, 18, 26, f);
|
||||||
let bx = |p: Vec3, s: Vec3, cl: Color| draw_cube(c + p, s, None, cl);
|
let bx = |p: Vec3, s: Vec3, cl: Color| crate::props::auto_cube(c + p, s, cl);
|
||||||
let skull = |p: Vec3, dir: Vec3| {
|
let skull = |p: Vec3, dir: Vec3| {
|
||||||
bx(p, vec3(0.15, 0.14, 0.15), bone);
|
bx(p, vec3(0.15, 0.14, 0.15), bone);
|
||||||
let side = vec3(dir.z, 0.0, -dir.x);
|
let side = vec3(dir.z, 0.0, -dir.x);
|
||||||
@@ -2240,11 +2240,11 @@ fn draw_dark_tower(tw: &Tower) {
|
|||||||
let (ax, az) = (tw.aim.cos(), tw.aim.sin());
|
let (ax, az) = (tw.aim.cos(), tw.aim.sin());
|
||||||
let along = |d: f32, y: f32| c + vec3(ax * d, h + y, az * d);
|
let along = |d: f32, y: f32| c + vec3(ax * d, h + y, az * d);
|
||||||
// the demon head: a heavy block with horns, its open jaw is the muzzle
|
// the demon head: a heavy block with horns, its open jaw is the muzzle
|
||||||
draw_cube(along(0.0, 0.24), Vec3::splat(0.34), None, iron);
|
crate::props::auto_cube(along(0.0, 0.24), Vec3::splat(0.34), iron);
|
||||||
for k in 1..4 {
|
for k in 1..4 {
|
||||||
draw_cube(along(k as f32 * 0.14, 0.24), Vec3::splat(0.3 - k as f32 * 0.02), None, shade_c(44, 42, 50, f));
|
crate::props::auto_cube(along(k as f32 * 0.14, 0.24), Vec3::splat(0.3 - k as f32 * 0.02), shade_c(44, 42, 50, f));
|
||||||
}
|
}
|
||||||
draw_cube(along(0.56, 0.24), Vec3::splat(0.26), None, obs(20));
|
crate::props::auto_cube(along(0.56, 0.24), Vec3::splat(0.26), obs(20));
|
||||||
for sgn in [-1.0f32, 1.0] {
|
for sgn in [-1.0f32, 1.0] {
|
||||||
let side = vec3(-az * sgn, 0.0, ax * sgn);
|
let side = vec3(-az * sgn, 0.0, ax * sgn);
|
||||||
line3(along(0.05, 0.4) + side * 0.14, along(-0.1, 0.72) + side * 0.26, 0.07, bone);
|
line3(along(0.05, 0.4) + side * 0.14, along(-0.1, 0.72) + side * 0.26, 0.07, bone);
|
||||||
@@ -2309,7 +2309,7 @@ fn draw_towers_solid(g: &Game) {
|
|||||||
let f = 0.75 + tw.flash * 1.5; // brightens briefly when firing
|
let f = 0.75 + tw.flash * 1.5; // brightens briefly when firing
|
||||||
// knight towers: bright limestone with dark blue shadows, wood and fittings in royal blue
|
// knight towers: bright limestone with dark blue shadows, wood and fittings in royal blue
|
||||||
let col = |r: u8, g: u8, b: u8| if tw.hero { knight_c(r, g, b, f) } else { shade_c(r, g, b, f) };
|
let col = |r: u8, g: u8, b: u8| if tw.hero { knight_c(r, g, b, f) } else { shade_c(r, g, b, f) };
|
||||||
let bx = |p: Vec3, s: Vec3, cl: Color| draw_cube(c + p, s, None, cl);
|
let bx = |p: Vec3, s: Vec3, cl: Color| crate::props::auto_cube(c + p, s, cl);
|
||||||
match tw.kind {
|
match tw.kind {
|
||||||
TowerKind::Arrow => {
|
TowerKind::Arrow => {
|
||||||
// stone plinth, masonry body with courses and arrow slits
|
// stone plinth, masonry body with courses and arrow slits
|
||||||
@@ -2414,7 +2414,7 @@ fn draw_towers_solid(g: &Game) {
|
|||||||
}
|
}
|
||||||
// level pips on the plinth
|
// level pips on the plinth
|
||||||
for k in 0..tw.level {
|
for k in 0..tw.level {
|
||||||
draw_cube(vec3(x - 0.2 + k as f32 * 0.2, 0.25, z + 0.46), Vec3::splat(0.09), None, Color::from_rgba(240, 200, 70, 255));
|
crate::props::auto_cube(vec3(x - 0.2 + k as f32 * 0.2, 0.25, z + 0.46), Vec3::splat(0.09), Color::from_rgba(240, 200, 70, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2571,15 +2571,15 @@ fn ring(c: Vec3, r: f32, color: Color) {
|
|||||||
// the obsidian throne of a soul core (centre c on the floor)
|
// the obsidian throne of a soul core (centre c on the floor)
|
||||||
fn draw_throne(c: Vec3, t: f32) {
|
fn draw_throne(c: Vec3, t: f32) {
|
||||||
let obs = |k: u8| Color::from_rgba(28 + k, 14 + k / 2, 20 + k / 2, 255);
|
let obs = |k: u8| Color::from_rgba(28 + k, 14 + k / 2, 20 + k / 2, 255);
|
||||||
draw_cube(c + vec3(0.0, 0.08, 0.0), vec3(2.9, 0.16, 2.9), None, obs(6));
|
crate::props::auto_cube(c + vec3(0.0, 0.08, 0.0), vec3(2.9, 0.16, 2.9), obs(6));
|
||||||
draw_cube(c + vec3(0.0, 0.22, 0.0), vec3(2.3, 0.14, 2.3), None, obs(14));
|
crate::props::auto_cube(c + vec3(0.0, 0.22, 0.0), vec3(2.3, 0.14, 2.3), obs(14));
|
||||||
draw_cube(c + vec3(0.0, 0.36, 0.0), vec3(1.5, 0.14, 1.5), None, obs(24));
|
crate::props::auto_cube(c + vec3(0.0, 0.36, 0.0), vec3(1.5, 0.14, 1.5), obs(24));
|
||||||
draw_cube(c + vec3(0.0, 0.48, 0.0), vec3(0.8, 0.1, 0.8), None, obs(32));
|
crate::props::auto_cube(c + vec3(0.0, 0.48, 0.0), vec3(0.8, 0.1, 0.8), obs(32));
|
||||||
let heart = c + vec3(0.0, 1.55, 0.0);
|
let heart = c + vec3(0.0, 1.55, 0.0);
|
||||||
let iron = Color::from_rgba(70, 64, 72, 255);
|
let iron = Color::from_rgba(70, 64, 72, 255);
|
||||||
for (k, (dx, dz)) in [(-1.2f32, -1.2f32), (1.2, -1.2), (1.2, 1.2), (-1.2, 1.2)].iter().enumerate() {
|
for (k, (dx, dz)) in [(-1.2f32, -1.2f32), (1.2, -1.2), (1.2, 1.2), (-1.2, 1.2)].iter().enumerate() {
|
||||||
let b = c + vec3(*dx, 0.0, *dz);
|
let b = c + vec3(*dx, 0.0, *dz);
|
||||||
draw_cube(b + vec3(0.0, 0.3, 0.0), vec3(0.36, 0.6, 0.36), None, obs(4));
|
crate::props::auto_cube(b + vec3(0.0, 0.3, 0.0), vec3(0.36, 0.6, 0.36), obs(4));
|
||||||
// a curved spike leaning towards the heart
|
// a curved spike leaning towards the heart
|
||||||
let mut prev = b + vec3(0.0, 0.55, 0.0);
|
let mut prev = b + vec3(0.0, 0.55, 0.0);
|
||||||
for q in 1..=5 {
|
for q in 1..=5 {
|
||||||
@@ -2614,11 +2614,11 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
let h = (m.name % 7) as f32 * 0.02;
|
let h = (m.name % 7) as f32 * 0.02;
|
||||||
let c = vec3(x as f32 + 0.5 + ((m.name >> 3) % 5) as f32 * 0.04 - 0.08, 0.0, y as f32 + 0.5);
|
let c = vec3(x as f32 + 0.5 + ((m.name >> 3) % 5) as f32 * 0.04 - 0.08, 0.0, y as f32 + 0.5);
|
||||||
let stone = Color::from_rgba(118, 114, 124, 255);
|
let stone = Color::from_rgba(118, 114, 124, 255);
|
||||||
draw_cube(c + vec3(0.0, 0.04, 0.0), vec3(0.42, 0.08, 0.26), None, Color::from_rgba(70, 66, 74, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.04, 0.0), vec3(0.42, 0.08, 0.26), Color::from_rgba(70, 66, 74, 255));
|
||||||
draw_cube(c + vec3(0.0, 0.3 + h * 0.5, 0.0), vec3(0.3, 0.46 + h, 0.1), None, stone);
|
crate::props::auto_cube(c + vec3(0.0, 0.3 + h * 0.5, 0.0), vec3(0.3, 0.46 + h, 0.1), stone);
|
||||||
draw_cube(c + vec3(0.0, 0.56 + h, 0.0), vec3(0.2, 0.06, 0.1), None, stone);
|
crate::props::auto_cube(c + vec3(0.0, 0.56 + h, 0.0), vec3(0.2, 0.06, 0.1), stone);
|
||||||
let glow = if m.level >= 8 { Color::from_rgba(255, 210, 90, 255) } else { Color::from_rgba(150, 120, 255, 255) };
|
let glow = if m.level >= 8 { Color::from_rgba(255, 210, 90, 255) } else { Color::from_rgba(150, 120, 255, 255) };
|
||||||
draw_cube(c + vec3(0.0, 0.34 + h * 0.5, 0.052), vec3(0.06, 0.14, 0.01), None, glow);
|
crate::props::auto_cube(c + vec3(0.0, 0.34 + h * 0.5, 0.052), vec3(0.06, 0.14, 0.01), glow);
|
||||||
}
|
}
|
||||||
// a ranger's snares: iron jaws on the floor, open and waiting
|
// a ranger's snares: iron jaws on the floor, open and waiting
|
||||||
for &i in &g.snares {
|
for &i in &g.snares {
|
||||||
@@ -2629,12 +2629,12 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
let c = vec3(x as f32 + 0.5, 0.0, y as f32 + 0.5);
|
let c = vec3(x as f32 + 0.5, 0.0, y as f32 + 0.5);
|
||||||
let iron = Color::from_rgba(96, 92, 100, 255);
|
let iron = Color::from_rgba(96, 92, 100, 255);
|
||||||
let dark = Color::from_rgba(40, 36, 42, 255);
|
let dark = Color::from_rgba(40, 36, 42, 255);
|
||||||
draw_cube(c + vec3(0.0, 0.02, 0.0), vec3(0.34, 0.03, 0.34), None, dark);
|
crate::props::auto_cube(c + vec3(0.0, 0.02, 0.0), vec3(0.34, 0.03, 0.34), dark);
|
||||||
for side in [-1.0f32, 1.0] {
|
for side in [-1.0f32, 1.0] {
|
||||||
draw_cube(c + vec3(side * 0.16, 0.06, 0.0), vec3(0.04, 0.08, 0.36), None, iron);
|
crate::props::auto_cube(c + vec3(side * 0.16, 0.06, 0.0), vec3(0.04, 0.08, 0.36), iron);
|
||||||
for k in 0..3 {
|
for k in 0..3 {
|
||||||
let z = -0.12 + k as f32 * 0.12;
|
let z = -0.12 + k as f32 * 0.12;
|
||||||
draw_cube(c + vec3(side * 0.12, 0.11, z), vec3(0.03, 0.05, 0.03), None, Color::from_rgba(200, 200, 210, 255));
|
crate::props::auto_cube(c + vec3(side * 0.12, 0.11, z), vec3(0.03, 0.05, 0.03), Color::from_rgba(200, 200, 210, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2654,14 +2654,14 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
let pc = vec3(px as f32 + 1.5, 0.0, py as f32 + 1.5);
|
let pc = vec3(px as f32 + 1.5, 0.0, py as f32 + 1.5);
|
||||||
let stone = |k: u8| if owned { hue_to(tint, Color::from_rgba(46 + k, 30 + k / 2, 58 + k, 255)) } else { Color::from_rgba(56 + k, 54 + k, 60 + k, 255) };
|
let stone = |k: u8| if owned { hue_to(tint, Color::from_rgba(46 + k, 30 + k / 2, 58 + k, 255)) } else { Color::from_rgba(56 + k, 54 + k, 60 + k, 255) };
|
||||||
let bone = if owned { Color::from_rgba(212, 200, 176, 255) } else { Color::from_rgba(150, 146, 140, 255) };
|
let bone = if owned { Color::from_rgba(212, 200, 176, 255) } else { Color::from_rgba(150, 146, 140, 255) };
|
||||||
draw_cube(pc + vec3(0.0, 0.05, 0.0), vec3(2.9, 0.1, 2.9), None, stone(0));
|
crate::props::auto_cube(pc + vec3(0.0, 0.05, 0.0), vec3(2.9, 0.1, 2.9), stone(0));
|
||||||
draw_cube(pc + vec3(0.0, 0.14, 0.0), vec3(2.4, 0.08, 1.4), None, stone(8));
|
crate::props::auto_cube(pc + vec3(0.0, 0.14, 0.0), vec3(2.4, 0.08, 1.4), stone(8));
|
||||||
let r = 1.25;
|
let r = 1.25;
|
||||||
for side in [-1.0f32, 1.0] {
|
for side in [-1.0f32, 1.0] {
|
||||||
// pillars of stacked, slightly offset blocks
|
// pillars of stacked, slightly offset blocks
|
||||||
for k in 0..5 {
|
for k in 0..5 {
|
||||||
let off = if k % 2 == 0 { 0.03 } else { -0.03 };
|
let off = if k % 2 == 0 { 0.03 } else { -0.03 };
|
||||||
draw_cube(pc + vec3(side * (r + off), 0.32 + k as f32 * 0.36, 0.0), vec3(0.42, 0.34, 0.5), None, stone((k * 5) as u8 + 6));
|
crate::props::auto_cube(pc + vec3(side * (r + off), 0.32 + k as f32 * 0.36, 0.0), vec3(0.42, 0.34, 0.5), stone((k * 5) as u8 + 6));
|
||||||
}
|
}
|
||||||
// a bone rib along the inner edge
|
// a bone rib along the inner edge
|
||||||
line3(pc + vec3(side * (r - 0.27), 0.2, 0.26), pc + vec3(side * (r - 0.27), 1.95, 0.26), 0.06, bone);
|
line3(pc + vec3(side * (r - 0.27), 0.2, 0.26), pc + vec3(side * (r - 0.27), 1.95, 0.26), 0.06, bone);
|
||||||
@@ -2671,13 +2671,13 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
for k in 0..=8 {
|
for k in 0..=8 {
|
||||||
let a = k as f32 / 8.0 * std::f32::consts::PI;
|
let a = k as f32 / 8.0 * std::f32::consts::PI;
|
||||||
let p = pc + vec3(a.cos() * r, 2.0 + a.sin() * r * 0.9, 0.0);
|
let p = pc + vec3(a.cos() * r, 2.0 + a.sin() * r * 0.9, 0.0);
|
||||||
draw_cube(p, vec3(0.4, 0.34, 0.52), None, stone(16 + (k % 3) as u8 * 4));
|
crate::props::auto_cube(p, vec3(0.4, 0.34, 0.52), stone(16 + (k % 3) as u8 * 4));
|
||||||
}
|
}
|
||||||
// keystone skull and horns
|
// keystone skull and horns
|
||||||
let top = pc + vec3(0.0, 2.0 + r * 0.9 + 0.12, 0.0);
|
let top = pc + vec3(0.0, 2.0 + r * 0.9 + 0.12, 0.0);
|
||||||
draw_cube(top, vec3(0.3, 0.28, 0.3), None, bone);
|
crate::props::auto_cube(top, vec3(0.3, 0.28, 0.3), bone);
|
||||||
for sgn in [-1.0f32, 1.0] {
|
for sgn in [-1.0f32, 1.0] {
|
||||||
draw_cube(top + vec3(sgn * 0.07, 0.03, 0.155), vec3(0.07, 0.07, 0.02), None, Color::from_rgba(20, 8, 16, 255));
|
crate::props::auto_cube(top + vec3(sgn * 0.07, 0.03, 0.155), vec3(0.07, 0.07, 0.02), Color::from_rgba(20, 8, 16, 255));
|
||||||
let mut prev = top + vec3(sgn * 0.15, 0.08, 0.0);
|
let mut prev = top + vec3(sgn * 0.15, 0.08, 0.0);
|
||||||
for q in 1..=4 {
|
for q in 1..=4 {
|
||||||
let f = q as f32 / 4.0;
|
let f = q as f32 / 4.0;
|
||||||
@@ -2697,33 +2697,33 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
let gold = Color::from_rgba(230, 200, 100, 255);
|
let gold = Color::from_rgba(230, 200, 100, 255);
|
||||||
let iron = Color::from_rgba(56, 58, 66, 255);
|
let iron = Color::from_rgba(56, 58, 66, 255);
|
||||||
for side in [-1.1f32, 1.1] {
|
for side in [-1.1f32, 1.1] {
|
||||||
draw_cube(vec3(gx + side, 0.12, gz), vec3(0.6, 0.24, 0.6), None, dark); // plinth
|
crate::props::auto_cube(vec3(gx + side, 0.12, gz), vec3(0.6, 0.24, 0.6), dark); // plinth
|
||||||
draw_cube(vec3(gx + side, 1.0, gz), vec3(0.45, 1.8, 0.45), None, stone);
|
crate::props::auto_cube(vec3(gx + side, 1.0, gz), vec3(0.45, 1.8, 0.45), stone);
|
||||||
for y in [0.6f32, 1.2] {
|
for y in [0.6f32, 1.2] {
|
||||||
draw_cube(vec3(gx + side, y, gz), vec3(0.48, 0.05, 0.48), None, dark); // bands
|
crate::props::auto_cube(vec3(gx + side, y, gz), vec3(0.48, 0.05, 0.48), dark); // bands
|
||||||
}
|
}
|
||||||
draw_cube(vec3(gx + side, 1.92, gz), vec3(0.56, 0.12, 0.56), None, dark); // capital
|
crate::props::auto_cube(vec3(gx + side, 1.92, gz), vec3(0.56, 0.12, 0.56), dark); // capital
|
||||||
// banner of the order: white with a golden sun
|
// banner of the order: white with a golden sun
|
||||||
draw_cube(vec3(gx + side, 1.35, gz + 0.25), vec3(0.32, 0.7, 0.02), None, Color::from_rgba(232, 234, 242, 255));
|
crate::props::auto_cube(vec3(gx + side, 1.35, gz + 0.25), vec3(0.32, 0.7, 0.02), Color::from_rgba(232, 234, 242, 255));
|
||||||
draw_cube(vec3(gx + side, 1.45, gz + 0.265), vec3(0.14, 0.14, 0.01), None, gold);
|
crate::props::auto_cube(vec3(gx + side, 1.45, gz + 0.265), vec3(0.14, 0.14, 0.01), gold);
|
||||||
draw_cube(vec3(gx + side, 1.02, gz + 0.26), vec3(0.32, 0.05, 0.02), None, Color::from_rgba(60, 90, 170, 255));
|
crate::props::auto_cube(vec3(gx + side, 1.02, gz + 0.26), vec3(0.32, 0.05, 0.02), Color::from_rgba(60, 90, 170, 255));
|
||||||
}
|
}
|
||||||
// stepped arch with a keystone
|
// stepped arch with a keystone
|
||||||
draw_cube(vec3(gx, 2.1, gz), vec3(2.8, 0.3, 0.55), None, stone);
|
crate::props::auto_cube(vec3(gx, 2.1, gz), vec3(2.8, 0.3, 0.55), stone);
|
||||||
draw_cube(vec3(gx, 1.88, gz), vec3(1.7, 0.14, 0.5), None, dark);
|
crate::props::auto_cube(vec3(gx, 1.88, gz), vec3(1.7, 0.14, 0.5), dark);
|
||||||
draw_cube(vec3(gx, 2.32, gz), vec3(2.2, 0.14, 0.5), None, dark);
|
crate::props::auto_cube(vec3(gx, 2.32, gz), vec3(2.2, 0.14, 0.5), dark);
|
||||||
draw_cube(vec3(gx, 2.2, gz), vec3(0.34, 0.5, 0.58), None, gold);
|
crate::props::auto_cube(vec3(gx, 2.2, gz), vec3(0.34, 0.5, 0.58), gold);
|
||||||
// portcullis (iron bars) in the opening, half raised
|
// portcullis (iron bars) in the opening, half raised
|
||||||
for k in 0..5 {
|
for k in 0..5 {
|
||||||
draw_cube(vec3(gx - 0.6 + k as f32 * 0.3, 1.45, gz), vec3(0.05, 0.85, 0.05), None, iron);
|
crate::props::auto_cube(vec3(gx - 0.6 + k as f32 * 0.3, 1.45, gz), vec3(0.05, 0.85, 0.05), iron);
|
||||||
}
|
}
|
||||||
for y in [1.15f32, 1.5, 1.8] {
|
for y in [1.15f32, 1.5, 1.8] {
|
||||||
draw_cube(vec3(gx, y, gz), vec3(1.7, 0.05, 0.05), None, iron);
|
crate::props::auto_cube(vec3(gx, y, gz), vec3(1.7, 0.05, 0.05), iron);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for k in 0..10 {
|
for k in 0..10 {
|
||||||
let a = k as f32 * 1.7;
|
let a = k as f32 * 1.7;
|
||||||
draw_cube(vec3(gx + a.cos() * 1.0, 0.15, gz + a.sin() * 0.8), vec3(0.35, 0.3, 0.3), None, Color::from_rgba(150, 150, 160, 255));
|
crate::props::auto_cube(vec3(gx + a.cos() * 1.0, 0.15, gz + a.sin() * 0.8), vec3(0.35, 0.3, 0.3), Color::from_rgba(150, 150, 160, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = t;
|
let _ = t;
|
||||||
@@ -2844,11 +2844,14 @@ fn draw_heart(base: Vec3, hp: f32, t: f32, cam_r: Vec3, tint: Option<Vec3>) {
|
|||||||
let hot = tc(1.0, 0.35 + 0.25 * beat, 0.3, 0.7);
|
let hot = tc(1.0, 0.35 + 0.25 * beat, 0.3, 0.7);
|
||||||
// two lobes and the point below, then the facets as bright chips
|
// two lobes and the point below, then the facets as bright chips
|
||||||
let s0 = 0.36 * pulse;
|
let s0 = 0.36 * pulse;
|
||||||
|
// the crystal's facets (the furniture material; the colour tints it)
|
||||||
|
let crystal = crate::props::material(crate::props::Mat::Crystal);
|
||||||
|
let red = if crystal.is_some() { Color::new((red.r * 1.35).min(1.0), red.g * 1.35, red.b * 1.35, red.a) } else { red };
|
||||||
for sgn in [-1.0f32, 1.0] {
|
for sgn in [-1.0f32, 1.0] {
|
||||||
draw_sphere(hc + right * (sgn * 0.21 * pulse) + up * (0.12 * pulse), s0 * 0.85, None, red);
|
draw_sphere(hc + right * (sgn * 0.21 * pulse) + up * (0.12 * pulse), s0 * 0.85, crystal.as_ref(), red);
|
||||||
}
|
}
|
||||||
for (k, (y, r)) in [(-0.05f32, 0.36f32), (-0.22, 0.28), (-0.36, 0.18), (-0.46, 0.09)].iter().enumerate() {
|
for (k, (y, r)) in [(-0.05f32, 0.36f32), (-0.22, 0.28), (-0.36, 0.18), (-0.46, 0.09)].iter().enumerate() {
|
||||||
draw_sphere(hc + up * (y * pulse), r * pulse, None, if k == 0 { red } else { tc(red.r * 0.9, red.g, red.b, 1.0) });
|
draw_sphere(hc + up * (y * pulse), r * pulse, crystal.as_ref(), if k == 0 { red } else { tc(red.r * 0.9, red.g, red.b, 1.0) });
|
||||||
}
|
}
|
||||||
draw_sphere(hc + right * (-0.12 * pulse) + up * (0.2 * pulse), 0.1 * pulse, None, tc(1.0, 0.75, 0.7, 0.75));
|
draw_sphere(hc + right * (-0.12 * pulse) + up * (0.2 * pulse), 0.1 * pulse, None, tc(1.0, 0.75, 0.7, 0.75));
|
||||||
for k in 0..7 {
|
for k in 0..7 {
|
||||||
@@ -3201,7 +3204,7 @@ fn draw_traps_solid(g: &Game, t: f32) {
|
|||||||
let fresh = (1.0 - tr.fired / 0.6).clamp(0.0, 1.0);
|
let fresh = (1.0 - tr.fired / 0.6).clamp(0.0, 1.0);
|
||||||
match tr.kind {
|
match tr.kind {
|
||||||
TrapKind::Spikes => {
|
TrapKind::Spikes => {
|
||||||
draw_cube(c + vec3(0.0, 0.02, 0.0), vec3(0.8, 0.04, 0.8), None, iron);
|
crate::props::auto_cube(c + vec3(0.0, 0.02, 0.0), vec3(0.8, 0.04, 0.8), iron);
|
||||||
let up = 0.06 + 0.3 * fresh;
|
let up = 0.06 + 0.3 * fresh;
|
||||||
for q in 0..9 {
|
for q in 0..9 {
|
||||||
let (dx, dz) = ((q % 3) as f32 * 0.24 - 0.24, (q / 3) as f32 * 0.24 - 0.24);
|
let (dx, dz) = ((q % 3) as f32 * 0.24 - 0.24, (q / 3) as f32 * 0.24 - 0.24);
|
||||||
@@ -3209,17 +3212,17 @@ fn draw_traps_solid(g: &Game, t: f32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrapKind::Poison => {
|
TrapKind::Poison => {
|
||||||
draw_cube(c + vec3(0.0, 0.03, 0.0), vec3(0.6, 0.06, 0.6), None, iron);
|
crate::props::auto_cube(c + vec3(0.0, 0.03, 0.0), vec3(0.6, 0.06, 0.6), iron);
|
||||||
for q in 0..3 {
|
for q in 0..3 {
|
||||||
draw_cube(c + vec3(q as f32 * 0.16 - 0.16, 0.065, 0.0), vec3(0.06, 0.02, 0.5), None, Color::from_rgba(30, 40, 26, 255));
|
crate::props::auto_cube(c + vec3(q as f32 * 0.16 - 0.16, 0.065, 0.0), vec3(0.06, 0.02, 0.5), Color::from_rgba(30, 40, 26, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrapKind::Fire => {
|
TrapKind::Fire => {
|
||||||
// a demon head on a pedestal, its mouth towards the last target
|
// a demon head on a pedestal, its mouth towards the last target
|
||||||
draw_cube(c + vec3(0.0, 0.15, 0.0), vec3(0.36, 0.3, 0.36), None, Color::from_rgba(50, 40, 44, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.15, 0.0), vec3(0.36, 0.3, 0.36), Color::from_rgba(50, 40, 44, 255));
|
||||||
let (ax, az) = (tr.aim.cos(), tr.aim.sin());
|
let (ax, az) = (tr.aim.cos(), tr.aim.sin());
|
||||||
draw_cube(c + vec3(0.0, 0.4, 0.0), vec3(0.3, 0.22, 0.3), None, Color::from_rgba(70, 56, 52, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.4, 0.0), vec3(0.3, 0.22, 0.3), Color::from_rgba(70, 56, 52, 255));
|
||||||
draw_cube(c + vec3(ax * 0.16, 0.38, az * 0.16), vec3(0.14, 0.1, 0.14), None, Color::from_rgba(30, 20, 20, 255));
|
crate::props::auto_cube(c + vec3(ax * 0.16, 0.38, az * 0.16), vec3(0.14, 0.1, 0.14), Color::from_rgba(30, 20, 20, 255));
|
||||||
for sgn in [-1.0f32, 1.0] {
|
for sgn in [-1.0f32, 1.0] {
|
||||||
line3(c + vec3(-az * 0.12 * sgn, 0.5, ax * 0.12 * sgn), c + vec3(-az * 0.2 * sgn - ax * 0.08, 0.68, ax * 0.2 * sgn - az * 0.08), 0.04, Color::from_rgba(214, 204, 178, 255));
|
line3(c + vec3(-az * 0.12 * sgn, 0.5, ax * 0.12 * sgn), c + vec3(-az * 0.2 * sgn - ax * 0.08, 0.68, ax * 0.2 * sgn - az * 0.08), 0.04, Color::from_rgba(214, 204, 178, 255));
|
||||||
}
|
}
|
||||||
@@ -3229,19 +3232,19 @@ fn draw_traps_solid(g: &Game, t: f32) {
|
|||||||
if tr.fired > 18.0 || tr.cd <= 0.0 {
|
if tr.fired > 18.0 || tr.cd <= 0.0 {
|
||||||
draw_sphere(c + vec3(0.0, 0.3, 0.0), 0.3, None, Color::from_rgba(120, 112, 104, 255));
|
draw_sphere(c + vec3(0.0, 0.3, 0.0), 0.3, None, Color::from_rgba(120, 112, 104, 255));
|
||||||
}
|
}
|
||||||
draw_cube(c + vec3(0.0, 0.03, 0.0), vec3(0.8, 0.06, 0.8), None, Color::from_rgba(60, 56, 52, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.03, 0.0), vec3(0.8, 0.06, 0.8), Color::from_rgba(60, 56, 52, 255));
|
||||||
}
|
}
|
||||||
TrapKind::Alarm => {
|
TrapKind::Alarm => {
|
||||||
draw_cube(c + vec3(0.0, 0.35, 0.0), vec3(0.06, 0.7, 0.06), None, Color::from_rgba(90, 64, 40, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.35, 0.0), vec3(0.06, 0.7, 0.06), Color::from_rgba(90, 64, 40, 255));
|
||||||
draw_cube(c + vec3(0.0, 0.7, 0.0), vec3(0.34, 0.05, 0.06), None, Color::from_rgba(90, 64, 40, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.7, 0.0), vec3(0.34, 0.05, 0.06), Color::from_rgba(90, 64, 40, 255));
|
||||||
let swing = (t * 18.0).sin() * 0.06 * fresh.max(((tr.fired < 3.0) as u8) as f32);
|
let swing = (t * 18.0).sin() * 0.06 * fresh.max(((tr.fired < 3.0) as u8) as f32);
|
||||||
draw_cube(c + vec3(swing, 0.58, 0.0), vec3(0.18, 0.18, 0.18), None, Color::from_rgba(220, 180, 70, 255));
|
crate::props::auto_cube(c + vec3(swing, 0.58, 0.0), vec3(0.18, 0.18, 0.18), Color::from_rgba(220, 180, 70, 255));
|
||||||
}
|
}
|
||||||
TrapKind::Mine => {
|
TrapKind::Mine => {
|
||||||
draw_cube(c + vec3(0.0, 0.015, 0.0), vec3(0.4, 0.03, 0.4), None, Color::from_rgba(50, 54, 66, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.015, 0.0), vec3(0.4, 0.03, 0.4), Color::from_rgba(50, 54, 66, 255));
|
||||||
}
|
}
|
||||||
TrapKind::Frost => {
|
TrapKind::Frost => {
|
||||||
draw_cube(c + vec3(0.0, 0.06, 0.0), vec3(0.4, 0.12, 0.4), None, Color::from_rgba(80, 90, 110, 255));
|
crate::props::auto_cube(c + vec3(0.0, 0.06, 0.0), vec3(0.4, 0.12, 0.4), Color::from_rgba(80, 90, 110, 255));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// doors: posts, lintel and the leaf across the corridor
|
// doors: posts, lintel and the leaf across the corridor
|
||||||
@@ -3254,17 +3257,17 @@ fn draw_traps_solid(g: &Game, t: f32) {
|
|||||||
_ => (Color::from_rgba(70, 36, 100, 255), Color::from_rgba(30, 20, 40, 255)),
|
_ => (Color::from_rgba(70, 36, 100, 255), Color::from_rgba(30, 20, 40, 255)),
|
||||||
};
|
};
|
||||||
for sgn in [-1.0f32, 1.0] {
|
for sgn in [-1.0f32, 1.0] {
|
||||||
draw_cube(c + len * (0.44 * sgn) + Vec3::Y * 0.6, size(0.12, 1.2, 0.3), None, Color::from_rgba(40, 32, 36, 255));
|
crate::props::auto_cube(c + len * (0.44 * sgn) + Vec3::Y * 0.6, size(0.12, 1.2, 0.3), Color::from_rgba(40, 32, 36, 255));
|
||||||
}
|
}
|
||||||
draw_cube(c + Vec3::Y * 1.22, size(1.0, 0.14, 0.32), None, Color::from_rgba(40, 32, 36, 255));
|
crate::props::auto_cube(c + Vec3::Y * 1.22, size(1.0, 0.14, 0.32), Color::from_rgba(40, 32, 36, 255));
|
||||||
let shake = if tr.fired < 0.2 { (t * 60.0).sin() * 0.02 } else { 0.0 };
|
let shake = if tr.fired < 0.2 { (t * 60.0).sin() * 0.02 } else { 0.0 };
|
||||||
draw_cube(c + Vec3::Y * 0.56 + thin * shake, size(0.76, 1.1, 0.1), None, leaf);
|
crate::props::auto_cube(c + Vec3::Y * 0.56 + thin * shake, size(0.76, 1.1, 0.1), leaf);
|
||||||
for y in [0.25f32, 0.85] {
|
for y in [0.25f32, 0.85] {
|
||||||
draw_cube(c + Vec3::Y * y, size(0.78, 0.06, 0.12), None, trim);
|
crate::props::auto_cube(c + Vec3::Y * y, size(0.78, 0.06, 0.12), trim);
|
||||||
}
|
}
|
||||||
if tr.locked {
|
if tr.locked {
|
||||||
draw_cube(c + Vec3::Y * 0.6, size(0.86, 0.08, 0.16), None, Color::from_rgba(60, 60, 66, 255));
|
crate::props::auto_cube(c + Vec3::Y * 0.6, size(0.86, 0.08, 0.16), Color::from_rgba(60, 60, 66, 255));
|
||||||
draw_cube(c + Vec3::Y * 0.6 + thin * 0.09, vec3(0.1, 0.12, 0.1), None, Color::from_rgba(230, 190, 70, 255));
|
crate::props::auto_cube(c + Vec3::Y * 0.6 + thin * 0.09, vec3(0.1, 0.12, 0.1), Color::from_rgba(230, 190, 70, 255));
|
||||||
}
|
}
|
||||||
// damage: darker the more it is beaten
|
// damage: darker the more it is beaten
|
||||||
let _ = tr.hp / tr.kind.hp();
|
let _ = tr.hp / tr.kind.hp();
|
||||||
@@ -3278,7 +3281,7 @@ fn draw_traps_solid(g: &Game, t: f32) {
|
|||||||
let spin = r.t * 9.0;
|
let spin = r.t * 9.0;
|
||||||
let at = vec3(r.x, 0.3, r.y);
|
let at = vec3(r.x, 0.3, r.y);
|
||||||
draw_sphere(at, 0.3, None, Color::from_rgba(120, 112, 104, 255));
|
draw_sphere(at, 0.3, None, Color::from_rgba(120, 112, 104, 255));
|
||||||
draw_cube(at + vec3(spin.cos() * 0.22 * r.dy.abs(), spin.sin() * 0.22, spin.cos() * 0.22 * r.dx.abs()), Vec3::splat(0.1), None, Color::from_rgba(80, 74, 70, 255));
|
crate::props::auto_cube(at + vec3(spin.cos() * 0.22 * r.dy.abs(), spin.sin() * 0.22, spin.cos() * 0.22 * r.dx.abs()), Vec3::splat(0.1), Color::from_rgba(80, 74, 70, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user