proof-engine 0.2.3

Real-time graphics from math: glyphs and particles moved by ODEs, strange attractors and force fields, drawn with HDR bloom on OpenGL.
Documentation

// ── Item Socket & Gem Extensions ──────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct GemCombination {
    pub gem_ids: Vec<u32>,
    pub result_gem_id: u32,
    pub result_quantity: u32,
    pub name: String,
}

impl GemCombination {
    pub fn new(result_gem_id: u32, result_quantity: u32, name: impl Into<String>) -> Self {
        Self { gem_ids: Vec::new(), result_gem_id, result_quantity, name: name.into() }
    }
    pub fn requires(mut self, gem_id: u32) -> Self { self.gem_ids.push(gem_id); self }
    pub fn ingredient_count(&self) -> usize { self.gem_ids.len() }
    pub fn produces_multiple(&self) -> bool { self.result_quantity > 1 }
}

#[derive(Clone, Debug)]
pub struct GemCombinationRegistry {
    pub combinations: Vec<GemCombination>,
}

impl GemCombinationRegistry {
    pub fn new() -> Self { Self { combinations: Vec::new() } }
    pub fn register(&mut self, combo: GemCombination) { self.combinations.push(combo); }
    pub fn find_for_gems(&self, gem_ids: &[u32]) -> Option<&GemCombination> {
        self.combinations.iter().find(|c| c.gem_ids.iter().all(|g| gem_ids.contains(g)) && c.gem_ids.len() == gem_ids.len())
    }
    pub fn total(&self) -> usize { self.combinations.len() }
}

impl Default for GemCombinationRegistry {
    fn default() -> Self { Self::new() }
}

// ── Loot System Health Check ──────────────────────────────────────────────────

pub struct LootSystemHealth {
    pub tables_ok: bool,
    pub pools_ok: bool,
    pub items_ok: bool,
    pub rng_ok: bool,
    pub warnings: Vec<String>,
    pub errors: Vec<String>,
}

impl LootSystemHealth {
    pub fn new() -> Self { Self { tables_ok: true, pools_ok: true, items_ok: true, rng_ok: true, warnings: Vec::new(), errors: Vec::new() } }
    pub fn add_warning(&mut self, w: impl Into<String>) { self.warnings.push(w.into()); }
    pub fn add_error(&mut self, e: impl Into<String>) { self.errors.push(e.into()); self.tables_ok = false; }
    pub fn is_healthy(&self) -> bool { self.errors.is_empty() }
    pub fn summary(&self) -> String {
        if self.is_healthy() { format!("OK ({} warnings)", self.warnings.len()) }
        else { format!("ERRORS: {} errors, {} warnings", self.errors.len(), self.warnings.len()) }
    }
}

impl Default for LootSystemHealth {
    fn default() -> Self { Self::new() }
}

pub const LOOT_GEM_COMBINE_MAX_INGREDIENTS: usize = 4;
pub const LOOT_SYSTEM_VERSION: &str = "3.2.1";
pub const LOOT_MAX_TOTAL_ITEMS: u32 = 100_000;
pub const LOOT_HEALTH_CHECK_INTERVAL_SECS: f32 = 60.0;

pub fn loot_system_health_check() -> LootSystemHealth {
    let mut health = LootSystemHealth::new();
    health.rng_ok = true;
    health
}