diff --git a/art/generated/textures/materials/PROMPTS.md b/art/generated/textures/materials/PROMPTS.md
index 4c48d8c..bc24a50 100644
--- a/art/generated/textures/materials/PROMPTS.md
+++ b/art/generated/textures/materials/PROMPTS.md
@@ -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.
```
+## 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
`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 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 crystal-raw.png crystal --crop 0.1,0.1,0.9,0.9 --mean 0.75
```
Copied to `assets/textures/mat/`.
diff --git a/art/generated/textures/materials/batch.py b/art/generated/textures/materials/batch.py
index 588c709..f90b565 100644
--- a/art/generated/textures/materials/batch.py
+++ b/art/generated/textures/materials/batch.py
@@ -11,6 +11,7 @@ MATS = {
"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, "
"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, "
"a small drawn magic circle and a red initial letter, in light neutral tones.",
}
diff --git a/art/generated/textures/materials/crystal-16.png b/art/generated/textures/materials/crystal-16.png
new file mode 100644
index 0000000..2a4b09b
Binary files /dev/null and b/art/generated/textures/materials/crystal-16.png differ
diff --git a/art/generated/textures/materials/crystal-64.png b/art/generated/textures/materials/crystal-64.png
new file mode 100644
index 0000000..68ddd41
Binary files /dev/null and b/art/generated/textures/materials/crystal-64.png differ
diff --git a/art/generated/textures/materials/crystal-raw.png b/art/generated/textures/materials/crystal-raw.png
new file mode 100644
index 0000000..ee46147
Binary files /dev/null and b/art/generated/textures/materials/crystal-raw.png differ
diff --git a/assets/textures/mat/crystal-16.png b/assets/textures/mat/crystal-16.png
new file mode 100644
index 0000000..2a4b09b
Binary files /dev/null and b/assets/textures/mat/crystal-16.png differ
diff --git a/assets/textures/mat/crystal-64.png b/assets/textures/mat/crystal-64.png
new file mode 100644
index 0000000..68ddd41
Binary files /dev/null and b/assets/textures/mat/crystal-64.png differ
diff --git a/src/gfx.rs b/src/gfx.rs
index c92bebd..7db9ae2 100644
--- a/src/gfx.rs
+++ b/src/gfx.rs
@@ -106,8 +106,8 @@ pub struct Gfx {
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_hd2: Texture2D, // the same with 128x128 tiles (close up)
- pub materials: [Texture2D; 8], // furniture materials, high-res (see crate::props::Mat)
- pub materials_px: [Texture2D; 8], // the same for the pixel-art style (16x16)
+ pub materials: [Texture2D; 9], // furniture materials, high-res (see crate::props::Mat)
+ pub materials_px: [Texture2D; 9], // the same for the pixel-art style (16x16)
pub cursors: Texture2D, // mouse pointer frames, 16x16 each (see CURSOR_*)
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
@@ -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])
};
}
-const MATERIALS: [(&[u8], &[u8]); 8] = [
+const MATERIALS: [(&[u8], &[u8]); 9] = [
material!("wood"),
material!("stone"),
material!("iron"),
@@ -363,6 +363,7 @@ const MATERIALS: [(&[u8], &[u8]); 8] = [
material!("fur"),
material!("book"),
material!("paper"),
+ material!("crystal"),
];
// ---- high-res tiles
diff --git a/src/props.rs b/src/props.rs
index d92c060..dbb5aac 100644
--- a/src/props.rs
+++ b/src/props.rs
@@ -49,17 +49,57 @@ pub enum Mat {
Fur,
Book,
Paper,
+ Crystal,
}
thread_local! {
// the material textures of the current graphics style (set every frame, see set_materials)
- static MATS: std::cell::RefCell> = std::cell::RefCell::new(None);
+ static MATS: std::cell::RefCell > = 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()));
}
+// the texture of a material in the current style
+pub fn material(m: Mat) -> Option {
+ 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 {
+ 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
fn mc(m: Mat, p: Vec3, s: Vec3, c: Color) {
let k = GROW.with(|g| g.get()).map_or(1.0, |g| g.1);
diff --git a/src/render3d.rs b/src/render3d.rs
index 0f74caa..b5be230 100644
--- a/src/render3d.rs
+++ b/src/render3d.rs
@@ -2167,7 +2167,7 @@ fn draw_dark_tower(tw: &Tower) {
let iron = shade_c(58, 56, 64, f);
let bone = shade_c(214, 204, 178, 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| {
bx(p, vec3(0.15, 0.14, 0.15), bone);
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 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
- 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 {
- 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] {
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);
@@ -2309,7 +2309,7 @@ fn draw_towers_solid(g: &Game) {
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
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 {
TowerKind::Arrow => {
// stone plinth, masonry body with courses and arrow slits
@@ -2414,7 +2414,7 @@ fn draw_towers_solid(g: &Game) {
}
// level pips on the plinth
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)
fn draw_throne(c: Vec3, t: f32) {
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));
- draw_cube(c + vec3(0.0, 0.22, 0.0), vec3(2.3, 0.14, 2.3), None, obs(14));
- draw_cube(c + vec3(0.0, 0.36, 0.0), vec3(1.5, 0.14, 1.5), None, 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.08, 0.0), vec3(2.9, 0.16, 2.9), obs(6));
+ crate::props::auto_cube(c + vec3(0.0, 0.22, 0.0), vec3(2.3, 0.14, 2.3), obs(14));
+ crate::props::auto_cube(c + vec3(0.0, 0.36, 0.0), vec3(1.5, 0.14, 1.5), obs(24));
+ 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 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() {
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
let mut prev = b + vec3(0.0, 0.55, 0.0);
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 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);
- 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));
- draw_cube(c + vec3(0.0, 0.3 + h * 0.5, 0.0), vec3(0.3, 0.46 + h, 0.1), None, 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.04, 0.0), vec3(0.42, 0.08, 0.26), Color::from_rgba(70, 66, 74, 255));
+ crate::props::auto_cube(c + vec3(0.0, 0.3 + h * 0.5, 0.0), vec3(0.3, 0.46 + h, 0.1), 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) };
- 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
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 iron = Color::from_rgba(96, 92, 100, 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] {
- 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 {
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 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) };
- draw_cube(pc + vec3(0.0, 0.05, 0.0), vec3(2.9, 0.1, 2.9), None, 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.05, 0.0), vec3(2.9, 0.1, 2.9), stone(0));
+ 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;
for side in [-1.0f32, 1.0] {
// pillars of stacked, slightly offset blocks
for k in 0..5 {
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
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 {
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);
- 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
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] {
- 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);
for q in 1..=4 {
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 iron = Color::from_rgba(56, 58, 66, 255);
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
- draw_cube(vec3(gx + side, 1.0, gz), vec3(0.45, 1.8, 0.45), None, stone);
+ crate::props::auto_cube(vec3(gx + side, 0.12, gz), vec3(0.6, 0.24, 0.6), dark); // plinth
+ 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] {
- 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
- 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));
- draw_cube(vec3(gx + side, 1.45, gz + 0.265), vec3(0.14, 0.14, 0.01), None, 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.35, gz + 0.25), vec3(0.32, 0.7, 0.02), Color::from_rgba(232, 234, 242, 255));
+ crate::props::auto_cube(vec3(gx + side, 1.45, gz + 0.265), vec3(0.14, 0.14, 0.01), gold);
+ 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
- draw_cube(vec3(gx, 2.1, gz), vec3(2.8, 0.3, 0.55), None, stone);
- draw_cube(vec3(gx, 1.88, gz), vec3(1.7, 0.14, 0.5), None, dark);
- draw_cube(vec3(gx, 2.32, gz), vec3(2.2, 0.14, 0.5), None, dark);
- draw_cube(vec3(gx, 2.2, gz), vec3(0.34, 0.5, 0.58), None, gold);
+ crate::props::auto_cube(vec3(gx, 2.1, gz), vec3(2.8, 0.3, 0.55), stone);
+ crate::props::auto_cube(vec3(gx, 1.88, gz), vec3(1.7, 0.14, 0.5), dark);
+ crate::props::auto_cube(vec3(gx, 2.32, gz), vec3(2.2, 0.14, 0.5), dark);
+ 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
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] {
- 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 {
for k in 0..10 {
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;
@@ -2844,11 +2844,14 @@ fn draw_heart(base: Vec3, hp: f32, t: f32, cam_r: Vec3, tint: Option) {
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
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] {
- 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() {
- 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));
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);
match tr.kind {
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;
for q in 0..9 {
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 => {
- 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 {
- 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 => {
// 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());
- 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));
- 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(0.0, 0.4, 0.0), vec3(0.3, 0.22, 0.3), Color::from_rgba(70, 56, 52, 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] {
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 {
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 => {
- 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));
- 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.35, 0.0), vec3(0.06, 0.7, 0.06), 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);
- 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 => {
- 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 => {
- 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
@@ -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)),
};
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 };
- 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] {
- 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 {
- draw_cube(c + Vec3::Y * 0.6, size(0.86, 0.08, 0.16), None, 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, size(0.86, 0.08, 0.16), Color::from_rgba(60, 60, 66, 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
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 at = vec3(r.x, 0.3, r.y);
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));
}
}