From 762b3be3c36ad177f60d7a46150ca945863e9723 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 4 Aug 2021 23:23:08 -0500 Subject: [PATCH] Modular weapons can now be dropped as loot or assigned to enemies. --- .../items/crafting_ing/cloth/cotton.ron | 2 +- .../items/crafting_ing/cloth/lifecloth.ron | 2 +- .../common/items/crafting_ing/cloth/linen.ron | 2 +- .../items/crafting_ing/cloth/linen_red.ron | 2 +- .../items/crafting_ing/cloth/moonweave.ron | 2 +- .../common/items/crafting_ing/cloth/silk.ron | 2 +- .../items/crafting_ing/cloth/sunsilk.ron | 2 +- .../common/items/crafting_ing/cloth/wool.ron | 2 +- .../items/crafting_ing/hide/carapace.ron | 2 +- .../items/crafting_ing/hide/dragon_scale.ron | 4 +- .../common/items/crafting_ing/hide/plate.ron | 2 +- .../common/items/crafting_ing/hide/scales.ron | 2 +- .../crafting_ing/leather/simple_leather.ron | 5 +- .../crafting_ing/leather/thick_leather.ron | 5 +- assets/common/items/log/bamboo.ron | 2 +- assets/common/items/log/eldwood.ron | 2 +- assets/common/items/log/frostwood.ron | 2 +- assets/common/items/log/hardwood.ron | 2 +- assets/common/items/log/ironwood.ron | 2 +- assets/common/items/log/wood.ron | 2 +- .../common/items/mineral/ingot/bloodsteel.ron | 2 +- assets/common/items/mineral/ingot/bronze.ron | 2 +- assets/common/items/mineral/ingot/cobalt.ron | 2 +- assets/common/items/mineral/ingot/copper.ron | 2 +- assets/common/items/mineral/ingot/gold.ron | 2 +- assets/common/items/mineral/ingot/iron.ron | 2 +- .../common/items/mineral/ingot/orichalcum.ron | 2 +- assets/common/items/mineral/ingot/silver.ron | 2 +- assets/common/items/mineral/ingot/steel.ron | 2 +- assets/common/items/mineral/ingot/tin.ron | 2 +- assets/common/recipe_book.ron | 42 +++--- common/src/comp/inventory/item/mod.rs | 23 ++-- common/src/comp/inventory/item/modular.rs | 128 +++++++++++++++++- common/src/comp/inventory/trade_pricing.rs | 2 + common/src/lottery.rs | 22 ++- voxygen/src/hud/crafting.rs | 10 +- 36 files changed, 220 insertions(+), 75 deletions(-) diff --git a/assets/common/items/crafting_ing/cloth/cotton.ron b/assets/common/items/crafting_ing/cloth/cotton.ron index b69f9656c2..94b94d6ded 100644 --- a/assets/common/items/crafting_ing/cloth/cotton.ron +++ b/assets/common/items/crafting_ing/cloth/cotton.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Cotton", ), quality: Direct(Low), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/lifecloth.ron b/assets/common/items/crafting_ing/cloth/lifecloth.ron index 16223be62b..508cf08dc9 100644 --- a/assets/common/items/crafting_ing/cloth/lifecloth.ron +++ b/assets/common/items/crafting_ing/cloth/lifecloth.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Lifecloth", ), quality: Direct(High), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/linen.ron b/assets/common/items/crafting_ing/cloth/linen.ron index 8c079d6252..f852c8b431 100644 --- a/assets/common/items/crafting_ing/cloth/linen.ron +++ b/assets/common/items/crafting_ing/cloth/linen.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Linen", ), quality: Direct(Low), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/linen_red.ron b/assets/common/items/crafting_ing/cloth/linen_red.ron index f1c3242f49..537d2a89a1 100644 --- a/assets/common/items/crafting_ing/cloth/linen_red.ron +++ b/assets/common/items/crafting_ing/cloth/linen_red.ron @@ -7,5 +7,5 @@ ItemDef( descriptor: "", ), quality: Direct(Low), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/moonweave.ron b/assets/common/items/crafting_ing/cloth/moonweave.ron index 34929e0fe1..1f0a6451d1 100644 --- a/assets/common/items/crafting_ing/cloth/moonweave.ron +++ b/assets/common/items/crafting_ing/cloth/moonweave.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Moonwoven", ), quality: Direct(Epic), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/silk.ron b/assets/common/items/crafting_ing/cloth/silk.ron index 08eacdcdcc..9bf310d18e 100644 --- a/assets/common/items/crafting_ing/cloth/silk.ron +++ b/assets/common/items/crafting_ing/cloth/silk.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Silken", ), quality: Direct(Moderate), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/sunsilk.ron b/assets/common/items/crafting_ing/cloth/sunsilk.ron index 687da69cbc..447037f5eb 100644 --- a/assets/common/items/crafting_ing/cloth/sunsilk.ron +++ b/assets/common/items/crafting_ing/cloth/sunsilk.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Sunsilken", ), quality: Direct(Legendary), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/cloth/wool.ron b/assets/common/items/crafting_ing/cloth/wool.ron index 65bc40aebb..e6ec58a67c 100644 --- a/assets/common/items/crafting_ing/cloth/wool.ron +++ b/assets/common/items/crafting_ing/cloth/wool.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Woolen", ), quality: Direct(Common), - tags: [Textile], + tags: [MaterialKind(Cloth)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/hide/carapace.ron b/assets/common/items/crafting_ing/hide/carapace.ron index 5cc16cd33f..6fed454ec4 100644 --- a/assets/common/items/crafting_ing/hide/carapace.ron +++ b/assets/common/items/crafting_ing/hide/carapace.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Carapace", ), quality: Direct(High), - tags: [], + tags: [MaterialKind(Hide)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/hide/dragon_scale.ron b/assets/common/items/crafting_ing/hide/dragon_scale.ron index 363af3173f..18876245a4 100644 --- a/assets/common/items/crafting_ing/hide/dragon_scale.ron +++ b/assets/common/items/crafting_ing/hide/dragon_scale.ron @@ -3,8 +3,8 @@ ItemDef( description: "Tough scale from a legendary beast.", kind: Ingredient( kind: "DragonScale", - descriptor: "Dragon Scaled", + descriptor: "Dragonscale", ), quality: Direct(Legendary), - tags: [], + tags: [MaterialKind(Hide)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/hide/plate.ron b/assets/common/items/crafting_ing/hide/plate.ron index 0b4d93aa47..fb757d93bb 100644 --- a/assets/common/items/crafting_ing/hide/plate.ron +++ b/assets/common/items/crafting_ing/hide/plate.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Plate", ), quality: Direct(Epic), - tags: [], + tags: [MaterialKind(Hide)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/hide/scales.ron b/assets/common/items/crafting_ing/hide/scales.ron index a43cae981f..aa74b7a12d 100644 --- a/assets/common/items/crafting_ing/hide/scales.ron +++ b/assets/common/items/crafting_ing/hide/scales.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Scale", ), quality: Direct(Moderate), - tags: [], + tags: [MaterialKind(Hide)], ) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/leather/simple_leather.ron b/assets/common/items/crafting_ing/leather/simple_leather.ron index 019b69fbbc..ad325460d0 100644 --- a/assets/common/items/crafting_ing/leather/simple_leather.ron +++ b/assets/common/items/crafting_ing/leather/simple_leather.ron @@ -3,9 +3,8 @@ ItemDef( description: "Light and flexible.", kind: Ingredient( kind: "SimpleLeather", - // Descriptor not needed - descriptor: "", + descriptor: "Raw Hide", ), quality: Direct(Low), - tags: [BaseMaterial, Leather], + tags: [BaseMaterial, Leather, MaterialKind(Hide)], ) diff --git a/assets/common/items/crafting_ing/leather/thick_leather.ron b/assets/common/items/crafting_ing/leather/thick_leather.ron index 3836017533..08f753bfa5 100644 --- a/assets/common/items/crafting_ing/leather/thick_leather.ron +++ b/assets/common/items/crafting_ing/leather/thick_leather.ron @@ -3,9 +3,8 @@ ItemDef( description: "Strong and durable.", kind: Ingredient( kind: "ThickLeather", - // Descriptor not needed - descriptor: "", + descriptor: "Leather", ), quality: Direct(Common), - tags: [BaseMaterial, Leather], + tags: [BaseMaterial, Leather, MaterialKind(Hide)], ) diff --git a/assets/common/items/log/bamboo.ron b/assets/common/items/log/bamboo.ron index 875de45497..921ce44af9 100644 --- a/assets/common/items/log/bamboo.ron +++ b/assets/common/items/log/bamboo.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Bamboo", ), quality: Direct(Common), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/log/eldwood.ron b/assets/common/items/log/eldwood.ron index 7025168e7c..98aa4a7cb0 100644 --- a/assets/common/items/log/eldwood.ron +++ b/assets/common/items/log/eldwood.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Eldwood", ), quality: Direct(Common), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/log/frostwood.ron b/assets/common/items/log/frostwood.ron index 1fa85309a7..b78cb578e3 100644 --- a/assets/common/items/log/frostwood.ron +++ b/assets/common/items/log/frostwood.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Frostwood", ), quality: Direct(Common), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/log/hardwood.ron b/assets/common/items/log/hardwood.ron index 1188ed3767..931eec7d1a 100644 --- a/assets/common/items/log/hardwood.ron +++ b/assets/common/items/log/hardwood.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Hardwood", ), quality: Direct(Common), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/log/ironwood.ron b/assets/common/items/log/ironwood.ron index 731202125b..01ea5e9842 100644 --- a/assets/common/items/log/ironwood.ron +++ b/assets/common/items/log/ironwood.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Ironwood", ), quality: Direct(High), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/log/wood.ron b/assets/common/items/log/wood.ron index 35a66153c3..cf5e003268 100644 --- a/assets/common/items/log/wood.ron +++ b/assets/common/items/log/wood.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Wooden", ), quality: Direct(Common), - tags: [], + tags: [MaterialKind(Wood)], ) \ No newline at end of file diff --git a/assets/common/items/mineral/ingot/bloodsteel.ron b/assets/common/items/mineral/ingot/bloodsteel.ron index b536f15bd1..2a2c6fa8b9 100644 --- a/assets/common/items/mineral/ingot/bloodsteel.ron +++ b/assets/common/items/mineral/ingot/bloodsteel.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Bloodsteel", ), quality: Direct(Epic), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/bronze.ron b/assets/common/items/mineral/ingot/bronze.ron index 64d5b41e75..11f7a90b7c 100644 --- a/assets/common/items/mineral/ingot/bronze.ron +++ b/assets/common/items/mineral/ingot/bronze.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Bronze", ), quality: Direct(Low), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/cobalt.ron b/assets/common/items/mineral/ingot/cobalt.ron index 8e21370114..b3c7c1c294 100644 --- a/assets/common/items/mineral/ingot/cobalt.ron +++ b/assets/common/items/mineral/ingot/cobalt.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Cobalt", ), quality: Direct(High), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/copper.ron b/assets/common/items/mineral/ingot/copper.ron index 950895a04f..a10bcb6b3d 100644 --- a/assets/common/items/mineral/ingot/copper.ron +++ b/assets/common/items/mineral/ingot/copper.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Copper", ), quality: Direct(Low), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/gold.ron b/assets/common/items/mineral/ingot/gold.ron index 93beb61201..694424e34b 100644 --- a/assets/common/items/mineral/ingot/gold.ron +++ b/assets/common/items/mineral/ingot/gold.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Golden", ), quality: Direct(Epic), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) \ No newline at end of file diff --git a/assets/common/items/mineral/ingot/iron.ron b/assets/common/items/mineral/ingot/iron.ron index 6b7d47d759..9c65b4bc73 100644 --- a/assets/common/items/mineral/ingot/iron.ron +++ b/assets/common/items/mineral/ingot/iron.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Iron", ), quality: Direct(Common), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/orichalcum.ron b/assets/common/items/mineral/ingot/orichalcum.ron index 897c9faf62..e34e0b70ce 100644 --- a/assets/common/items/mineral/ingot/orichalcum.ron +++ b/assets/common/items/mineral/ingot/orichalcum.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Orichalcum", ), quality: Direct(Legendary), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) \ No newline at end of file diff --git a/assets/common/items/mineral/ingot/silver.ron b/assets/common/items/mineral/ingot/silver.ron index 76b3e1e8db..340f8ef60e 100644 --- a/assets/common/items/mineral/ingot/silver.ron +++ b/assets/common/items/mineral/ingot/silver.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Silver", ), quality: Direct(Epic), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) \ No newline at end of file diff --git a/assets/common/items/mineral/ingot/steel.ron b/assets/common/items/mineral/ingot/steel.ron index 3c461b2ff3..e0634ba36e 100644 --- a/assets/common/items/mineral/ingot/steel.ron +++ b/assets/common/items/mineral/ingot/steel.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Steel", ), quality: Direct(Moderate), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/items/mineral/ingot/tin.ron b/assets/common/items/mineral/ingot/tin.ron index dfd9c28d6b..f158dd33ad 100644 --- a/assets/common/items/mineral/ingot/tin.ron +++ b/assets/common/items/mineral/ingot/tin.ron @@ -6,5 +6,5 @@ ItemDef( descriptor: "Tin", ), quality: Direct(Common), - tags: [MetalIngot], + tags: [MaterialKind(Metal)], ) diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index 222198417a..b2543765b7 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -1902,7 +1902,7 @@ "longsword blade": ( output: ("common.items.crafting_ing.modular.damage.sword.longsword", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1910,7 +1910,7 @@ "sawblade": ( output: ("common.items.crafting_ing.modular.damage.sword.sawblade", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1918,7 +1918,7 @@ "katana blade": ( output: ("common.items.crafting_ing.modular.damage.sword.katana", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1926,7 +1926,7 @@ "zweihander blade": ( output: ("common.items.crafting_ing.modular.damage.sword.zweihander", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1934,7 +1934,7 @@ "sabre blade": ( output: ("common.items.crafting_ing.modular.damage.sword.sabre", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1942,7 +1942,7 @@ "greatsword blade": ( output: ("common.items.crafting_ing.modular.damage.sword.greatsword", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1950,7 +1950,7 @@ "ornate sword blade": ( output: ("common.items.crafting_ing.modular.damage.sword.ornate", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1984,7 +1984,7 @@ "hammer head": ( output: ("common.items.crafting_ing.modular.damage.hammer.hammer", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -1992,7 +1992,7 @@ "spiked mace head": ( output: ("common.items.crafting_ing.modular.damage.hammer.spikedmace", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2000,7 +2000,7 @@ "warhammer head": ( output: ("common.items.crafting_ing.modular.damage.hammer.warhammer", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2008,7 +2008,7 @@ "maul head": ( output: ("common.items.crafting_ing.modular.damage.hammer.maul", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2016,7 +2016,7 @@ "great mace head": ( output: ("common.items.crafting_ing.modular.damage.hammer.greatmace", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2024,7 +2024,7 @@ "greathammer head": ( output: ("common.items.crafting_ing.modular.damage.hammer.greathammer", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2032,7 +2032,7 @@ "ornate hammer head": ( output: ("common.items.crafting_ing.modular.damage.hammer.ornate", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2066,7 +2066,7 @@ "axe head": ( output: ("common.items.crafting_ing.modular.damage.axe.axe", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2074,7 +2074,7 @@ "jagged axe head": ( output: ("common.items.crafting_ing.modular.damage.axe.jagged", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2082,7 +2082,7 @@ "battleaxe head": ( output: ("common.items.crafting_ing.modular.damage.axe.battleaxe", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2090,7 +2090,7 @@ "poleaxe head": ( output: ("common.items.crafting_ing.modular.damage.axe.poleaxe", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2098,7 +2098,7 @@ "labrys axe head": ( output: ("common.items.crafting_ing.modular.damage.axe.labrys", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2106,7 +2106,7 @@ "greataxe head": ( output: ("common.items.crafting_ing.modular.damage.axe.greataxe", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, @@ -2114,7 +2114,7 @@ "ornate axe head": ( output: ("common.items.crafting_ing.modular.damage.axe.ornate", 1), inputs: [ - (TagSameItem(MetalIngot), 5, true), + (TagSameItem(MaterialKind(Metal)), 5, true), ], craft_sprite: Some(Anvil), is_recycling: false, diff --git a/common/src/comp/inventory/item/mod.rs b/common/src/comp/inventory/item/mod.rs index adc4a1ff6c..8a7a2131a4 100644 --- a/common/src/comp/inventory/item/mod.rs +++ b/common/src/comp/inventory/item/mod.rs @@ -96,7 +96,7 @@ pub trait TagExampleInfo { fn exemplar_identifier(&self) -> Cow<'static, str>; } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, IntoStaticStr)] pub enum MaterialKind { Metal, Wood, @@ -184,12 +184,12 @@ impl Material { Material::Cobalt => Some("common.items.mineral.ingot.cobalt"), Material::Bloodsteel => Some("common.items.mineral.ingot.bloodsteel"), Material::Orichalcum => Some("common.items.mineral.ingot.orichalcum"), - Material::Wood - | Material::Bamboo - | Material::Hardwood - | Material::Ironwood - | Material::Frostwood - | Material::Eldwood => None, + Material::Wood => Some("common.items.log.wood"), + Material::Bamboo => Some("common.items.log.bamboo"), + Material::Hardwood => Some("common.items.log.hardwood"), + Material::Ironwood => Some("common.items.log.ironwood"), + Material::Frostwood => Some("common.items.log.frostwood"), + Material::Eldwood => Some("common.items.log.eldwood"), Material::Rock | Material::Granite | Material::Bone @@ -232,10 +232,9 @@ impl TagExampleInfo for MaterialTag { #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] pub enum ItemTag { - MetalIngot, - Textile, Leather, Material(MaterialTag), + MaterialKind(MaterialKind), ModularComponent(ModularComponentTag), Cultist, Potion, @@ -252,8 +251,7 @@ impl TagExampleInfo for ItemTag { match self { ItemTag::Material(material) => material.name(), ItemTag::ModularComponent(kind) => kind.name(), - ItemTag::MetalIngot => Cow::Borrowed("metal ingot"), - ItemTag::Textile => Cow::Borrowed("textile"), + ItemTag::MaterialKind(material_kind) => Cow::Borrowed(material_kind.into()), ItemTag::Leather => Cow::Borrowed("leather"), ItemTag::Cultist => Cow::Borrowed("cultist"), ItemTag::Potion => Cow::Borrowed("potion"), @@ -271,8 +269,7 @@ impl TagExampleInfo for ItemTag { match self { ItemTag::Material(_) => Cow::Borrowed("common.items.tag_examples.placeholder"), ItemTag::ModularComponent(tag) => tag.exemplar_identifier(), - ItemTag::MetalIngot => Cow::Borrowed("common.items.tag_examples.metal_ingot"), - ItemTag::Textile => Cow::Borrowed("common.items.tag_examples.textile"), + ItemTag::MaterialKind(_) => Cow::Borrowed("common.items.tag_examples.placeholder"), ItemTag::Leather => Cow::Borrowed("common.items.tag_examples.leather"), ItemTag::Cultist => Cow::Borrowed("common.items.tag_examples.cultist"), ItemTag::Potion => Cow::Borrowed("common.items.tag_examples.placeholder"), diff --git a/common/src/comp/inventory/item/modular.rs b/common/src/comp/inventory/item/modular.rs index cc565b1463..422f09f3eb 100644 --- a/common/src/comp/inventory/item/modular.rs +++ b/common/src/comp/inventory/item/modular.rs @@ -2,7 +2,11 @@ use super::{ tool::{self, Hands}, Item, ItemKind, ItemName, ItemTag, RawItemDef, TagExampleInfo, ToolKind, }; -use crate::recipe::{RawRecipe, RawRecipeBook, RawRecipeInput}; +use crate::{ + assets::AssetExt, + lottery::Lottery, + recipe::{self, RawRecipe, RawRecipeBook, RawRecipeInput}, +}; use hashbrown::HashMap; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; @@ -21,6 +25,16 @@ impl ModularComponentKind { ModularComponentKind::Held => "held", } } + + /// Returns the main component of a weapon, i.e. which component has a + /// material component + fn main_component(tool: ToolKind) -> Self { + match tool { + ToolKind::Sword | ToolKind::Axe | ToolKind::Hammer => Self::Damage, + ToolKind::Bow | ToolKind::Staff | ToolKind::Sceptre => Self::Held, + _ => unreachable!(), + } + } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -328,3 +342,115 @@ pub(super) fn resolve_quality(item: &Item) -> super::Quality { .iter() .fold(super::Quality::Common, |a, b| a.max(b.quality())) } + +/// Returns directory that contains components for a particular combination of +/// toolkind and modular component kind +fn make_mod_comp_dir_def(tool: ToolKind, mod_kind: ModularComponentKind) -> String { + const MOD_COMP_DIR_PREFIX: &str = "common.items.crafting_ing.modular"; + format!( + "{}.{}.{}", + MOD_COMP_DIR_PREFIX, + mod_kind.identifier_name(), + tool.identifier_name() + ) +} + +/// Creates a random modular weapon when provided with a toolkind, material, and +/// optionally the handedness +pub fn random_weapon(tool: ToolKind, material: super::Material, hands: Option) -> Item { + // Returns inner modular component of an item if it has one + fn unwrap_modular_component(item: &Item) -> Option<&ModularComponent> { + if let ItemKind::ModularComponent(mod_comp) = item.kind() { + Some(mod_comp) + } else { + None + } + } + + // Loads default ability map and material stat manifest for later use + let ability_map = Default::default(); + let msm = Default::default(); + + // Initialize modular weapon + let mut modular_weapon = Item::new_from_asset_expect(&make_weapon_def(tool).0); + + // Load recipe book (done to check that material is valid for a particular + // component) + let recipe::RawRecipeBook(recipes) = + recipe::RawRecipeBook::load_expect_cloned("common.recipe_book"); + + // Closure to check that an Item has a recipe that uses the provided material + let is_composed_of = |item: &str| { + // Iterate over all recipes in the raw recipe book + recipes + .values() + // Filter by recipes that have an output of the item of interest + .filter(|recipe| recipe.output.0.eq(item)) + // Check that item is composed of material, uses heuristic that assumes all modular components use the TagSameItem recipe input + .any(|recipe| { + recipe + .inputs + .iter() + .any(|input| { + matches!(input.0, recipe::RawRecipeInput::TagSameItem(item_tag) if item_tag == super::ItemTag::MaterialKind(material.material_kind())) + }) + }) + }; + + // Finds which component has a material as a subcomponent + let material_comp = ModularComponentKind::main_component(tool); + + // Closure to return vec of components that are eligible to be used in the + // modular weapon + let create_component = |directory, hands| { + // Load directory of components + let components = Item::new_from_asset_glob(directory) + .expect("Asset directory did not properly load") + .into_iter() + // Filter by handedness requirement + .filter(|item| { + matches!(unwrap_modular_component(item), Some(ModularComponent { hand_restriction, .. }) if hand_restriction.zip(hands).map_or(true, |(hr1, hr2)| hr1 == hr2)) + }) + // Filter by if component does not have a material, or if material can be used in the modular component + .filter(|item| { + matches!(unwrap_modular_component(item), Some(ModularComponent { modkind, .. }) if *modkind != material_comp) + || is_composed_of(item.item_definition_id()) + }) + .map(|item| (1.0, item)) + .collect::>(); + + // Create lottery and choose item + Lottery::::from(components).choose_owned() + }; + + // Creates components of modular weapon + let damage_comp_dir = make_mod_comp_dir_def(tool, ModularComponentKind::Damage); + let mut damage_component = create_component(&damage_comp_dir, hands); + // Takes whichever is more restrictive of hand restriction passed in and hand + // restriction from damage component e.g. if None is passed to function, and + // damage component chooses piece with two handed restriction, then makes held + // component have two handed restriction as well + let damage_hands = unwrap_modular_component(&damage_component) + .and_then(|mc| mc.hand_restriction) + .map_or(hands, Some); + let held_comp_dir = make_mod_comp_dir_def(tool, ModularComponentKind::Held); + let mut held_component = create_component(&held_comp_dir, damage_hands); + let material_component = Item::new_from_asset_expect(material.asset_identifier().expect("Code reviewers: open comment here if I forget about this, I got lazy during a rebase")); + + // Insert material item into modular component of appropriate kind + match material_comp { + ModularComponentKind::Damage => { + damage_component.add_component(material_component, &ability_map, &msm); + }, + ModularComponentKind::Held => { + held_component.add_component(material_component, &ability_map, &msm); + }, + } + + // Insert components onto modular weapon + modular_weapon.add_component(damage_component, &ability_map, &msm); + modular_weapon.add_component(held_component, &ability_map, &msm); + + // Returns fully created modular weapon + modular_weapon +} diff --git a/common/src/comp/inventory/trade_pricing.rs b/common/src/comp/inventory/trade_pricing.rs index d49da1ad8c..cd21d4430b 100644 --- a/common/src/comp/inventory/trade_pricing.rs +++ b/common/src/comp/inventory/trade_pricing.rs @@ -260,6 +260,8 @@ impl From)>> for ProbabilityFile { .into_iter() }, LootSpec::Nothing => Vec::new().into_iter(), + // TODO: Let someone else wrangle modular weapons into the economy + LootSpec::ModularWeapon { .. } => vec![].into_iter(), }) .collect(), } diff --git a/common/src/lottery.rs b/common/src/lottery.rs index 46c26399b5..8ca57e4a42 100644 --- a/common/src/lottery.rs +++ b/common/src/lottery.rs @@ -28,7 +28,7 @@ use crate::{ assets::{self, AssetExt}, - comp::Item, + comp::{inventory::item, Item}, }; use rand::prelude::*; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -69,8 +69,21 @@ impl Lottery { .1 } + pub fn choose_seeded_owned(mut self, seed: u32) -> T { + let x = ((seed % 65536) as f32 / 65536.0) * self.total; + self.items + .remove( + self.items + .binary_search_by(|(y, _)| y.partial_cmp(&x).unwrap()) + .unwrap_or_else(|i| i.saturating_sub(1)), + ) + .1 + } + pub fn choose(&self) -> &T { self.choose_seeded(thread_rng().gen()) } + pub fn choose_owned(self) -> T { self.choose_seeded_owned(thread_rng().gen()) } + pub fn iter(&self) -> impl Iterator { self.items.iter() } pub fn total(&self) -> f32 { self.total } @@ -86,6 +99,12 @@ pub enum LootSpec> { LootTable(T), /// No loot given Nothing, + /// Modular weapon + ModularWeapon { + tool: item::tool::ToolKind, + material: item::Material, + hands: Option, + }, } impl> LootSpec { @@ -120,6 +139,7 @@ impl> LootSpec { .choose() .to_item(), Self::Nothing => None, + Self::ModularWeapon { tool, material, hands } => Some(item::modular::random_weapon(*tool, *material, *hands)), } } } diff --git a/voxygen/src/hud/crafting.rs b/voxygen/src/hud/crafting.rs index 2bc848b6bb..2036a76dc1 100644 --- a/voxygen/src/hud/crafting.rs +++ b/voxygen/src/hud/crafting.rs @@ -199,10 +199,12 @@ impl CraftingTab { CraftingTab::Glider => matches!(item.kind(), ItemKind::Glider(_)), CraftingTab::Potion => item.tags().contains(&ItemTag::Potion), CraftingTab::ProcessedMaterial => { - item.tags().contains(&ItemTag::MetalIngot) - || item.tags().contains(&ItemTag::Textile) - || item.tags().contains(&ItemTag::Leather) - || item.tags().contains(&ItemTag::BaseMaterial) + item.tags().iter().any(|tag| { + matches!( + tag, + &ItemTag::MaterialKind(_) | &ItemTag::Leather | &ItemTag::BaseMaterial + ) + }) }, CraftingTab::Bag => item.tags().contains(&ItemTag::Bag), CraftingTab::Tool => item.tags().contains(&ItemTag::CraftingTool),