pub mod formation;
pub mod cohesion;
pub mod ai;
use crate::glyph::GlyphId;
use crate::math::ForceField;
use glam::{Vec3, Vec4};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EntityId(pub u32);
#[derive(Clone)]
pub struct AmorphousEntity {
pub name: String,
pub position: Vec3,
pub binding_field: ForceField,
pub glyph_ids: Vec<GlyphId>,
pub formation: Vec<Vec3>,
pub formation_chars: Vec<char>,
pub formation_colors: Vec<Vec4>,
pub hp: f32,
pub max_hp: f32,
pub entity_mass: f32,
pub entity_temperature: f32,
pub entity_entropy: f32,
pub cohesion: f32,
pub pulse_rate: f32, pub pulse_depth: f32,
pub age: f32,
pub tags: Vec<String>,
pub despawn_requested: bool,
}
impl AmorphousEntity {
pub fn new(name: impl Into<String>, position: Vec3) -> Self {
Self {
name: name.into(),
position,
binding_field: ForceField::Gravity {
center: position,
strength: 5.0,
falloff: crate::math::Falloff::InverseSquare,
},
glyph_ids: Vec::new(),
formation: Vec::new(),
formation_chars: Vec::new(),
formation_colors: Vec::new(),
hp: 100.0,
max_hp: 100.0,
entity_mass: 10.0,
entity_temperature: 0.5,
entity_entropy: 0.1,
cohesion: 1.0,
pulse_rate: 1.0,
pulse_depth: 0.05,
age: 0.0,
tags: Vec::new(),
despawn_requested: false,
}
}
pub fn hp_frac(&self) -> f32 {
(self.hp / self.max_hp.max(0.001)).clamp(0.0, 1.0)
}
pub fn update_cohesion(&mut self) {
self.cohesion = self.hp_frac().sqrt();
}
pub fn tick(&mut self, dt: f32, _time: f32) -> bool {
self.age += dt;
self.update_cohesion();
self.hp <= 0.0
}
pub fn take_damage(&mut self, amount: f32) {
self.hp = (self.hp - amount).max(0.0);
}
pub fn is_dead(&self) -> bool { self.hp <= 0.0 }
}
impl Default for AmorphousEntity {
fn default() -> Self { Self::new("", Vec3::ZERO) }
}