Files
Verbatim/tests/physics_lava.rs
T
Emil e96744b958 feat: rigid living entities, ragdoll corpses, fix WASD movement
- Entity: rigid body mode for alive entities (single object, no wobble)
  - Center position + velocity, bodies positioned from rest offsets
  - Collision: all 16 bodies checked, push applied to center
  - Movement: velocity applied to center, all bodies move together
- Entity: ragdoll mode for corpses (loose Verlet constraints)
  - kill() switches rigid->ragdoll, gives each body inherited velocity
  - Constraints go slack (stiffness=0), bodies fall independently
- Player: move_left/right now applies velocity to entity center (was: head only)
- Physics: lava heat conductivity 0.05 (was 0.5), initial temp 1500 (was 1200)
  Lava cooling threshold 400 (was 800), heat transfer rate 0.1 (was 0.5)
  Lava stays hot long enough for entities to take damage
- Tests: 28/28 passing, updated for new lava and rigid body behavior
2026-06-20 21:39:26 +03:00

60 lines
2.8 KiB
Rust

use verbatim::ai::GameSession;
use verbatim::ai::AiAction;
fn setup_empty() -> GameSession {
let mut s = GameSession::new_seeded(42);
s.init_empty();
s.clear_area(95, 95, 40, 40);
s
}
#[test]
fn lava_flows_down() {
let mut s = setup_empty();
s.perform_action(&AiAction::FillRect { x: 100, y: 115, w: 10, h: 3, material: "stone".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 110, material: "lava".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 111, material: "lava".into() });
s.step(10);
let lava_count = s.count_material_in_region(103, 110, 5, 6, "lava");
let stone_count = s.count_material_in_region(103, 110, 5, 6, "stone");
assert!(lava_count > 0 || stone_count >= 4,
"lava should have flowed down or cooled to stone, lava={} stone={}", lava_count, stone_count);
}
#[test]
fn lava_plus_water_makes_steam() {
let mut s = setup_empty();
s.perform_action(&AiAction::FillRect { x: 100, y: 120, w: 20, h: 1, material: "stone".into() });
s.perform_action(&AiAction::FillRect { x: 100, y: 99, w: 20, h: 1, material: "stone".into() });
s.perform_action(&AiAction::FillRect { x: 102, y: 110, w: 4, h: 3, material: "lava".into() });
s.perform_action(&AiAction::FillRect { x: 108, y: 110, w: 4, h: 3, material: "water".into() });
s.step(40);
let steam_count = s.count_material_in_region(100, 100, 20, 15, "steam");
assert!(steam_count > 0, "lava + water should produce steam, got {} steam cells", steam_count);
}
#[test]
fn lava_ignites_wood() {
let mut s = setup_empty();
s.perform_action(&AiAction::FillRect { x: 100, y: 115, w: 10, h: 1, material: "stone".into() });
s.perform_action(&AiAction::SetCell { x: 104, y: 114, material: "wood".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 114, material: "wood".into() });
s.perform_action(&AiAction::SetCell { x: 106, y: 114, material: "wood".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 113, material: "lava".into() });
s.step(15);
let wood_remaining = s.count_material_in_region(103, 113, 5, 3, "wood");
assert_eq!(wood_remaining, 0, "all wood should have been ignited by lava, got {} wood cells", wood_remaining);
}
#[test]
fn lava_ignites_grass() {
let mut s = setup_empty();
s.perform_action(&AiAction::FillRect { x: 100, y: 115, w: 10, h: 1, material: "stone".into() });
s.perform_action(&AiAction::FillRect { x: 100, y: 114, w: 5, h: 1, material: "grass".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 113, material: "lava".into() });
s.perform_action(&AiAction::SetCell { x: 105, y: 114, material: "lava".into() });
s.step(15);
let grass_remaining = s.count_material_in_region(99, 113, 7, 3, "grass");
assert_eq!(grass_remaining, 0, "grass should have been ignited by lava");
}