use std::{fmt::Display, path::PathBuf}; use serde::Deserialize; #[derive(Debug, Deserialize, PartialEq, Eq)] pub struct EnemyDrop { pub from: String, pub chance: EnemyDropChance, #[serde(default)] pub info: Option, } impl EnemyDrop { pub fn texture(&self) -> String { self.from.replace(" ", "_").to_lowercase() } } #[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum EnemyDropChance { Fixed(u8), Variable(String), } impl Display for EnemyDropChance { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { EnemyDropChance::Fixed(val) => f.write_str(&format!("{val}%")), EnemyDropChance::Variable(val) => f.write_str(val), } } } #[derive(Debug, Default, Deserialize, PartialEq, Eq)] #[serde(default)] pub struct MaterialDrops { pub kind: String, pub shard: Vec, pub stone: Vec, pub gem: Vec, pub crystal: Vec, } impl MaterialDrops { pub fn import(path: &str) -> Vec { let mut drops: Vec = vec![]; // Loading multiple files into one vector due to the size of each board let paths = std::fs::read_dir(path) .unwrap() .filter_map(|f| f.ok()) .map(|f| f.path()) .filter_map(|p| match p.extension().is_some_and(|e| e == "toml") { true => Some(p), false => None, }) .collect::>(); for path in paths { let drops_str = std::fs::read_to_string(path).unwrap(); let enemy_drops = toml::from_str::(&drops_str).unwrap(); drops.push(enemy_drops); } drops.sort_by(|a, b| a.kind.cmp(&b.kind)); drops } pub fn drops(&self, kind: &str) -> &[EnemyDrop] { match kind { "shard" => &self.shard, "stone" => &self.stone, "gem" => &self.gem, "crystal" => &self.crystal, _ => &self.shard, } } }