diff --git a/src/controller/settings.rs b/src/controller/settings.rs index 3178f274..a22abba5 100644 --- a/src/controller/settings.rs +++ b/src/controller/settings.rs @@ -670,7 +670,7 @@ impl std::fmt::Display for UserSettings { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - r#" log level: {} + r#" log level: {} show/hide HUD key: {} power cycle key: {} utility cycle key: {} diff --git a/src/data/armor.rs b/src/data/armor.rs index 05458c36..565696f2 100644 --- a/src/data/armor.rs +++ b/src/data/armor.rs @@ -24,6 +24,12 @@ impl ArmorType { } } +impl std::fmt::Display for ArmorType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "icon={}; color='{}';", self.icon, self.color) + } +} + impl HasIcon for ArmorType { fn color(&self) -> Color { self.color.color() @@ -99,7 +105,7 @@ impl HasKeywords for ArmorType { } else if !QUIVERS.is_disjoint(tagset) { Icon::ArmorQuiver } else { - log::warn!("We couldn't classify this armor! name='{name}'; keywords: {keywords:?}"); + log::debug!("Falling back to generic armor icon: name='{name}'; keywords={keywords:?}"); Icon::ArmorHeavy }; diff --git a/src/data/base.rs b/src/data/base.rs index d0aa05cb..fdc7ffde 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -1,7 +1,5 @@ //! Base item kinds, from the starting icon set. -use strum::Display; - use super::ammo::AmmoType; use super::armor::ArmorType; use super::color::InvColor; @@ -15,7 +13,7 @@ use super::{HasIcon, HasKeywords}; use crate::images::icons::Icon; use crate::plugin::{Color, ItemCategory}; -#[derive(Clone, Debug, Default, Display, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] pub enum BaseType { #[default] Empty, @@ -35,13 +33,41 @@ pub enum BaseType { Equipset(Icon), } -#[derive(Clone, Debug, Display, Eq, Hash, PartialEq)] +impl std::fmt::Display for BaseType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BaseType::Empty => write!(f, ""), + BaseType::Ammo(t) => write!(f, "{t}"), + BaseType::Armor(t) => write!(f, "{t}"), + BaseType::Book => write!(f, "Book"), + BaseType::Food(t) => write!(f, "{t}"), + BaseType::HandToHand => write!(f, "Empty hand"), + BaseType::Light(t) => write!(f, "{t}"), + BaseType::Potion(t) => write!(f, "{t}"), + BaseType::PotionProxy(t) => write!(f, "{t}"), + BaseType::Power(t) => write!(f, "{t}"), + BaseType::Scroll(t) => write!(f, "{t}"), + BaseType::Shout(t) => write!(f, "{t}"), + BaseType::Spell(t) => write!(f, "{t}"), + BaseType::Weapon(t) => write!(f, "{t}"), + BaseType::Equipset(t) => write!(f, "{t}"), + } + } +} + +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Proxy { Health, Magicka, Stamina, } +impl std::fmt::Display for Proxy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Potion Proxy") + } +} + impl HasIcon for Proxy { fn color(&self) -> Color { match self { @@ -60,13 +86,19 @@ impl HasIcon for Proxy { } } -#[derive(Clone, Debug, Display, Eq, Hash, PartialEq, Default)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)] pub enum LightType { #[default] Torch, Lantern, } +impl std::fmt::Display for LightType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Light") + } +} + impl HasIcon for LightType { fn color(&self) -> Color { InvColor::Sun.color() diff --git a/src/data/food.rs b/src/data/food.rs index ddac35ef..fb12ca13 100644 --- a/src/data/food.rs +++ b/src/data/food.rs @@ -16,6 +16,12 @@ pub struct FoodType { color: InvColor, } +impl std::fmt::Display for FoodType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "icon={}; color='{}';", self.icon, self.color) + } +} + /// Quack quack icon trait. impl HasIcon for FoodType { fn color(&self) -> Color { @@ -68,7 +74,7 @@ impl HasKeywords for FoodType { } else if !ICON_STEW_BOWL.is_disjoint(containers) { Icon::FoodStew } else { - log::debug!("Falling back to default food icon: name='{name}'; keywords={keywords:?}"); + log::debug!("Falling back to generic food icon: name='{name}'; keywords={keywords:?}"); Icon::Food }; // ContainerKeywords::OCF_VesselBottlePotion => Icon::PotionDefault, diff --git a/src/data/huditem.rs b/src/data/huditem.rs index c9661fb9..58b852d3 100644 --- a/src/data/huditem.rs +++ b/src/data/huditem.rs @@ -420,13 +420,23 @@ impl HudItem { impl Display for HudItem { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "name='{}'; kind='{:?}'; count={}; form_string='{}';", - self.name(), - self.kind(), - self.count(), - self.form_string(), - ) + if self.count_matters() { + write!( + f, + "name=\"{}\"; {} count={}; form_string='{}';", + self.name(), + self.kind(), + self.count(), + self.form_string(), + ) + } else { + write!( + f, + "name=\"{}\" {} form_string='{}';", + self.name(), + self.kind(), + self.form_string(), + ) + } } } diff --git a/src/data/magic.rs b/src/data/magic.rs index 367d43fc..9b2e969b 100644 --- a/src/data/magic.rs +++ b/src/data/magic.rs @@ -48,6 +48,16 @@ impl SpellData { } } +impl std::fmt::Display for SpellData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "school='{}'; hostile={}; damage-type={}; level={}; archetype={};", + self.school, self.level, self.hostile, self.damage, self.archetype + ) + } +} + #[derive(Clone, Debug, Default, Display, Hash, Eq, PartialEq)] pub enum MagicCategory { #[default] diff --git a/src/data/potion.rs b/src/data/potion.rs index fd325bb0..c210917b 100644 --- a/src/data/potion.rs +++ b/src/data/potion.rs @@ -43,7 +43,7 @@ impl PotionType { ActorValue::ResistDisease => PotionType::Resist(MagicCategory::Disease), ActorValue::PoisonResist => PotionType::Resist(MagicCategory::Poison), _ => { - log::debug!("Falling back to default potion type; effect={effect}"); + log::debug!("Falling back to generic potion type; effect={effect}"); PotionType::Default } } diff --git a/src/data/power.rs b/src/data/power.rs index 1e3d6088..253b3e60 100644 --- a/src/data/power.rs +++ b/src/data/power.rs @@ -19,7 +19,7 @@ impl PowerType { let icon = if let Some(found) = icon_for_tagset(&kywds) { found } else { - log::debug!("Falling back to default icon for power; name='{name}'; keywords={tags:?}"); + log::debug!("Falling back to generic icon for power; name='{name}'; keywords={tags:?}"); Icon::Power }; @@ -42,3 +42,9 @@ impl HasIcon for PowerType { &self.icon } } + +impl std::fmt::Display for PowerType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "icon={}; color='{}';", self.icon, self.color) + } +} diff --git a/src/data/shout.rs b/src/data/shout.rs index d25daa47..a41e66bb 100644 --- a/src/data/shout.rs +++ b/src/data/shout.rs @@ -35,6 +35,18 @@ impl HasIcon for ShoutType { } } +impl std::fmt::Display for ShoutType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "shout='{:?}'; icon='{}.svg'; translation='{}';", + self.variant, + self.icon, + self.translation() + ) + } +} + impl ShoutType { pub fn new(tags: Vec) -> Self { let keywords = strings_to_enumset::(&tags); diff --git a/src/data/spell.rs b/src/data/spell.rs index 27c2c004..b87901d4 100644 --- a/src/data/spell.rs +++ b/src/data/spell.rs @@ -9,6 +9,8 @@ //! if other icons aren't available. 90% of the classification work is done in `keywords.rs`, //! which creates enum sets to match keywords against. +use std::fmt::Display; + use enumset::EnumSet; use super::color::{color_from_keywords, InvColor}; @@ -98,3 +100,13 @@ impl HasIcon for SpellType { self.color.color() } } + +impl Display for SpellType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Spell: icon='{}'; color='{}'; data: {}", + self.icon, self.color, self.data + ) + } +} diff --git a/src/data/weapon.rs b/src/data/weapon.rs index d2815562..b4817592 100644 --- a/src/data/weapon.rs +++ b/src/data/weapon.rs @@ -150,7 +150,7 @@ impl HasKeywords for WeaponType { } else if !WARAXES.is_disjoint(tagset) { Icon::WeaponAxeOneHanded } else { - log::debug!("Falling back to default icon for weapon '{name}'; keywords={keywords:?}"); + log::debug!("Falling back to generic icon for weapon '{name}'; keywords={keywords:?}"); Icon::WeaponSwordOneHanded }; @@ -178,6 +178,16 @@ impl HasIcon for WeaponType { } } +impl std::fmt::Display for WeaponType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Weapon: icon={}; color={}; equip-type={:?}", + self.icon, self.color, self.equiptype + ) + } +} + // Enum sets to let us pluck out matches from keywords efficiently. const BATTLEAXES: EnumSet = enum_set!( diff --git a/src/renderer/ui_renderer.cpp b/src/renderer/ui_renderer.cpp index a2b98f50..e4d3d82f 100644 --- a/src/renderer/ui_renderer.cpp +++ b/src/renderer/ui_renderer.cpp @@ -182,7 +182,8 @@ namespace ui if (loadedImg.width == 0) { return false; } if (d3dTextureFromBuffer(&loadedImg, &ICON_MAP[key].texture, ICON_MAP[key].width, ICON_MAP[key].height)) { - rlog::info("Lazy-loaded icon '{}'; width={}; height={}", key, ICON_MAP[key].width, ICON_MAP[key].height); + rlog::info( + "Lazy-loaded icon '{}.svg'; width={}; height={}", key, ICON_MAP[key].width, ICON_MAP[key].height); return true; } return false;