diff --git a/client/src/lib.rs b/client/src/lib.rs index 794ace1d55..5baf84d9f7 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1026,13 +1026,13 @@ impl Client { .map_or(false, |item| item.is_salvageable()) } - pub fn salvage_item(&mut self, slot: InvSlotId) -> bool { + pub fn salvage_item(&mut self, slot: InvSlotId, salvage_pos: Vec3) -> bool { let is_salvageable = self.can_salvage_item(slot); if is_salvageable { self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryEvent( InventoryEvent::CraftRecipe { craft_event: CraftEvent::Salvage(slot), - craft_sprite: None, + craft_sprite: Some(salvage_pos), }, ))); } diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index 3fa3a07bb0..19cb1ba87c 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -12,6 +12,7 @@ use common::{ }, consts::MAX_PICKUP_RANGE, recipe::{self, default_recipe_book}, + terrain::SpriteKind, trade::Trades, uid::Uid, util::find_dist::{self, FindDist}, @@ -613,7 +614,33 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv .ok() }), CraftEvent::Salvage(slot) => { - recipe::try_salvage(&mut inventory, slot, ability_map, &msm).ok() + 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::SalvagingBench)) { + recipe::try_salvage(&mut inventory, slot, ability_map, &msm).ok() + } else { + None + } }, }; diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 4c7c2410fe..88370c2175 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -521,7 +521,10 @@ pub enum Event { recipe: String, craft_sprite: Option<(Vec3, SpriteKind)>, }, - SalvageItem(InvSlotId), + SalvageItem { + slot: InvSlotId, + salvage_pos: Vec3, + }, InviteMember(Uid), AcceptInvite, DeclineInvite, @@ -725,6 +728,7 @@ impl Show { self.selected_crafting_tab(tab); self.crafting(true); self.craft_sprite = self.craft_sprite.or(craft_sprite); + self.salvage = matches!(craft_sprite, Some((_, SpriteKind::SalvagingBench))); } fn diary(&mut self, open: bool) { @@ -1079,8 +1083,6 @@ impl Hud { camera: &Camera, interactable: Option, ) -> Vec { - self.show.salvage = - self.show.crafting && matches!(self.show.crafting_tab, CraftingTab::Dismantle); span!(_guard, "update_layout", "Hud::update_layout"); let mut events = core::mem::take(&mut self.events); if global_state.settings.interface.map_show_voxel_map { @@ -3334,11 +3336,13 @@ impl Hud { slot::Event::Used(from) => { // Item used (selected and then clicked again) if let Some(from) = to_slot(from) { - if self.show.crafting + if self.show.salvage && matches!(self.show.crafting_tab, CraftingTab::Dismantle) { - if let Slot::Inventory(slot) = from { - events.push(Event::SalvageItem(slot)) + if let (Slot::Inventory(slot), Some((salvage_pos, _sprite_kind))) = + (from, self.show.craft_sprite) + { + events.push(Event::SalvageItem { slot, salvage_pos }) } } else { events.push(Event::UseSlot { diff --git a/voxygen/src/scene/terrain/watcher.rs b/voxygen/src/scene/terrain/watcher.rs index f05714656c..e801d0feff 100644 --- a/voxygen/src/scene/terrain/watcher.rs +++ b/voxygen/src/scene/terrain/watcher.rs @@ -114,9 +114,8 @@ impl BlocksOfInterest { Some(SpriteKind::SmokeDummy) => { smokers.push(pos); }, - Some(SpriteKind::Forge) => { - interactables.push((pos, Interaction::Craft(CraftingTab::Dismantle))) - }, + Some(SpriteKind::Forge) => interactables + .push((pos, Interaction::Craft(CraftingTab::ProcessedMaterial))), Some(SpriteKind::TanningRack) => interactables .push((pos, Interaction::Craft(CraftingTab::ProcessedMaterial))), Some(SpriteKind::SpinningWheel) => { diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 7d04cea671..b891446e8d 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -1412,8 +1412,8 @@ impl PlayState for SessionState { .craft_recipe(&recipe, slots, craft_sprite); } }, - HudEvent::SalvageItem(slot) => { - self.client.borrow_mut().salvage_item(slot); + HudEvent::SalvageItem { slot, salvage_pos } => { + self.client.borrow_mut().salvage_item(slot, salvage_pos); }, HudEvent::InviteMember(uid) => { self.client.borrow_mut().send_invite(uid, InviteKind::Group);