Made changes to crafting to allow modular weapons to work as intended.

This commit is contained in:
Sam 2021-07-16 17:54:35 -05:00
parent d69f76461f
commit 77934c9214
9 changed files with 658 additions and 613 deletions

View File

@ -7,9 +7,9 @@ ItemDef(
stats: (
equip_time_secs: 0.25,
power: 1.0,
effect_power: 0.75,
speed: 0.0,
crit_chance: 0.1,
effect_power: 1.0,
speed: 1.0,
crit_chance: 0.2,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,

View File

@ -0,0 +1,21 @@
ItemDef(
name: "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))],
)

View File

@ -3,9 +3,9 @@
"common.items.mineral.ingot.bloodsteel": (
equip_time_secs: 1.0,
power: 1.75,
effect_power: 1.75,
speed: 1.75,
crit_chance: 1.75,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
@ -13,9 +13,9 @@
"common.items.mineral.ingot.bronze": (
equip_time_secs: 1.0,
power: 0.75,
effect_power: 0.75,
speed: 0.75,
crit_chance: 0.75,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
@ -23,19 +23,19 @@
"common.items.mineral.ingot.cobalt": (
equip_time_secs: 1.0,
power: 1.5,
effect_power: 1.5,
speed: 1.5,
crit_chance: 1.5,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
),
"common.items.mineral.ingot.copper": (
equip_time_secs: 1.0,
power: 0.4,
effect_power: 0.4,
speed: 0.4,
crit_chance: 0.4,
power: 0.5,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
@ -53,19 +53,19 @@
"common.items.mineral.ingot.steel": (
equip_time_secs: 1.0,
power: 1.25,
effect_power: 1.25,
speed: 1.25,
crit_chance: 1.25,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
),
"common.items.mineral.ingot.tin": (
equip_time_secs: 1.0,
power: 0.25,
effect_power: 0.25,
speed: 0.25,
crit_chance: 0.25,
power: 0.5,
effect_power: 1.0,
speed: 1.0,
crit_chance: 1.0,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,

File diff suppressed because it is too large Load Diff

View File

@ -812,6 +812,9 @@ impl Item {
match recipe_input {
RecipeInput::Item(item_def) => self.is_same_item_def(item_def),
RecipeInput::Tag(tag) => self.item_def.tags.contains(tag),
RecipeInput::TagSameItem(tag, amount) => {
self.item_def.tags.contains(tag) && u32::from(self.amount) >= *amount
},
}
}

View File

@ -230,7 +230,7 @@ fn make_recipe_def(identifier: String, toolkind: ToolKind) -> RawRecipe {
toolkind,
modkind,
}));
inputs.push((input, 1));
inputs.push((input, 1, true));
}
RawRecipe {
output,

View File

@ -533,7 +533,7 @@ impl TradePricing {
input: recipe
.inputs
.iter()
.filter_map(|&(ref recipe_input, count)| {
.filter_map(|&(ref recipe_input, count, _)| {
if let RecipeInput::Item(it) = recipe_input {
// If item is not consumed in craft, ignore it
if count == 0 {

View File

@ -15,12 +15,15 @@ use std::sync::Arc;
pub enum RecipeInput {
Item(Arc<ItemDef>),
Tag(ItemTag),
TagSameItem(ItemTag, u32),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Recipe {
pub output: (Arc<ItemDef>, u32),
pub inputs: Vec<(RecipeInput, u32)>,
/// Input required for recipe, amount of input needed, whether input should
/// be tracked as a modular component
pub inputs: Vec<(RecipeInput, u32, bool)>,
pub craft_sprite: Option<SpriteKind>,
}
@ -45,7 +48,7 @@ impl Recipe {
self.inputs
.iter()
.enumerate()
.for_each(|(i, (input, mut required))| {
.for_each(|(i, (input, mut required, _is_component))| {
// Check used for recipes that have an input that is not consumed, e.g.
// craftsman hammer
let mut contains_any = false;
@ -100,10 +103,10 @@ impl Recipe {
}
}
pub fn inputs(&self) -> impl ExactSizeIterator<Item = (&RecipeInput, u32)> {
pub fn inputs(&self) -> impl ExactSizeIterator<Item = (&RecipeInput, u32, bool)> {
self.inputs
.iter()
.map(|(item_def, amount)| (item_def, *amount))
.map(|(item_def, amount, is_mod_comp)| (item_def, *amount, *is_mod_comp))
}
/// Determine whether the inventory contains the ingredients for a recipe.
@ -124,7 +127,7 @@ impl Recipe {
// The inputs to a recipe that have missing items, and the amount missing
let mut missing = Vec::<(&RecipeInput, u32)>::new();
for (i, (input, mut needed)) in self.inputs().enumerate() {
for (i, (input, mut needed, _)) in self.inputs().enumerate() {
let mut contains_any = false;
// Checks through every slot, filtering to only those that contain items that
// can satisfy the input
@ -213,12 +216,13 @@ impl RecipeBook {
pub enum RawRecipeInput {
Item(String),
Tag(ItemTag),
TagSameItem(ItemTag),
}
#[derive(Clone, Deserialize)]
pub(crate) struct RawRecipe {
pub(crate) output: (String, u32),
pub(crate) inputs: Vec<(RawRecipeInput, u32)>,
pub(crate) inputs: Vec<(RawRecipeInput, u32, bool)>,
pub(crate) craft_sprite: Option<SpriteKind>,
}
@ -245,13 +249,14 @@ impl assets::Compound for RecipeBook {
#[inline]
fn load_recipe_input(
spec: &(RawRecipeInput, u32),
) -> Result<(RecipeInput, u32), assets::Error> {
let def = match &spec.0 {
(input, amount, is_mod_comp): &(RawRecipeInput, u32, bool),
) -> Result<(RecipeInput, u32, bool), assets::Error> {
let def = match &input {
RawRecipeInput::Item(name) => RecipeInput::Item(Arc::<ItemDef>::load_cloned(name)?),
RawRecipeInput::Tag(tag) => RecipeInput::Tag(*tag),
RawRecipeInput::TagSameItem(tag) => RecipeInput::TagSameItem(*tag, *amount),
};
Ok((def, spec.1))
Ok((def, *amount, *is_mod_comp))
}
let mut raw = cache.load::<RawRecipeBook>(specifier)?.cloned();
@ -259,9 +264,9 @@ impl assets::Compound for RecipeBook {
// Avoid showing purple-question-box recipes until the assets are added
// (the `if false` is needed because commenting out the call will add a warning
// that there are no other uses of append_modular_recipes)
if false {
modular::append_modular_recipes(&mut raw);
}
// if false {
modular::append_modular_recipes(&mut raw);
// }
let recipes = raw
.0

View File

@ -465,10 +465,11 @@ impl<'a> Widget for Crafting<'a> {
.iter()
.all(|&substring| output_name.contains(substring))
},
SearchFilter::Input => recipe.inputs().any(|(input, _)| {
SearchFilter::Input => recipe.inputs().any(|(input, _, _)| {
let input_name = match input {
RecipeInput::Item(def) => def.name.as_str(),
RecipeInput::Tag(tag) => tag.name(),
RecipeInput::TagSameItem(tag, _) => tag.name(),
}
.to_lowercase();
search_keys
@ -903,25 +904,27 @@ impl<'a> Widget for Crafting<'a> {
};
// Widget generation for every ingredient
for (i, (recipe_input, amount)) in recipe.inputs.iter().enumerate() {
for (i, (recipe_input, amount, _)) in recipe.inputs.iter().enumerate() {
let item_def = match recipe_input {
RecipeInput::Item(item_def) => Arc::clone(item_def),
RecipeInput::Tag(tag) => Arc::<ItemDef>::load_expect_cloned(
&self
.inventory
.slots()
.filter_map(|slot| {
slot.as_ref().and_then(|item| {
if item.matches_recipe_input(recipe_input) {
Some(item.item_definition_id().to_string())
} else {
None
}
RecipeInput::Tag(tag) | RecipeInput::TagSameItem(tag, _) => {
Arc::<ItemDef>::load_expect_cloned(
&self
.inventory
.slots()
.filter_map(|slot| {
slot.as_ref().and_then(|item| {
if item.matches_recipe_input(recipe_input) {
Some(item.item_definition_id().to_string())
} else {
None
}
})
})
})
.next()
.unwrap_or_else(|| tag.exemplar_identifier().to_string()),
),
.next()
.unwrap_or_else(|| tag.exemplar_identifier().to_string()),
)
},
};
// Grey color for images and text if their amount is too low to craft the item
@ -1020,7 +1023,9 @@ impl<'a> Widget for Crafting<'a> {
// Ingredients
let name = match recipe_input {
RecipeInput::Item(_) => item_def.name().to_string(),
RecipeInput::Tag(tag) => format!("Any {} item", tag.name()),
RecipeInput::Tag(tag) | RecipeInput::TagSameItem(tag, _) => {
format!("Any {} item", tag.name())
},
};
let input = format!(
"{}x {} ({})",