Rank badges and level equipment; no edge scrolling before the mouse has moved
- Military rank badges instead of level numbers: Lv 2-4 bronze chevrons, Lv 5-7 silver bars, Lv 8-9 gold stars, Lv 10 gold star in a wreath; rank names in the unit info (EN/DE) - Equipment grows with the level: shoulder pieces (bronze/silver/gold), helmets with horns (creatures) or plumes (heroes), capes from Lv 7, glowing ring from Lv 9, aura at Lv 10 - Fix: before the first mouse move the pointer counts as (0, 0) and the edge scrolling moved the camera at the start and after loading a savegame Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
52d49b0243
commit
729dd4fe4c
6 files changed
+170
-5
No files matched your search
+79
-3
@@ -1020,6 +1020,7 @@ impl R3d {
|
||||
}
|
||||
draw_landmarks_solid(g, t);
|
||||
draw_towers_solid(g);
|
||||
draw_gear(g, cam);
|
||||
crate::props::draw_props_solid(g, cam, t);
|
||||
|
||||
// ---- unlit glow / overlays
|
||||
@@ -1052,6 +1053,7 @@ impl R3d {
|
||||
// translucent glows and effects last (they write depth, see glow_material)
|
||||
draw_landmarks_glow(g, t);
|
||||
draw_towers_glow(g, t);
|
||||
draw_gear_glow(g, cam, t);
|
||||
crate::props::draw_props_glow(g, cam, t);
|
||||
for f in &g.fx {
|
||||
draw_fx(f, t);
|
||||
@@ -1176,9 +1178,11 @@ impl R3d {
|
||||
if e.guard {
|
||||
gfx.glyph(0x0F, head.x - (GW * small * 0.5).floor(), head.y - 2.0 * GH * small, small, Color::from_rgba(255, 220, 90, 255));
|
||||
}
|
||||
if e.level > 1 && px_per_tile >= 24.0 * F() as f32 {
|
||||
let x = head.x - (cols as f32 * cw * 0.5).floor() - 2.0 * cw;
|
||||
gfx.text_sh(&e.level.to_string(), x, head.y - GH * small, small, Color::from_rgba(255, 220, 90, 255));
|
||||
// rank badge left of the health bar
|
||||
if e.level > 1 && px_per_tile >= 20.0 * F() as f32 {
|
||||
let k = 2.0 * F() as f32;
|
||||
let x = head.x - (cols as f32 * cw * 0.5).floor() - 12.0 * k;
|
||||
gfx.badge(x, head.y - GH * small - 4.0 * k, e.level, k);
|
||||
}
|
||||
if matches!(e.job, Job::Sleep(_)) && !e.moving {
|
||||
let k = (t * 1.5 + e.anim) % 1.0;
|
||||
@@ -1216,6 +1220,78 @@ fn shade_c(r: u8, g: u8, b: u8, f: f32) -> Color {
|
||||
Color::new(r as f32 / 255.0 * f, g as f32 / 255.0 * f, b as f32 / 255.0 * f, 1.0)
|
||||
}
|
||||
|
||||
// size of a unit's sprite (same as in the billboards)
|
||||
fn sprite_size(k: EK) -> f32 {
|
||||
if k == EK::Chainbreaker {
|
||||
1.0
|
||||
} else if matches!(k, EK::Ogre | EK::Paladin | EK::Jailer) {
|
||||
0.8
|
||||
} else {
|
||||
0.62
|
||||
}
|
||||
}
|
||||
|
||||
fn gear_shown(e: &Ent) -> bool {
|
||||
e.alive && !e.held && e.captive == 0 && e.level >= 3 && !(matches!(e.job, Job::Sleep(_)) && !e.moving)
|
||||
}
|
||||
|
||||
// Equipment that grows with the level: shoulder pieces (Lv 3+: bronze, 5+: silver, 8+: gold),
|
||||
// a helmet (Lv 5+: horns for creatures, a plume for heroes) and a cape (Lv 7+).
|
||||
fn draw_gear(g: &Game, cam: &Cam) {
|
||||
let (_, r, _) = cam.basis();
|
||||
let toward = cam.eye_dir();
|
||||
for e in g.ents.iter().filter(|e| gear_shown(e)) {
|
||||
let w = sprite_size(e.kind);
|
||||
let bob = if e.moving { (e.anim * 12.0).sin().abs() * 0.06 } else { 0.0 };
|
||||
let base = vec3(e.x, bob, e.y) + toward * 0.5;
|
||||
let at = |dx: f32, dy: f32| base + r * (dx * w) + Vec3::Y * (dy * w);
|
||||
let metal = if e.level >= 8 {
|
||||
Color::from_rgba(240, 200, 70, 255)
|
||||
} else if e.level >= 5 {
|
||||
Color::from_rgba(200, 206, 220, 255)
|
||||
} else {
|
||||
Color::from_rgba(190, 120, 60, 255)
|
||||
};
|
||||
if e.level >= 7 {
|
||||
// cape behind the figure
|
||||
let back = base - toward * 0.1;
|
||||
draw_cube(back + Vec3::Y * (0.5 * w), vec3(0.42 * w, 0.55 * w, 0.42 * w), None, if e.hero { Color::from_rgba(40, 70, 150, 255) } else { Color::from_rgba(120, 20, 30, 255) });
|
||||
}
|
||||
for side in [-1.0f32, 1.0] {
|
||||
draw_cube(at(side * 0.26, 0.6), Vec3::splat(0.09 * w + 0.02), None, metal);
|
||||
}
|
||||
if e.level >= 5 {
|
||||
draw_cube(at(0.0, 0.93), vec3(0.2 * w, 0.06 * w, 0.2 * w), None, metal);
|
||||
if e.hero {
|
||||
draw_cube(at(0.0, 1.02), vec3(0.04, 0.1 * w, 0.04), None, Color::from_rgba(200, 40, 40, 255));
|
||||
} else {
|
||||
for side in [-1.0f32, 1.0] {
|
||||
draw_cube(at(side * 0.16, 1.0), vec3(0.035, 0.09 * w, 0.035), None, Color::from_rgba(230, 220, 200, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lv 9+: a glowing ring above the head, Lv 10 also a faint aura at the feet
|
||||
fn draw_gear_glow(g: &Game, cam: &Cam, t: f32) {
|
||||
let toward = cam.eye_dir();
|
||||
for e in g.ents.iter().filter(|e| gear_shown(e) && e.level >= 9) {
|
||||
let w = sprite_size(e.kind);
|
||||
let base = vec3(e.x, 0.0, e.y) + toward * 0.5;
|
||||
let c = if e.hero { Color::new(0.8, 0.9, 1.0, 0.8) } else { Color::new(1.0, 0.8, 0.3, 0.8) };
|
||||
let y = w * 1.12 + (t * 2.0 + e.anim).sin() * 0.02;
|
||||
for k in 0..8 {
|
||||
let a0 = k as f32 * 0.785 + t;
|
||||
let a1 = a0 + 0.785;
|
||||
line3(base + vec3(a0.cos() * 0.12, y, a0.sin() * 0.12), base + vec3(a1.cos() * 0.12, y, a1.sin() * 0.12), 0.025, c);
|
||||
}
|
||||
if e.level >= 10 {
|
||||
disc(vec3(e.x, 0.015, e.y), 0.42 + 0.03 * (t * 3.0).sin(), Color::new(c.r, c.g, c.b, 0.18), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_towers_solid(g: &Game) {
|
||||
for tw in &g.towers {
|
||||
let (x, z) = tw.pos();
|
||||
|
||||
Reference in new issue
Block a user