WIP modular weapon pricing.

This commit is contained in:
Avi Weinstock 2022-07-02 12:20:10 -04:00 committed by Christof Petig
parent 80d491f003
commit 27d2cdeb79
6 changed files with 79 additions and 28 deletions

View File

@ -1,6 +1,6 @@
use crate::{
assets::{self, AssetExt},
comp::item::Item,
comp::item::{Item, ItemDefinitionId},
lottery::LootSpec,
recipe::{default_recipe_book, RecipeInput},
trade::Good,
@ -61,6 +61,22 @@ impl std::ops::Add for MaterialUse {
}
}
impl std::ops::AddAssign for MaterialUse {
fn add_assign(&mut self, rhs: Self) {
vector_add_eq(&mut self.0, &rhs.0);
}
}
impl std::iter::Sum<MaterialUse> for MaterialUse {
fn sum<I>(iter: I) -> Self where I: Iterator<Item=Self> {
let mut ret = Self::default();
for i in iter {
ret += i;
}
ret
}
}
impl std::ops::Deref for MaterialUse {
type Target = [(f32, Good)];
@ -362,6 +378,7 @@ impl TradePricing {
_ if name.starts_with("common.items.armor.") => Good::Armor,
_ if name.starts_with("common.items.weapons.") => Good::Tools,
_ if name.starts_with("common.items.modular.weapon.") => Good::Tools,
_ if name.starts_with("common.items.tool.") => Good::Tools,
_ if name.starts_with("common.items.crafting_ing.") => Good::Ingredients,
@ -663,7 +680,16 @@ impl TradePricing {
result
}
fn get_materials_impl(&self, item: &str) -> Option<&MaterialUse> { self.price_lookup(item) }
fn get_materials_impl(&self, item: ItemDefinitionId<'_>) -> Option<MaterialUse> {
let tmp = format!("{:?}", item);
let ret = match item {
ItemDefinitionId::Simple(id) => self.price_lookup(id).cloned(),
ItemDefinitionId::Modular { components, .. } => Some(components.into_iter().filter_map(|comp| self.get_materials_impl(comp)).sum()),
ItemDefinitionId::Compound { simple_base, components } => Some(self.price_lookup(simple_base).cloned().unwrap_or_else(MaterialUse::default) + components.into_iter().filter_map(|comp| self.get_materials_impl(comp)).sum()),
};
println!("{} -> {:?}", tmp, ret);
ret
}
#[must_use]
pub fn random_items(
@ -677,7 +703,7 @@ impl TradePricing {
}
#[must_use]
pub fn get_materials(item: &str) -> Option<&MaterialUse> {
pub fn get_materials(item: ItemDefinitionId<'_>) -> Option<MaterialUse> {
TRADE_PRICING.get_materials_impl(item)
}

View File

@ -5,7 +5,7 @@ use crate::{
item::{
modular,
tool::{AbilityMap, ToolKind},
ItemBase, ItemDef, ItemKind, ItemTag, MaterialStatManifest,
ItemBase, ItemDef, ItemDefinitionIdOwned, ItemKind, ItemTag, MaterialStatManifest,
},
Inventory, Item,
},
@ -472,6 +472,11 @@ pub struct ComponentRecipeBook {
recipes: HashMap<ComponentKey, ComponentRecipe>,
}
#[derive(Clone, Debug)]
pub struct ReverseComponentRecipeBook {
recipes: HashMap<ItemDefinitionIdOwned, ComponentRecipe>,
}
impl ComponentRecipeBook {
pub fn get(&self, key: &ComponentKey) -> Option<&ComponentRecipe> { self.recipes.get(key) }
@ -480,6 +485,10 @@ impl ComponentRecipeBook {
}
}
impl ReverseComponentRecipeBook {
pub fn get(&self, key: &ItemDefinitionIdOwned) -> Option<&ComponentRecipe> { self.recipes.get(key) }
}
#[derive(Clone, Deserialize)]
#[serde(transparent)]
struct RawComponentRecipeBook(Vec<RawComponentRecipe>);
@ -646,6 +655,26 @@ impl ComponentRecipe {
)
}
pub fn itemdef_output(&self) -> ItemDefinitionIdOwned {
match &self.output {
ComponentOutput::ItemComponents {
item: item_def,
components,
} => {
let components = components
.iter()
.map(|item_def| {
ItemDefinitionIdOwned::Simple(item_def.id().to_owned())
})
.collect::<Vec<_>>();
ItemDefinitionIdOwned::Compound {
simple_base: item_def.id().to_owned(),
components,
}
},
}
}
pub fn item_output(&self, ability_map: &AbilityMap, msm: &MaterialStatManifest) -> Item {
match &self.output {
ComponentOutput::ItemComponents {
@ -818,3 +847,14 @@ pub fn default_recipe_book() -> AssetHandle<RecipeBook> {
pub fn default_component_recipe_book() -> AssetHandle<ComponentRecipeBook> {
ComponentRecipeBook::load_expect("common.component_recipe_book")
}
impl assets::Compound for ReverseComponentRecipeBook {
fn load(cache: assets::AnyCache, specifier: &str) -> Result<Self, assets::BoxedError> {
let forward = cache.load::<ComponentRecipeBook>(specifier)?.cloned();
let mut recipes = HashMap::new();
for (_, recipe) in forward.iter() {
recipes.insert(recipe.itemdef_output(), recipe.clone());
}
Ok(ReverseComponentRecipeBook { recipes })
}
}

View File

@ -389,12 +389,7 @@ impl SitePrices {
.as_ref()
.and_then(|ri| {
ri.inventory.get(slot).map(|item| {
if let Some(vec) = item
.name
.as_ref()
// TODO: This won't handle compound items with components well, or pure modular items at all
.itemdef_id()
.and_then(TradePricing::get_materials)
if let Some(vec) = TradePricing::get_materials(item.name.as_ref())
{
vec.iter()
.map(|(amount2, material)| {

View File

@ -3644,11 +3644,7 @@ impl Hud {
false,
);
if let Some(item) = inventory.get(slot) {
if let Some(materials) = item
.item_definition_id()
.itemdef_id()
.and_then(TradePricing::get_materials)
{
if let Some(materials) = TradePricing::get_materials(item.item_definition_id()) {
let unit_price: f32 = materials
.iter()
.map(|e| {

View File

@ -5,7 +5,7 @@ use common::{
item::{
armor::{Armor, ArmorKind, Protection},
tool::{Hands, Tool, ToolKind},
ItemDesc, ItemKind, MaterialKind, MaterialStatManifest,
ItemDefinitionId, ItemDesc, ItemKind, MaterialKind, MaterialStatManifest,
},
BuffKind,
},
@ -18,7 +18,7 @@ use std::{borrow::Cow, fmt::Write};
pub fn price_desc(
prices: &Option<SitePrices>,
item_definition_id: &str,
item_definition_id: ItemDefinitionId<'_>,
i18n: &Localization,
) -> Option<(String, String, f32)> {
if let Some(prices) = prices {

View File

@ -1357,11 +1357,7 @@ impl<'a> Widget for ItemTooltip<'a> {
}
// Price display
if let Some((buy, sell, factor)) = item
.item_definition_id()
.itemdef_id()
.and_then(|id| util::price_desc(self.prices, id, i18n))
{
if let Some((buy, sell, factor)) = util::price_desc(self.prices, item.item_definition_id(), i18n) {
widget::Text::new(&buy)
.x_align_to(state.ids.item_frame, conrod_core::position::Align::Start)
.graphics_for(id)
@ -1393,9 +1389,10 @@ impl<'a> Widget for ItemTooltip<'a> {
//Tooltips for trade mini-tutorial
widget::Text::new(&format!(
"{}\n{}",
"{}\n{}\n{:?}",
i18n.get("hud.trade.tooltip_hint_1"),
i18n.get("hud.trade.tooltip_hint_2")
i18n.get("hud.trade.tooltip_hint_2"),
item.item_definition_id()
))
.x_align_to(state.ids.item_frame, conrod_core::position::Align::Start)
.graphics_for(id)
@ -1457,10 +1454,7 @@ impl<'a> Widget for ItemTooltip<'a> {
};
// Price
let price_h: f64 = if let Some((buy, sell, _)) = item
.item_definition_id()
.itemdef_id()
.and_then(|id| util::price_desc(self.prices, id, self.localized_strings))
let price_h: f64 = if let Some((buy, sell, _)) = util::price_desc(self.prices, item.item_definition_id(), self.localized_strings)
{
//Get localized tooltip strings (gotten here because these should only show if
// in a trade- aka if buy/sell prices are present)