Faint block highlight on hover and inside the dig rectangle
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f710a19351
commit
5fd0d37c14
2 files changed
+46
-11
No files matched your search
@@ -19,6 +19,7 @@ An original dungeon management game (genre: dungeon building & defence) that run
|
||||
- Units: **pixel sprites as billboards** (always facing the camera)
|
||||
- Lighting: **dark + torches** – dark base level; claimed areas and light sources (torches, core, portal, gate) are bright, flickering light
|
||||
- **Dig marking**: a marked block glows as a translucent yellow box with a yellow outline around all edges
|
||||
- **Hover**: the wall block under the mouse gets a faint version of that box (in the colour of the active tool); while dragging a dig rectangle, every block inside is tinted faintly; floor tiles get an outline
|
||||
- **Tile outlines**: subtle dark lines around every tile (floors, wall tops, vertical wall edges), following the irregular surface; toggle with G (later in the graphics settings)
|
||||
- The UI is a 2D layer on top, including a minimap
|
||||
|
||||
|
||||
+45
-11
@@ -416,13 +416,19 @@ const MARK_LINE: [u8; 4] = [255, 220, 70, 235];
|
||||
|
||||
// Glowing yellow box around a block that is marked for digging
|
||||
fn mark_block(mk: &mut MB, map: &Map, x: i32, z: i32) {
|
||||
let (x0, z0) = (x as f32 - 0.06, z as f32 - 0.06);
|
||||
let (x1, z1) = (x as f32 + 1.06, z as f32 + 1.06);
|
||||
let top = WALL_H + 0.16;
|
||||
block_box(mk, map, x, z, MARK_FILL, MARK_LINE, 0.06, 1.0);
|
||||
}
|
||||
|
||||
// Translucent box around a wall block: fill on top and open sides, outline on all edges.
|
||||
// pad = how far the box sticks out, lw = line width factor
|
||||
fn block_box(mk: &mut MB, map: &Map, x: i32, z: i32, fill: [u8; 4], line: [u8; 4], pad: f32, lw: f32) {
|
||||
let (x0, z0) = (x as f32 - pad, z as f32 - pad);
|
||||
let (x1, z1) = (x as f32 + 1.0 + pad, z as f32 + 1.0 + pad);
|
||||
let top = WALL_H + 0.1 + pad;
|
||||
let c = [x0, z0, x1, z1];
|
||||
let p = |xx: f32, y: f32, zz: f32| vec3(xx, y, zz);
|
||||
// top face
|
||||
mk.quad([p(c[0], top, c[1]), p(c[2], top, c[1]), p(c[2], top, c[3]), p(c[0], top, c[3])], [Vec2::ZERO; 4], [MARK_FILL; 4], [Vec3::Y; 4]);
|
||||
mk.quad([p(c[0], top, c[1]), p(c[2], top, c[1]), p(c[2], top, c[3]), p(c[0], top, c[3])], [Vec2::ZERO; 4], [fill; 4], [Vec3::Y; 4]);
|
||||
let corners = [p(c[0], 0.0, c[1]), p(c[2], 0.0, c[1]), p(c[2], 0.0, c[3]), p(c[0], 0.0, c[3])];
|
||||
// side faces towards open neighbours, outline on all edges
|
||||
for k in 0..4 {
|
||||
@@ -432,16 +438,16 @@ fn mark_block(mk: &mut MB, map: &Map, x: i32, z: i32) {
|
||||
let up = vec3(0.0, top, 0.0);
|
||||
let out = vec3(dx as f32, 0.0, dz as f32);
|
||||
if !solid_at(map, x + dx, z + dz) {
|
||||
mk.quad([a, b, b + up, a + up], [Vec2::ZERO; 4], [MARK_FILL; 4], [out; 4]);
|
||||
mk.strip(a + vec3(0.0, 0.02, 0.0), b + vec3(0.0, 0.02, 0.0), out, 0.05, MARK_LINE);
|
||||
mk.quad([a, b, b + up, a + up], [Vec2::ZERO; 4], [fill; 4], [out; 4]);
|
||||
mk.strip(a + vec3(0.0, 0.02, 0.0), b + vec3(0.0, 0.02, 0.0), out, 0.05 * lw, line);
|
||||
}
|
||||
mk.strip(a + up, b + up, Vec3::Y, 0.06, MARK_LINE);
|
||||
mk.strip(a + up, b + up, Vec3::Y, 0.06 * lw, line);
|
||||
// vertical edge at this corner: down to the floor only where a side is open,
|
||||
// otherwise just the part that sticks out above the neighbouring walls
|
||||
let (pdx, pdz) = DIR4[(k + 3) % 4];
|
||||
let open_here = !solid_at(map, x + dx, z + dz) || !solid_at(map, x + pdx, z + pdz);
|
||||
let bottom = if open_here { 0.0 } else { WALL_H - 0.05 };
|
||||
mk.strip(a + vec3(0.0, bottom, 0.0), a + up, out, 0.05, MARK_LINE);
|
||||
mk.strip(a + vec3(0.0, bottom, 0.0), a + up, out, 0.05 * lw, line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1190,15 +1196,43 @@ fn outline(x0: f32, z0: f32, x1: f32, z1: f32, y: f32, c: Color) {
|
||||
}
|
||||
}
|
||||
|
||||
// Hover feedback: wall blocks get a faint version of the dig-mark box (in the tool colour),
|
||||
// floor tiles an outline. While dragging a dig rectangle, every block inside is tinted.
|
||||
fn draw_overlay(map: &Map, ov: &Overlay) {
|
||||
let y_of = |x: i32, z: i32| if ov.high && map.get(x, z).map_or(false, |t| t.solid()) { WALL_H + 0.14 } else { 0.04 };
|
||||
const MAX_BOXES: usize = 400; // keeps the per-frame mesh within one draw call
|
||||
let c = ov.color;
|
||||
let fill = [(c.r * 255.0) as u8, (c.g * 255.0) as u8, (c.b * 255.0) as u8, 28];
|
||||
let line = [(c.r * 255.0) as u8, (c.g * 255.0) as u8, (c.b * 255.0) as u8, 110];
|
||||
let solid = |x: i32, z: i32| map.get(x, z).map_or(false, |t| t.solid());
|
||||
let mut mb = MB::new();
|
||||
if let Some((x0, z0, x1, z1)) = ov.rect {
|
||||
let (ax, bx) = (x0.min(x1), x0.max(x1));
|
||||
let (az, bz) = (z0.min(z1), z0.max(z1));
|
||||
let y = if ov.high { WALL_H + 0.14 } else { 0.04 };
|
||||
let mut boxes = 0;
|
||||
if ov.high {
|
||||
'outer: for z in az..=bz {
|
||||
for x in ax..=bx {
|
||||
if map.get(x, z).map_or(false, |t| t.diggable()) {
|
||||
if boxes >= MAX_BOXES {
|
||||
break 'outer;
|
||||
}
|
||||
block_box(&mut mb, map, x, z, fill, line, 0.08, 0.6);
|
||||
boxes += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let y = if ov.high { WALL_H + 0.18 } else { 0.04 };
|
||||
outline(ax as f32, az as f32, bx as f32 + 1.0, bz as f32 + 1.0, y, ov.color);
|
||||
} else if let Some((x, z)) = ov.hover {
|
||||
outline(x as f32, z as f32, x as f32 + 1.0, z as f32 + 1.0, y_of(x, z), ov.color);
|
||||
if solid(x, z) {
|
||||
block_box(&mut mb, map, x, z, fill, line, 0.08, 0.6);
|
||||
} else {
|
||||
outline(x as f32, z as f32, x as f32 + 1.0, z as f32 + 1.0, 0.04, ov.color);
|
||||
}
|
||||
}
|
||||
if let Some(m) = mb.into_plain_mesh() {
|
||||
draw_mesh(&m);
|
||||
}
|
||||
if let Some((x, z, r)) = ov.radius {
|
||||
ring(vec3(x, 0.05, z), r, ov.color);
|
||||
|
||||
Reference in new issue
Block a user