From a1cfd9ea3c635e5d9aa31fe47145eaec79bea9bf Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Sun, 4 Apr 2021 13:47:05 -0400 Subject: [PATCH] Make merchants spawn with stacks of stackable items. --- CHANGELOG.md | 1 + common/src/comp/inventory/loadout_builder.rs | 35 ++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5faff0b923..f76d46a62b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Retiered most sceptres and staves - Loot tables can now recursively reference loot tables - "max_sfx_channels" default now set to 30 +- Merchants now have stacks of stackable items instead of just one per slot ### Removed diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 8986cf0aee..e66f740524 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -595,10 +595,28 @@ impl LoadoutBuilder { *i = Some(Item::new_from_asset_expect(&item_id)); } } + let mut rng = rand::thread_rng(); + let mut item_with_amount = |item_id: &str, amount: &mut f32| { + if *amount > 0.0 { + let mut item = Item::new_from_asset_expect(&item_id); + if *amount > 1.0 && item.is_stackable() { + let n = rng.gen_range(0..amount.min(100.0) as u32).max(1); + item.set_amount(n).unwrap_or_else(|_| { + panic!("{} should be stackable (n={})", item_id, n) + }); + *amount -= n as f32; + } else { + *amount -= 1.0; + } + Some(item) + } else { + None + } + }; let mut bag2 = Item::new_from_asset_expect( "common.items.armor.misc.bag.reliable_backpack", ); - let ingredients = economy + let mut ingredients = economy .map(|e| e.unconsumed_stock.get(&Good::Ingredients)) .flatten() .copied() @@ -608,27 +626,32 @@ impl LoadoutBuilder { if let Some(item_id) = TradePricing::random_item(Good::Ingredients, ingredients) { - *i = Some(Item::new_from_asset_expect(&item_id)); + *i = item_with_amount(&item_id, &mut ingredients); } } let mut bag3 = Item::new_from_asset_expect( "common.items.armor.misc.bag.reliable_backpack", ); - let food = economy + // TODO: currently econsim spends all its food on population, resulting in none + // for the players to buy; the `.max` is temporary to ensure that there's some + // food for sale at every site, to be used until we have some solution like NPC + // houses as a limit on econsim population growth + let mut food = economy .map(|e| e.unconsumed_stock.get(&Good::Food)) .flatten() .copied() .unwrap_or_default() + .max(10000.0) / 10.0; for i in bag3.slots_mut() { if let Some(item_id) = TradePricing::random_item(Good::Food, food) { - *i = Some(Item::new_from_asset_expect(&item_id)); + *i = item_with_amount(&item_id, &mut food); } } let mut bag4 = Item::new_from_asset_expect( "common.items.armor.misc.bag.reliable_backpack", ); - let potions = economy + let mut potions = economy .map(|e| e.unconsumed_stock.get(&Good::Potions)) .flatten() .copied() @@ -636,7 +659,7 @@ impl LoadoutBuilder { / 10.0; for i in bag4.slots_mut() { if let Some(item_id) = TradePricing::random_item(Good::Potions, potions) { - *i = Some(Item::new_from_asset_expect(&item_id)); + *i = item_with_amount(&item_id, &mut potions); } } LoadoutBuilder::new()