Added handedness requirements to recipes and components.

This commit is contained in:
Sam 2021-07-25 16:27:00 -05:00
parent 68c8160ecb
commit 85b7382487
15 changed files with 260 additions and 172 deletions

View File

@ -6,16 +6,19 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 1.1,
effect_power: 1.6,
speed: 0.85,
power: 0.9,
effect_power: 2.0,
speed: 0.8,
crit_chance: 0.15,
range: 1.0,
energy_efficiency: 0.8,
buff_strength: 0.8,
),
hand_restriction: Some(Two),
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -6,16 +6,19 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 0.7,
power: 0.9,
effect_power: 0.8,
speed: 1.5,
crit_chance: 0.2,
range: 0.8,
energy_efficiency: 1.2,
buff_strength: 1.0,
crit_chance: 0.15,
range: 1.0,
energy_efficiency: 0.8,
buff_strength: 0.8,
),
hand_restriction: Some(One),
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
],
)

View File

@ -14,8 +14,12 @@ ItemDef(
energy_efficiency: 1.0,
buff_strength: 1.0,
),
hand_restriction: None,
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -6,16 +6,20 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 0.8,
power: 0.9,
effect_power: 0.8,
speed: 1.0,
speed: 0.9,
crit_chance: 0.5,
range: 1.0,
energy_efficiency: 1.1,
energy_efficiency: 0.8,
buff_strength: 0.8,
),
hand_restriction: None,
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -6,16 +6,20 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 1.6,
effect_power: 0.9,
speed: 0.8,
crit_chance: 0.2,
range: 0.9,
energy_efficiency: 0.9,
buff_strength: 0.9,
power: 1.5,
effect_power: 0.8,
speed: 0.9,
crit_chance: 0.15,
range: 1.0,
energy_efficiency: 0.8,
buff_strength: 0.8,
),
hand_restriction: None,
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -6,16 +6,20 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 0.8,
effect_power: 0.7,
power: 0.9,
effect_power: 0.8,
speed: 0.9,
crit_chance: 0.25,
crit_chance: 0.15,
range: 1.0,
energy_efficiency: 0.75,
buff_strength: 1.8,
energy_efficiency: 0.8,
buff_strength: 2.0,
),
hand_restriction: None,
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -6,16 +6,19 @@ ItemDef(
modkind: Damage,
stats: (
equip_time_secs: 0.25,
power: 1.4,
effect_power: 1.1,
speed: 0.7,
crit_chance: 0.1,
power: 1.0,
effect_power: 0.9,
speed: 0.9,
crit_chance: 0.2,
range: 1.5,
energy_efficiency: 0.8,
buff_strength: 1.1,
energy_efficiency: 0.9,
buff_strength: 0.9,
),
hand_restriction: Some(Two),
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Damage))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -0,0 +1,24 @@
ItemDef(
name: "Hand-and-a-half sword hilt",
description: "A sword hilt.",
kind: ModularComponent((
toolkind: Sword,
modkind: Held,
stats: (
equip_time_secs: 1.0,
power: 1.0,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
),
)),
quality: Common,
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -14,8 +14,11 @@ ItemDef(
energy_efficiency: 1.1,
buff_strength: 0.9,
),
hand_restriction: Some(One),
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Held))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: One)),
],
)

View File

@ -14,8 +14,11 @@ ItemDef(
energy_efficiency: 0.9,
buff_strength: 1.1,
),
hand_restriction: Some(Two),
)),
quality: Common,
tags: [ModularComponent((toolkind: Sword, modkind: Held))],
tags: [
ModularComponent((toolkind: Sword, modkind: Held, hands: Two)),
],
)

View File

@ -24,7 +24,7 @@ use crossbeam_utils::atomic::AtomicCell;
use serde::{de, Deserialize, Serialize, Serializer};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::{collections::hash_map::DefaultHasher, fmt, sync::Arc};
use std::{borrow::Cow, collections::hash_map::DefaultHasher, fmt, sync::Arc};
use strum::IntoStaticStr;
use tracing::error;
use vek::Rgb;
@ -83,10 +83,10 @@ pub enum Quality {
}
pub trait TagExampleInfo {
fn name(&self) -> &'static str;
fn name(&self) -> Cow<'static, str>;
/// What item to show in the crafting hud if the player has nothing with the
/// tag
fn exemplar_identifier(&self) -> &'static str;
fn exemplar_identifier(&self) -> Cow<'static, str>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
@ -216,9 +216,11 @@ impl MaterialTag {
}
impl TagExampleInfo for MaterialTag {
fn name(&self) -> &'static str { self.material.into() }
fn name(&self) -> Cow<'static, str> { Cow::Borrowed(self.material.into()) }
fn exemplar_identifier(&self) -> &'static str { "common.items.tag_examples.placeholder" }
fn exemplar_identifier(&self) -> Cow<'static, str> {
Cow::Borrowed("common.items.tag_examples.placeholder")
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
@ -239,40 +241,40 @@ pub enum ItemTag {
}
impl TagExampleInfo for ItemTag {
fn name(&self) -> &'static str {
fn name(&self) -> Cow<'static, str> {
match self {
ItemTag::Material(material) => material.name(),
ItemTag::ModularComponent(kind) => kind.name(),
ItemTag::MetalIngot => "metal ingot",
ItemTag::Textile => "textile",
ItemTag::Leather => "leather",
ItemTag::Cultist => "cultist",
ItemTag::Potion => "potion",
ItemTag::Food => "food",
ItemTag::BaseMaterial => "basemat",
ItemTag::CraftingTool => "tool",
ItemTag::Utility => "utility",
ItemTag::Bag => "bag",
ItemTag::SalvageInto(_) => "salvage",
ItemTag::MetalIngot => Cow::Borrowed("metal ingot"),
ItemTag::Textile => Cow::Borrowed("textile"),
ItemTag::Leather => Cow::Borrowed("leather"),
ItemTag::Cultist => Cow::Borrowed("cultist"),
ItemTag::Potion => Cow::Borrowed("potion"),
ItemTag::Food => Cow::Borrowed("food"),
ItemTag::BaseMaterial => Cow::Borrowed("basemat"),
ItemTag::CraftingTool => Cow::Borrowed("tool"),
ItemTag::Utility => Cow::Borrowed("utility"),
ItemTag::Bag => Cow::Borrowed("bag"),
ItemTag::SalvageInto(_) => Cow::Borrowed("salvage"),
}
}
// TODO: Autogenerate these?
fn exemplar_identifier(&self) -> &'static str {
fn exemplar_identifier(&self) -> Cow<'static, str> {
match self {
ItemTag::Material(_) => "common.items.tag_examples.placeholder",
ItemTag::Material(_) => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::ModularComponent(tag) => tag.exemplar_identifier(),
ItemTag::MetalIngot => "common.items.tag_examples.metal_ingot",
ItemTag::Textile => "common.items.tag_examples.textile",
ItemTag::Leather => "common.items.tag_examples.leather",
ItemTag::Cultist => "common.items.tag_examples.cultist",
ItemTag::Potion => "common.items.tag_examples.placeholder",
ItemTag::Food => "common.items.tag_examples.placeholder",
ItemTag::BaseMaterial => "common.items.tag_examples.placeholder",
ItemTag::CraftingTool => "common.items.tag_examples.placeholder",
ItemTag::Utility => "common.items.tag_examples.placeholder",
ItemTag::Bag => "common.items.tag_examples.placeholder",
ItemTag::SalvageInto(_) => "common.items.tag_examples.placeholder",
ItemTag::MetalIngot => Cow::Borrowed("common.items.tag_examples.metal_ingot"),
ItemTag::Textile => Cow::Borrowed("common.items.tag_examples.textile"),
ItemTag::Leather => Cow::Borrowed("common.items.tag_examples.leather"),
ItemTag::Cultist => Cow::Borrowed("common.items.tag_examples.cultist"),
ItemTag::Potion => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::Food => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::BaseMaterial => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::CraftingTool => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::Utility => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::Bag => Cow::Borrowed("common.items.tag_examples.placeholder"),
ItemTag::SalvageInto(_) => Cow::Borrowed("common.items.tag_examples.placeholder"),
}
}
}

View File

@ -1,8 +1,12 @@
use super::{tool, ItemKind, ItemTag, Quality, RawItemDef, TagExampleInfo, ToolKind};
use super::{
tool::{self, Hands},
ItemKind, ItemTag, Quality, RawItemDef, TagExampleInfo, ToolKind,
};
use crate::recipe::{RawRecipe, RawRecipeBook, RawRecipeInput};
use hashbrown::HashMap;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ModularComponentKind {
@ -30,87 +34,63 @@ pub struct ModularComponent {
pub struct ModularComponentTag {
toolkind: ToolKind,
modkind: ModularComponentKind,
hands: Hands,
}
impl TagExampleInfo for ModularComponentTag {
fn name(&self) -> &'static str {
match self.modkind {
ModularComponentKind::Damage => match self.toolkind {
ToolKind::Sword => "sword blade",
ToolKind::Axe => "axe head",
ToolKind::Hammer => "hammer head",
ToolKind::Bow => "bow limbs",
ToolKind::Dagger => "dagger blade",
ToolKind::Staff => "staff head",
ToolKind::Sceptre => "sceptre head",
// TODO: naming
ToolKind::Spear => "spear damage component",
ToolKind::Blowgun => "blowgun damage component",
ToolKind::Shield => "shield damage component",
ToolKind::Debug => "debug damage component",
ToolKind::Farming => "farming damage component",
ToolKind::Pick => "pickaxe head",
ToolKind::Natural => "natural damage component",
ToolKind::Empty => "empty damage component",
},
ModularComponentKind::Held => match self.toolkind {
ToolKind::Sword => "sword hilt",
ToolKind::Axe => "axe shaft",
ToolKind::Hammer => "hammer shaft",
ToolKind::Bow => "bow riser",
ToolKind::Dagger => "dagger grip",
ToolKind::Staff => "staff shaft",
ToolKind::Sceptre => "sceptre shaft",
// TODO: naming
ToolKind::Spear => "spear held component",
ToolKind::Blowgun => "blowgun held component",
ToolKind::Shield => "shield held component",
ToolKind::Natural => "natural held component",
ToolKind::Debug => "debug held component",
ToolKind::Farming => "farming held component",
ToolKind::Pick => "pickaxe handle",
ToolKind::Empty => "empty held component",
},
}
fn name(&self) -> Cow<'static, str> {
Cow::Owned(format!(
"{} {}",
self.hands.identifier_name().to_owned(),
match self.modkind {
ModularComponentKind::Damage => match self.toolkind {
ToolKind::Sword => "sword blade",
ToolKind::Axe => "axe head",
ToolKind::Hammer => "hammer head",
ToolKind::Bow => "bow limbs",
ToolKind::Dagger => "dagger blade",
ToolKind::Staff => "staff head",
ToolKind::Sceptre => "sceptre head",
// TODO: naming
ToolKind::Spear => "spear damage component",
ToolKind::Blowgun => "blowgun damage component",
ToolKind::Shield => "shield damage component",
ToolKind::Debug => "debug damage component",
ToolKind::Farming => "farming damage component",
ToolKind::Pick => "pickaxe head",
ToolKind::Natural => "natural damage component",
ToolKind::Empty => "empty damage component",
},
ModularComponentKind::Held => match self.toolkind {
ToolKind::Sword => "sword hilt",
ToolKind::Axe => "axe shaft",
ToolKind::Hammer => "hammer shaft",
ToolKind::Bow => "bow riser",
ToolKind::Dagger => "dagger grip",
ToolKind::Staff => "staff shaft",
ToolKind::Sceptre => "sceptre shaft",
// TODO: naming
ToolKind::Spear => "spear held component",
ToolKind::Blowgun => "blowgun held component",
ToolKind::Shield => "shield held component",
ToolKind::Natural => "natural held component",
ToolKind::Debug => "debug held component",
ToolKind::Farming => "farming held component",
ToolKind::Pick => "pickaxe handle",
ToolKind::Empty => "empty held component",
},
}
))
}
fn exemplar_identifier(&self) -> &'static str {
match self.modkind {
ModularComponentKind::Damage => match self.toolkind {
ToolKind::Sword => "common.items.tag_examples.modular.damage.sword",
ToolKind::Axe => "common.items.tag_examples.modular.damage.axe",
ToolKind::Hammer => "common.items.tag_examples.modular.damage.hammer",
ToolKind::Bow => "common.items.tag_examples.modular.damage.bow",
ToolKind::Dagger => "common.items.tag_examples.modular.damage.dagger",
ToolKind::Staff => "common.items.tag_examples.modular.damage.staff",
ToolKind::Sceptre => "common.items.tag_examples.modular.damage.sceptre",
ToolKind::Shield => "common.items.tag_examples.modular.damage.shield",
ToolKind::Spear => "common.items.tag_examples.modular.damage.spear",
ToolKind::Blowgun => "common.items.tag_examples.modular.damage.blowgun",
ToolKind::Natural => "common.items.tag_examples.modular.damage.natural",
ToolKind::Debug => "common.items.tag_examples.modular.damage.debug",
ToolKind::Farming => "common.items.tag_examples.modular.damage.farming",
ToolKind::Pick => "common.items.tag_examples.modular.damage.pick",
ToolKind::Empty => "common.items.tag_examples.modular.damage.empty",
},
ModularComponentKind::Held => match self.toolkind {
ToolKind::Sword => "common.items.tag_examples.modular.held.sword",
ToolKind::Axe => "common.items.tag_examples.modular.held.axe",
ToolKind::Hammer => "common.items.tag_examples.modular.held.hammer",
ToolKind::Bow => "common.items.tag_examples.modular.held.bow",
ToolKind::Dagger => "common.items.tag_examples.modular.held.dagger",
ToolKind::Staff => "common.items.tag_examples.modular.held.staff",
ToolKind::Sceptre => "common.items.tag_examples.modular.held.sceptre",
ToolKind::Shield => "common.items.tag_examples.modular.held.shield",
ToolKind::Spear => "common.items.tag_examples.modular.held.spear",
ToolKind::Blowgun => "common.items.tag_examples.modular.held.blowgun",
ToolKind::Natural => "common.items.tag_examples.modular.held.natural",
ToolKind::Debug => "common.items.tag_examples.modular.held.debug",
ToolKind::Farming => "common.items.tag_examples.modular.held.farming",
ToolKind::Pick => "common.items.tag_examples.modular.held.pick",
ToolKind::Empty => "common.items.tag_examples.modular.held.empty",
},
}
fn exemplar_identifier(&self) -> Cow<'static, str> {
Cow::Owned(format!(
"{}.{}.{}.{}",
TAG_EXAMPLES_PREFIX,
self.modkind.identifier_name(),
self.toolkind.identifier_name(),
self.hands.identifier_name()
))
}
}
@ -128,13 +108,28 @@ const MODKINDS: [ModularComponentKind; 2] =
const WEAPON_PREFIX: &str = "common.items.weapons.modular";
const TAG_EXAMPLES_PREFIX: &str = "common.items.tag_examples.modular";
fn make_weapon_def(toolkind: ToolKind) -> (String, RawItemDef) {
let identifier = format!("{}.{}", WEAPON_PREFIX, toolkind.identifier_name(),);
let name = format!("Modular {}", toolkind.identifier_name());
let description = format!("A {} made of components", toolkind.identifier_name());
const HANDS: [Hands; 2] = [Hands::One, Hands::Two];
fn make_weapon_def(toolkind: ToolKind, hands: Hands) -> (String, RawItemDef) {
let identifier = format!(
"{}.{}.{}",
WEAPON_PREFIX,
toolkind.identifier_name(),
hands.identifier_name()
);
let name = format!(
"Modular {} {}",
hands.identifier_name(),
toolkind.identifier_name()
);
let description = format!(
"A {} {} made of components",
hands.identifier_name(),
toolkind.identifier_name()
);
let tool = tool::Tool {
kind: toolkind,
hands: tool::Hands::Two,
hands,
stats: tool::StatKind::Modular,
};
let kind = ItemKind::Tool(tool);
@ -151,13 +146,14 @@ fn make_weapon_def(toolkind: ToolKind) -> (String, RawItemDef) {
(identifier, item)
}
fn make_recipe_def(identifier: String, toolkind: ToolKind) -> RawRecipe {
fn make_recipe_def(identifier: String, toolkind: ToolKind, hands: Hands) -> RawRecipe {
let output = (identifier, 1);
let mut inputs = Vec::new();
for &modkind in &MODKINDS {
let input = RawRecipeInput::Tag(ItemTag::ModularComponent(ModularComponentTag {
toolkind,
modkind,
hands,
}));
inputs.push((input, 1, true));
}
@ -168,14 +164,23 @@ fn make_recipe_def(identifier: String, toolkind: ToolKind) -> RawRecipe {
}
}
fn make_tagexample_def(toolkind: ToolKind, modkind: ModularComponentKind) -> (String, RawItemDef) {
fn make_tagexample_def(
toolkind: ToolKind,
modkind: ModularComponentKind,
hands: Hands,
) -> (String, RawItemDef) {
let identifier = format!(
"{}.{}.{}",
"{}.{}.{}.{}",
TAG_EXAMPLES_PREFIX,
modkind.identifier_name(),
toolkind.identifier_name(),
hands.identifier_name(),
);
let tag = ModularComponentTag { toolkind, modkind };
let tag = ModularComponentTag {
toolkind,
modkind,
hands,
};
// TODO: i18n
let name = format!("Any {}", tag.name());
let description = format!(
@ -205,15 +210,15 @@ fn initialize_modular_assets() -> (HashMap<String, RawItemDef>, RawRecipeBook) {
let mut itemdefs = HashMap::new();
let mut recipes = HashMap::new();
for &toolkind in &SUPPORTED_TOOLKINDS {
let (identifier, item) = make_weapon_def(toolkind);
itemdefs.insert(identifier.clone(), item);
let recipe = make_recipe_def(identifier.clone(), toolkind);
recipes.insert(identifier, recipe);
}
for &toolkind in &SUPPORTED_TOOLKINDS {
for &modkind in &MODKINDS {
let (identifier, item) = make_tagexample_def(toolkind, modkind);
itemdefs.insert(identifier, item);
for &hands in &HANDS {
let (identifier, item) = make_weapon_def(toolkind, hands);
itemdefs.insert(identifier.clone(), item);
let recipe = make_recipe_def(identifier.clone(), toolkind, hands);
recipes.insert(identifier, recipe);
for &modkind in &MODKINDS {
let (identifier, item) = make_tagexample_def(toolkind, modkind, hands);
itemdefs.insert(identifier, item);
}
}
}
(itemdefs, RawRecipeBook(recipes))

View File

@ -39,6 +39,7 @@ pub enum ToolKind {
}
impl ToolKind {
// Changing this will break persistence of modular weapons
pub fn identifier_name(&self) -> &'static str {
match self {
ToolKind::Sword => "sword",
@ -76,12 +77,22 @@ impl ToolKind {
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Hands {
One,
Two,
}
impl Hands {
// Changing this will break persistence of modular weapons
pub fn identifier_name(&self) -> &'static str {
match self {
Hands::One => "one-handed",
Hands::Two => "two-handed",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub struct Stats {
pub equip_time_secs: f32,
@ -108,6 +119,19 @@ impl Stats {
}
}
pub fn oned() -> Stats {
Stats {
equip_time_secs: 1.0,
power: 1.0,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
}
}
#[must_use]
pub fn clamp_speed(mut self) -> Self {
// if a tool has 0.0 speed, that panics due to being infinite duration, so
@ -205,16 +229,18 @@ impl StatKind {
pub fn resolve_stats(&self, msm: &MaterialStatManifest, components: &[Item]) -> Stats {
let mut stats = match self {
StatKind::Direct(stats) => *stats,
StatKind::Modular => Stats::zeroed(),
StatKind::Modular => Stats::oned(),
};
let mut multipliers: Vec<Stats> = Vec::new();
for item in components.iter() {
match item.kind() {
// Modular components directly multiply against the base stats
ItemKind::ModularComponent(mc) => {
let inner_stats =
StatKind::Direct(mc.stats).resolve_stats(msm, item.components());
stats += inner_stats;
stats *= inner_stats;
},
// Ingredients push multiplier to vec as the ingredient multipliers are averaged
ItemKind::Ingredient { .. } => {
if let Some(mult_stats) = msm.0.get(item.item_definition_id()) {
multipliers.push(*mult_stats);
@ -224,7 +250,7 @@ impl StatKind {
_ => (),
}
}
// Take the average of the material multipliers, to allow alloyed blades
// Take the average of the material multipliers
if !multipliers.is_empty() {
let mut average_mult = Stats::zeroed();
for stat in multipliers.iter() {

View File

@ -2,7 +2,7 @@ use core::ops::Not;
use serde::{Deserialize, Serialize};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::{convert::TryFrom, mem, ops::Range};
use std::{borrow::Cow, convert::TryFrom, mem, ops::Range};
use tracing::{debug, trace, warn};
use vek::Vec3;
@ -128,8 +128,8 @@ impl Inventory {
// Quality is sorted in reverse since we want high quality items first
InventorySortOrder::Quality => Ord::cmp(&b.quality(), &a.quality()),
InventorySortOrder::Tag => Ord::cmp(
a.tags.first().map_or("", |tag| tag.name()),
b.tags.first().map_or("", |tag| tag.name()),
&a.tags.first().map_or(Cow::Borrowed(""), |tag| tag.name()),
&b.tags.first().map_or(Cow::Borrowed(""), |tag| tag.name()),
),
});

View File

@ -28,7 +28,7 @@ use conrod_core::{
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
};
use i18n::Localization;
use std::sync::Arc;
use std::{borrow::Cow, sync::Arc};
use strum::{EnumIter, IntoEnumIterator};
@ -467,7 +467,7 @@ impl<'a> Widget for Crafting<'a> {
},
SearchFilter::Input => recipe.inputs().any(|(input, _, _)| {
let input_name = match input {
RecipeInput::Item(def) => def.name.as_str(),
RecipeInput::Item(def) => Cow::Borrowed(def.name()),
RecipeInput::Tag(tag) => tag.name(),
RecipeInput::TagSameItem(tag, _) => tag.name(),
}