From 36e95e0c036a54cc4e172b3be7cb03bacdd18848 Mon Sep 17 00:00:00 2001
From: Joshua Barretto <joshua.s.barretto@gmail.com>
Date: Tue, 20 Apr 2021 12:33:22 +0100
Subject: [PATCH] Cleaned up client-side recipe handling

---
 client/src/lib.rs                    | 30 ++++++++++++++++------------
 common/src/recipe.rs                 |  1 -
 server/src/events/inventory_manip.rs |  6 +++---
 3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/client/src/lib.rs b/client/src/lib.rs
index afb0cd5a9e..5f225758bc 100644
--- a/client/src/lib.rs
+++ b/client/src/lib.rs
@@ -974,18 +974,19 @@ impl Client {
         &self.available_recipes
     }
 
-    pub fn can_craft_recipe(&self, recipe: &str) -> Option<Option<SpriteKind>> {
+    /// Returns whether the specified recipe can be crafted and the sprite, if
+    /// any, that is required to do so.
+    pub fn can_craft_recipe(&self, recipe: &str) -> (bool, Option<SpriteKind>) {
         self.recipe_book
             .get(recipe)
             .zip(self.inventories().get(self.entity()))
             .map(|(recipe, inv)| {
-                if inv.contains_ingredients(&*recipe).is_ok() {
-                    Some(recipe.craft_sprite)
-                } else {
-                    None
-                }
+                (
+                    inv.contains_ingredients(&*recipe).is_ok(),
+                    recipe.craft_sprite,
+                )
             })
-            .unwrap_or(None)
+            .unwrap_or((false, None))
     }
 
     pub fn craft_recipe(
@@ -993,10 +994,9 @@ impl Client {
         recipe: &str,
         craft_sprite: Option<(Vec3<i32>, SpriteKind)>,
     ) -> bool {
-        let can_craft = self.can_craft_recipe(recipe).map_or(false, |cs| {
-            cs.map_or(true, |cs| Some(cs) == craft_sprite.map(|(_, s)| s))
-        });
-        if can_craft {
+        let (can_craft, required_sprite) = self.can_craft_recipe(recipe);
+        let has_sprite = required_sprite.map_or(true, |s| Some(s) == craft_sprite.map(|(_, s)| s));
+        if can_craft && has_sprite {
             self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryEvent(
                 InventoryEvent::CraftRecipe {
                     recipe: recipe.to_string(),
@@ -1015,8 +1015,12 @@ impl Client {
             .iter()
             .map(|(name, _)| name.clone())
             .filter_map(|name| {
-                let required_sprite = self.can_craft_recipe(&name)?;
-                Some((name, required_sprite))
+                let (can_craft, required_sprite) = self.can_craft_recipe(&name);
+                if can_craft {
+                    Some((name, required_sprite))
+                } else {
+                    None
+                }
             })
             .collect();
     }
diff --git a/common/src/recipe.rs b/common/src/recipe.rs
index 2a1110948d..1e0a3f3987 100644
--- a/common/src/recipe.rs
+++ b/common/src/recipe.rs
@@ -98,7 +98,6 @@ pub(crate) struct RawRecipe {
 
 #[derive(Clone, Deserialize)]
 #[serde(transparent)]
-#[allow(clippy::type_complexity)]
 pub(crate) struct RawRecipeBook(pub(crate) HashMap<String, RawRecipe>);
 
 impl assets::Asset for RawRecipeBook {
diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs
index f921f584ca..fa9e41b01d 100644
--- a/server/src/events/inventory_manip.rs
+++ b/server/src/events/inventory_manip.rs
@@ -596,8 +596,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
                                 }) {
                                     debug!(
                                         ?entity_cylinder,
-                                        "Failed to pick up block as not within range, block pos: \
-                                         {}",
+                                        "Failed to craft recipe as not within range of required \
+                                         sprite, sprite pos: {}",
                                         pos
                                     );
                                     false
@@ -609,7 +609,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
                             .and_then(|block| block.get_sprite());
                         Some(needed_sprite) == sprite
                     } else {
-                        false
+                        true
                     }
                 })
                 .and_then(|r| {