feat: Noita-style humanoid entities with per-part colors

Redesigned entity from solid 5x5 block to humanoid silhouette:

Shape (23 bodies, was 27):
     H H H        (head, 3 wide)
     H H H
   A T T T A      (shoulders + arms, 5 wide)
   A T T T A
     T T T        (torso, 3 wide)
     L   R        (legs, split with gap)
     L   R

Per-part colors (Noita-inspired):
- Player: head=bright yellow, torso=golden, arms=amber, legs=dark gold
- Goblin: head=bright green, torso=green, arms=olive, legs=dark green
- Corpse: desaturated browns

SubBody now has color: [u8; 4] field, set by build_humanoid.
All renderers (terminal, ascii, graphics) use b.color directly.
Fire effect: flickering orange overlay on burning entities.

half_w adjusted from 3.5 to 3.0, half_h from 2.5 to 3.5
(taller shape, narrower than old block).

109 tests, 0 failures
This commit is contained in:
Emil
2026-06-21 10:13:22 +03:00
parent 586c25f44c
commit 5cd1a5e197
6 changed files with 283 additions and 101 deletions
+5 -10
View File
@@ -546,18 +546,13 @@ impl GraphicsRenderer {
let sx = b.x as i32 - cam_x;
let sy = b.y as i32 - cam_y;
if sx >= 0 && sx < self.grid_w as i32 && sy >= 0 && sy < self.grid_h as i32 {
let fg = if e.on_fire {
[255, 160, 40, 255]
} else if !e.alive {
[100, 60, 60, 255]
let color = if e.on_fire {
let flicker = b.fire_timer % 4;
[255, 120 + flicker as u8 * 20, 20 + flicker as u8 * 10, 255]
} else {
match e.kind {
EntityKind::Player => [255, 255, 100, 255],
EntityKind::Goblin => [100, 220, 100, 255],
_ => [180, 50, 50, 255],
}
b.color
};
entity_map.insert((sx, sy), fg);
entity_map.insert((sx, sy), color);
}
}
}