mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added crafting method for modular weapons.
This commit is contained in:
parent
b7aa0a7a9f
commit
00649f8ebb
@ -98,6 +98,11 @@ pub enum CraftEvent {
|
||||
slots: Vec<(u32, InvSlotId)>,
|
||||
},
|
||||
Salvage(InvSlotId),
|
||||
// TODO: Maybe look at making this more general when there are more modular recipes?
|
||||
ModularWeapon {
|
||||
damage_component: InvSlotId,
|
||||
held_component: InvSlotId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -355,6 +355,11 @@ fn make_mod_comp_dir_def(tool: ToolKind, mod_kind: ModularComponentKind) -> Stri
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates initial item for a modular weapon
|
||||
pub fn initialize_modular_weapon(toolkind: ToolKind) -> Item {
|
||||
Item::new_from_asset_expect(&make_weapon_def(toolkind).0)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
@ -372,7 +377,7 @@ pub fn random_weapon(tool: ToolKind, material: super::Material, hands: Option<Ha
|
||||
let msm = Default::default();
|
||||
|
||||
// Initialize modular weapon
|
||||
let mut modular_weapon = Item::new_from_asset_expect(&make_weapon_def(tool).0);
|
||||
let mut modular_weapon = initialize_modular_weapon(tool);
|
||||
|
||||
// Load recipe book (done to check that material is valid for a particular
|
||||
// component)
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
assets::{self, AssetExt, AssetHandle},
|
||||
comp::{
|
||||
inventory::slot::InvSlotId,
|
||||
item::{modular, tool::AbilityMap, ItemDef, ItemTag, MaterialStatManifest},
|
||||
item::{modular, tool::AbilityMap, ItemDef, ItemKind, ItemTag, MaterialStatManifest},
|
||||
Inventory, Item,
|
||||
},
|
||||
terrain::SpriteKind,
|
||||
@ -193,6 +193,87 @@ pub fn try_salvage(
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ModularWeaponError {
|
||||
InvalidSlot,
|
||||
ComponentMismatch,
|
||||
DifferentTools,
|
||||
DifferentHands,
|
||||
}
|
||||
|
||||
pub fn modular_weapon(
|
||||
inv: &mut Inventory,
|
||||
damage_component: InvSlotId,
|
||||
held_component: InvSlotId,
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> Result<Item, ModularWeaponError> {
|
||||
use modular::{ModularComponent, ModularComponentKind};
|
||||
// Closure to get inner modular component info from item in a given slot
|
||||
let unwrap_modular = |slot| -> Option<&ModularComponent> {
|
||||
if let Some(ItemKind::ModularComponent(mod_comp)) = inv.get(slot).map(|item| &item.kind) {
|
||||
Some(mod_comp)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// Checks if both components are comptabile, and if so returns the toolkind to
|
||||
// make weapon of
|
||||
let compatiblity = if let (Some(damage_component), Some(held_component)) = (
|
||||
unwrap_modular(damage_component),
|
||||
unwrap_modular(held_component),
|
||||
) {
|
||||
// Checks that damage and held component slots each contain a damage and held
|
||||
// modular component respectively
|
||||
if matches!(damage_component.modkind, ModularComponentKind::Damage)
|
||||
&& matches!(held_component.modkind, ModularComponentKind::Held)
|
||||
{
|
||||
// Checks that both components are of the same tool kind
|
||||
if damage_component.toolkind == held_component.toolkind {
|
||||
// Checks that if both components have a hand restriction, they are the same
|
||||
let hands_check = damage_component.hand_restriction.map_or(true, |hands| {
|
||||
held_component
|
||||
.hand_restriction
|
||||
.map_or(true, |hands2| hands == hands2)
|
||||
});
|
||||
if hands_check {
|
||||
Ok(damage_component.toolkind)
|
||||
} else {
|
||||
Err(ModularWeaponError::DifferentHands)
|
||||
}
|
||||
} else {
|
||||
Err(ModularWeaponError::DifferentTools)
|
||||
}
|
||||
} else {
|
||||
Err(ModularWeaponError::ComponentMismatch)
|
||||
}
|
||||
} else {
|
||||
Err(ModularWeaponError::InvalidSlot)
|
||||
};
|
||||
|
||||
match compatiblity {
|
||||
Ok(tool_kind) => {
|
||||
// Remove components from inventory
|
||||
let damage_component = inv
|
||||
.take(damage_component, ability_map, msm)
|
||||
.expect("Expected component to exist");
|
||||
let held_component = inv
|
||||
.take(held_component, ability_map, msm)
|
||||
.expect("Expected component to exist");
|
||||
|
||||
// Initialize modular weapon
|
||||
let mut modular_weapon = modular::initialize_modular_weapon(tool_kind);
|
||||
|
||||
// Insert components into modular weapon item
|
||||
modular_weapon.add_component(damage_component, ability_map, msm);
|
||||
modular_weapon.add_component(held_component, ability_map, msm);
|
||||
|
||||
Ok(modular_weapon)
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RecipeBook {
|
||||
recipes: HashMap<String, Recipe>,
|
||||
|
@ -660,6 +660,46 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
None
|
||||
}
|
||||
},
|
||||
CraftEvent::ModularWeapon {
|
||||
damage_component,
|
||||
held_component,
|
||||
} => {
|
||||
let sprite = craft_sprite
|
||||
.filter(|pos| {
|
||||
let entity_cylinder = get_cylinder(state, entity);
|
||||
if !within_pickup_range(entity_cylinder, || {
|
||||
Some(find_dist::Cube {
|
||||
min: pos.as_(),
|
||||
side_length: 1.0,
|
||||
})
|
||||
}) {
|
||||
debug!(
|
||||
?entity_cylinder,
|
||||
"Failed to craft recipe as not within range of required \
|
||||
sprite, sprite pos: {}",
|
||||
pos
|
||||
);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.and_then(|pos| state.terrain().get(pos).ok().copied())
|
||||
.and_then(|block| block.get_sprite());
|
||||
if matches!(sprite, Some(SpriteKind::CraftingBench)) {
|
||||
recipe::modular_weapon(
|
||||
&mut inventory,
|
||||
damage_component,
|
||||
held_component,
|
||||
ability_map,
|
||||
&msm,
|
||||
)
|
||||
.ok()
|
||||
.map(|item| vec![item])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Attempt to insert items into inventory, dropping them if there is not enough
|
||||
|
Loading…
Reference in New Issue
Block a user