Files
Verbatim/tests/body_template.rs
Emil e287b0d22a feat: larger detailed entities — 47 parts, hats, belts, ears
Entities are now ~3x larger and more detailed:

Player (47 parts, was 15):
  - Hat: 3 top + 2 brim (dark purple)
  - Head: 3x2 face (lavender skin)
  - Belt: golden accent across torso
  - Shirt: 3x2 torso + arms out to 3 cells each side
  - Hands: 4 cells (2 per arm, pale lavender)
  - Pants: 3 wide hips + 5 wide legs + split
  - Boots: 3 cells + 2 foot tips (dark purple)
  - half_w=4, half_h=6 (was 2.5x3.5)

Goblin (41 parts):
  - Pointed ears (2 cells)
  - Ragged shirt (green, darker shade)
  - Bare feet (green skin, no boots)
  - Loincloth (dark green)

Auto-constraints: all parts connected to all others (n^2)
  - Simplified from manual constraint lists
  - Works for any template shape
  - Ragdoll will look natural — all parts hold together

macro_rules! p! for compact part definitions
117 tests, 0 failures
2026-06-21 10:34:28 +03:00

129 lines
3.4 KiB
Rust

use verbatim::entity::body_template::{BodyPart, BodyTemplate};
#[test]
fn player_template_has_correct_shape() {
let t = BodyTemplate::humanoid_player();
assert_eq!(t.name, "player");
assert!(
t.parts.len() >= 30,
"player should have 30+ parts, got {}",
t.parts.len()
);
assert_eq!(t.half_w, 4.0);
assert_eq!(t.half_h, 6.0);
}
#[test]
fn goblin_template_has_correct_shape() {
let t = BodyTemplate::humanoid_goblin();
assert_eq!(t.name, "goblin");
assert!(
t.parts.len() >= 30,
"goblin should have 30+ parts, got {}",
t.parts.len()
);
}
#[test]
fn boulder_template_has_correct_shape() {
let t = BodyTemplate::boulder();
assert_eq!(t.name, "boulder");
assert_eq!(t.parts.len(), 16);
assert!(t.parts.iter().all(|p| p.label == "rock"));
}
#[test]
fn template_json_roundtrip() {
let t = BodyTemplate::humanoid_player();
let json = t.to_json();
let t2 = BodyTemplate::from_json(&json).expect("parse");
assert_eq!(t2.name, t.name);
assert_eq!(t2.parts.len(), t.parts.len());
assert_eq!(t2.half_w, t.half_w);
assert_eq!(t2.half_h, t.half_h);
}
#[test]
fn preview_ascii_not_empty() {
let t = BodyTemplate::humanoid_player();
let preview = t.preview_ascii();
assert!(!preview.is_empty());
assert!(preview.contains("O"));
}
#[test]
fn custom_template_works() {
let t = BodyTemplate {
name: "snake".to_string(),
half_w: 3.0,
half_h: 0.5,
radius: 0.5,
parts: vec![
BodyPart {
x: -3.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: -2.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: -1.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: 0.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: 1.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: 2.0,
y: 0.0,
color: [100, 200, 50, 255],
label: "body".into(),
},
BodyPart {
x: 3.0,
y: 0.0,
color: [80, 180, 40, 255],
label: "head".into(),
},
],
constraints: vec![(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)],
};
assert_eq!(t.parts.len(), 7);
let json = t.to_json();
let t2 = BodyTemplate::from_json(&json).expect("parse");
assert_eq!(t2.parts.len(), 7);
assert_eq!(t2.name, "snake");
}
#[test]
fn template_apply_to_entity() {
use verbatim::entity::entity::{Entity, EntityKind};
let mut e = Entity::new(0, EntityKind::Goblin);
let t = BodyTemplate::humanoid_goblin();
t.apply_to(&mut e, 100.0, 100.0);
assert!(
e.bodies.len() >= 30,
"goblin should have 30+ bodies, got {}",
e.bodies.len()
);
assert_eq!(e.cx, 100.0);
assert_eq!(e.cy, 100.0);
assert!(!e.constraints.is_empty());
}