khguide/src/common/enemy.rs

92 lines
2.0 KiB
Rust

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<String>,
#[serde(default)]
pub world: Vec<SpawnLocation>,
#[serde(default)]
pub drops: Vec<EnemyDrop>,
}
impl Enemy {
pub fn import(path: &str) -> Vec<Enemy> {
let mut enemies: Vec<Enemy> = 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::<Vec<PathBuf>>();
for path in paths {
let enemy_str = std::fs::read_to_string(path).unwrap();
let mut enemy = toml::from_str::<Enemy>(&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<String>,
pub material: Option<MaterialDetails>,
}
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<f32>),
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<String>,
}