mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Finish plumbing MaterialStatsManifest. Fix issue with speed clamping when recursing through components. Improve statblocks in item tooltips.
This commit is contained in:
parent
78014d7d3b
commit
e1484c28c0
@ -5,5 +5,5 @@ ItemDef(
|
||||
kind: "TinIngot",
|
||||
),
|
||||
quality: Common,
|
||||
tags: [MetalIngot(0.25)],
|
||||
tags: [MetalIngot],
|
||||
)
|
||||
|
@ -363,11 +363,11 @@
|
||||
(Item("common.items.crafting_tools.sewing_set"), 0),
|
||||
],
|
||||
),
|
||||
"metal_blade": (
|
||||
("common.items.crafting_ing.modular.damage.sword.metal_blade", 1),
|
||||
[
|
||||
(Tag(MetalIngot), 5),
|
||||
(Item("common.items.crafting_tools.craftsman_hammer"), 0),
|
||||
],
|
||||
),
|
||||
//"metal_blade": (
|
||||
// ("common.items.crafting_ing.modular.damage.sword.metal_blade", 1),
|
||||
// [
|
||||
// (Tag(MetalIngot), 5),
|
||||
// (Item("common.items.crafting_tools.craftsman_hammer"), 0),
|
||||
// ],
|
||||
//),
|
||||
}
|
||||
|
@ -72,6 +72,13 @@ impl Stats {
|
||||
speed: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clamp_speed(mut self) -> Stats {
|
||||
// if a tool has 0.0 speed, that panics due to being infinite duration, so
|
||||
// enforce speed >= 0.1 on the final product (but not the intermediates)
|
||||
self.speed = self.speed.max(0.1);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Asset for Stats {
|
||||
@ -112,7 +119,7 @@ impl DivAssign<usize> for Stats {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct MaterialStatManifest(HashMap<String, Stats>);
|
||||
pub struct MaterialStatManifest(pub HashMap<String, Stats>);
|
||||
|
||||
// This could be a Compound that also loads the keys, but the RecipeBook
|
||||
// Compound impl already does that, so checking for existence here is redundant.
|
||||
@ -166,16 +173,13 @@ impl StatKind {
|
||||
average_mult /= multipliers.len();
|
||||
stats *= average_mult;
|
||||
}
|
||||
// if an item has 0.0 speed, that panics due to being infinite duration, so
|
||||
// enforce speed >= 0.1
|
||||
stats.speed = stats.speed.max(0.1);
|
||||
stats
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(&MaterialStatManifest, &[Item], &Tool)> for Stats {
|
||||
fn from((msm, components, tool): (&MaterialStatManifest, &[Item], &Tool)) -> Self {
|
||||
let raw_stats = tool.stats.resolve_stats(msm, components);
|
||||
let raw_stats = tool.stats.resolve_stats(msm, components).clamp_speed();
|
||||
let (power, speed) = match tool.hands {
|
||||
Hands::One => (0.67, 1.33),
|
||||
// TODO: Restore this when one-handed weapons are made accessible
|
||||
@ -245,7 +249,10 @@ impl Tool {
|
||||
}
|
||||
|
||||
pub fn base_speed(&self, msm: &MaterialStatManifest, components: &[Item]) -> f32 {
|
||||
self.stats.resolve_stats(msm, components).speed
|
||||
self.stats
|
||||
.resolve_stats(msm, components)
|
||||
.clamp_speed()
|
||||
.speed
|
||||
}
|
||||
|
||||
pub fn equip_time(&self, msm: &MaterialStatManifest, components: &[Item]) -> Duration {
|
||||
|
@ -509,6 +509,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Head)),
|
||||
|| (i18n.get("hud.bag.head"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let head_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Head))
|
||||
@ -531,6 +532,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Neck)),
|
||||
|| (i18n.get("hud.bag.neck"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let neck_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Neck))
|
||||
@ -554,6 +556,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Chest)),
|
||||
|| (i18n.get("hud.bag.chest"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let chest_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Chest))
|
||||
@ -576,6 +579,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Shoulders)),
|
||||
|| (i18n.get("hud.bag.shoulders"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let shoulder_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Shoulders))
|
||||
@ -598,6 +602,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Hands)),
|
||||
|| (i18n.get("hud.bag.hands"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let chest_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Hands))
|
||||
@ -620,6 +625,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Belt)),
|
||||
|| (i18n.get("hud.bag.belt"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let belt_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Belt))
|
||||
@ -642,6 +648,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Legs)),
|
||||
|| (i18n.get("hud.bag.legs"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let legs_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Legs))
|
||||
@ -664,6 +671,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Ring1)),
|
||||
|| (i18n.get("hud.bag.ring"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let ring_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Ring1))
|
||||
@ -686,6 +694,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Ring2)),
|
||||
|| (i18n.get("hud.bag.ring"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let ring2_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Ring2))
|
||||
@ -708,6 +717,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Back)),
|
||||
|| (i18n.get("hud.bag.back"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let back_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Back))
|
||||
@ -730,6 +740,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Feet)),
|
||||
|| (i18n.get("hud.bag.feet"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let foot_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Feet))
|
||||
@ -749,9 +760,11 @@ impl<'a> Widget for Bag<'a> {
|
||||
)
|
||||
.set(state.ids.feet_slot, ui);
|
||||
// Lantern
|
||||
let (title, desc) = loadout_slot_text(inventory.equipped(EquipSlot::Lantern), || {
|
||||
(i18n.get("hud.bag.lantern"), "")
|
||||
});
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Lantern),
|
||||
|| (i18n.get("hud.bag.lantern"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let lantern_q_col = inventory
|
||||
.equipped(EquipSlot::Lantern)
|
||||
.map(|item| get_quality_col(item))
|
||||
@ -770,9 +783,11 @@ impl<'a> Widget for Bag<'a> {
|
||||
)
|
||||
.set(state.ids.lantern_slot, ui);
|
||||
// Glider
|
||||
let (title, desc) = loadout_slot_text(inventory.equipped(EquipSlot::Glider), || {
|
||||
(i18n.get("hud.bag.glider"), "")
|
||||
});
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Glider),
|
||||
|| (i18n.get("hud.bag.glider"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let glider_q_col = inventory
|
||||
.equipped(EquipSlot::Glider)
|
||||
.map(|item| get_quality_col(item))
|
||||
@ -794,6 +809,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Tabard)),
|
||||
|| (i18n.get("hud.bag.tabard"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let tabard_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Tabard))
|
||||
@ -813,9 +829,11 @@ impl<'a> Widget for Bag<'a> {
|
||||
)
|
||||
.set(state.ids.tabard_slot, ui);
|
||||
// Mainhand/Left-Slot
|
||||
let (title, desc) = loadout_slot_text(inventory.equipped(EquipSlot::Mainhand), || {
|
||||
(i18n.get("hud.bag.mainhand"), "")
|
||||
});
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Mainhand),
|
||||
|| (i18n.get("hud.bag.mainhand"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let mainhand_q_col = inventory
|
||||
.equipped(EquipSlot::Mainhand)
|
||||
.map(|item| get_quality_col(item))
|
||||
@ -834,9 +852,11 @@ impl<'a> Widget for Bag<'a> {
|
||||
)
|
||||
.set(state.ids.mainhand_slot, ui);
|
||||
// Offhand/Right-Slot
|
||||
let (title, desc) = loadout_slot_text(inventory.equipped(EquipSlot::Offhand), || {
|
||||
(i18n.get("hud.bag.offhand"), "")
|
||||
});
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Offhand),
|
||||
|| (i18n.get("hud.bag.offhand"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let offhand_q_col = inventory
|
||||
.equipped(EquipSlot::Offhand)
|
||||
.map(|item| get_quality_col(item))
|
||||
@ -859,6 +879,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Bag1)),
|
||||
|| (i18n.get("hud.bag.bag"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let bag1_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Bag1))
|
||||
@ -885,6 +906,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Bag2)),
|
||||
|| (i18n.get("hud.bag.bag"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let bag2_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Bag2))
|
||||
@ -907,6 +929,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Bag3)),
|
||||
|| (i18n.get("hud.bag.bag"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let bag3_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Bag3))
|
||||
@ -929,6 +952,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
let (title, desc) = loadout_slot_text(
|
||||
inventory.equipped(EquipSlot::Armor(ArmorSlot::Bag4)),
|
||||
|| (i18n.get("hud.bag.bag"), ""),
|
||||
&self.msm,
|
||||
);
|
||||
let bag4_q_col = inventory
|
||||
.equipped(EquipSlot::Armor(ArmorSlot::Bag4))
|
||||
@ -1011,7 +1035,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
}
|
||||
|
||||
if let Some(item) = item {
|
||||
let (title, desc) = super::util::item_text(item);
|
||||
let (title, desc) = super::util::item_text(item, &self.msm);
|
||||
let quality_col = get_quality_col(item);
|
||||
let quality_col_img = match item.quality() {
|
||||
Quality::Low => self.imgs.inv_slot_grey,
|
||||
|
@ -12,7 +12,7 @@ use client::{self, Client};
|
||||
use common::{
|
||||
assets::AssetExt,
|
||||
comp::{
|
||||
item::{ItemDef, ItemDesc, Quality, TagExampleInfo},
|
||||
item::{ItemDef, ItemDesc, MaterialStatManifest, Quality, TagExampleInfo},
|
||||
Inventory,
|
||||
},
|
||||
recipe::RecipeInput,
|
||||
@ -68,6 +68,7 @@ pub struct Crafting<'a> {
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
item_imgs: &'a ItemImgs,
|
||||
inventory: &'a Inventory,
|
||||
msm: &'a MaterialStatManifest,
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
}
|
||||
@ -83,6 +84,7 @@ impl<'a> Crafting<'a> {
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
item_imgs: &'a ItemImgs,
|
||||
inventory: &'a Inventory,
|
||||
msm: &'a MaterialStatManifest,
|
||||
) -> Self {
|
||||
Self {
|
||||
client,
|
||||
@ -94,6 +96,7 @@ impl<'a> Crafting<'a> {
|
||||
tooltip_manager,
|
||||
item_imgs,
|
||||
inventory,
|
||||
msm,
|
||||
common: widget::CommonBuilder::default(),
|
||||
}
|
||||
}
|
||||
@ -297,7 +300,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
{
|
||||
let output_text = format!("x{}", &recipe.output.1.to_string());
|
||||
// Output Image
|
||||
let (title, desc) = super::util::item_text(&*recipe.output.0);
|
||||
let (title, desc) = super::util::item_text(&*recipe.output.0, self.msm);
|
||||
let quality_col = get_quality_col(&*recipe.output.0);
|
||||
Button::image(animate_by_pulse(
|
||||
&self
|
||||
@ -488,7 +491,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
};
|
||||
frame.set(state.ids.ingredient_frame[i], ui);
|
||||
//Item Image
|
||||
let (title, desc) = super::util::item_text(&*item_def);
|
||||
let (title, desc) = super::util::item_text(&*item_def, self.msm);
|
||||
Button::image(animate_by_pulse(
|
||||
&self.item_imgs.img_ids_or_not_found_img((&*item_def).into()),
|
||||
self.pulse,
|
||||
|
@ -2143,6 +2143,7 @@ impl Hud {
|
||||
tooltip_manager,
|
||||
&mut self.slot_manager,
|
||||
i18n,
|
||||
&msm,
|
||||
self.pulse,
|
||||
)
|
||||
.set(self.ids.trade, ui_widgets)
|
||||
@ -2207,6 +2208,7 @@ impl Hud {
|
||||
tooltip_manager,
|
||||
&self.item_imgs,
|
||||
&inventory,
|
||||
&msm,
|
||||
)
|
||||
.set(self.ids.crafting_window, ui_widgets)
|
||||
{
|
||||
|
@ -400,7 +400,13 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.stamina_txt, ui);
|
||||
}
|
||||
// Slots
|
||||
let content_source = (self.hotbar, self.inventory, self.energy, self.ability_map); // TODO: avoid this
|
||||
let content_source = (
|
||||
self.hotbar,
|
||||
self.inventory,
|
||||
self.energy,
|
||||
self.ability_map,
|
||||
self.msm,
|
||||
); // TODO: avoid this
|
||||
let image_source = (self.item_imgs, self.imgs);
|
||||
let mut slot_maker = SlotMaker {
|
||||
// TODO: is a separate image needed for the frame?
|
||||
|
@ -2,13 +2,12 @@ use super::{
|
||||
hotbar::{self, Slot as HotbarSlot},
|
||||
img_ids,
|
||||
item_imgs::{ItemImgs, ItemKey},
|
||||
util::MATERIAL_STATS_MANIFEST,
|
||||
};
|
||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||
use common::comp::{
|
||||
item::{
|
||||
tool::{AbilityMap, Hands, ToolKind},
|
||||
ItemKind,
|
||||
ItemKind, MaterialStatManifest,
|
||||
},
|
||||
slot::InvSlotId,
|
||||
Energy, Inventory,
|
||||
@ -102,7 +101,13 @@ pub enum HotbarImage {
|
||||
BowJumpBurst,
|
||||
}
|
||||
|
||||
type HotbarSource<'a> = (&'a hotbar::State, &'a Inventory, &'a Energy, &'a AbilityMap);
|
||||
type HotbarSource<'a> = (
|
||||
&'a hotbar::State,
|
||||
&'a Inventory,
|
||||
&'a Energy,
|
||||
&'a AbilityMap,
|
||||
&'a MaterialStatManifest,
|
||||
);
|
||||
type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs);
|
||||
|
||||
impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
@ -110,7 +115,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
|
||||
fn image_key(
|
||||
&self,
|
||||
(hotbar, inventory, energy, ability_map): &HotbarSource<'a>,
|
||||
(hotbar, inventory, energy, ability_map, msm): &HotbarSource<'a>,
|
||||
) -> Option<(Self::ImageKey, Option<Color>)> {
|
||||
hotbar.get(*self).and_then(|contents| match contents {
|
||||
hotbar::SlotContents::Inventory(idx) => inventory
|
||||
@ -131,11 +136,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
(
|
||||
i,
|
||||
if let Some(skill) = tool
|
||||
.get_abilities(
|
||||
&MATERIAL_STATS_MANIFEST,
|
||||
item.components(),
|
||||
ability_map,
|
||||
)
|
||||
.get_abilities(&msm, item.components(), ability_map)
|
||||
.abilities
|
||||
.get(0)
|
||||
{
|
||||
@ -178,11 +179,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
(
|
||||
i,
|
||||
if let Some(skill) = tool
|
||||
.get_abilities(
|
||||
&MATERIAL_STATS_MANIFEST,
|
||||
item.components(),
|
||||
ability_map,
|
||||
)
|
||||
.get_abilities(&msm, item.components(), ability_map)
|
||||
.abilities
|
||||
.get(skill_index)
|
||||
{
|
||||
@ -201,7 +198,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
})
|
||||
}
|
||||
|
||||
fn amount(&self, (hotbar, inventory, _, _): &HotbarSource<'a>) -> Option<u32> {
|
||||
fn amount(&self, (hotbar, inventory, _, _, _): &HotbarSource<'a>) -> Option<u32> {
|
||||
hotbar
|
||||
.get(*self)
|
||||
.and_then(|content| match content {
|
||||
|
@ -15,7 +15,10 @@ use crate::{
|
||||
};
|
||||
use client::Client;
|
||||
use common::{
|
||||
comp::{inventory::item::Quality, Inventory},
|
||||
comp::{
|
||||
inventory::item::{MaterialStatManifest, Quality},
|
||||
Inventory,
|
||||
},
|
||||
trade::{PendingTrade, TradeAction, TradePhase},
|
||||
};
|
||||
use common_net::sync::WorldSyncExt;
|
||||
@ -61,6 +64,7 @@ pub struct Trade<'a> {
|
||||
common: widget::CommonBuilder,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
localized_strings: &'a Localization,
|
||||
msm: &'a MaterialStatManifest,
|
||||
pulse: f32,
|
||||
}
|
||||
|
||||
@ -74,6 +78,7 @@ impl<'a> Trade<'a> {
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
localized_strings: &'a Localization,
|
||||
msm: &'a MaterialStatManifest,
|
||||
pulse: f32,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -84,9 +89,9 @@ impl<'a> Trade<'a> {
|
||||
rot_imgs,
|
||||
tooltip_manager,
|
||||
common: widget::CommonBuilder::default(),
|
||||
//tooltip_manager,
|
||||
slot_manager,
|
||||
localized_strings,
|
||||
msm,
|
||||
pulse,
|
||||
}
|
||||
}
|
||||
@ -295,7 +300,7 @@ impl<'a> Trade<'a> {
|
||||
);
|
||||
let slot_id = state.ids.inv_slots[i + who * MAX_TRADE_SLOTS];
|
||||
if let Some(Some(item)) = slot.invslot.and_then(|slotid| inventory.slot(slotid)) {
|
||||
let (title, desc) = super::util::item_text(item);
|
||||
let (title, desc) = super::util::item_text(item, self.msm);
|
||||
let quality_col = get_quality_col(item);
|
||||
let quality_col_img = match item.quality() {
|
||||
Quality::Low => self.imgs.inv_slot_grey,
|
||||
|
@ -1,30 +1,28 @@
|
||||
use common::comp::item::{
|
||||
armor::{Armor, ArmorKind, Protection},
|
||||
tool::{Hands, StatKind, Tool, ToolKind},
|
||||
tool::{Hands, StatKind, Stats, Tool, ToolKind},
|
||||
Item, ItemDesc, ItemKind, MaterialStatManifest, ModularComponent,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{borrow::Cow, fmt::Write};
|
||||
|
||||
lazy_static! {
|
||||
// TODO: even more plumbing
|
||||
pub static ref MATERIAL_STATS_MANIFEST: MaterialStatManifest = MaterialStatManifest::default();
|
||||
}
|
||||
|
||||
pub fn loadout_slot_text<'a>(
|
||||
item: Option<&'a impl ItemDesc>,
|
||||
mut empty: impl FnMut() -> (&'a str, &'a str),
|
||||
msm: &'a MaterialStatManifest,
|
||||
) -> (&'a str, Cow<'a, str>) {
|
||||
item.map_or_else(
|
||||
|| {
|
||||
let (title, desc) = empty();
|
||||
(title, Cow::Borrowed(desc))
|
||||
},
|
||||
item_text,
|
||||
|item| item_text(item, msm),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn item_text<'a>(item: &'a impl ItemDesc) -> (&'_ str, Cow<'a, str>) {
|
||||
pub fn item_text<'a>(
|
||||
item: &'a impl ItemDesc,
|
||||
msm: &'a MaterialStatManifest,
|
||||
) -> (&'a str, Cow<'a, str>) {
|
||||
let desc: Cow<str> = match item.kind() {
|
||||
ItemKind::Armor(armor) => {
|
||||
Cow::Owned(armor_desc(armor, item.description(), item.num_slots()))
|
||||
@ -32,20 +30,24 @@ pub fn item_text<'a>(item: &'a impl ItemDesc) -> (&'_ str, Cow<'a, str>) {
|
||||
ItemKind::Tool(tool) => Cow::Owned(tool_desc(
|
||||
&tool,
|
||||
item.components(),
|
||||
&MATERIAL_STATS_MANIFEST,
|
||||
&msm,
|
||||
item.description(),
|
||||
)),
|
||||
ItemKind::ModularComponent(mc) => Cow::Owned(modular_component_desc(
|
||||
mc,
|
||||
item.components(),
|
||||
&MATERIAL_STATS_MANIFEST,
|
||||
&msm,
|
||||
item.description(),
|
||||
)),
|
||||
ItemKind::Glider(_glider) => Cow::Owned(glider_desc(item.description())),
|
||||
ItemKind::Consumable { .. } => Cow::Owned(consumable_desc(item.description())),
|
||||
ItemKind::Throwable { .. } => Cow::Owned(throwable_desc(item.description())),
|
||||
ItemKind::Utility { .. } => Cow::Owned(utility_desc(item.description())),
|
||||
ItemKind::Ingredient { .. } => Cow::Owned(ingredient_desc(item.description())),
|
||||
ItemKind::Ingredient { .. } => Cow::Owned(ingredient_desc(
|
||||
item.description(),
|
||||
item.item_definition_id(),
|
||||
msm,
|
||||
)),
|
||||
ItemKind::Lantern { .. } => Cow::Owned(lantern_desc(item.description())),
|
||||
ItemKind::TagExamples { .. } => Cow::Borrowed(item.description()),
|
||||
//_ => Cow::Borrowed(item.description()),
|
||||
@ -61,13 +63,11 @@ fn modular_component_desc(
|
||||
msm: &MaterialStatManifest,
|
||||
description: &str,
|
||||
) -> String {
|
||||
let mut result = format!(
|
||||
"Modular Component\n\n{:?}\n\n{}",
|
||||
StatKind::Direct(mc.stats).resolve_stats(msm, components),
|
||||
description
|
||||
);
|
||||
let stats = StatKind::Direct(mc.stats).resolve_stats(msm, components);
|
||||
let statblock = statblock_desc(&stats);
|
||||
let mut result = format!("Modular Component\n\n{}\n\n{}", statblock, description);
|
||||
if !components.is_empty() {
|
||||
result += "Made from:\n";
|
||||
result += "\n\nMade from:\n";
|
||||
for component in components {
|
||||
result += component.name();
|
||||
result += "\n"
|
||||
@ -88,7 +88,14 @@ fn throwable_desc(desc: &str) -> String {
|
||||
|
||||
fn utility_desc(desc: &str) -> String { format!("{}\n\n<Right-Click to use>", desc) }
|
||||
|
||||
fn ingredient_desc(desc: &str) -> String { format!("Crafting Ingredient\n\n{}", desc) }
|
||||
fn ingredient_desc(desc: &str, item_id: &str, msm: &MaterialStatManifest) -> String {
|
||||
let mut result = format!("Crafting Ingredient\n\n{}", desc);
|
||||
if let Some(stats) = msm.0.get(item_id) {
|
||||
result += "\n\nStat multipliers:\n";
|
||||
result += &statblock_desc(stats);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn lantern_desc(desc: &str) -> String { format!("Lantern\n\n{}\n\n<Right-Click to use>", desc) }
|
||||
|
||||
@ -153,26 +160,16 @@ fn tool_desc(tool: &Tool, components: &[Item], msm: &MaterialStatManifest, desc:
|
||||
};
|
||||
|
||||
// Get tool stats
|
||||
let power = tool.base_power(msm, components);
|
||||
let stats = tool.stats.resolve_stats(msm, components).clamp_speed();
|
||||
|
||||
//let poise_strength = tool.base_poise_strength();
|
||||
let hands = match tool.hands {
|
||||
Hands::One => "One",
|
||||
Hands::Two => "Two",
|
||||
};
|
||||
let speed = tool.base_speed(msm, components);
|
||||
|
||||
let mut result = format!(
|
||||
"{}-Handed {}\n\nDPS: {:0.1}\n\nPower: {:0.1}\n\nSpeed: {:0.1}\n\n",
|
||||
// add back when ready for poise
|
||||
//"{}\n\nDPS: {:0.1}\n\nPower: {:0.1}\n\nPoise Strength: {:0.1}\n\nSpeed: \
|
||||
// {:0.1}\n\n{}\n\n<Right-Click to use>",
|
||||
hands,
|
||||
kind,
|
||||
speed * power * 10.0, // Damage per second
|
||||
power * 10.0,
|
||||
//poise_strength * 10.0,
|
||||
speed
|
||||
);
|
||||
let mut result = format!("{}-Handed {}\n\n", hands, kind);
|
||||
result += &statblock_desc(&stats);
|
||||
if !components.is_empty() {
|
||||
result += "Made from:\n";
|
||||
for component in components {
|
||||
@ -188,6 +185,19 @@ fn tool_desc(tool: &Tool, components: &[Item], msm: &MaterialStatManifest, desc:
|
||||
result
|
||||
}
|
||||
|
||||
fn statblock_desc(stats: &Stats) -> String {
|
||||
format!(
|
||||
"DPS: {:0.1}\n\nPower: {:0.1}\n\nSpeed: {:0.1}\n\n",
|
||||
// add back when ready for poise
|
||||
//"{}\n\nDPS: {:0.1}\n\nPower: {:0.1}\n\nPoise Strength: {:0.1}\n\nSpeed: \
|
||||
// {:0.1}\n\n{}\n\n<Right-Click to use>",
|
||||
stats.speed * stats.power * 10.0, // Damage per second
|
||||
stats.power * 10.0,
|
||||
//stats.poise_strength * 10.0,
|
||||
stats.speed
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -234,11 +244,29 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_ingredient_desc() {
|
||||
let item_description = "mushrooms";
|
||||
let mut testmsm = MaterialStatManifest(hashbrown::HashMap::new());
|
||||
testmsm.0.insert(
|
||||
"common.items.crafting_ing.bronze_ingot".to_string(),
|
||||
Stats {
|
||||
equip_time_millis: 0,
|
||||
power: 3.0,
|
||||
poise_strength: 5.0,
|
||||
speed: 7.0,
|
||||
},
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"Crafting Ingredient\n\nmushrooms",
|
||||
ingredient_desc(item_description)
|
||||
ingredient_desc("mushrooms", "common.items.food.mushroom", &testmsm)
|
||||
);
|
||||
assert_eq!(
|
||||
"Crafting Ingredient\n\nA bronze ingot.\n\nStat multipliers:\nDPS: 210.0\n\nPower: \
|
||||
30.0\n\nSpeed: 7.0\n\n",
|
||||
ingredient_desc(
|
||||
"A bronze ingot.",
|
||||
"common.items.crafting_ing.bronze_ingot",
|
||||
&testmsm
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user