Addressed second round of balance feedback (no assets).

This commit is contained in:
Sam
2022-05-08 23:30:56 -04:00
parent d46cdf60b5
commit c0dd748bc7
16 changed files with 153 additions and 103 deletions

View File

@ -1004,7 +1004,7 @@ impl CharacterAbility {
}| { }| {
// Do we want to make buff_strength affect this instead of power? // Do we want to make buff_strength affect this instead of power?
// Look into during modular weapon transition // Look into during modular weapon transition
*strength *= stats.power; *strength *= stats.buff_strength;
}, },
); );
*range *= stats.range; *range *= stats.range;
@ -1046,7 +1046,7 @@ impl CharacterAbility {
} => { } => {
// Do we want to make buff_strength affect this instead of power? // Do we want to make buff_strength affect this instead of power?
// Look into during modular weapon transition // Look into during modular weapon transition
*buff_strength *= stats.power; *buff_strength *= stats.buff_strength;
*buildup_duration /= stats.speed; *buildup_duration /= stats.speed;
*cast_duration /= stats.speed; *cast_duration /= stats.speed;
*recover_duration /= stats.speed; *recover_duration /= stats.speed;

View File

@ -35,12 +35,13 @@ impl<T: ItemDesc> From<&T> for ItemKey {
ItemDefinitionId::Modular { .. } => { ItemDefinitionId::Modular { .. } => {
ItemKey::ModularWeapon(modular::weapon_to_key(item_desc)) ItemKey::ModularWeapon(modular::weapon_to_key(item_desc))
}, },
ItemDefinitionId::Compound { .. } => ItemKey::Empty,
}, },
ItemKind::ModularComponent(mod_comp) => { ItemKind::ModularComponent(mod_comp) => {
use modular::ModularComponent; use modular::ModularComponent;
match mod_comp { match mod_comp {
ModularComponent::ToolPrimaryComponent { .. } => { ModularComponent::ToolPrimaryComponent { .. } => {
if let Some(id) = item_definition_id.raw() { if let ItemDefinitionId::Simple(id) = item_definition_id {
match modular::weapon_component_to_key(id, item_desc.components()) { match modular::weapon_component_to_key(id, item_desc.components()) {
Ok(key) => ItemKey::ModularWeaponComponent(key), Ok(key) => ItemKey::ModularWeaponComponent(key),
// TODO: Maybe use a different ItemKey? // TODO: Maybe use a different ItemKey?
@ -51,7 +52,7 @@ impl<T: ItemDesc> From<&T> for ItemKey {
} }
}, },
ModularComponent::ToolSecondaryComponent { .. } => { ModularComponent::ToolSecondaryComponent { .. } => {
if let Some(id) = item_definition_id.raw() { if let ItemDefinitionId::Simple(id) = item_definition_id {
// TODO: Maybe use a different ItemKey? // TODO: Maybe use a different ItemKey?
ItemKey::Tool(id.to_owned()) ItemKey::Tool(id.to_owned())
} else { } else {
@ -65,7 +66,7 @@ impl<T: ItemDesc> From<&T> for ItemKey {
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()), ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind), ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
ItemKind::Consumable { .. } => { ItemKind::Consumable { .. } => {
if let Some(id) = item_definition_id.raw() { if let ItemDefinitionId::Simple(id) = item_definition_id {
ItemKey::Consumable(id.to_owned()) ItemKey::Consumable(id.to_owned())
} else { } else {
ItemKey::Empty ItemKey::Empty

View File

@ -448,6 +448,10 @@ pub enum ItemDefinitionId<'a> {
pseudo_base: &'a str, pseudo_base: &'a str,
components: Vec<ItemDefinitionId<'a>>, components: Vec<ItemDefinitionId<'a>>,
}, },
Compound {
simple_base: &'a str,
components: Vec<ItemDefinitionId<'a>>,
},
} }
#[derive(Clone, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq)]
@ -457,6 +461,10 @@ pub enum ItemDefinitionIdOwned {
pseudo_base: String, pseudo_base: String,
components: Vec<ItemDefinitionIdOwned>, components: Vec<ItemDefinitionIdOwned>,
}, },
Compound {
simple_base: String,
components: Vec<ItemDefinitionIdOwned>,
},
} }
impl ItemDefinitionIdOwned { impl ItemDefinitionIdOwned {
@ -470,15 +478,23 @@ impl ItemDefinitionIdOwned {
pseudo_base, pseudo_base,
components: components.iter().map(|comp| comp.as_ref()).collect(), components: components.iter().map(|comp| comp.as_ref()).collect(),
}, },
Self::Compound {
ref simple_base,
ref components,
} => ItemDefinitionId::Compound {
simple_base,
components: components.iter().map(|comp| comp.as_ref()).collect(),
},
} }
} }
} }
impl<'a> ItemDefinitionId<'a> { impl<'a> ItemDefinitionId<'a> {
pub fn raw(&self) -> Option<&str> { pub fn itemdef_id(&self) -> Option<&str> {
match self { match self {
Self::Simple(id) => Some(id), Self::Simple(id) => Some(id),
Self::Modular { .. } => None, Self::Modular { .. } => None,
Self::Compound { simple_base, .. } => Some(simple_base),
} }
} }
@ -492,6 +508,13 @@ impl<'a> ItemDefinitionId<'a> {
pseudo_base: String::from(*pseudo_base), pseudo_base: String::from(*pseudo_base),
components: components.iter().map(|comp| comp.to_owned()).collect(), components: components.iter().map(|comp| comp.to_owned()).collect(),
}, },
Self::Compound {
simple_base,
components,
} => ItemDefinitionIdOwned::Compound {
simple_base: String::from(*simple_base),
components: components.iter().map(|comp| comp.to_owned()).collect(),
},
} }
} }
} }
@ -894,7 +917,20 @@ impl Item {
pub fn item_definition_id(&self) -> ItemDefinitionId<'_> { pub fn item_definition_id(&self) -> ItemDefinitionId<'_> {
match &self.item_base { match &self.item_base {
ItemBase::Simple(item_def) => ItemDefinitionId::Simple(&item_def.item_definition_id), ItemBase::Simple(item_def) => {
if self.components.is_empty() {
ItemDefinitionId::Simple(&item_def.item_definition_id)
} else {
ItemDefinitionId::Compound {
simple_base: &item_def.item_definition_id,
components: self
.components
.iter()
.map(|item| item.item_definition_id())
.collect(),
}
}
},
ItemBase::Modular(mod_base) => ItemDefinitionId::Modular { ItemBase::Modular(mod_base) => ItemDefinitionId::Modular {
pseudo_base: mod_base.pseudo_item_id(), pseudo_base: mod_base.pseudo_item_id(),
components: self components: self

View File

@ -240,7 +240,7 @@ impl ModularComponent {
.iter() .iter()
.filter_map(|comp| { .filter_map(|comp| {
comp.item_definition_id() comp.item_definition_id()
.raw() .itemdef_id()
.and_then(|id| msm.0.get(id)) .and_then(|id| msm.0.get(id))
.copied() .copied()
.zip(Some(1)) .zip(Some(1))
@ -314,7 +314,7 @@ lazy_static! {
if let Ok(items) = Item::new_from_asset_glob(&directory) { if let Ok(items) = Item::new_from_asset_glob(&directory) {
items items
.into_iter() .into_iter()
.filter_map(|comp| Some(comp.item_definition_id().raw()?.to_owned())) .filter_map(|comp| Some(comp.item_definition_id().itemdef_id()?.to_owned()))
.filter_map(|id| Arc::<ItemDef>::load_cloned(&id).ok()) .filter_map(|id| Arc::<ItemDef>::load_cloned(&id).ok())
.for_each(|comp_def| { .for_each(|comp_def| {
if let ItemKind::ModularComponent(ModularComponent::ToolSecondaryComponent { hand_restriction, .. }) = comp_def.kind { if let ItemKind::ModularComponent(ModularComponent::ToolSecondaryComponent { hand_restriction, .. }) = comp_def.kind {
@ -476,9 +476,11 @@ pub fn weapon_to_key(mod_weap: impl ItemDesc) -> ModularWeaponKey {
.iter() .iter()
.find_map(|comp| match &*comp.kind() { .find_map(|comp| match &*comp.kind() {
ItemKind::ModularComponent(ModularComponent::ToolPrimaryComponent { .. }) => { ItemKind::ModularComponent(ModularComponent::ToolPrimaryComponent { .. }) => {
let component_id = comp.item_definition_id().raw()?.to_owned(); let component_id = comp.item_definition_id().itemdef_id()?.to_owned();
let material_id = comp.components().iter().find_map(|mat| match &*mat.kind() { let material_id = comp.components().iter().find_map(|mat| match &*mat.kind() {
ItemKind::Ingredient { .. } => Some(mat.item_definition_id().raw()?.to_owned()), ItemKind::Ingredient { .. } => {
Some(mat.item_definition_id().itemdef_id()?.to_owned())
},
_ => None, _ => None,
}); });
Some((component_id, material_id)) Some((component_id, material_id))
@ -504,7 +506,7 @@ pub fn weapon_component_to_key(
components: &[Item], components: &[Item],
) -> Result<ModularWeaponComponentKey, ModularWeaponComponentKeyError> { ) -> Result<ModularWeaponComponentKey, ModularWeaponComponentKeyError> {
match components.iter().find_map(|mat| match &*mat.kind() { match components.iter().find_map(|mat| match &*mat.kind() {
ItemKind::Ingredient { .. } => Some(mat.item_definition_id().raw()?.to_owned()), ItemKind::Ingredient { .. } => Some(mat.item_definition_id().itemdef_id()?.to_owned()),
_ => None, _ => None,
}) { }) {
Some(material_id) => Ok((item_def_id.to_owned(), material_id)), Some(material_id) => Ok((item_def_id.to_owned(), material_id)),

View File

@ -369,6 +369,7 @@ impl TradePricing {
_ if name.starts_with("common.items.crafting_ing.") => Good::Ingredients, _ if name.starts_with("common.items.crafting_ing.") => Good::Ingredients,
_ if name.starts_with("common.items.mineral.") => Good::Ingredients, _ if name.starts_with("common.items.mineral.") => Good::Ingredients,
_ if name.starts_with("common.items.log.") => Good::Ingredients,
_ if name.starts_with("common.items.flowers.") => Good::Ingredients, _ if name.starts_with("common.items.flowers.") => Good::Ingredients,
_ if name.starts_with("common.items.consumable.") => Good::Potions, _ if name.starts_with("common.items.consumable.") => Good::Potions,

View File

@ -276,16 +276,16 @@ impl SwordTreeModifiers {
const fn get() -> Self { const fn get() -> Self {
Self { Self {
dash: SwordDashModifiers { dash: SwordDashModifiers {
energy_cost: 0.9, energy_cost: 0.95,
energy_drain: 0.9, energy_drain: 0.95,
base_damage: 1.1, base_damage: 1.05,
scaled_damage: 1.1, scaled_damage: 1.05,
forward_speed: 1.05, forward_speed: 1.025,
}, },
spin: SwordSpinModifiers { spin: SwordSpinModifiers {
base_damage: 1.2, base_damage: 1.1,
swing_duration: 0.9, swing_duration: 0.95,
energy_cost: 0.9, energy_cost: 0.95,
num: 1, num: 1,
}, },
} }
@ -315,15 +315,15 @@ impl AxeTreeModifiers {
const fn get() -> Self { const fn get() -> Self {
Self { Self {
spin: AxeSpinModifiers { spin: AxeSpinModifiers {
base_damage: 1.2, base_damage: 1.1,
swing_duration: 0.85, swing_duration: 0.95,
energy_cost: 0.85, energy_cost: 0.9,
}, },
leap: AxeLeapModifiers { leap: AxeLeapModifiers {
base_damage: 1.2, base_damage: 1.1,
knockback: 1.2, knockback: 1.1,
energy_cost: 0.75, energy_cost: 0.85,
leap_strength: 1.1, leap_strength: 1.05,
}, },
} }
} }
@ -359,17 +359,17 @@ impl HammerTreeModifiers {
Self { Self {
single_strike: HammerStrikeModifiers { knockback: 1.25 }, single_strike: HammerStrikeModifiers { knockback: 1.25 },
charged: HammerChargedModifers { charged: HammerChargedModifers {
scaled_damage: 1.2, scaled_damage: 1.1,
scaled_knockback: 1.3, scaled_knockback: 1.15,
energy_drain: 0.85, energy_drain: 0.95,
charge_rate: 1.15, charge_rate: 1.1,
}, },
leap: HammerLeapModifiers { leap: HammerLeapModifiers {
base_damage: 1.25, base_damage: 1.15,
knockback: 1.3, knockback: 1.15,
energy_cost: 0.75, energy_cost: 0.85,
leap_strength: 1.1, leap_strength: 1.05,
range: 0.5, range: 0.25,
}, },
} }
} }
@ -412,25 +412,25 @@ impl BowTreeModifiers {
const fn get() -> Self { const fn get() -> Self {
Self { Self {
universal: BowUniversalModifiers { universal: BowUniversalModifiers {
projectile_speed: 1.1, projectile_speed: 1.05,
}, },
charged: BowChargedModifiers { charged: BowChargedModifiers {
damage_scaling: 1.1, damage_scaling: 1.05,
regen_scaling: 1.1, regen_scaling: 1.05,
knockback_scaling: 1.1, knockback_scaling: 1.05,
charge_rate: 1.1, charge_rate: 1.05,
move_speed: 1.1, move_speed: 1.05,
}, },
repeater: BowRepeaterModifiers { repeater: BowRepeaterModifiers {
power: 1.1, power: 1.05,
energy_cost: 0.9, energy_cost: 0.95,
max_speed: 1.2, max_speed: 1.1,
}, },
shotgun: BowShotgunModifiers { shotgun: BowShotgunModifiers {
power: 1.1, power: 1.05,
energy_cost: 0.9, energy_cost: 0.95,
num_projectiles: 1, num_projectiles: 1,
spread: 0.9, spread: 0.95,
}, },
} }
} }
@ -466,21 +466,21 @@ impl StaffTreeModifiers {
const fn get() -> Self { const fn get() -> Self {
Self { Self {
fireball: StaffFireballModifiers { fireball: StaffFireballModifiers {
power: 1.1, power: 1.05,
regen: 1.1, regen: 1.05,
range: 1.1, range: 1.05,
}, },
flamethrower: StaffFlamethrowerModifiers { flamethrower: StaffFlamethrowerModifiers {
damage: 1.2, damage: 1.1,
range: 1.1, range: 1.05,
energy_drain: 0.9, energy_drain: 0.95,
velocity: 1.1, velocity: 1.05,
}, },
shockwave: StaffShockwaveModifiers { shockwave: StaffShockwaveModifiers {
damage: 1.15, damage: 1.1,
knockback: 1.15, knockback: 1.05,
duration: 1.1, duration: 1.05,
energy_cost: 0.9, energy_cost: 0.95,
}, },
} }
} }
@ -517,21 +517,21 @@ impl SceptreTreeModifiers {
const fn get() -> Self { const fn get() -> Self {
Self { Self {
beam: SceptreBeamModifiers { beam: SceptreBeamModifiers {
damage: 1.1, damage: 1.05,
range: 1.1, range: 1.05,
energy_regen: 1.1, energy_regen: 1.05,
lifesteal: 1.05, lifesteal: 1.05,
}, },
healing_aura: SceptreHealingAuraModifiers { healing_aura: SceptreHealingAuraModifiers {
strength: 1.05, strength: 1.05,
duration: 1.1, duration: 1.05,
range: 1.1, range: 1.05,
energy_cost: 0.90, energy_cost: 0.95,
}, },
warding_aura: SceptreWardingAuraModifiers { warding_aura: SceptreWardingAuraModifiers {
strength: 1.05, strength: 1.05,
duration: 1.1, duration: 1.05,
range: 1.1, range: 1.05,
energy_cost: 0.95, energy_cost: 0.95,
}, },
} }

View File

@ -228,13 +228,13 @@ pub mod tests {
material, material,
hands, hands,
} => { } => {
item::modular::random_weapon_primary_component(*tool, *material, *hands, &mut rng).unwrap_or_else( item::modular::random_weapon_primary_component(*tool, *material, *hands, &mut rng)
|_| { .unwrap_or_else(|_| {
panic!( panic!(
"Failed to synthesize a modular weapon primary component: {tool:?} made of {material:?} that had a hand restriction of {hands:?}." "Failed to synthesize a modular weapon primary component: {tool:?} \
made of {material:?} that had a hand restriction of {hands:?}."
) )
}, });
);
}, },
} }
} }

View File

@ -392,7 +392,8 @@ impl SitePrices {
if let Some(vec) = item if let Some(vec) = item
.name .name
.as_ref() .as_ref()
.raw() // TODO: This won't handle compound items with components well, or pure modular items at all
.itemdef_id()
.and_then(TradePricing::get_materials) .and_then(TradePricing::get_materials)
{ {
vec.iter() vec.iter()

View File

@ -178,7 +178,7 @@ pub fn handle_mine_block(
tool, tool,
state.ecs().uid_from_entity(entity), state.ecs().uid_from_entity(entity),
item.item_definition_id() item.item_definition_id()
.raw() .itemdef_id()
.and_then(|id| RESOURCE_EXPERIENCE_MANIFEST.read().0.get(id).copied()), .and_then(|id| RESOURCE_EXPERIENCE_MANIFEST.read().0.get(id).copied()),
) { ) {
let skill_group = SkillGroupKind::Weapon(tool); let skill_group = SkillGroupKind::Weapon(tool);
@ -222,7 +222,7 @@ pub fn handle_mine_block(
rng.gen_bool(chance_mod * f64::from(skill_level)) rng.gen_bool(chance_mod * f64::from(skill_level))
}; };
let double_gain = item.item_definition_id().raw().map_or(false, |id| { let double_gain = item.item_definition_id().itemdef_id().map_or(false, |id| {
(id.contains("mineral.ore.") && need_double_ore(&mut rng)) (id.contains("mineral.ore.") && need_double_ore(&mut rng))
|| (id.contains("mineral.gem.") && need_double_gem(&mut rng)) || (id.contains("mineral.gem.") && need_double_gem(&mut rng))
}); });

View File

@ -679,9 +679,9 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
} => { } => {
let component_recipes = default_component_recipe_book().read(); let component_recipes = default_component_recipe_book().read();
let item_id = |slot| { let item_id = |slot| {
inventory inventory.get(slot).and_then(|item| {
.get(slot) item.item_definition_id().itemdef_id().map(String::from)
.and_then(|item| item.item_definition_id().raw().map(String::from)) })
}; };
if let Some(material_item_id) = item_id(material) { if let Some(material_item_id) = item_id(material) {
component_recipes component_recipes

View File

@ -167,6 +167,7 @@ pub fn convert_items_to_database_items(
let persistence_item_id = match item.item_definition_id() { let persistence_item_id = match item.item_definition_id() {
ItemDefinitionId::Simple(id) => id.to_owned(), ItemDefinitionId::Simple(id) => id.to_owned(),
ItemDefinitionId::Compound { simple_base, .. } => simple_base.to_owned(),
ItemDefinitionId::Modular { pseudo_base, .. } => pseudo_base.to_owned(), ItemDefinitionId::Modular { pseudo_base, .. } => pseudo_base.to_owned(),
}; };

View File

@ -17,8 +17,7 @@ use common::{
comp::inventory::{ comp::inventory::{
item::{ item::{
item_key::ItemKey, item_key::ItemKey,
modular, modular::{self, ModularComponent},
modular::ModularComponent,
tool::{AbilityMap, ToolKind}, tool::{AbilityMap, ToolKind},
Item, ItemBase, ItemDef, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality, Item, ItemBase, ItemDef, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality,
TagExampleInfo, TagExampleInfo,
@ -257,6 +256,10 @@ impl CraftingTab {
CraftingTab::Utility => item.tags().contains(&ItemTag::Utility), CraftingTab::Utility => item.tags().contains(&ItemTag::Utility),
CraftingTab::Weapon => match &*item.kind() { CraftingTab::Weapon => match &*item.kind() {
ItemKind::Tool(_) => !item.tags().contains(&ItemTag::CraftingTool), ItemKind::Tool(_) => !item.tags().contains(&ItemTag::CraftingTool),
ItemKind::ModularComponent(
ModularComponent::ToolPrimaryComponent { .. }
| ModularComponent::ToolSecondaryComponent { .. },
) => true,
_ => false, _ => false,
}, },
} }
@ -900,7 +903,7 @@ impl<'a> Widget for Crafting<'a> {
.filter(|(key, _)| key.toolkind == toolkind) .filter(|(key, _)| key.toolkind == toolkind)
.any(|(key, _)| { .any(|(key, _)| {
Some(key.material.as_str()) Some(key.material.as_str())
== item.item_definition_id().raw() == item.item_definition_id().itemdef_id()
}) })
}) })
} else { } else {
@ -991,7 +994,7 @@ impl<'a> Widget for Crafting<'a> {
.filter(|(key, _)| key.toolkind == toolkind) .filter(|(key, _)| key.toolkind == toolkind)
.any(|(key, _)| { .any(|(key, _)| {
key.modifier.as_deref() key.modifier.as_deref()
== item.item_definition_id().raw() == item.item_definition_id().itemdef_id()
}) })
}) })
} else { } else {
@ -1143,7 +1146,9 @@ impl<'a> Widget for Crafting<'a> {
if let Some(material) = primary_slot if let Some(material) = primary_slot
.invslot .invslot
.and_then(|slot| self.inventory.get(slot)) .and_then(|slot| self.inventory.get(slot))
.and_then(|item| item.item_definition_id().raw().map(String::from)) .and_then(|item| {
item.item_definition_id().itemdef_id().map(String::from)
})
{ {
let component_key = ComponentKey { let component_key = ComponentKey {
toolkind, toolkind,
@ -1152,7 +1157,7 @@ impl<'a> Widget for Crafting<'a> {
.invslot .invslot
.and_then(|slot| self.inventory.get(slot)) .and_then(|slot| self.inventory.get(slot))
.and_then(|item| { .and_then(|item| {
item.item_definition_id().raw().map(String::from) item.item_definition_id().itemdef_id().map(String::from)
}), }),
}; };
self.client.component_recipe_book().get(&component_key).map( self.client.component_recipe_book().get(&component_key).map(
@ -1451,14 +1456,16 @@ impl<'a> Widget for Crafting<'a> {
RecipeKind::Component(toolkind) => { RecipeKind::Component(toolkind) => {
if let Some(material) = modular_primary_slot if let Some(material) = modular_primary_slot
.and_then(|slot| self.inventory.get(slot)) .and_then(|slot| self.inventory.get(slot))
.and_then(|item| item.item_definition_id().raw().map(String::from)) .and_then(|item| item.item_definition_id().itemdef_id().map(String::from))
{ {
let component_key = ComponentKey { let component_key = ComponentKey {
toolkind, toolkind,
material, material,
modifier: modular_secondary_slot modifier: modular_secondary_slot
.and_then(|slot| self.inventory.get(slot)) .and_then(|slot| self.inventory.get(slot))
.and_then(|item| item.item_definition_id().raw().map(String::from)), .and_then(|item| {
item.item_definition_id().itemdef_id().map(String::from)
}),
}; };
if let Some(comp_recipe) = if let Some(comp_recipe) =
self.client.component_recipe_book().get(&component_key) self.client.component_recipe_book().get(&component_key)
@ -1544,7 +1551,7 @@ impl<'a> Widget for Crafting<'a> {
slot.as_ref().and_then(|item| { slot.as_ref().and_then(|item| {
if item.matches_recipe_input(recipe_input, amount) { if item.matches_recipe_input(recipe_input, amount) {
item.item_definition_id() item.item_definition_id()
.raw() .itemdef_id()
.map(Arc::<ItemDef>::load_expect_cloned) .map(Arc::<ItemDef>::load_expect_cloned)
} else { } else {
None None
@ -1562,7 +1569,7 @@ impl<'a> Widget for Crafting<'a> {
slot.as_ref().and_then(|item| { slot.as_ref().and_then(|item| {
if item.matches_recipe_input(recipe_input, amount) { if item.matches_recipe_input(recipe_input, amount) {
item.item_definition_id() item.item_definition_id()
.raw() .itemdef_id()
.map(Arc::<ItemDef>::load_expect_cloned) .map(Arc::<ItemDef>::load_expect_cloned)
} else { } else {
None None
@ -1572,7 +1579,7 @@ impl<'a> Widget for Crafting<'a> {
.or_else(|| { .or_else(|| {
item_defs.first().and_then(|i| { item_defs.first().and_then(|i| {
i.item_definition_id() i.item_definition_id()
.raw() .itemdef_id()
.map(Arc::<ItemDef>::load_expect_cloned) .map(Arc::<ItemDef>::load_expect_cloned)
}) })
}), }),

View File

@ -6,7 +6,7 @@ use super::{
}; };
use crate::ui::{fonts::Fonts, ImageFrame, ItemTooltip, ItemTooltipManager, ItemTooltipable}; use crate::ui::{fonts::Fonts, ImageFrame, ItemTooltip, ItemTooltipManager, ItemTooltipable};
use client::Client; use client::Client;
use common::comp::inventory::item::{ItemDef, ItemDesc, MaterialStatManifest, Quality}; use common::comp::inventory::item::{Item, ItemDesc, MaterialStatManifest, Quality};
use conrod_core::{ use conrod_core::{
color, color,
position::Dimension, position::Dimension,
@ -14,7 +14,7 @@ use conrod_core::{
widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
}; };
use i18n::Localization; use i18n::Localization;
use std::{collections::VecDeque, sync::Arc}; use std::collections::VecDeque;
widget_ids! { widget_ids! {
struct Ids{ struct Ids{
@ -97,7 +97,7 @@ impl<'a> LootScroller<'a> {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct LootMessage { pub struct LootMessage {
pub item: Arc<ItemDef>, pub item: Item,
pub amount: u32, pub amount: u32,
} }
@ -162,11 +162,9 @@ impl<'a> Widget for LootScroller<'a> {
state.update(|s| { state.update(|s| {
s.messages.retain(|(message, t)| { s.messages.retain(|(message, t)| {
if *t >= oldest_merge_pulse { if *t >= oldest_merge_pulse {
if let Some(i) = self if let Some(i) = self.new_messages.iter().position(|m| {
.new_messages m.item.item_definition_id() == message.item.item_definition_id()
.iter() }) {
.position(|m| m.item.id() == message.item.id())
{
self.new_messages[i].amount += message.amount; self.new_messages[i].amount += message.amount;
false false
} else { } else {
@ -310,7 +308,7 @@ impl<'a> Widget for LootScroller<'a> {
Quality::Artifact => self.imgs.inv_slot_orange, Quality::Artifact => self.imgs.inv_slot_orange,
_ => self.imgs.inv_slot_red, _ => self.imgs.inv_slot_red,
}; };
let quality_col = get_quality_col(&**item); let quality_col = get_quality_col(&*item);
Image::new(self.imgs.pixel) Image::new(self.imgs.pixel)
.color(Some(shade_color(quality_col.alpha(0.7)))) .color(Some(shade_color(quality_col.alpha(0.7))))
@ -325,7 +323,7 @@ impl<'a> Widget for LootScroller<'a> {
.set(state.ids.message_icon_frames[i], ui); .set(state.ids.message_icon_frames[i], ui);
Image::new(animate_by_pulse( Image::new(animate_by_pulse(
&self.item_imgs.img_ids_or_not_found_img((&**item).into()), &self.item_imgs.img_ids_or_not_found_img((&*item).into()),
self.pulse, self.pulse,
)) ))
.color(Some(shade_color(color::hsla(0.0, 0.0, 1.0, 1.0)))) .color(Some(shade_color(color::hsla(0.0, 0.0, 1.0, 1.0))))
@ -333,7 +331,7 @@ impl<'a> Widget for LootScroller<'a> {
.middle_of(state.ids.message_icon_bgs[i]) .middle_of(state.ids.message_icon_bgs[i])
.with_item_tooltip( .with_item_tooltip(
self.item_tooltip_manager, self.item_tooltip_manager,
core::iter::once(&**item as &dyn ItemDesc), core::iter::once(&*item as &dyn ItemDesc),
&None, &None,
&item_tooltip, &item_tooltip,
) )

View File

@ -3693,7 +3693,7 @@ impl Hud {
if let Some(item) = inventory.get(slot) { if let Some(item) = inventory.get(slot) {
if let Some(materials) = item if let Some(materials) = item
.item_definition_id() .item_definition_id()
.raw() .itemdef_id()
.and_then(TradePricing::get_materials) .and_then(TradePricing::get_materials)
{ {
let unit_price: f32 = materials let unit_price: f32 = materials

View File

@ -226,6 +226,9 @@ impl CharacterCacheKey {
ItemDefinitionId::Modular { .. } => { ItemDefinitionId::Modular { .. } => {
ToolKey::Modular(modular::weapon_to_key(item)) ToolKey::Modular(modular::weapon_to_key(item))
}, },
ItemDefinitionId::Compound { simple_base, .. } => {
ToolKey::Tool(String::from(simple_base))
},
}; };
Some(CharacterToolKey { Some(CharacterToolKey {
active: inventory active: inventory

View File

@ -1340,7 +1340,7 @@ impl<'a> Widget for ItemTooltip<'a> {
// Price display // Price display
if let Some((buy, sell, factor)) = item if let Some((buy, sell, factor)) = item
.item_definition_id() .item_definition_id()
.raw() .itemdef_id()
.and_then(|id| util::price_desc(self.prices, id, i18n)) .and_then(|id| util::price_desc(self.prices, id, i18n))
{ {
widget::Text::new(&buy) widget::Text::new(&buy)
@ -1439,7 +1439,7 @@ impl<'a> Widget for ItemTooltip<'a> {
// Price // Price
let price_h: f64 = if let Some((buy, sell, _)) = item let price_h: f64 = if let Some((buy, sell, _)) = item
.item_definition_id() .item_definition_id()
.raw() .itemdef_id()
.and_then(|id| util::price_desc(self.prices, id, self.localized_strings)) .and_then(|id| util::price_desc(self.prices, id, self.localized_strings))
{ {
//Get localized tooltip strings (gotten here because these should only show if //Get localized tooltip strings (gotten here because these should only show if