New system for drop tracking combined into enemy data
parent
904a03733d
commit
d8fd3d7111
|
@ -12,6 +12,7 @@ tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
itertools = "0.14"
|
itertools = "0.14"
|
||||||
blake3 = "1.8"
|
blake3 = "1.8"
|
||||||
|
ordered-float = { version = "5.0", features = ["serde"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["bbs", "ddd", "kh3", "kh2", "kh1"]
|
default = ["bbs", "ddd", "kh3", "kh2", "kh1"]
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
name = "Air Pirate"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Neverland"
|
||||||
|
room = ""
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Mega-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,24 @@
|
||||||
|
name = "Air Soldier"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = ""
|
||||||
|
room = ""
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Spirit Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "spirit"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,18 @@
|
||||||
|
name = "Angel Star"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Gale"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "stormy"
|
||||||
|
kind = "crystal"
|
|
@ -0,0 +1,18 @@
|
||||||
|
name = "Aquatank"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Atlantica"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Mega-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Thunder Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 8
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "thunder"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,24 @@
|
||||||
|
name = "Bandit"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Agrabah"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Blaze Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "blaze"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,20 @@
|
||||||
|
name = "Barrel Spider"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Neverland"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Camping Set"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Cottage"
|
||||||
|
kind = "item"
|
||||||
|
chance = 0.5
|
|
@ -0,0 +1,34 @@
|
||||||
|
name = "Battleship"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Neverland"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Elixir"
|
||||||
|
kind = "item"
|
||||||
|
chance = 0.5
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Elixir"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
info = "Destroy the Stern, Cannons or Mast"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "gem"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 8
|
||||||
|
info = "Destroy the Stern, Cannons or Mast"
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,30 @@
|
||||||
|
name = "Blue Rhapsody"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Wonderland"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Hollow Bastion"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Frost Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 12
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "frost"
|
||||||
|
kind = "shard"
|
|
@ -0,0 +1,43 @@
|
||||||
|
name = "Bouncywild"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Deep Jungle"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 8
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "shard"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 20
|
||||||
|
info = "When it slips on the banana peel"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Mega-Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 4
|
||||||
|
info = "When it slips on the banana peel"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 8
|
||||||
|
info = "When it slips on the banana peel"
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "shard"
|
|
@ -0,0 +1,24 @@
|
||||||
|
name = "Darkball"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Hollow Bastion"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Lucid Crystal"
|
||||||
|
kind = "material"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "lucid"
|
||||||
|
kind = "crystal"
|
|
@ -0,0 +1,29 @@
|
||||||
|
name = "Defender"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Hollow Bastion"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Elixir"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Bright Crystal"
|
||||||
|
kind = "material"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "bright"
|
||||||
|
kind = "crystal"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Defender"
|
||||||
|
kind = "equipment"
|
||||||
|
chance = 0.2
|
|
@ -0,0 +1,24 @@
|
||||||
|
name = "Fat Bandit"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Agrabah"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Blaze Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 8
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "blaze"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,26 @@
|
||||||
|
name = "Gargoyle"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Holloween Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Mega-Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 0.5
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Lucid Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "lucid"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,33 @@
|
||||||
|
name = "Green Requiem"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Agrabah"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Deep Jungle"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Hollow Bastion"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Ether"
|
||||||
|
kind = "item"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Bright Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 10
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "bright"
|
||||||
|
kind = "shard"
|
|
@ -0,0 +1,18 @@
|
||||||
|
name = "Invisible"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Gale"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "stormy"
|
||||||
|
kind = "crystal"
|
|
@ -0,0 +1,34 @@
|
||||||
|
name = "Large Body"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Wonderland"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Agrabah"
|
||||||
|
marked = true
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Hollow Bastion"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Spirit Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 10
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "spirit"
|
||||||
|
kind = "shard"
|
|
@ -0,0 +1,29 @@
|
||||||
|
name = "Pirate"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Neverland"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Monstro"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "End of the World"
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Hi-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 2
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Mega-Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 1
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Power Gem"
|
||||||
|
kind = "material"
|
||||||
|
chance = 4
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "power"
|
||||||
|
kind = "gem"
|
|
@ -0,0 +1,19 @@
|
||||||
|
name = "Shadow"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
room = ""
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Potion"
|
||||||
|
kind = "item"
|
||||||
|
chance = 6
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Lucid Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 3
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "lucid"
|
||||||
|
kind = "shard"
|
|
@ -0,0 +1,14 @@
|
||||||
|
name = "Soldier"
|
||||||
|
|
||||||
|
[[world]]
|
||||||
|
name = "Traverse Town"
|
||||||
|
room = ""
|
||||||
|
|
||||||
|
[[drops]]
|
||||||
|
name = "Spirit Shard"
|
||||||
|
kind = "material"
|
||||||
|
chance = 6
|
||||||
|
|
||||||
|
[drops.material]
|
||||||
|
category = "spirit"
|
||||||
|
kind = "shard"
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod direction;
|
pub mod direction;
|
||||||
|
pub mod enemy;
|
||||||
pub mod materials;
|
pub mod materials;
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
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>,
|
||||||
|
pub world: Vec<SpawnLocation>,
|
||||||
|
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 icon: Option<String>,
|
||||||
|
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>,
|
||||||
|
}
|
|
@ -1,80 +1,100 @@
|
||||||
use std::{fmt::Display, path::PathBuf};
|
use std::{collections::HashMap, fmt::Display};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
use super::enemy::{Enemy, EnemyDrop};
|
||||||
pub struct EnemyDrop {
|
|
||||||
pub from: String,
|
|
||||||
pub chance: EnemyDropChance,
|
|
||||||
|
|
||||||
#[serde(default)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub info: Option<String>,
|
pub struct MaterialDetails {
|
||||||
|
pub category: String,
|
||||||
|
pub kind: MaterialKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnemyDrop {
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub fn texture(&self) -> String {
|
#[serde(rename_all = "lowercase")]
|
||||||
self.from.replace(" ", "_").to_lowercase()
|
pub enum MaterialKind {
|
||||||
}
|
Shard,
|
||||||
|
Stone,
|
||||||
|
Gem,
|
||||||
|
Crystal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
impl Display for MaterialKind {
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum EnemyDropChance {
|
|
||||||
Fixed(u8),
|
|
||||||
Variable(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for EnemyDropChance {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
EnemyDropChance::Fixed(val) => f.write_str(&format!("{val}%")),
|
MaterialKind::Shard => f.write_str("shard"),
|
||||||
EnemyDropChance::Variable(val) => f.write_str(val),
|
MaterialKind::Stone => f.write_str("stone"),
|
||||||
|
MaterialKind::Gem => f.write_str("gem"),
|
||||||
|
MaterialKind::Crystal => f.write_str("crystal"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
#[serde(default)]
|
|
||||||
pub struct MaterialDrops {
|
pub struct MaterialDrops {
|
||||||
pub kind: String,
|
pub name: String,
|
||||||
pub shard: Vec<EnemyDrop>,
|
pub icon: String,
|
||||||
pub stone: Vec<EnemyDrop>,
|
pub category: String,
|
||||||
pub gem: Vec<EnemyDrop>,
|
pub kind: MaterialKind,
|
||||||
pub crystal: Vec<EnemyDrop>,
|
pub drops: Vec<EnemyDrop>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for MaterialDrops {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
if self.category.cmp(&other.category) == std::cmp::Ordering::Equal {
|
||||||
|
return Some(self.kind.cmp(&other.kind));
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(self.category.cmp(&other.category))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaterialDrops {
|
impl MaterialDrops {
|
||||||
pub fn import(path: &str) -> Vec<MaterialDrops> {
|
pub fn new(enemies: Vec<Enemy>) -> Vec<MaterialDrops> {
|
||||||
let mut drops: Vec<MaterialDrops> = vec![];
|
let mut mat_map = HashMap::<(String, MaterialKind), MaterialDrops>::new();
|
||||||
|
|
||||||
// Loading multiple files into one vector due to the size of each board
|
for enemy in enemies {
|
||||||
let paths = std::fs::read_dir(path)
|
for drop in &enemy.drops {
|
||||||
.unwrap()
|
let Some(material) = &drop.material else {
|
||||||
.filter_map(|f| f.ok())
|
continue;
|
||||||
.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 key = (material.category.clone(), material.kind.clone());
|
||||||
let drops_str = std::fs::read_to_string(path).unwrap();
|
|
||||||
let enemy_drops = toml::from_str::<MaterialDrops>(&drops_str).unwrap();
|
mat_map
|
||||||
drops.push(enemy_drops);
|
.entry(key)
|
||||||
|
.and_modify(|d| d.drops.push(drop.clone()))
|
||||||
|
.or_insert(MaterialDrops {
|
||||||
|
name: drop.name.to_string(),
|
||||||
|
icon: "".to_string(),
|
||||||
|
category: material.category.clone(),
|
||||||
|
kind: material.kind.clone(),
|
||||||
|
drops: vec![drop.clone()],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drops.sort_by(|a, b| a.kind.cmp(&b.kind));
|
|
||||||
|
|
||||||
drops
|
let mut values: Vec<MaterialDrops> = mat_map.into_values().collect();
|
||||||
|
|
||||||
|
values.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||||
|
|
||||||
|
values
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drops(&self, kind: &str) -> &[EnemyDrop] {
|
pub fn drops(&self, kind: &str) -> Vec<&EnemyDrop> {
|
||||||
match kind {
|
match kind {
|
||||||
"shard" => &self.shard,
|
"shard" => self.get_drop_kind(MaterialKind::Shard),
|
||||||
"stone" => &self.stone,
|
"stone" => self.get_drop_kind(MaterialKind::Stone),
|
||||||
"gem" => &self.gem,
|
"gem" => self.get_drop_kind(MaterialKind::Gem),
|
||||||
"crystal" => &self.crystal,
|
"crystal" => self.get_drop_kind(MaterialKind::Crystal),
|
||||||
_ => &self.shard,
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_drop_kind(&self, kind: MaterialKind) -> Vec<&EnemyDrop> {
|
||||||
|
self.drops
|
||||||
|
.iter()
|
||||||
|
.filter(|d| d.material.as_ref().map(|m| m.kind == kind).unwrap_or(false))
|
||||||
|
.collect::<Vec<&EnemyDrop>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/kh1.rs
12
src/kh1.rs
|
@ -3,13 +3,18 @@ use std::sync::OnceLock;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use blake3::Hash;
|
use blake3::Hash;
|
||||||
|
|
||||||
use crate::{RuntimeModule, common::materials::MaterialDrops, create_file, create_hashes};
|
use crate::{
|
||||||
|
RuntimeModule,
|
||||||
|
common::{enemy::Enemy, materials::MaterialDrops},
|
||||||
|
create_file, create_hashes,
|
||||||
|
};
|
||||||
|
|
||||||
const MATERIAL_KINDS: &[&str] = &[
|
const MATERIAL_KINDS: &[&str] = &[
|
||||||
"lucid", "spirit", "power", "blaze", "frost", "thunder", "shiny", "bright", "mystery", "gale",
|
"lucid", "spirit", "power", "blaze", "frost", "thunder", "shiny", "bright", "mystery", "gale",
|
||||||
"mythril",
|
"mythril",
|
||||||
];
|
];
|
||||||
const DROPS_PATH: &str = "./input/kh1/drops";
|
const DROPS_PATH: &str = "./input/kh1/drops";
|
||||||
|
const ENEMIES_PATH: &str = "./input/kh1/enemies";
|
||||||
static JS_HASH: OnceLock<Hash> = OnceLock::new();
|
static JS_HASH: OnceLock<Hash> = OnceLock::new();
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
|
@ -22,8 +27,11 @@ pub struct Module;
|
||||||
|
|
||||||
impl RuntimeModule for Module {
|
impl RuntimeModule for Module {
|
||||||
fn start_module() {
|
fn start_module() {
|
||||||
|
tracing::info!("Loading enemy data from {}", ENEMIES_PATH);
|
||||||
|
let enemies = Enemy::import(ENEMIES_PATH);
|
||||||
|
|
||||||
tracing::info!("Loading enemy drops data from {}", DROPS_PATH);
|
tracing::info!("Loading enemy drops data from {}", DROPS_PATH);
|
||||||
let drops = MaterialDrops::import(DROPS_PATH);
|
let drops = MaterialDrops::new(enemies);
|
||||||
|
|
||||||
tracing::info!("Generating the KH1 drops template");
|
tracing::info!("Generating the KH1 drops template");
|
||||||
let drops_template = DropsTemplate { drops };
|
let drops_template = DropsTemplate { drops };
|
||||||
|
|
|
@ -33,12 +33,12 @@ pub struct Module;
|
||||||
impl RuntimeModule for Module {
|
impl RuntimeModule for Module {
|
||||||
fn start_module() {
|
fn start_module() {
|
||||||
tracing::info!("Loading enemy drops data from {}", DROPS_PATH);
|
tracing::info!("Loading enemy drops data from {}", DROPS_PATH);
|
||||||
let drops = MaterialDrops::import(DROPS_PATH);
|
// let drops = MaterialDrops::import(DROPS_PATH);
|
||||||
|
|
||||||
tracing::info!("Generating the KH2 drops template");
|
tracing::info!("Generating the KH2 drops template");
|
||||||
let drops_template = DropsTemplate { drops };
|
// let drops_template = DropsTemplate { drops };
|
||||||
|
|
||||||
create_file("./out/kh2", "drops", drops_template.render().unwrap()).unwrap();
|
// create_file("./out/kh2", "drops", drops_template.render().unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_js_hash() -> String {
|
fn get_js_hash() -> String {
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
{% macro drop(label) %}
|
{% macro drop(label) %}
|
||||||
{% let drops = category.drops(label) %}
|
{% let drops = drop.drops(label) %}
|
||||||
{% if drops.len() > 0 %}
|
{% if drops.len() > 0 %}
|
||||||
<div
|
<div
|
||||||
class="category-wrapper"
|
class="category-wrapper"
|
||||||
data-mat-kind="{{ category.kind }}"
|
data-mat-kind="{{ drop.category }}"
|
||||||
data-mat-type="{{ label }}"
|
data-mat-type="{{ label }}"
|
||||||
>
|
>
|
||||||
<div class="category">
|
<div class="category">
|
||||||
<img
|
<img
|
||||||
src="../public/assets/materials/{{ category.kind }}/{{ label }}.webp"
|
src="../public/assets/materials/{{ drop.category }}/{{ label }}.webp"
|
||||||
width="64"
|
width="64"
|
||||||
height="64"
|
height="64"
|
||||||
/>
|
/>
|
||||||
<h1>{{ category.kind|capitalize +}} {{+ label|capitalize }}</h1>
|
<!-- <h1> -->
|
||||||
|
<!-- {{ drop.category|capitalize +}} {{+ label|capitalize }} -->
|
||||||
|
<!-- </h1> -->
|
||||||
|
<h1>{{ drop.name }}</h1>
|
||||||
<button onclick="track(this)">Start tracking</button>
|
<button onclick="track(this)">Start tracking</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="enemies">
|
<div class="enemies">
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
{% include "components/common/kind-filters.html" %}
|
{% include "components/common/kind-filters.html" %}
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
{% for category in drops %}
|
{% for drop in drops %}
|
||||||
{% call macros::drop("shard") %}
|
{% call macros::drop("shard") %}
|
||||||
{% call macros::drop("stone") %}
|
{% call macros::drop("stone") %}
|
||||||
{% call macros::drop("gem") %}
|
{% call macros::drop("gem") %}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
{% include "components/common/kind-filters.html" %}
|
{% include "components/common/kind-filters.html" %}
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
{% for category in drops %}
|
{% for drop in drops %}
|
||||||
{% call macros::drop("shard") %}
|
{% call macros::drop("shard") %}
|
||||||
{% call macros::drop("stone") %}
|
{% call macros::drop("stone") %}
|
||||||
{% call macros::drop("gem") %}
|
{% call macros::drop("gem") %}
|
||||||
|
|
Loading…
Reference in New Issue