Files
Verbatim/src/world/material.rs
T
Emil 68f6292c4d feat: Verbatim MVP - terminal renderer, cellular automaton, Verlet physics
- World: 250x250 grid with 14 materials (sand, water, lava, stone, wood, etc.)
- Physics: cellular automaton for materials + Verlet solver for entities
- Entity: multi-cell humanoid (7 sub-bodies with distance constraints)
- Render: terminal renderer with ANSI colors and diff-based updates
- Game loop: fixed 60Hz timestep with accumulator pattern
- Input: WASD movement, number keys for material painting
2026-06-20 18:21:26 +03:00

287 lines
9.6 KiB
Rust

use crate::world::cell::MaterialId;
#[derive(Clone, Copy, Debug)]
pub struct Material {
pub id: MaterialId,
pub name: &'static str,
pub density: f32,
pub solid: bool,
pub liquid: bool,
pub gas: bool,
pub static_: bool,
pub flammable: bool,
pub ignition_temp: f32,
pub melt_temp: f32,
pub heat_conductivity: f32,
pub color_fg: (u8, u8, u8),
pub color_bg: (u8, u8, u8),
pub display_char: char,
}
impl Material {
pub const fn empty() -> Self {
Self {
id: MaterialId::Empty,
name: "empty",
density: 0.0,
solid: false,
liquid: false,
gas: false,
static_: true,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.0,
color_fg: (0, 0, 0),
color_bg: (0, 0, 0),
display_char: ' ',
}
}
}
pub struct MaterialRegistry {
materials: [Material; 14],
}
impl MaterialRegistry {
fn new() -> Self {
Self {
materials: [
Material {
id: MaterialId::Empty,
name: "empty",
density: 0.0,
solid: false,
liquid: false,
gas: false,
static_: true,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.0,
color_fg: (15, 15, 20),
color_bg: (10, 10, 15),
display_char: ' ',
},
Material {
id: MaterialId::Sand,
name: "sand",
density: 1.5,
solid: true,
liquid: false,
gas: false,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: 1700.0,
heat_conductivity: 0.2,
color_fg: (218, 178, 90),
color_bg: (60, 50, 30),
display_char: '.',
},
Material {
id: MaterialId::Water,
name: "water",
density: 1.0,
solid: false,
liquid: true,
gas: false,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: 0.0,
heat_conductivity: 0.4,
color_fg: (64, 128, 220),
color_bg: (20, 40, 80),
display_char: '~',
},
Material {
id: MaterialId::Stone,
name: "stone",
density: 3.0,
solid: true,
liquid: false,
gas: false,
static_: true,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: 1200.0,
heat_conductivity: 0.3,
color_fg: (120, 120, 130),
color_bg: (40, 40, 50),
display_char: '#',
},
Material {
id: MaterialId::Lava,
name: "lava",
density: 2.5,
solid: false,
liquid: true,
gas: false,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.5,
color_fg: (255, 80, 20),
color_bg: (120, 20, 0),
display_char: '#',
},
Material {
id: MaterialId::Wood,
name: "wood",
density: 0.8,
solid: true,
liquid: false,
gas: false,
static_: true,
flammable: true,
ignition_temp: 300.0,
melt_temp: f32::INFINITY,
heat_conductivity: 0.1,
color_fg: (140, 90, 50),
color_bg: (50, 30, 20),
display_char: 'T',
},
Material {
id: MaterialId::Flesh,
name: "flesh",
density: 1.06,
solid: true,
liquid: false,
gas: false,
static_: false,
flammable: true,
ignition_temp: 200.0,
melt_temp: f32::INFINITY,
heat_conductivity: 0.15,
color_fg: (180, 50, 50),
color_bg: (60, 15, 15),
display_char: '%',
},
Material {
id: MaterialId::Bone,
name: "bone",
density: 1.8,
solid: true,
liquid: false,
gas: false,
static_: true,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.1,
color_fg: (220, 210, 190),
color_bg: (60, 55, 50),
display_char: '`',
},
Material {
id: MaterialId::Steam,
name: "steam",
density: 0.3,
solid: false,
liquid: false,
gas: true,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.2,
color_fg: (200, 200, 220),
color_bg: (30, 30, 40),
display_char: '~',
},
Material {
id: MaterialId::Fire,
name: "fire",
density: 0.1,
solid: false,
liquid: false,
gas: true,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.6,
color_fg: (255, 160, 40),
color_bg: (100, 30, 0),
display_char: '^',
},
Material {
id: MaterialId::Acid,
name: "acid",
density: 1.2,
solid: false,
liquid: true,
gas: false,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.3,
color_fg: (100, 255, 60),
color_bg: (20, 60, 10),
display_char: '~',
},
Material {
id: MaterialId::Smoke,
name: "smoke",
density: 0.2,
solid: false,
liquid: false,
gas: true,
static_: false,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.1,
color_fg: (100, 100, 100),
color_bg: (20, 20, 20),
display_char: '*',
},
Material {
id: MaterialId::Grass,
name: "grass",
density: 1.0,
solid: true,
liquid: false,
gas: false,
static_: true,
flammable: true,
ignition_temp: 250.0,
melt_temp: f32::INFINITY,
heat_conductivity: 0.1,
color_fg: (80, 200, 60),
color_bg: (20, 50, 15),
display_char: '"',
},
Material {
id: MaterialId::Dirt,
name: "dirt",
density: 1.3,
solid: true,
liquid: false,
gas: false,
static_: true,
flammable: false,
ignition_temp: f32::INFINITY,
melt_temp: f32::INFINITY,
heat_conductivity: 0.2,
color_fg: (100, 70, 50),
color_bg: (40, 30, 20),
display_char: ':',
},
],
}
}
pub fn get(&self, id: MaterialId) -> &Material {
&self.materials[id as usize]
}
pub fn instance() -> &'static MaterialRegistry {
static REGISTRY: std::sync::OnceLock<MaterialRegistry> = std::sync::OnceLock::new();
REGISTRY.get_or_init(MaterialRegistry::new)
}
}