From 28c9ea029b8ed5cd6103b789f7c42571a9a37d82 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Sat, 3 Jul 2021 02:37:22 +0300 Subject: [PATCH 1/2] Fill trade_pricing with craftable items --- assets/common/item_price_calculation.ron | 34 ++++++----- assets/common/loot_tables/trading.ron | 37 ------------ assets/common/loot_tables/trading/buying.ron | 10 ++++ .../common/loot_tables/trading/collection.ron | 22 +++++++ assets/common/loot_tables/trading/food.ron | 24 ++++++++ .../common/loot_tables/trading/jewellery.ron | 11 ++++ .../trading/sellable_materials.ron | 58 +++++++++++++++++++ .../trading/unsellable_materials.ron | 32 ++++++++++ common/src/comp/inventory/trade_pricing.rs | 44 +++++++------- 9 files changed, 200 insertions(+), 72 deletions(-) delete mode 100644 assets/common/loot_tables/trading.ron create mode 100644 assets/common/loot_tables/trading/buying.ron create mode 100644 assets/common/loot_tables/trading/collection.ron create mode 100644 assets/common/loot_tables/trading/food.ron create mode 100644 assets/common/loot_tables/trading/jewellery.ron create mode 100644 assets/common/loot_tables/trading/sellable_materials.ron create mode 100644 assets/common/loot_tables/trading/unsellable_materials.ron diff --git a/assets/common/item_price_calculation.ron b/assets/common/item_price_calculation.ron index 9bbe7bb14f..24fded7293 100644 --- a/assets/common/item_price_calculation.ron +++ b/assets/common/item_price_calculation.ron @@ -12,18 +12,21 @@ loot_tables: [ (0.025, false, "common.loot_tables.weapons.cultist"), (0.025, false, "common.loot_tables.weapons.cave"), (0.02, false, "common.loot_tables.weapons.legendary"), - // Armor + + // Non-craftable Armor (20.0, true, "common.loot_tables.armor.cloth"), (1.0, true, "common.loot_tables.armor.twigs"), (1.0, true, "common.loot_tables.armor.twigsflowers"), (1.0, true, "common.loot_tables.armor.twigsleaves"), - // Materials - (7.5, true, "common.loot_tables.materials.common"), - (8.0, true, "common.loot_tables.materials.underground"), - // Food - (0.3, true, "common.loot_tables.food.farm_ingredients"), - (0.4, true, "common.loot_tables.food.wild_ingredients"), - (0.2, true, "common.loot_tables.food.prepared"), + (0.01, false, "common.loot_tables.trading.jewellery"), + + // Ingredients + (1.0, true, "common.loot_tables.trading.sellable_materials"), + (1.0, false, "common.loot_tables.trading.unsellable_materials"), + + // Food Ingredients + (1.0, true, "common.loot_tables.trading.food"), + // Potions // // crafted from food, no need to duplicate it here. @@ -35,16 +38,17 @@ loot_tables: [ // // Misc (0.1, true, "common.loot_tables.consumable.throwable"), - (0.7, true, "common.loot_tables.consumable.misc"), - (1.0, false, "common.loot_tables.trading"), + // Collections + (0.00001, false, "common.loot_tables.trading.collection"), ], + // this is the amount of that good the most common item represents // so basically this table balances the goods against each other (higher=less valuable) good_scaling: [ - (Potions, 0.0075), // common.items.consumable.potion_minor - (Food, 0.1), // common.items.food.mushroom + (Potions, 0.005), // common.items.consumable.potion_minor + (Food, 0.5), // common.items.food.mushroom (Coin, 1.0), // common.items.utility.coins - (Armor, 1.0), // common.items.armor.misc.pants.worker_blue - (Tools, 0.25), // common.items.weapons.staff.starter_staff - (Ingredients, 0.25), // common.items.crafting_ing.leather_scraps + (Armor, 0.5), // common.items.armor.misc.pants.worker_blue + (Tools, 0.5), // common.items.weapons.staff.starter_staff + (Ingredients, 0.5), // common.items.crafting_ing.leather_scraps ]) diff --git a/assets/common/loot_tables/trading.ron b/assets/common/loot_tables/trading.ron deleted file mode 100644 index 3bb520da04..0000000000 --- a/assets/common/loot_tables/trading.ron +++ /dev/null @@ -1,37 +0,0 @@ -// Loot table that exists purely for price rationalisation -// Please keep it sorting by rarity so it's easier to reason about things -[ - // Ores - (0.03, Item("common.items.mineral.ore.gold")), - (0.045, Item("common.items.mineral.ore.silver")), - (0.1, Item("common.items.mineral.ore.bloodstone")), - (0.2, Item("common.items.mineral.ore.cobalt")), - (0.25, Item("common.items.mineral.ore.coal")), - (0.3, Item("common.items.mineral.ore.iron")), - (0.5, Item("common.items.mineral.ore.velorite")), - (0.6, Item("common.items.mineral.ore.veloritefrag")), - (1.5, Item("common.items.mineral.ore.copper")), - (1.5, Item("common.items.mineral.ore.tin")), - // Animal Hide - (0.05, Item("common.items.crafting_ing.hide.dragon_scale")), - (0.05, Item("common.items.crafting_ing.hide.plate")), - (0.1, Item("common.items.crafting_ing.leather.rigid_leather")), - (0.1, Item("common.items.crafting_ing.hide.carapace")), - (0.2, Item("common.items.crafting_ing.hide.scales")), - (0.7, Item("common.items.crafting_ing.hide.tough_hide")), - (1.0, Item("common.items.crafting_ing.hide.animal_hide")), - (1.5, Item("common.items.crafting_ing.leather.leather_strips")), - // Mob Drops - (0.01, Item("common.items.crafting_ing.animal_misc.phoenix_feather")), - (0.08, Item("common.items.crafting_ing.animal_misc.large_horn")), - (0.1, Item("common.items.crafting_ing.animal_misc.icy_fang")), - (0.15, Item("common.items.crafting_ing.animal_misc.grim_eyeball")), - (0.15, Item("common.items.crafting_ing.animal_misc.lively_vine")), - (1.2, Item("common.items.crafting_ing.animal_misc.fur")), - // Meats - (0.6, Item("common.items.food.meat.beast_large_raw")), - (0.8, Item("common.items.food.meat.tough_raw")), - (1.0, Item("common.items.food.meat.beast_small_raw")), - (1.2, Item("common.items.food.meat.fish_raw")), - (1.3, Item("common.items.food.meat.bird_raw")), -] diff --git a/assets/common/loot_tables/trading/buying.ron b/assets/common/loot_tables/trading/buying.ron new file mode 100644 index 0000000000..31bfd830c9 --- /dev/null +++ b/assets/common/loot_tables/trading/buying.ron @@ -0,0 +1,10 @@ +// Loot table that exists purely for price rationalisation +// Put here anything that doesn't fit in anything else. +// +// This loot table should be marked as un-sellable. +// If you want to add something that merchants can buy and sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ +] diff --git a/assets/common/loot_tables/trading/collection.ron b/assets/common/loot_tables/trading/collection.ron new file mode 100644 index 0000000000..069a912e22 --- /dev/null +++ b/assets/common/loot_tables/trading/collection.ron @@ -0,0 +1,22 @@ +// Loot table that exists purely for price rationalisation +// Put here anything that doesn't fit in anything else. +// +// This loot table should be marked as un-sellable. +// If you want to add something that merchants can buy and sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + /// Non-craftable gliders + // Butterfly gliders + (5, Item("common.items.glider.glider_morpho")), + (5, Item("common.items.glider.glider_monarch")), + (5, Item("common.items.glider.glider_moth")), + // Skullgrin + (2, Item("common.items.glider.glider_purp")), + + /// Lanterns + (5, Item("common.items.lantern.geode_purp")), + (2, Item("common.items.lantern.blue_0")), + (2, Item("common.items.boss_drops.lantern")), +] diff --git a/assets/common/loot_tables/trading/food.ron b/assets/common/loot_tables/trading/food.ron new file mode 100644 index 0000000000..e98d52abf0 --- /dev/null +++ b/assets/common/loot_tables/trading/food.ron @@ -0,0 +1,24 @@ +// Loot table that exists purely for price rationalisation +// +// This loot table should be marked as sellable. +// If you want to add something that merchants can buy but not sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + // Meats + (0.0125, Item("common.items.food.meat.bird_large_raw")), + (0.5, Item("common.items.food.meat.beast_large_raw")), + (2.0, Item("common.items.food.meat.bird_raw")), + (2.0, Item("common.items.food.meat.fish_raw")), + (2.0, Item("common.items.food.meat.tough_raw")), + (4.0, Item("common.items.food.meat.beast_small_raw")), + // Gatherables + (0.025, Item("common.items.food.coconut")), + (0.25, Item("common.items.food.cheese")), + (0.25, Item("common.items.food.apple")), + (2.0, Item("common.items.food.carrot")), + (2.0, Item("common.items.food.lettuce")), + (2.0, Item("common.items.food.tomato")), + (2.0, Item("common.items.food.mushroom")), +] diff --git a/assets/common/loot_tables/trading/jewellery.ron b/assets/common/loot_tables/trading/jewellery.ron new file mode 100644 index 0000000000..cc55273026 --- /dev/null +++ b/assets/common/loot_tables/trading/jewellery.ron @@ -0,0 +1,11 @@ +// Loot table that exists purely for price rationalisation +// +// This loot table should be marked as un-sellable. +// If you want to add something that merchants can buy and sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + (1, Item("common.items.armor.misc.back.dungeon_purple")), + (1, Item("common.items.armor.misc.ring.skull")), +] diff --git a/assets/common/loot_tables/trading/sellable_materials.ron b/assets/common/loot_tables/trading/sellable_materials.ron new file mode 100644 index 0000000000..c486d78e58 --- /dev/null +++ b/assets/common/loot_tables/trading/sellable_materials.ron @@ -0,0 +1,58 @@ +// Loot table that exists purely for price rationalisation +// +// This loot table should be marked as sellable. +// If you want to add something that merchants can buy but not sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + // Stones + (0.02, Item("common.items.mineral.gem.diamond")), + (0.08, Item("common.items.mineral.gem.ruby")), + (0.1, Item("common.items.mineral.gem.emerald")), + (0.2, Item("common.items.mineral.gem.sapphire")), + (0.25, Item("common.items.mineral.ore.velorite")), + (0.5, Item("common.items.mineral.ore.veloritefrag")), + (0.75, Item("common.items.mineral.gem.topaz")), + (1.0, Item("common.items.mineral.gem.amethyst")), + (4.0, Item("common.items.crafting_ing.stones")), + + // Ores + (0.5, Item("common.items.mineral.ore.velorite")), + (0.6, Item("common.items.mineral.ore.veloritefrag")), + (2.5, Item("common.items.mineral.ore.copper")), + (2.5, Item("common.items.mineral.ore.iron")), + (2.5, Item("common.items.mineral.ore.tin")), + + // Animal Hide + (2.5, Item("common.items.crafting_ing.hide.tough_hide")), + (4.0, Item("common.items.crafting_ing.hide.animal_hide")), + + // Mob Drops + (0.15, Item("common.items.crafting_ing.animal_misc.grim_eyeball")), + (0.15, Item("common.items.crafting_ing.animal_misc.lively_vine")), + (0.5, Item("common.items.crafting_ing.animal_misc.raptor_feather")), + (1.0, Item("common.items.crafting_ing.animal_misc.icy_fang")), + (1.2, Item("common.items.crafting_ing.animal_misc.claw")), + (2.5, Item("common.items.crafting_ing.animal_misc.fur")), + (2.5, Item("common.items.crafting_ing.animal_misc.sharp_fang")), + (2.5, Item("common.items.crafting_ing.animal_misc.venom_sac")), + (2.5, Item("common.items.crafting_ing.animal_misc.viscous_ooze")), + (4.0, Item("common.items.crafting_ing.cloth.wool")), + + // Junk + (4.0, Item("common.items.crafting_ing.bowl")), + (4.0, Item("common.items.crafting_ing.empty_vial")), + + // Gatherables + (0.1, Item("common.items.crafting_ing.seashells")), + (0.2, Item("common.items.crafting_ing.honey")), + (0.2, Item("common.items.flowers.moonbell")), + (1.0, Item("common.items.crafting_ing.cactus")), + (1.0, Item("common.items.crafting_ing.cotton_boll")), + (1.0, Item("common.items.flowers.pyrebloom")), + (3.0, Item("common.items.crafting_ing.twigs")), + (4.0, Item("common.items.flowers.red")), + (4.0, Item("common.items.flowers.wild_flax")), + (9.0, Item("common.items.flowers.sunflower")), +] diff --git a/assets/common/loot_tables/trading/unsellable_materials.ron b/assets/common/loot_tables/trading/unsellable_materials.ron new file mode 100644 index 0000000000..e08cf09ed7 --- /dev/null +++ b/assets/common/loot_tables/trading/unsellable_materials.ron @@ -0,0 +1,32 @@ +// Loot table that exists purely for price rationalisation +// +// This loot table should be marked as un-sellable. +// If you want to add something that merchants can buy and sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + // High tier Ores + (0.025, Item("common.items.mineral.ore.gold")), + (0.03, Item("common.items.mineral.ore.silver")), + (0.1, Item("common.items.mineral.ore.bloodstone")), + (0.2, Item("common.items.mineral.ore.cobalt")), + (0.25, Item("common.items.mineral.ore.coal")), + + // High tier Animal Hide + (0.025, Item("common.items.crafting_ing.hide.dragon_scale")), + (0.05, Item("common.items.crafting_ing.hide.plate")), + (0.05, Item("common.items.crafting_ing.hide.leather_troll")), + (0.05, Item("common.items.crafting_ing.hide.rugged_hide")), + (0.2, Item("common.items.crafting_ing.hide.carapace")), + (0.2, Item("common.items.crafting_ing.hide.scales")), + + // High tier Mob drops + (0.005, Item("common.items.crafting_ing.animal_misc.phoenix_feather")), + (0.08, Item("common.items.crafting_ing.animal_misc.large_horn")), + (0.08, Item("common.items.crafting_ing.animal_misc.lively_vine")), + (0.225, Item("common.items.crafting_ing.sticky_thread")), + + // Ultra Rare drops + (0.0005, Item("common.items.crafting_ing.mindflayer_bag_damaged")), +] diff --git a/common/src/comp/inventory/trade_pricing.rs b/common/src/comp/inventory/trade_pricing.rs index b8ea4298ee..aa339f7eab 100644 --- a/common/src/comp/inventory/trade_pricing.rs +++ b/common/src/comp/inventory/trade_pricing.rs @@ -223,8 +223,6 @@ impl TradePricing { fn get_list_by_path(&self, name: &str) -> &[Entry] { match name { // Armor - // TODO: balance mindflayer bag price so this isn't needed - "common.items.crafting_ing.mindflayer_bag_damaged" => &self.armor.entries, _ if name.starts_with("common.items.armor.") => &self.armor.entries, // Tools _ if name.starts_with("common.items.weapons.") => &self.tools.entries, @@ -253,8 +251,6 @@ impl TradePricing { fn get_list_by_path_mut(&mut self, name: &str) -> &mut Entries { match name { // Armor - // TODO: balance mindflayer bag price so this isn't needed - "common.items.crafting_ing.mindflayer_bag_damaged" => &mut self.armor, _ if name.starts_with("common.items.armor.") => &mut self.armor, // Tools _ if name.starts_with("common.items.weapons.") => &mut self.tools, @@ -350,22 +346,30 @@ impl TradePricing { let mut ordered_recipes: Vec = Vec::new(); for (_, recipe) in book.iter() { let (ref asset_path, amount) = recipe.output; - ordered_recipes.push(RememberedRecipe { - output: asset_path.id().into(), - amount, - material_cost: Self::UNAVAILABLE_PRICE, - input: recipe - .inputs - .iter() - .filter_map(|&(ref recipe_input, count)| { - if let RecipeInput::Item(it) = recipe_input { - Some((it.id().into(), count)) - } else { - None - } - }) - .collect(), - }); + // Trading don't know how to work with recycling yet + if !recipe.is_recycling { + ordered_recipes.push(RememberedRecipe { + output: asset_path.id().into(), + amount, + material_cost: Self::UNAVAILABLE_PRICE, + input: recipe + .inputs + .iter() + .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 { + None + } else { + Some((it.id().into(), count)) + } + } else { + None + } + }) + .collect(), + }); + } } // re-evaluate prices based on crafting tables From 0640902b7fcb5eba195b401b2986175c17b9bde6 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Sat, 3 Jul 2021 15:19:21 +0300 Subject: [PATCH 2/2] Make ItemEquality work + Create own directory for trade_pricing `assets/common/trading` + Move fictive loot tables there + Mark sellable/non-sellable items in trade_pricing tests --- assets/common/item_price_equality.ron | 4 - assets/common/loot_tables/trading/buying.ron | 10 -- assets/common/recipe_book.ron | 1 - assets/common/trading/balance.ron | 19 ++++ .../{loot_tables => }/trading/collection.ron | 0 .../common/{loot_tables => }/trading/food.ron | 8 +- .../{ => trading}/item_price_calculation.ron | 28 +++--- assets/common/trading/item_price_equality.ron | 58 ++++++++++++ .../{loot_tables => }/trading/jewellery.ron | 0 .../trading/sellable_materials.ron | 5 +- .../trading/unsellable_materials.ron | 1 + common/src/comp/inventory/trade_pricing.rs | 94 ++++++++++++------- 12 files changed, 159 insertions(+), 69 deletions(-) delete mode 100644 assets/common/item_price_equality.ron delete mode 100644 assets/common/loot_tables/trading/buying.ron create mode 100644 assets/common/trading/balance.ron rename assets/common/{loot_tables => }/trading/collection.ron (100%) rename assets/common/{loot_tables => }/trading/food.ron (79%) rename assets/common/{ => trading}/item_price_calculation.ron (72%) create mode 100644 assets/common/trading/item_price_equality.ron rename assets/common/{loot_tables => }/trading/jewellery.ron (100%) rename assets/common/{loot_tables => }/trading/sellable_materials.ron (92%) rename assets/common/{loot_tables => }/trading/unsellable_materials.ron (95%) diff --git a/assets/common/item_price_equality.ron b/assets/common/item_price_equality.ron deleted file mode 100644 index 76dd365a0d..0000000000 --- a/assets/common/item_price_equality.ron +++ /dev/null @@ -1,4 +0,0 @@ -[ - ["common.items.weapons.sceptre.caduceus", "common.items.weapons.sceptre.root_evil"], - ["common.items.weapons.staff.laevateinn", "common.items.weapons.staff.phoenix" ], -] diff --git a/assets/common/loot_tables/trading/buying.ron b/assets/common/loot_tables/trading/buying.ron deleted file mode 100644 index 31bfd830c9..0000000000 --- a/assets/common/loot_tables/trading/buying.ron +++ /dev/null @@ -1,10 +0,0 @@ -// Loot table that exists purely for price rationalisation -// Put here anything that doesn't fit in anything else. -// -// This loot table should be marked as un-sellable. -// If you want to add something that merchants can buy and sell, -// add another loot table -// -// Please keep it sorted by rarity so it's easier to reason about things -[ -] diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index cb6cb55f72..5a1f2a8515 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -531,7 +531,6 @@ inputs: [ (Item("common.items.crafting_ing.leather.leather_strips"), 4), (Item("common.items.crafting_ing.twigs"), 10), - (Item("common.items.mineral.ore.veloritefrag"), 1), ], craft_sprite: Some(Anvil), is_recycling: false, diff --git a/assets/common/trading/balance.ron b/assets/common/trading/balance.ron new file mode 100644 index 0000000000..02ad4990b4 --- /dev/null +++ b/assets/common/trading/balance.ron @@ -0,0 +1,19 @@ +// Loot table that exists purely for price rationalisation +// +// NOTE: it shouln't be considered source of resources. +// Place here things which have greater prices than intended. +// +// This loot table should be marked as un-sellable. +// If you want to add something that merchants can buy and sell, +// add another loot table +// +// Please keep it sorted by rarity so it's easier to reason about things +[ + // Mostly tools here because crafting turn rarity from input ingredients, + // and move it to output, which isn't desired + (1.0, Item("common.items.tool.pickaxe_steel")), + (20.0, Item("common.items.tool.craftsman_hammer")), + (20.0, Item("common.items.tool.pickaxe_stone")), + (20.0, Item("common.items.weapons.hammer.burnt_drumstick")), + (20.0, Item("common.items.weapons.sword.wood-2")), +] diff --git a/assets/common/loot_tables/trading/collection.ron b/assets/common/trading/collection.ron similarity index 100% rename from assets/common/loot_tables/trading/collection.ron rename to assets/common/trading/collection.ron diff --git a/assets/common/loot_tables/trading/food.ron b/assets/common/trading/food.ron similarity index 79% rename from assets/common/loot_tables/trading/food.ron rename to assets/common/trading/food.ron index e98d52abf0..a220506326 100644 --- a/assets/common/loot_tables/trading/food.ron +++ b/assets/common/trading/food.ron @@ -7,16 +7,16 @@ // Please keep it sorted by rarity so it's easier to reason about things [ // Meats - (0.0125, Item("common.items.food.meat.bird_large_raw")), + (0.125, Item("common.items.food.meat.bird_large_raw")), (0.5, Item("common.items.food.meat.beast_large_raw")), (2.0, Item("common.items.food.meat.bird_raw")), (2.0, Item("common.items.food.meat.fish_raw")), (2.0, Item("common.items.food.meat.tough_raw")), (4.0, Item("common.items.food.meat.beast_small_raw")), // Gatherables - (0.025, Item("common.items.food.coconut")), - (0.25, Item("common.items.food.cheese")), - (0.25, Item("common.items.food.apple")), + (0.25, Item("common.items.food.coconut")), + (0.5, Item("common.items.food.cheese")), + (1.0, Item("common.items.food.apple")), (2.0, Item("common.items.food.carrot")), (2.0, Item("common.items.food.lettuce")), (2.0, Item("common.items.food.tomato")), diff --git a/assets/common/item_price_calculation.ron b/assets/common/trading/item_price_calculation.ron similarity index 72% rename from assets/common/item_price_calculation.ron rename to assets/common/trading/item_price_calculation.ron index 24fded7293..91a49da8da 100644 --- a/assets/common/item_price_calculation.ron +++ b/assets/common/trading/item_price_calculation.ron @@ -3,29 +3,31 @@ loot_tables: [ // balance the loot tables against each other (higher= more common= smaller price) // Weapons (32.0, true, "common.loot_tables.weapons.starter"), - (16.0, true, "common.loot_tables.weapons.tier-0"), - (8.0, true, "common.loot_tables.weapons.tier-1"), - (4.0, true, "common.loot_tables.weapons.tier-2"), - (2.0, true, "common.loot_tables.weapons.tier-3"), - (1.0, false, "common.loot_tables.weapons.tier-4"), - (0.5, false, "common.loot_tables.weapons.tier-5"), (0.025, false, "common.loot_tables.weapons.cultist"), (0.025, false, "common.loot_tables.weapons.cave"), (0.02, false, "common.loot_tables.weapons.legendary"), + // Weapons sets + (16.0, true, "common.loot_tables.weapons.tier-0"), + (8.0, true, "common.loot_tables.weapons.tier-1"), + (1.0, true, "common.loot_tables.weapons.tier-2"), + (0.125, true, "common.loot_tables.weapons.tier-3"), + (0.0625, false, "common.loot_tables.weapons.tier-4"), + (0.03, false, "common.loot_tables.weapons.tier-5"), + // Non-craftable Armor (20.0, true, "common.loot_tables.armor.cloth"), (1.0, true, "common.loot_tables.armor.twigs"), (1.0, true, "common.loot_tables.armor.twigsflowers"), (1.0, true, "common.loot_tables.armor.twigsleaves"), - (0.01, false, "common.loot_tables.trading.jewellery"), + (0.01, false, "common.trading.jewellery"), // Ingredients - (1.0, true, "common.loot_tables.trading.sellable_materials"), - (1.0, false, "common.loot_tables.trading.unsellable_materials"), + (1.0, true, "common.trading.sellable_materials"), + (1.0, false, "common.trading.unsellable_materials"), // Food Ingredients - (1.0, true, "common.loot_tables.trading.food"), + (1.0, true, "common.trading.food"), // Potions // @@ -39,14 +41,16 @@ loot_tables: [ // Misc (0.1, true, "common.loot_tables.consumable.throwable"), // Collections - (0.00001, false, "common.loot_tables.trading.collection"), + (0.00001, false, "common.trading.collection"), + // Manual balance + (1.0, false, "common.trading.balance"), ], // this is the amount of that good the most common item represents // so basically this table balances the goods against each other (higher=less valuable) good_scaling: [ (Potions, 0.005), // common.items.consumable.potion_minor - (Food, 0.5), // common.items.food.mushroom + (Food, 0.15), // common.items.food.mushroom (Coin, 1.0), // common.items.utility.coins (Armor, 0.5), // common.items.armor.misc.pants.worker_blue (Tools, 0.5), // common.items.weapons.staff.starter_staff diff --git a/assets/common/trading/item_price_equality.ron b/assets/common/trading/item_price_equality.ron new file mode 100644 index 0000000000..6b1a027090 --- /dev/null +++ b/assets/common/trading/item_price_equality.ron @@ -0,0 +1,58 @@ +[ + // Tier-0 weapons + LootTable("common.loot_tables.weapons.sword.stone"), + LootTable("common.loot_tables.weapons.axe.stone"), + LootTable("common.loot_tables.weapons.hammer.stone"), + LootTable("common.loot_tables.weapons.bow.wood"), + LootTable("common.loot_tables.weapons.staff.wood"), + + // Tier-1 weapons + LootTable("common.loot_tables.weapons.sword.bronze"), + LootTable("common.loot_tables.weapons.axe.bronze"), + LootTable("common.loot_tables.weapons.hammer.bronze"), + LootTable("common.loot_tables.weapons.bow.bone"), + LootTable("common.loot_tables.weapons.staff.bamboo"), + LootTable("common.loot_tables.weapons.sceptre.bamboo"), + + // Tier-2 weapons + LootTable("common.loot_tables.weapons.sword.iron"), + LootTable("common.loot_tables.weapons.axe.iron"), + LootTable("common.loot_tables.weapons.hammer.iron"), + LootTable("common.loot_tables.weapons.bow.hardwood"), + LootTable("common.loot_tables.weapons.staff.hardwood"), + LootTable("common.loot_tables.weapons.sceptre.hardwood"), + + // Tier-3 weapons + LootTable("common.loot_tables.weapons.sword.steel"), + LootTable("common.loot_tables.weapons.axe.steel"), + LootTable("common.loot_tables.weapons.hammer.steel"), + LootTable("common.loot_tables.weapons.bow.metal"), + LootTable("common.loot_tables.weapons.staff.ironwood"), + LootTable("common.loot_tables.weapons.sceptre.ironwood"), + + // Tier-4 weapons + LootTable("common.loot_tables.weapons.sword.cobalt"), + LootTable("common.loot_tables.weapons.axe.cobalt"), + LootTable("common.loot_tables.weapons.hammer.cobalt"), + LootTable("common.loot_tables.weapons.bow.frostwood"), + LootTable("common.loot_tables.weapons.staff.frostwood"), + LootTable("common.loot_tables.weapons.sceptre.frostwood"), + + // Tier-5 weapons + LootTable("common.loot_tables.weapons.sword.bloodsteel"), + LootTable("common.loot_tables.weapons.axe.bloodsteel"), + LootTable("common.loot_tables.weapons.hammer.bloodsteel"), + LootTable("common.loot_tables.weapons.bow.eldwood"), + LootTable("common.loot_tables.weapons.staff.eldwood"), + LootTable("common.loot_tables.weapons.sceptre.eldwood"), + + // Legendary staves and sceptres + Set([ + "common.items.weapons.staff.phoenix", + "common.items.weapons.staff.laevateinn", + ]), + Set([ + "common.items.weapons.sceptre.root_evil", + "common.items.weapons.sceptre.caduceus", + ]), +] diff --git a/assets/common/loot_tables/trading/jewellery.ron b/assets/common/trading/jewellery.ron similarity index 100% rename from assets/common/loot_tables/trading/jewellery.ron rename to assets/common/trading/jewellery.ron diff --git a/assets/common/loot_tables/trading/sellable_materials.ron b/assets/common/trading/sellable_materials.ron similarity index 92% rename from assets/common/loot_tables/trading/sellable_materials.ron rename to assets/common/trading/sellable_materials.ron index c486d78e58..0736ccaaf9 100644 --- a/assets/common/loot_tables/trading/sellable_materials.ron +++ b/assets/common/trading/sellable_materials.ron @@ -30,9 +30,8 @@ // Mob Drops (0.15, Item("common.items.crafting_ing.animal_misc.grim_eyeball")), - (0.15, Item("common.items.crafting_ing.animal_misc.lively_vine")), + (0.15, Item("common.items.crafting_ing.animal_misc.icy_fang")), (0.5, Item("common.items.crafting_ing.animal_misc.raptor_feather")), - (1.0, Item("common.items.crafting_ing.animal_misc.icy_fang")), (1.2, Item("common.items.crafting_ing.animal_misc.claw")), (2.5, Item("common.items.crafting_ing.animal_misc.fur")), (2.5, Item("common.items.crafting_ing.animal_misc.sharp_fang")), @@ -48,10 +47,10 @@ (0.1, Item("common.items.crafting_ing.seashells")), (0.2, Item("common.items.crafting_ing.honey")), (0.2, Item("common.items.flowers.moonbell")), - (1.0, Item("common.items.crafting_ing.cactus")), (1.0, Item("common.items.crafting_ing.cotton_boll")), (1.0, Item("common.items.flowers.pyrebloom")), (3.0, Item("common.items.crafting_ing.twigs")), + (4.0, Item("common.items.crafting_ing.cactus")), (4.0, Item("common.items.flowers.red")), (4.0, Item("common.items.flowers.wild_flax")), (9.0, Item("common.items.flowers.sunflower")), diff --git a/assets/common/loot_tables/trading/unsellable_materials.ron b/assets/common/trading/unsellable_materials.ron similarity index 95% rename from assets/common/loot_tables/trading/unsellable_materials.ron rename to assets/common/trading/unsellable_materials.ron index e08cf09ed7..5c333cc8b2 100644 --- a/assets/common/loot_tables/trading/unsellable_materials.ron +++ b/assets/common/trading/unsellable_materials.ron @@ -25,6 +25,7 @@ (0.005, Item("common.items.crafting_ing.animal_misc.phoenix_feather")), (0.08, Item("common.items.crafting_ing.animal_misc.large_horn")), (0.08, Item("common.items.crafting_ing.animal_misc.lively_vine")), + (0.15, Item("common.items.crafting_ing.animal_misc.lively_vine")), (0.225, Item("common.items.crafting_ing.sticky_thread")), // Ultra Rare drops diff --git a/common/src/comp/inventory/trade_pricing.rs b/common/src/comp/inventory/trade_pricing.rs index aa339f7eab..9ca594da8f 100644 --- a/common/src/comp/inventory/trade_pricing.rs +++ b/common/src/comp/inventory/trade_pricing.rs @@ -44,10 +44,7 @@ struct Entries { impl Entries { fn add(&mut self, eqset: &EqualitySet, item_name: &str, probability: f32, can_sell: bool) { - let canonical_itemname = eqset - .equivalence_class - .get(item_name) - .map_or(item_name, |i| &**i); + let canonical_itemname = eqset.canonical(item_name); let old = self .entries @@ -66,10 +63,15 @@ impl Entries { } self.entries .push((canonical_itemname.to_owned(), probability, can_sell)); - if canonical_itemname != item_name { - // Add the non-canonical item so that it'll show up in merchant inventories - self.entries.push((item_name.to_owned(), 0.0, can_sell)); - } + } + + // Add the non-canonical item so that it'll show up in merchant inventories + // It will have infinity as its price, but it's fine, + // because we determine all prices based on canonical value + if canonical_itemname != item_name + && !self.entries.iter().any(|(name, _, _)| name == item_name) + { + self.entries.push((item_name.to_owned(), 0.0, can_sell)); } } } @@ -136,27 +138,54 @@ struct EqualitySet { equivalence_class: HashMap, } +impl EqualitySet { + fn canonical<'a>(&'a self, item_name: &'a str) -> &'a str { + let canonical_itemname = self + .equivalence_class + .get(item_name) + .map_or(item_name, |i| &**i); + + canonical_itemname + } +} + impl assets::Compound for EqualitySet { fn load( cache: &assets::AssetCache, id: &str, ) -> Result { - let manifest = cache.load::>>>(id)?; - let mut ret = Self { + #[derive(Debug, Deserialize)] + enum EqualitySpec { + LootTable(String), + Set(Vec), + } + + let mut eqset = Self { equivalence_class: HashMap::new(), }; - for set in &manifest.read().0 { - let mut iter = set.iter(); + + let manifest = &cache.load::>>(id)?.read().0; + for set in manifest { + let items = match set { + EqualitySpec::LootTable(table) => { + let acc = &ProbabilityFile::load_expect(table).read().content; + + acc.iter().map(|(_p, item)| item).cloned().collect() + }, + EqualitySpec::Set(xs) => xs.clone(), + }; + let mut iter = items.iter(); if let Some(first) = iter.next() { let first = first.to_string(); - ret.equivalence_class.insert(first.clone(), first.clone()); + eqset.equivalence_class.insert(first.clone(), first.clone()); for item in iter { - ret.equivalence_class + eqset + .equivalence_class .insert(item.to_string(), first.clone()); } } } - Ok(ret) + Ok(eqset) } } @@ -278,10 +307,7 @@ impl TradePricing { // look up price (inverse frequency) of an item fn price_lookup(&self, eqset: &EqualitySet, requested_name: &str) -> f32 { - let canonical_name = eqset - .equivalence_class - .get(requested_name) - .map_or(requested_name, |name| &**name); + let canonical_name = eqset.canonical(requested_name); let goods = self.get_list_by_path(canonical_name); // even if we multiply by INVEST_FACTOR we need to remain @@ -322,8 +348,9 @@ impl TradePricing { #[allow(clippy::cast_precision_loss)] fn read() -> Self { let mut result = Self::default(); - let price_config = TradingPriceFile::load_expect("common.item_price_calculation").read(); - let eqset = EqualitySet::load_expect("common.item_price_equality").read(); + let price_config = + TradingPriceFile::load_expect("common.trading.item_price_calculation").read(); + let eqset = EqualitySet::load_expect("common.trading.item_price_equality").read(); result.equality_set = eqset.clone(); for table in &price_config.loot_tables { if PRICING_DEBUG { @@ -382,7 +409,7 @@ impl TradePricing { let actual_cost = result.calculate_material_cost(recipe, &eqset); let output_tradeable = recipe.input.iter().all(|(input, _)| { result - .get_list_by_path(&input) + .get_list_by_path(input) .iter() .find(|(item, _, _)| item == input) .map_or(false, |(_, _, tradeable)| *tradeable) @@ -468,11 +495,7 @@ impl TradePricing { if item == Self::COIN_ITEM { (Good::Coin, 1.0) } else { - let item = TRADE_PRICING - .equality_set - .equivalence_class - .get(item) - .map_or(item, |i| &**i); + let item = TRADE_PRICING.equality_set.canonical(item); TRADE_PRICING.material_cache.get(item).copied().map_or( (Good::Terrain(crate::terrain::BiomeKind::Void), 0.0), @@ -489,20 +512,21 @@ impl TradePricing { use crate::comp::item::{armor, tool, Item, ItemKind}; // we pass the item and the inverse of the price to the closure - fn printvec(x: &str, e: &[(String, f32, bool)], f: F) + fn printvec(good_kind: &str, entries: &[(String, f32, bool)], f: F) where F: Fn(&Item, f32) -> String, { - println!("\n======{:^15}======", x); - for i in e.iter() { - let it = Item::new_from_asset_expect(&i.0); - let price = 1.0 / i.1; + println!("\n======{:^15}======", good_kind); + for (item_id, p, can_sell) in entries.iter() { + let it = Item::new_from_asset_expect(item_id); + let price = 1.0 / p; println!( - "<{}>\n{:>4.2} {:?} {}", - i.0, + "<{}> {}\n{:>4.2} {:?} {}", + item_id, + if *can_sell { "+" } else { "-" }, price, it.quality, - f(&it, i.1) + f(&it, *p) ); } }