mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Crafting slots now properly check component recipe book to see if an input is valid.
This commit is contained in:
parent
e9f36b9486
commit
1b85258838
@ -2,7 +2,7 @@ use super::{
|
|||||||
get_quality_col,
|
get_quality_col,
|
||||||
img_ids::{Imgs, ImgsRot},
|
img_ids::{Imgs, ImgsRot},
|
||||||
item_imgs::{animate_by_pulse, ItemImgs},
|
item_imgs::{animate_by_pulse, ItemImgs},
|
||||||
slots::{CraftSlot, SlotManager},
|
slots::{CraftSlot, CraftSlotInfo, SlotManager},
|
||||||
Show, TEXT_COLOR, TEXT_DULL_RED_COLOR, TEXT_GRAY_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
Show, TEXT_COLOR, TEXT_DULL_RED_COLOR, TEXT_GRAY_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||||
};
|
};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
@ -20,8 +20,8 @@ use common::{
|
|||||||
modular,
|
modular,
|
||||||
modular::ModularComponent,
|
modular::ModularComponent,
|
||||||
tool::{AbilityMap, ToolKind},
|
tool::{AbilityMap, ToolKind},
|
||||||
Item, ItemBase, ItemDef, ItemDesc, ItemKind, ItemTag, MaterialKind,
|
Item, ItemBase, ItemDef, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality,
|
||||||
MaterialStatManifest, Quality, TagExampleInfo,
|
TagExampleInfo,
|
||||||
},
|
},
|
||||||
slot::InvSlotId,
|
slot::InvSlotId,
|
||||||
Inventory,
|
Inventory,
|
||||||
@ -38,8 +38,8 @@ use conrod_core::{
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use i18n::Localization;
|
use i18n::Localization;
|
||||||
use std::{collections::BTreeMap, sync::Arc};
|
use std::{collections::BTreeMap, sync::Arc};
|
||||||
|
|
||||||
use strum::{EnumIter, IntoEnumIterator};
|
use strum::{EnumIter, IntoEnumIterator};
|
||||||
|
use tracing::warn;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
widget_ids! {
|
widget_ids! {
|
||||||
@ -882,7 +882,7 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
index: 0,
|
index: 0,
|
||||||
invslot: self.show.crafting_fields.recipe_inputs.get(&0).copied(),
|
invslot: self.show.crafting_fields.recipe_inputs.get(&0).copied(),
|
||||||
requirement: match recipe_kind {
|
requirement: match recipe_kind {
|
||||||
RecipeKind::ModularWeapon => |item| {
|
RecipeKind::ModularWeapon => |item, _, _| {
|
||||||
item.map_or(false, |item| {
|
item.map_or(false, |item| {
|
||||||
matches!(
|
matches!(
|
||||||
&*item.kind(),
|
&*item.kind(),
|
||||||
@ -892,43 +892,26 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// TODO: Maybe try to figure out way to get this to work?
|
RecipeKind::Component(_) => |item, comp_recipes, info| {
|
||||||
// Captures self and toolkind which prevents it from becoming a function
|
if let Some(CraftSlotInfo::Tool(toolkind)) = info {
|
||||||
// Some(RecipeKind::Component(toolkind)) => |inv, slot| {
|
item.map_or(false, |item| {
|
||||||
// inv.and_then(|inv| inv.get(slot)).map_or(false, |item| {
|
comp_recipes
|
||||||
// self.client.component_recipe_book().iter().filter(|(key,
|
|
||||||
// _recipe)| key.toolkind == toolkind).any(|(key, _recipe)| key.material
|
|
||||||
// == item.item_definition_id()) })
|
|
||||||
// },
|
|
||||||
RecipeKind::Component(
|
|
||||||
ToolKind::Sword | ToolKind::Axe | ToolKind::Hammer,
|
|
||||||
) => |item| {
|
|
||||||
item.map_or(false, |item| {
|
|
||||||
matches!(&*item.kind(), ItemKind::Ingredient { .. })
|
|
||||||
&& item
|
|
||||||
.tags()
|
|
||||||
.contains(&ItemTag::MaterialKind(MaterialKind::Metal))
|
|
||||||
&& item
|
|
||||||
.tags()
|
|
||||||
.iter()
|
.iter()
|
||||||
.any(|tag| matches!(tag, ItemTag::Material(_)))
|
.filter(|(key, _)| key.toolkind == toolkind)
|
||||||
})
|
.any(|(key, _)| {
|
||||||
|
Some(key.material.as_str())
|
||||||
|
== item.item_definition_id().raw()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
RecipeKind::Component(
|
RecipeKind::Simple => |_, _, _| unreachable!(),
|
||||||
ToolKind::Bow | ToolKind::Staff | ToolKind::Sceptre,
|
},
|
||||||
) => |item| {
|
info: match recipe_kind {
|
||||||
item.map_or(false, |item| {
|
RecipeKind::Component(toolkind) => Some(CraftSlotInfo::Tool(toolkind)),
|
||||||
matches!(&*item.kind(), ItemKind::Ingredient { .. })
|
RecipeKind::ModularWeapon | RecipeKind::Simple => None,
|
||||||
&& item
|
|
||||||
.tags()
|
|
||||||
.contains(&ItemTag::MaterialKind(MaterialKind::Wood))
|
|
||||||
&& item
|
|
||||||
.tags()
|
|
||||||
.iter()
|
|
||||||
.any(|tag| matches!(tag, ItemTag::Material(_)))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
RecipeKind::Component(_) | RecipeKind::Simple => |_| unreachable!(),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -957,7 +940,7 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
index: 1,
|
index: 1,
|
||||||
invslot: self.show.crafting_fields.recipe_inputs.get(&1).copied(),
|
invslot: self.show.crafting_fields.recipe_inputs.get(&1).copied(),
|
||||||
requirement: match recipe_kind {
|
requirement: match recipe_kind {
|
||||||
RecipeKind::ModularWeapon => |item| {
|
RecipeKind::ModularWeapon => |item, _, _| {
|
||||||
item.map_or(false, |item| {
|
item.map_or(false, |item| {
|
||||||
matches!(
|
matches!(
|
||||||
&*item.kind(),
|
&*item.kind(),
|
||||||
@ -967,22 +950,26 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// TODO: Maybe try to figure out way to get this to work?
|
RecipeKind::Component(_) => |item, comp_recipes, info| {
|
||||||
// Captures self and toolkind which prevents it from becoming a function
|
if let Some(CraftSlotInfo::Tool(toolkind)) = info {
|
||||||
// Some(RecipeKind::Component(toolkind)) => |inv, slot| {
|
item.map_or(false, |item| {
|
||||||
// inv.and_then(|inv| inv.get(slot)).map_or(false, |item| {
|
comp_recipes
|
||||||
// self.client.component_recipe_book().iter().filter(|(key,
|
.iter()
|
||||||
// _recipe)| key.toolkind == toolkind).any(|(key, _recipe)| key.modifier
|
.filter(|(key, _)| key.toolkind == toolkind)
|
||||||
// == Some(item.item_definition_id()))
|
.any(|(key, _)| {
|
||||||
// }) },
|
key.modifier.as_deref()
|
||||||
RecipeKind::Component(_) => |item| {
|
== item.item_definition_id().raw()
|
||||||
item.map_or(false, |item| {
|
})
|
||||||
item.item_definition_id().raw().map_or(false, |id| {
|
|
||||||
id.starts_with("common.items.crafting_ing.animal_misc")
|
|
||||||
})
|
})
|
||||||
})
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
RecipeKind::Simple => |_| unreachable!(),
|
RecipeKind::Simple => |_, _, _| unreachable!(),
|
||||||
|
},
|
||||||
|
info: match recipe_kind {
|
||||||
|
RecipeKind::Component(toolkind) => Some(CraftSlotInfo::Tool(toolkind)),
|
||||||
|
RecipeKind::ModularWeapon | RecipeKind::Simple => None,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1493,7 +1480,7 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
// Widget generation for every ingredient
|
// Widget generation for every ingredient
|
||||||
for (i, (recipe_input, amount)) in ingredients.enumerate() {
|
for (i, (recipe_input, amount)) in ingredients.enumerate() {
|
||||||
let item_def = match recipe_input {
|
let item_def = match recipe_input {
|
||||||
RecipeInput::Item(item_def) => Arc::clone(item_def),
|
RecipeInput::Item(item_def) => Some(Arc::clone(item_def)),
|
||||||
RecipeInput::Tag(tag) | RecipeInput::TagSameItem(tag) => self
|
RecipeInput::Tag(tag) | RecipeInput::TagSameItem(tag) => self
|
||||||
.inventory
|
.inventory
|
||||||
.slots()
|
.slots()
|
||||||
@ -1508,11 +1495,9 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.or_else(|| {
|
||||||
Arc::<ItemDef>::load_expect_cloned(
|
tag.exemplar_identifier()
|
||||||
tag.exemplar_identifier()
|
.map(Arc::<ItemDef>::load_expect_cloned)
|
||||||
.unwrap_or("common.items.weapons.empty.empty"),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
RecipeInput::ListSameItem(item_defs) => self
|
RecipeInput::ListSameItem(item_defs) => self
|
||||||
.inventory
|
.inventory
|
||||||
@ -1528,22 +1513,25 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.or_else(|| {
|
||||||
item_defs
|
item_defs.first().and_then(|i| {
|
||||||
.first()
|
i.item_definition_id()
|
||||||
.and_then(|i| {
|
.raw()
|
||||||
i.item_definition_id()
|
.map(Arc::<ItemDef>::load_expect_cloned)
|
||||||
.raw()
|
})
|
||||||
.map(Arc::<ItemDef>::load_expect_cloned)
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
Arc::<ItemDef>::load_expect_cloned(
|
|
||||||
"common.items.weapons.empty.empty",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let item_def = if let Some(item_def) = item_def {
|
||||||
|
item_def
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Failed to create example item def for recipe input {:?}",
|
||||||
|
recipe_input
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
// Grey color for images and text if their amount is too low to craft the
|
// Grey color for images and text if their amount is too low to craft the
|
||||||
// item
|
// item
|
||||||
let item_count_in_inventory = self.inventory.item_count(&*item_def);
|
let item_count_in_inventory = self.inventory.item_count(&*item_def);
|
||||||
|
@ -3479,6 +3479,8 @@ impl Hud {
|
|||||||
inventories
|
inventories
|
||||||
.get(client.entity())
|
.get(client.entity())
|
||||||
.and_then(|inv| inv.get(i.slot)),
|
.and_then(|inv| inv.get(i.slot)),
|
||||||
|
client.component_recipe_book(),
|
||||||
|
c.info,
|
||||||
) {
|
) {
|
||||||
self.show
|
self.show
|
||||||
.crafting_fields
|
.crafting_fields
|
||||||
|
@ -5,10 +5,14 @@ use super::{
|
|||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||||
use common::comp::{
|
use common::{
|
||||||
ability::{Ability, AbilityInput, AuxiliaryAbility},
|
comp::{
|
||||||
slot::InvSlotId,
|
ability::{Ability, AbilityInput, AuxiliaryAbility},
|
||||||
ActiveAbilities, Body, Energy, Inventory, Item, ItemKey, SkillSet,
|
item::tool::ToolKind,
|
||||||
|
slot::InvSlotId,
|
||||||
|
ActiveAbilities, Body, Energy, Inventory, Item, ItemKey, SkillSet,
|
||||||
|
},
|
||||||
|
recipe::ComponentRecipeBook,
|
||||||
};
|
};
|
||||||
use conrod_core::{image, Color};
|
use conrod_core::{image, Color};
|
||||||
use specs::Entity as EcsEntity;
|
use specs::Entity as EcsEntity;
|
||||||
@ -239,7 +243,13 @@ impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
|
|||||||
pub struct CraftSlot {
|
pub struct CraftSlot {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub invslot: Option<InvSlotId>,
|
pub invslot: Option<InvSlotId>,
|
||||||
pub requirement: fn(Option<&Item>) -> bool,
|
pub requirement: fn(Option<&Item>, &ComponentRecipeBook, Option<CraftSlotInfo>) -> bool,
|
||||||
|
pub info: Option<CraftSlotInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum CraftSlotInfo {
|
||||||
|
Tool(ToolKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for CraftSlot {
|
impl PartialEq for CraftSlot {
|
||||||
|
Loading…
Reference in New Issue
Block a user