Added mythril and generic icons + better texture pathing for materials

master
Wynd 2025-06-28 00:47:43 +03:00
parent 68da7ae3fb
commit 65e0880851
11 changed files with 167 additions and 14 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1,3 +1,14 @@
use serde::Deserialize;
pub mod direction; pub mod direction;
pub mod enemy; pub mod enemy;
pub mod materials; pub mod materials;
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Game {
Kh1,
Kh2,
Kh3,
Bbs,
Ddd,
}

View File

@ -1,16 +1,130 @@
use std::{collections::HashMap, fmt::Display}; use std::{collections::HashMap, fmt::Display, fs, path};
use serde::Deserialize; use serde::Deserialize;
use super::enemy::{Enemy, EnemyDrop}; use crate::ASSETS_FOLDER_PATH;
use super::{
Game,
enemy::{Enemy, EnemyDrop},
};
pub const GENERIC_MATERIAL_ICON: &str = "generic";
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct MaterialDetails { pub struct MaterialDetails {
pub category: String, pub category: MaterialCategory,
pub kind: MaterialKind, pub kind: MaterialKind,
} }
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(rename_all = "lowercase")]
pub enum MaterialCategory {
// Common
#[serde(alias = "blaze")]
Blazing,
#[serde(alias = "soothing")]
Bright,
#[serde(alias = "betwixt")]
Dense,
#[serde(alias = "writhing")]
Dark,
#[serde(alias = "wellspring")]
Energy,
Frost,
#[serde(alias = "thunder")]
Lightning,
Lucid,
Mythril,
Power,
#[serde(alias = "shiny")]
Shimmering,
#[serde(alias = "mystery", alias = "hungry")]
Serenity,
Twilight,
// KH1 Only
Spirit,
Stormy,
// KH2 Only
Remembrance,
}
impl MaterialCategory {
pub fn get_texture_group(&self) -> String {
match self {
MaterialCategory::Blazing => "blazing".to_string(),
MaterialCategory::Bright => "bright".to_string(),
MaterialCategory::Dense => "dense".to_string(),
MaterialCategory::Dark => "dark".to_string(),
MaterialCategory::Energy => "energy".to_string(),
MaterialCategory::Frost => "frost".to_string(),
MaterialCategory::Lightning => "lightning".to_string(),
MaterialCategory::Lucid => "lucid".to_string(),
MaterialCategory::Mythril => "mythril".to_string(),
MaterialCategory::Power => "power".to_string(),
MaterialCategory::Shimmering => "shimmering".to_string(),
MaterialCategory::Serenity => "serenity".to_string(),
MaterialCategory::Twilight => "twilight".to_string(),
MaterialCategory::Spirit => "spirit".to_string(),
MaterialCategory::Stormy => "stormy".to_string(),
MaterialCategory::Remembrance => "remembrance".to_string(),
}
}
pub fn get_category(&self, game: &Game) -> String {
match self {
MaterialCategory::Blazing => match game {
Game::Kh1 => "blaze".to_string(),
_ => "blazing".to_string(),
},
MaterialCategory::Bright => match game {
Game::Kh1 | Game::Kh2 => "bright".to_string(),
_ => "soothing".to_string(),
},
MaterialCategory::Dense => match game {
Game::Kh2 => "dense".to_string(),
_ => "betwixt".to_string(),
},
MaterialCategory::Dark => match game {
Game::Kh2 => "dark".to_string(),
_ => "writhing".to_string(),
},
MaterialCategory::Energy => match game {
Game::Kh1 | Game::Kh2 => "energy".to_string(),
_ => "wellspring".to_string(),
},
MaterialCategory::Frost => "frost".to_string(),
MaterialCategory::Lightning => match game {
Game::Kh1 => "thunder".to_string(),
_ => "lightning".to_string(),
},
MaterialCategory::Lucid => "lucid".to_string(),
MaterialCategory::Mythril => "mythril".to_string(),
MaterialCategory::Power => "power".to_string(),
MaterialCategory::Shimmering => match game {
Game::Kh1 => "shiny".to_string(),
_ => "shimmering".to_string(),
},
MaterialCategory::Serenity => match game {
Game::Kh1 => "mystery".to_string(),
Game::Bbs => "hungry".to_string(),
_ => "serenity".to_string(),
},
MaterialCategory::Twilight => "twilight".to_string(),
MaterialCategory::Spirit => "spirit".to_string(),
MaterialCategory::Stormy => "stormy".to_string(),
MaterialCategory::Remembrance => "remembrance".to_string(),
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum MaterialKind { pub enum MaterialKind {
Shard, Shard,
@ -34,7 +148,7 @@ impl Display for MaterialKind {
pub struct MaterialDrops { pub struct MaterialDrops {
pub name: String, pub name: String,
pub icon: String, pub icon: String,
pub category: String, pub category: MaterialCategory,
pub kind: MaterialKind, pub kind: MaterialKind,
pub drops: Vec<EnemyDrop>, pub drops: Vec<EnemyDrop>,
} }
@ -51,7 +165,7 @@ impl PartialOrd for MaterialDrops {
impl MaterialDrops { impl MaterialDrops {
pub fn new(enemies: Vec<Enemy>) -> Vec<MaterialDrops> { pub fn new(enemies: Vec<Enemy>) -> Vec<MaterialDrops> {
let mut mat_map = HashMap::<(String, MaterialKind), MaterialDrops>::new(); let mut mat_map = HashMap::<(MaterialCategory, MaterialKind), MaterialDrops>::new();
for enemy in enemies { for enemy in enemies {
for drop in &enemy.drops { for drop in &enemy.drops {
@ -97,4 +211,23 @@ impl MaterialDrops {
.filter(|d| d.material.as_ref().map(|m| m.kind == kind).unwrap_or(false)) .filter(|d| d.material.as_ref().map(|m| m.kind == kind).unwrap_or(false))
.collect::<Vec<&EnemyDrop>>() .collect::<Vec<&EnemyDrop>>()
} }
pub fn texture(&self, game: &Game) -> String {
if *game == Game::Kh1 {
return GENERIC_MATERIAL_ICON.to_string();
}
let category = self.category.get_category(game);
let kind = self.kind.to_string();
let path = format!(
"{}/materials/{}/{}.webp",
ASSETS_FOLDER_PATH, category, kind
);
let path = path::Path::new(&path);
if path.exists() {
format!("{}/{}", self.category.get_category(game), self.kind)
} else {
GENERIC_MATERIAL_ICON.to_string()
}
}
} }

View File

@ -6,7 +6,7 @@ use itertools::Itertools;
use crate::{ use crate::{
RuntimeModule, RuntimeModule,
common::{enemy::Enemy, materials::MaterialDrops}, common::{Game, enemy::Enemy, materials::MaterialDrops},
create_file, create_hashes, create_file, create_hashes,
}; };
@ -16,6 +16,7 @@ static JS_HASH: OnceLock<Hash> = OnceLock::new();
#[derive(Template)] #[derive(Template)]
#[template(path = "pages/kh1/drops.html")] #[template(path = "pages/kh1/drops.html")]
struct DropsTemplate { struct DropsTemplate {
pub game: Game,
pub drops: Vec<MaterialDrops>, pub drops: Vec<MaterialDrops>,
pub material_kinds: Vec<String>, pub material_kinds: Vec<String>,
} }
@ -28,10 +29,15 @@ impl RuntimeModule for Module {
let enemies = Enemy::import(ENEMIES_PATH); let enemies = Enemy::import(ENEMIES_PATH);
let drops = MaterialDrops::new(enemies); let drops = MaterialDrops::new(enemies);
let material_kinds = drops.iter().map(|d| d.category.clone()).dedup().collect(); let material_kinds = drops
.iter()
.map(|d| d.category.get_category(&Game::Kh1))
.dedup()
.collect();
tracing::info!("Generating the KH1 drops template"); tracing::info!("Generating the KH1 drops template");
let drops_template = DropsTemplate { let drops_template = DropsTemplate {
game: Game::Kh1,
drops, drops,
material_kinds, material_kinds,
}; };

View File

@ -3,7 +3,11 @@ 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::{Game, materials::MaterialDrops},
create_file, create_hashes,
};
const MATERIAL_KINDS: &[&str] = &[ const MATERIAL_KINDS: &[&str] = &[
"blazing", "blazing",
@ -25,6 +29,7 @@ static JS_HASH: OnceLock<Hash> = OnceLock::new();
#[derive(Template)] #[derive(Template)]
#[template(path = "pages/kh2/drops.html")] #[template(path = "pages/kh2/drops.html")]
struct DropsTemplate { struct DropsTemplate {
pub game: Game,
pub drops: Vec<MaterialDrops>, pub drops: Vec<MaterialDrops>,
pub material_kinds: Vec<String>, pub material_kinds: Vec<String>,
} }

View File

@ -24,6 +24,7 @@ mod kh2;
mod kh3; mod kh3;
pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const ASSETS_FOLDER_PATH: &str = "./public/assets";
pub trait RuntimeModule { pub trait RuntimeModule {
fn start_module(); fn start_module();

View File

@ -3,18 +3,15 @@
{% if drops.len() > 0 %} {% if drops.len() > 0 %}
<div <div
class="category-wrapper" class="category-wrapper"
data-mat-kind="{{ drop.category }}" data-mat-kind="{{ drop.category.get_category(game) }}"
data-mat-type="{{ label }}" data-mat-type="{{ label }}"
> >
<div class="category"> <div class="category">
<img <img
src="../public/assets/materials/{{ drop.category }}/{{ label }}.webp" src="../public/assets/materials/{{ drop.texture(game) }}.webp"
width="64" width="64"
height="64" height="64"
/> />
<!-- <h1> -->
<!-- {{ drop.category|capitalize +}} {{+ label|capitalize }} -->
<!-- </h1> -->
<h1>{{ drop.name }}</h1> <h1>{{ drop.name }}</h1>
<button onclick="track(this)">Start tracking</button> <button onclick="track(this)">Start tracking</button>
</div> </div>