Simplified item key (no assets)

This commit is contained in:
Sam 2022-05-18 16:28:06 -04:00
parent c3377547c3
commit 534c7dc8b9
16 changed files with 141 additions and 282 deletions

View File

@ -186,18 +186,18 @@ fn get_tool_hands(tool: &Tool) -> String {
fn get_armor_kind(kind: &ArmorKind) -> String { fn get_armor_kind(kind: &ArmorKind) -> String {
match kind { match kind {
ArmorKind::Shoulder(_) => "Shoulder".to_string(), ArmorKind::Shoulder => "Shoulder".to_string(),
ArmorKind::Chest(_) => "Chest".to_string(), ArmorKind::Chest => "Chest".to_string(),
ArmorKind::Belt(_) => "Belt".to_string(), ArmorKind::Belt => "Belt".to_string(),
ArmorKind::Hand(_) => "Hand".to_string(), ArmorKind::Hand => "Hand".to_string(),
ArmorKind::Pants(_) => "Pants".to_string(), ArmorKind::Pants => "Pants".to_string(),
ArmorKind::Foot(_) => "Foot".to_string(), ArmorKind::Foot => "Foot".to_string(),
ArmorKind::Back(_) => "Back".to_string(), ArmorKind::Back => "Back".to_string(),
ArmorKind::Ring(_) => "Ring".to_string(), ArmorKind::Ring => "Ring".to_string(),
ArmorKind::Neck(_) => "Neck".to_string(), ArmorKind::Neck => "Neck".to_string(),
ArmorKind::Head(_) => "Head".to_string(), ArmorKind::Head => "Head".to_string(),
ArmorKind::Tabard(_) => "Tabard".to_string(), ArmorKind::Tabard => "Tabard".to_string(),
ArmorKind::Bag(_) => "Bag".to_string(), ArmorKind::Bag => "Bag".to_string(),
} }
} }

View File

@ -73,7 +73,7 @@ fn armor_stats() -> Result<(), Box<dyn Error>> {
{ {
match &*item.kind() { match &*item.kind() {
comp::item::ItemKind::Armor(armor) => { comp::item::ItemKind::Armor(armor) => {
if let ArmorKind::Bag(_) = armor.kind { if let ArmorKind::Bag = armor.kind {
continue; continue;
} }

View File

@ -66,20 +66,20 @@ impl From<&Item> for Body {
ItemKind::Tool(Tool { kind, .. }) => Body::Tool(*kind), ItemKind::Tool(Tool { kind, .. }) => Body::Tool(*kind),
ItemKind::ModularComponent(_) => Body::ModularComponent, ItemKind::ModularComponent(_) => Body::ModularComponent,
ItemKind::Lantern(_) => Body::Lantern, ItemKind::Lantern(_) => Body::Lantern,
ItemKind::Glider(_) => Body::Glider, ItemKind::Glider => Body::Glider,
ItemKind::Armor(armor) => match armor.kind { ItemKind::Armor(armor) => match armor.kind {
ArmorKind::Shoulder(_) => Body::Armor(ItemDropArmorKind::Shoulder), ArmorKind::Shoulder => Body::Armor(ItemDropArmorKind::Shoulder),
ArmorKind::Chest(_) => Body::Armor(ItemDropArmorKind::Chest), ArmorKind::Chest => Body::Armor(ItemDropArmorKind::Chest),
ArmorKind::Belt(_) => Body::Armor(ItemDropArmorKind::Belt), ArmorKind::Belt => Body::Armor(ItemDropArmorKind::Belt),
ArmorKind::Hand(_) => Body::Armor(ItemDropArmorKind::Hand), ArmorKind::Hand => Body::Armor(ItemDropArmorKind::Hand),
ArmorKind::Pants(_) => Body::Armor(ItemDropArmorKind::Pants), ArmorKind::Pants => Body::Armor(ItemDropArmorKind::Pants),
ArmorKind::Foot(_) => Body::Armor(ItemDropArmorKind::Foot), ArmorKind::Foot => Body::Armor(ItemDropArmorKind::Foot),
ArmorKind::Back(_) => Body::Armor(ItemDropArmorKind::Back), ArmorKind::Back => Body::Armor(ItemDropArmorKind::Back),
ArmorKind::Ring(_) => Body::Armor(ItemDropArmorKind::Ring), ArmorKind::Ring => Body::Armor(ItemDropArmorKind::Ring),
ArmorKind::Neck(_) => Body::Armor(ItemDropArmorKind::Neck), ArmorKind::Neck => Body::Armor(ItemDropArmorKind::Neck),
ArmorKind::Head(_) => Body::Armor(ItemDropArmorKind::Head), ArmorKind::Head => Body::Armor(ItemDropArmorKind::Head),
ArmorKind::Tabard(_) => Body::Armor(ItemDropArmorKind::Tabard), ArmorKind::Tabard => Body::Armor(ItemDropArmorKind::Tabard),
ArmorKind::Bag(_) => Body::Armor(ItemDropArmorKind::Bag), ArmorKind::Bag => Body::Armor(ItemDropArmorKind::Bag),
}, },
ItemKind::Utility { kind, .. } => match kind { ItemKind::Utility { kind, .. } => match kind {
Utility::Coins => { Utility::Coins => {

View File

@ -1,20 +1,20 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{cmp::Ordering, ops::Sub}; use std::{cmp::Ordering, ops::Sub};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ArmorKind { pub enum ArmorKind {
Shoulder(String), Shoulder,
Chest(String), Chest,
Belt(String), Belt,
Hand(String), Hand,
Pants(String), Pants,
Foot(String), Foot,
Back(String), Back,
Ring(String), Ring,
Neck(String), Neck,
Head(String), Head,
Tabard(String), Tabard,
Bag(String), Bag,
} }
impl Armor { impl Armor {

View File

@ -1,26 +1,15 @@
use crate::{ use crate::{
assets::AssetExt, assets::AssetExt,
comp::inventory::item::{ comp::inventory::item::{modular, ItemDef, ItemDefinitionId, ItemDesc, ItemKind},
armor::{Armor, ArmorKind},
modular, Glider, ItemDef, ItemDefinitionId, ItemDesc, ItemKind, Lantern, Throwable,
Utility,
},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
#[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)]
pub enum ItemKey { pub enum ItemKey {
Tool(String), Simple(String),
ModularWeapon(modular::ModularWeaponKey), ModularWeapon(modular::ModularWeaponKey),
ModularWeaponComponent(modular::ModularWeaponComponentKey), ModularWeaponComponent(modular::ModularWeaponComponentKey),
Lantern(String),
Glider(String),
Armor(ArmorKind),
Utility(Utility),
Consumable(String),
Throwable(Throwable),
Ingredient(String),
TagExamples(Vec<ItemKey>), TagExamples(Vec<ItemKey>),
Empty, Empty,
} }
@ -29,46 +18,29 @@ impl<T: ItemDesc> From<&T> for ItemKey {
fn from(item_desc: &T) -> Self { fn from(item_desc: &T) -> Self {
let item_definition_id = item_desc.item_definition_id(); let item_definition_id = item_desc.item_definition_id();
match &*item_desc.kind() { if let ItemKind::TagExamples { item_ids } = &*item_desc.kind() {
ItemKind::Tool(_) => match item_definition_id { ItemKey::TagExamples(
ItemDefinitionId::Simple(id) => ItemKey::Tool(id.to_string()), item_ids
ItemDefinitionId::Modular { .. } => { .iter()
ItemKey::ModularWeapon(modular::weapon_to_key(item_desc)) .map(|id| ItemKey::from(&*Arc::<ItemDef>::load_expect_cloned(id)))
}, .collect(),
ItemDefinitionId::Compound { .. } => ItemKey::Empty, )
}, } else {
ItemKind::ModularComponent(_) => match item_definition_id { match item_definition_id {
ItemDefinitionId::Simple(id) => ItemKey::Tool(id.to_owned()), ItemDefinitionId::Simple(id) => ItemKey::Simple(String::from(id)),
ItemDefinitionId::Compound { simple_base, .. } => { ItemDefinitionId::Compound { simple_base, .. } => {
if let Ok(key) = if let Ok(key) =
modular::weapon_component_to_key(simple_base, item_desc.components()) modular::weapon_component_to_key(simple_base, item_desc.components())
{ {
ItemKey::ModularWeaponComponent(key) ItemKey::ModularWeaponComponent(key)
} else { } else {
ItemKey::Tool(simple_base.to_owned()) ItemKey::Simple(simple_base.to_owned())
} }
}, },
ItemDefinitionId::Modular { .. } => ItemKey::Empty, ItemDefinitionId::Modular { .. } => {
}, ItemKey::ModularWeapon(modular::weapon_to_key(item_desc))
ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(kind.clone()), },
ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()), }
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
ItemKind::Consumable { .. } => {
if let ItemDefinitionId::Simple(id) = item_definition_id {
ItemKey::Consumable(id.to_owned())
} else {
ItemKey::Empty
}
},
ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind),
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
ItemKind::TagExamples { item_ids } => ItemKey::TagExamples(
item_ids
.iter()
.map(|id| ItemKey::from(&*Arc::<ItemDef>::load_expect_cloned(id)))
.collect(),
),
} }
} }
} }

View File

@ -53,7 +53,6 @@ pub enum Utility {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Lantern { pub struct Lantern {
pub kind: String,
color: Rgb<u32>, color: Rgb<u32>,
strength_thousandths: u32, strength_thousandths: u32,
flicker_thousandths: u32, flicker_thousandths: u32,
@ -65,11 +64,6 @@ impl Lantern {
pub fn color(&self) -> Rgb<f32> { self.color.map(|c| c as f32 / 255.0) } pub fn color(&self) -> Rgb<f32> { self.color.map(|c| c as f32 / 255.0) }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Glider {
pub kind: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Copy, PartialOrd, Ord)] #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Copy, PartialOrd, Ord)]
pub enum Quality { pub enum Quality {
Low, // Grey Low, // Grey
@ -273,7 +267,7 @@ pub enum ItemKind {
ModularComponent(modular::ModularComponent), ModularComponent(modular::ModularComponent),
Lantern(Lantern), Lantern(Lantern),
Armor(armor::Armor), Armor(armor::Armor),
Glider(Glider), Glider,
Consumable { Consumable {
kind: ConsumableKind, kind: ConsumableKind,
effects: Vec<Effect>, effects: Vec<Effect>,
@ -285,7 +279,6 @@ pub enum ItemKind {
kind: Utility, kind: Utility,
}, },
Ingredient { Ingredient {
kind: String,
/// Used to generate names for modular items composed of this ingredient /// Used to generate names for modular items composed of this ingredient
descriptor: String, descriptor: String,
}, },
@ -307,7 +300,7 @@ impl ItemKind {
pub fn is_equippable(&self) -> bool { pub fn is_equippable(&self) -> bool {
matches!( matches!(
self, self,
ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Glider(_) | ItemKind::Lantern(_) ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Glider | ItemKind::Lantern(_)
) )
} }
} }

View File

@ -474,7 +474,7 @@ mod tests {
let result = loadout let result = loadout
.get_slot_to_equip_into(&ItemKind::Armor(Armor::test_armor( .get_slot_to_equip_into(&ItemKind::Armor(Armor::test_armor(
ArmorKind::Bag("test".to_string()), ArmorKind::Bag,
Protection::Normal(0.0), Protection::Normal(0.0),
Protection::Normal(0.0), Protection::Normal(0.0),
))) )))
@ -494,7 +494,7 @@ mod tests {
let result = loadout let result = loadout
.get_slot_to_equip_into(&ItemKind::Armor(Armor::test_armor( .get_slot_to_equip_into(&ItemKind::Armor(Armor::test_armor(
ArmorKind::Bag("test".to_string()), ArmorKind::Bag,
Protection::Normal(0.0), Protection::Normal(0.0),
Protection::Normal(0.0), Protection::Normal(0.0),
))) )))

View File

@ -127,7 +127,7 @@ impl EquipSlot {
(Self::InactiveMainhand, ItemKind::Tool(_)) => true, (Self::InactiveMainhand, ItemKind::Tool(_)) => true,
(Self::InactiveOffhand, ItemKind::Tool(tool)) => matches!(tool.hands, tool::Hands::One), (Self::InactiveOffhand, ItemKind::Tool(tool)) => matches!(tool.hands, tool::Hands::One),
(Self::Lantern, ItemKind::Lantern(_)) => true, (Self::Lantern, ItemKind::Lantern(_)) => true,
(Self::Glider, ItemKind::Glider(_)) => true, (Self::Glider, ItemKind::Glider) => true,
_ => false, _ => false,
} }
} }
@ -137,22 +137,22 @@ impl ArmorSlot {
fn can_hold(self, armor: &item::armor::ArmorKind) -> bool { fn can_hold(self, armor: &item::armor::ArmorKind) -> bool {
matches!( matches!(
(self, armor), (self, armor),
(Self::Head, ArmorKind::Head(_)) (Self::Head, ArmorKind::Head)
| (Self::Neck, ArmorKind::Neck(_)) | (Self::Neck, ArmorKind::Neck)
| (Self::Shoulders, ArmorKind::Shoulder(_)) | (Self::Shoulders, ArmorKind::Shoulder)
| (Self::Chest, ArmorKind::Chest(_)) | (Self::Chest, ArmorKind::Chest)
| (Self::Hands, ArmorKind::Hand(_)) | (Self::Hands, ArmorKind::Hand)
| (Self::Ring1, ArmorKind::Ring(_)) | (Self::Ring1, ArmorKind::Ring)
| (Self::Ring2, ArmorKind::Ring(_)) | (Self::Ring2, ArmorKind::Ring)
| (Self::Back, ArmorKind::Back(_)) | (Self::Back, ArmorKind::Back)
| (Self::Belt, ArmorKind::Belt(_)) | (Self::Belt, ArmorKind::Belt)
| (Self::Legs, ArmorKind::Pants(_)) | (Self::Legs, ArmorKind::Pants)
| (Self::Feet, ArmorKind::Foot(_)) | (Self::Feet, ArmorKind::Foot)
| (Self::Tabard, ArmorKind::Tabard(_)) | (Self::Tabard, ArmorKind::Tabard)
| (Self::Bag1, ArmorKind::Bag(_)) | (Self::Bag1, ArmorKind::Bag)
| (Self::Bag2, ArmorKind::Bag(_)) | (Self::Bag2, ArmorKind::Bag)
| (Self::Bag3, ArmorKind::Bag(_)) | (Self::Bag3, ArmorKind::Bag)
| (Self::Bag4, ArmorKind::Bag(_)) | (Self::Bag4, ArmorKind::Bag)
) )
} }
} }

View File

@ -13,7 +13,7 @@ pub(super) fn get_test_bag(slots: u16) -> Item {
let item_def = ItemDef::new_test( let item_def = ItemDef::new_test(
"common.items.testing.test_bag".to_string(), "common.items.testing.test_bag".to_string(),
ItemKind::Armor(armor::Armor::test_armor( ItemKind::Armor(armor::Armor::test_armor(
ArmorKind::Bag("Test Bag".to_string()), ArmorKind::Bag,
Protection::Normal(0.0), Protection::Normal(0.0),
Protection::Normal(0.0), Protection::Normal(0.0),
)), )),

View File

@ -167,7 +167,7 @@ impl<'a> System<'a> for Sys {
.equipped(EquipSlot::Glider) .equipped(EquipSlot::Glider)
.as_ref() .as_ref()
.map_or(false, |item| { .map_or(false, |item| {
matches!(&*item.kind(), comp::item::ItemKind::Glider(_)) matches!(&*item.kind(), comp::item::ItemKind::Glider)
}); });
let is_gliding = matches!( let is_gliding = matches!(

View File

@ -92,7 +92,7 @@ use common::{
assets::{self, AssetExt, AssetHandle}, assets::{self, AssetExt, AssetHandle},
comp::{ comp::{
beam, biped_large, biped_small, humanoid, beam, biped_large, biped_small, humanoid,
item::{ItemKind, ToolKind}, item::{ItemDefinitionId, ItemKind, ToolKind},
object, object,
poise::PoiseState, poise::PoiseState,
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType, quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType,
@ -306,11 +306,10 @@ impl From<&InventoryUpdateEvent> for SfxEvent {
ItemKind::Tool(tool) => { ItemKind::Tool(tool) => {
SfxEvent::Inventory(SfxInventoryEvent::CollectedTool(tool.kind)) SfxEvent::Inventory(SfxInventoryEvent::CollectedTool(tool.kind))
}, },
ItemKind::Ingredient { kind, .. } => match &kind[..] { ItemKind::Ingredient { .. } if matches!(item.item_definition_id(), ItemDefinitionId::Simple(id) if id.contains("mineral.gem.")) => {
"Diamond" | "Ruby" | "Emerald" | "Sapphire" | "Topaz" | "Amethyst" => { SfxEvent::Inventory(SfxInventoryEvent::CollectedItem(String::from(
SfxEvent::Inventory(SfxInventoryEvent::CollectedItem(kind.clone())) "Gemstone",
}, )))
_ => SfxEvent::Inventory(SfxInventoryEvent::Collected),
}, },
_ => SfxEvent::Inventory(SfxInventoryEvent::Collected), _ => SfxEvent::Inventory(SfxInventoryEvent::Collected),
} }

View File

@ -245,7 +245,7 @@ impl CraftingTab {
ItemKind::Armor(_) => !item.tags().contains(&ItemTag::Bag), ItemKind::Armor(_) => !item.tags().contains(&ItemTag::Bag),
_ => false, _ => false,
}, },
CraftingTab::Glider => matches!(&*item.kind(), ItemKind::Glider(_)), CraftingTab::Glider => matches!(&*item.kind(), ItemKind::Glider),
CraftingTab::Potion => item.tags().contains(&ItemTag::Potion), CraftingTab::Potion => item.tags().contains(&ItemTag::Potion),
CraftingTab::ProcessedMaterial => item CraftingTab::ProcessedMaterial => item
.tags() .tags()
@ -782,7 +782,7 @@ impl<'a> Widget for Crafting<'a> {
Button::image(animate_by_pulse( Button::image(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool(station_img_str.to_string())), .img_ids_or_not_found_img(ItemKey::Simple(station_img_str.to_string())),
self.pulse, self.pulse,
)) ))
.image_color(color::LIGHT_RED) .image_color(color::LIGHT_RED)
@ -1413,7 +1413,7 @@ impl<'a> Widget for Crafting<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool(station_img.to_string())), .img_ids_or_not_found_img(ItemKey::Simple(station_img.to_string())),
self.pulse, self.pulse,
)) ))
.w_h(25.0, 25.0) .w_h(25.0, 25.0)
@ -1754,7 +1754,7 @@ impl<'a> Widget for Crafting<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("DismantlingBench".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("DismantlingBench".to_string())),
self.pulse, self.pulse,
)) ))
.wh([size; 2]) .wh([size; 2])

View File

@ -1361,9 +1361,9 @@ impl<'a> Diary<'a> {
use ToolKind::*; use ToolKind::*;
// General Combat // General Combat
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self.item_imgs.img_ids_or_not_found_img(ItemKey::Simple(
.item_imgs "example_general_combat_left".to_string(),
.img_ids_or_not_found_img(ItemKey::Tool("example_general_combat_left".to_string())), )),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -1372,7 +1372,7 @@ impl<'a> Diary<'a> {
.set(state.ids.general_combat_render_0, ui); .set(state.ids.general_combat_render_0, ui);
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self.item_imgs.img_ids_or_not_found_img(ItemKey::Tool( &self.item_imgs.img_ids_or_not_found_img(ItemKey::Simple(
"example_general_combat_right".to_string(), "example_general_combat_right".to_string(),
)), )),
self.pulse, self.pulse,
@ -1541,7 +1541,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_sword".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_sword".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -1712,7 +1712,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_hammer".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_hammer".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -1870,7 +1870,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_axe".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_axe".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -2028,7 +2028,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_sceptre".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_sceptre".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -2180,7 +2180,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_bow".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_bow".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -2338,7 +2338,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_staff_fire".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_staff_fire".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)
@ -2485,7 +2485,7 @@ impl<'a> Diary<'a> {
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self &self
.item_imgs .item_imgs
.img_ids_or_not_found_img(ItemKey::Tool("example_pick".to_string())), .img_ids_or_not_found_img(ItemKey::Simple("example_pick".to_string())),
self.pulse, self.pulse,
)) ))
.wh(ART_SIZE) .wh(ART_SIZE)

View File

@ -89,7 +89,7 @@ pub fn kind_text<'a>(kind: &ItemKind, i18n: &'a Localization) -> Cow<'a, str> {
Cow::Borrowed(i18n.get("common.kind.modular_component")) Cow::Borrowed(i18n.get("common.kind.modular_component"))
} }
}, },
ItemKind::Glider(_glider) => Cow::Borrowed(i18n.get("common.kind.glider")), ItemKind::Glider => Cow::Borrowed(i18n.get("common.kind.glider")),
ItemKind::Consumable { .. } => Cow::Borrowed(i18n.get("common.kind.consumable")), ItemKind::Consumable { .. } => Cow::Borrowed(i18n.get("common.kind.consumable")),
ItemKind::Throwable { .. } => Cow::Borrowed(i18n.get("common.kind.throwable")), ItemKind::Throwable { .. } => Cow::Borrowed(i18n.get("common.kind.throwable")),
ItemKind::Utility { .. } => Cow::Borrowed(i18n.get("common.kind.utility")), ItemKind::Utility { .. } => Cow::Borrowed(i18n.get("common.kind.utility")),
@ -112,7 +112,7 @@ pub fn material_kind_text<'a>(kind: &MaterialKind, i18n: &'a Localization) -> &'
pub fn stats_count(item: &dyn ItemDesc) -> usize { pub fn stats_count(item: &dyn ItemDesc) -> usize {
let mut count = match &*item.kind() { let mut count = match &*item.kind() {
ItemKind::Armor(armor) => { ItemKind::Armor(armor) => {
if matches!(armor.kind, ArmorKind::Bag(_)) { if matches!(armor.kind, ArmorKind::Bag) {
0 0
} else { } else {
armor.stats.energy_reward().is_some() as usize armor.stats.energy_reward().is_some() as usize
@ -129,7 +129,7 @@ pub fn stats_count(item: &dyn ItemDesc) -> usize {
}; };
let is_bag = match &*item.kind() { let is_bag = match &*item.kind() {
ItemKind::Armor(armor) => matches!(armor.kind, ArmorKind::Bag(_)), ItemKind::Armor(armor) => matches!(armor.kind, ArmorKind::Bag),
_ => false, _ => false,
}; };
if item.num_slots() != 0 && !is_bag { if item.num_slots() != 0 && !is_bag {
@ -224,18 +224,18 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
// Armor // Armor
fn armor_kind<'a>(armor: &Armor, i18n: &'a Localization) -> &'a str { fn armor_kind<'a>(armor: &Armor, i18n: &'a Localization) -> &'a str {
let kind = match armor.kind { let kind = match armor.kind {
ArmorKind::Shoulder(_) => i18n.get("hud.bag.shoulders"), ArmorKind::Shoulder => i18n.get("hud.bag.shoulders"),
ArmorKind::Chest(_) => i18n.get("hud.bag.chest"), ArmorKind::Chest => i18n.get("hud.bag.chest"),
ArmorKind::Belt(_) => i18n.get("hud.bag.belt"), ArmorKind::Belt => i18n.get("hud.bag.belt"),
ArmorKind::Hand(_) => i18n.get("hud.bag.hands"), ArmorKind::Hand => i18n.get("hud.bag.hands"),
ArmorKind::Pants(_) => i18n.get("hud.bag.legs"), ArmorKind::Pants => i18n.get("hud.bag.legs"),
ArmorKind::Foot(_) => i18n.get("hud.bag.feet"), ArmorKind::Foot => i18n.get("hud.bag.feet"),
ArmorKind::Back(_) => i18n.get("hud.bag.back"), ArmorKind::Back => i18n.get("hud.bag.back"),
ArmorKind::Ring(_) => i18n.get("hud.bag.ring"), ArmorKind::Ring => i18n.get("hud.bag.ring"),
ArmorKind::Neck(_) => i18n.get("hud.bag.neck"), ArmorKind::Neck => i18n.get("hud.bag.neck"),
ArmorKind::Head(_) => i18n.get("hud.bag.head"), ArmorKind::Head => i18n.get("hud.bag.head"),
ArmorKind::Tabard(_) => i18n.get("hud.bag.tabard"), ArmorKind::Tabard => i18n.get("hud.bag.tabard"),
ArmorKind::Bag(_) => i18n.get("hud.bag.bag"), ArmorKind::Bag => i18n.get("hud.bag.bag"),
}; };
kind kind
} }

View File

@ -12,11 +12,7 @@ use common::{
slot::{ArmorSlot, EquipSlot}, slot::{ArmorSlot, EquipSlot},
Inventory, Inventory,
}, },
item::{ item::{item_key::ItemKey, modular, Item, ItemDefinitionId},
armor::{Armor, ArmorKind},
item_key::ItemKey,
modular, Item, ItemDefinitionId, ItemKind,
},
CharacterState, CharacterState,
}, },
figure::Segment, figure::Segment,
@ -128,6 +124,20 @@ impl CharacterCacheKey {
CameraMode::ThirdPerson | CameraMode::Freefly => false, CameraMode::ThirdPerson | CameraMode::Freefly => false,
}; };
let key_from_slot = |slot| {
inventory
.equipped(slot)
.map(|i| i.item_definition_id())
.map(|id| match id {
// TODO: Properly handle items with components here. Probably wait until modular
// armor?
ItemDefinitionId::Simple(id) => id,
ItemDefinitionId::Compound { simple_base, .. } => simple_base,
ItemDefinitionId::Modular { pseudo_base, .. } => pseudo_base,
})
.map(String::from)
};
// Third person tools are only modeled when the camera is either not first // Third person tools are only modeled when the camera is either not first
// person, or the camera is first person and we are in a tool-using // person, or the camera is first person and we are in a tool-using
// state. // state.
@ -146,78 +156,12 @@ impl CharacterCacheKey {
None None
} else { } else {
Some(CharacterThirdPersonKey { Some(CharacterThirdPersonKey {
head: if let Some(ItemKind::Armor(Armor { head: key_from_slot(EquipSlot::Armor(ArmorSlot::Head)),
kind: ArmorKind::Head(armor), shoulder: key_from_slot(EquipSlot::Armor(ArmorSlot::Shoulders)),
.. chest: key_from_slot(EquipSlot::Armor(ArmorSlot::Chest)),
})) = inventory belt: key_from_slot(EquipSlot::Armor(ArmorSlot::Belt)),
.equipped(EquipSlot::Armor(ArmorSlot::Head)) back: key_from_slot(EquipSlot::Armor(ArmorSlot::Back)),
.map(|i| i.kind()) pants: key_from_slot(EquipSlot::Armor(ArmorSlot::Legs)),
.as_deref()
{
Some(armor.clone())
} else {
None
},
shoulder: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Shoulder(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Shoulders))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
chest: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Chest(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Chest))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
belt: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Belt(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Belt))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
back: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Back(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Back))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
pants: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Pants(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Legs))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
}) })
}, },
tool: if are_tools_visible { tool: if are_tools_visible {
@ -241,60 +185,11 @@ impl CharacterCacheKey {
} else { } else {
None None
}, },
lantern: if let Some(ItemKind::Lantern(lantern)) = inventory lantern: key_from_slot(EquipSlot::Lantern),
.equipped(EquipSlot::Lantern) glider: key_from_slot(EquipSlot::Glider),
.map(|i| i.kind()) hand: key_from_slot(EquipSlot::Armor(ArmorSlot::Hands)),
.as_deref() foot: key_from_slot(EquipSlot::Armor(ArmorSlot::Feet)),
{ head: key_from_slot(EquipSlot::Armor(ArmorSlot::Head)),
Some(lantern.kind.clone())
} else {
None
},
glider: if let Some(ItemKind::Glider(glider)) = inventory
.equipped(EquipSlot::Glider)
.map(|i| i.kind())
.as_deref()
{
Some(glider.kind.clone())
} else {
None
},
hand: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Hand(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Hands))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
foot: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Foot(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Feet))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
head: if let Some(ItemKind::Armor(Armor {
kind: ArmorKind::Head(armor),
..
})) = inventory
.equipped(EquipSlot::Armor(ArmorSlot::Head))
.map(|i| i.kind())
.as_deref()
{
Some(armor.clone())
} else {
None
},
} }
} }
} }

View File

@ -802,7 +802,7 @@ impl<'a> Widget for ItemTooltip<'a> {
}, },
ItemKind::Armor(armor) => { ItemKind::Armor(armor) => {
match armor.kind { match armor.kind {
ArmorKind::Bag(_) => { ArmorKind::Bag => {
// Bags // Bags
widget::Text::new(&format!( widget::Text::new(&format!(
"{} {}", "{} {}",