use std::{fmt::Display, path::PathBuf}; use serde::Deserialize; use super::materials::MaterialDetails; #[derive(Debug, Deserialize, PartialEq, Eq)] pub struct Enemy { pub name: String, pub icon: Option, #[serde(default)] pub world: Vec, #[serde(default)] pub drops: Vec, } impl Enemy { pub fn import(path: &str) -> Vec { let mut enemies: 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 enemy_str = std::fs::read_to_string(path).unwrap(); let mut enemy = toml::from_str::(&enemy_str).unwrap(); enemy .drops .iter_mut() .for_each(|d| d.from = enemy.name.clone()); enemies.push(enemy); } enemies } } #[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct EnemyDrop { pub name: String, #[serde(skip)] pub from: String, pub chance: EnemyDropChance, pub kind: EnemyDropKind, pub info: Option, pub material: Option, } impl EnemyDrop { pub fn texture(&self) -> String { self.from.replace(" ", "_").to_lowercase() } } #[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "lowercase")] pub enum EnemyDropKind { Item, Material, Equipment, } #[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(untagged)] pub enum EnemyDropChance { Fixed(ordered_float::OrderedFloat), 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, Deserialize, PartialEq, Eq)] pub struct SpawnLocation { pub name: String, pub room: Option, }