mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Modular weapons can now be dropped as loot or assigned to enemies.
This commit is contained in:
parent
c01fe655f1
commit
762b3be3c3
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Cotton",
|
||||
),
|
||||
quality: Direct(Low),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Lifecloth",
|
||||
),
|
||||
quality: Direct(High),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Linen",
|
||||
),
|
||||
quality: Direct(Low),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -7,5 +7,5 @@ ItemDef(
|
||||
descriptor: "",
|
||||
),
|
||||
quality: Direct(Low),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Moonwoven",
|
||||
),
|
||||
quality: Direct(Epic),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Silken",
|
||||
),
|
||||
quality: Direct(Moderate),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Sunsilken",
|
||||
),
|
||||
quality: Direct(Legendary),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Woolen",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [Textile],
|
||||
tags: [MaterialKind(Cloth)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Carapace",
|
||||
),
|
||||
quality: Direct(High),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Hide)],
|
||||
)
|
@ -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)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Plate",
|
||||
),
|
||||
quality: Direct(Epic),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Hide)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Scale",
|
||||
),
|
||||
quality: Direct(Moderate),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Hide)],
|
||||
)
|
@ -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)],
|
||||
)
|
||||
|
@ -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)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Bamboo",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Eldwood",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Frostwood",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Hardwood",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Ironwood",
|
||||
),
|
||||
quality: Direct(High),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Wooden",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [],
|
||||
tags: [MaterialKind(Wood)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Bloodsteel",
|
||||
),
|
||||
quality: Direct(Epic),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Bronze",
|
||||
),
|
||||
quality: Direct(Low),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Cobalt",
|
||||
),
|
||||
quality: Direct(High),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Copper",
|
||||
),
|
||||
quality: Direct(Low),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Golden",
|
||||
),
|
||||
quality: Direct(Epic),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Iron",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Orichalcum",
|
||||
),
|
||||
quality: Direct(Legendary),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Silver",
|
||||
),
|
||||
quality: Direct(Epic),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Steel",
|
||||
),
|
||||
quality: Direct(Moderate),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -6,5 +6,5 @@ ItemDef(
|
||||
descriptor: "Tin",
|
||||
),
|
||||
quality: Direct(Common),
|
||||
tags: [MetalIngot],
|
||||
tags: [MaterialKind(Metal)],
|
||||
)
|
||||
|
@ -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,
|
||||
|
@ -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"),
|
||||
|
@ -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<Hands>) -> 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::<Vec<_>>();
|
||||
|
||||
// Create lottery and choose item
|
||||
Lottery::<Item>::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
|
||||
}
|
||||
|
@ -260,6 +260,8 @@ impl From<Vec<(f32, LootSpec<String>)>> 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(),
|
||||
}
|
||||
|
@ -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<T> Lottery<T> {
|
||||
.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<Item = &(f32, T)> { self.items.iter() }
|
||||
|
||||
pub fn total(&self) -> f32 { self.total }
|
||||
@ -86,6 +99,12 @@ pub enum LootSpec<T: AsRef<str>> {
|
||||
LootTable(T),
|
||||
/// No loot given
|
||||
Nothing,
|
||||
/// Modular weapon
|
||||
ModularWeapon {
|
||||
tool: item::tool::ToolKind,
|
||||
material: item::Material,
|
||||
hands: Option<item::tool::Hands>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> LootSpec<T> {
|
||||
@ -120,6 +139,7 @@ impl<T: AsRef<str>> LootSpec<T> {
|
||||
.choose()
|
||||
.to_item(),
|
||||
Self::Nothing => None,
|
||||
Self::ModularWeapon { tool, material, hands } => Some(item::modular::random_weapon(*tool, *material, *hands)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user