From 1fa467eb5825ec0ddd4de8ca92cc2df8b2448846 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Fri, 7 Aug 2015 22:00:35 +0200 Subject: [PATCH] Proper recipe ingredient matching, fixed crafting type resetting --- src/pocketmine/Player.php | 15 ++- src/pocketmine/inventory/CraftingManager.php | 121 ++++++++++++++++--- src/pocketmine/inventory/ShapedRecipe.php | 20 +-- src/pocketmine/item/Item.php | 3 + 4 files changed, 121 insertions(+), 38 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b03125dc9..a59460f32 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2082,7 +2082,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade break; } - $this->craftingType = 0; $packet->eid = $this->id; $pos = new Vector3($packet->x, $packet->y, $packet->z); @@ -2577,7 +2576,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade break; } - /*foreach($packet->input as $i => $item){ + foreach($packet->input as $i => $item){ if($item->getDamage() === -1 or $item->getDamage() === 0xffff){ $item->setDamage(null); } @@ -2585,7 +2584,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($i < 9 and $item->getId() > 0){ $item->setCount(1); } - }*/ + } $canCraft = true; @@ -2593,10 +2592,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($recipe instanceof ShapedRecipe){ for($x = 0; $x < 3 and $canCraft; ++$x){ for($y = 0; $y < 3; ++$y){ - $item = $packet->input[$x * 3 + $y]; + $item = $packet->input[$y * 3 + $x]; $ingredient = $recipe->getIngredient($x, $y); if($item->getCount() > 0 and $item->getId() > 0){ - if($ingredient === null or !$ingredient->deepEquals($item, $ingredient->getDamage() === null, $ingredient->getCompoundTag() === null)){ + if($ingredient === null or !$ingredient->deepEquals($item, $ingredient->getDamage() !== null, $ingredient->getCompoundTag() !== null)){ $canCraft = false; break; } @@ -2612,10 +2611,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade for($x = 0; $x < 3 and $canCraft; ++$x){ for($y = 0; $y < 3; ++$y){ - $item = clone $packet->input[$x * 3 + $y]; + $item = clone $packet->input[$y * 3 + $x]; foreach($needed as $k => $n){ - if($n->deepEquals($item, $n->getDamage() === null, $n->getCompoundTag() === null)){ + if($n->deepEquals($item, $n->getDamage() !== null, $n->getCompoundTag() !== null)){ $remove = min($n->getCount(), $item->getCount()); $n->setCount($n->getCount() - $remove); $item->setCount($item->getCount() - $remove); @@ -2655,7 +2654,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade foreach($ingredients as $ingredient){ $slot = -1; foreach($this->inventory->getContents() as $index => $i){ - if($ingredient->getId() !== 0 and $ingredient->deepEquals($i) and ($i->getCount() - $used[$index]) >= 1){ + if($ingredient->getId() !== 0 and $ingredient->deepEquals($i, $i->getDamage() !== null) and ($i->getCount() - $used[$index]) >= 1){ $slot = $index; $used[$index]++; break; diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index ae3a430ae..2d0fc6c7f 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -55,13 +55,26 @@ class CraftingManager{ $this->registerFood(); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::CLAY_BLOCK, 0, 1)))->addIngredient(Item::get(Item::CLAY, 0, 4))); - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WORKBENCH, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 4))); + + $this->registerRecipe((new ShapedRecipe(Item::get(Item::WORKBENCH, 0, 1), + "XX", + "XX" + ))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null))); + $this->registerRecipe((new ShapelessRecipe(Item::get(Item::GLOWSTONE_BLOCK, 0, 1)))->addIngredient(Item::get(Item::GLOWSTONE_DUST, 0, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::LIT_PUMPKIN, 0, 1)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1))->addIngredient(Item::get(Item::TORCH, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_BLOCK, 0, 1)))->addIngredient(Item::get(Item::SNOWBALL, 0, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_LAYER, 0, 6)))->addIngredient(Item::get(Item::SNOW_BLOCK, 0, 3))); - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STICK, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 2))); - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STONECUTTER, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 4))); + + $this->registerRecipe((new ShapedRecipe(Item::get(Item::STICK, 0, 4), + "X ", + "X " + ))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null))); + + $this->registerRecipe((new ShapedRecipe(Item::get(Item::STONECUTTER, 0, 1), + "XX", + "XX" + ))->setIngredient("X", Item::get(Item::COBBLESTONE))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4), "X" @@ -214,7 +227,6 @@ class CraftingManager{ } protected function registerArmor(){ - $cost = [5, 8, 7, 4]; $types = [ [Item::LEATHER, Item::FIRE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::LEATHER_CAP, Item::CHAIN_HELMET, Item::IRON_HELMET, Item::DIAMOND_HELMET, Item::GOLD_HELMET], @@ -222,31 +234,68 @@ class CraftingManager{ [Item::LEATHER_PANTS, Item::CHAIN_LEGGINGS, Item::IRON_LEGGINGS, Item::DIAMOND_LEGGINGS, Item::GOLD_LEGGINGS], [Item::LEATHER_BOOTS, Item::CHAIN_BOOTS, Item::IRON_BOOTS, Item::DIAMOND_BOOTS, Item::GOLD_BOOTS], ]; + + $shapes = [ + [ + "XXX", + "X X", + " " + ], + [ + "X X", + "XXX", + "XXX" + ], + [ + "XXX", + "X X", + "X X" + ], + [ + " ", + "X X", + "X X" + ] + ]; + for($i = 1; $i < 5; ++$i){ foreach($types[$i] as $j => $type){ - $this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], 0, $cost[$i - 1]))); + $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], 0, 1))); } } } protected function registerWeapons(){ - $cost = [2]; $types = [ [Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::WOODEN_SWORD, Item::STONE_SWORD, Item::IRON_SWORD, Item::DIAMOND_SWORD, Item::GOLD_SWORD], ]; + + for($i = 1; $i < 2; ++$i){ foreach($types[$i] as $j => $type){ - $this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], null, $cost[$i - 1]))->addIngredient(Item::get(Item::STICK, 0, 1))); + $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), + " X ", + " X ", + " I " + ))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK))); } } - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::ARROW, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 1))->addIngredient(Item::get(Item::FLINT, 0, 1))->addIngredient(Item::get(Item::FEATHER, 0, 1))); - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::BOW, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 3))->addIngredient(Item::get(Item::STICK, 0, 3))); + $this->registerRecipe((new BigShapedRecipe(Item::get(Item::ARROW, 0, 1), + " F ", + " S ", + " P " + ))->setIngredient("S", Item::get(Item::STICK))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("P", Item::get(Item::FEATHER))); + + $this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOW, 0, 1), + " X~", + "X ~", + " X~" + ))->setIngredient("~", Item::get(Item::STRING))->setIngredient("X", Item::get(Item::STICK))); } protected function registerTools(){ - $cost = [3, 1, 3, 2]; $types = [ [Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::WOODEN_PICKAXE, Item::STONE_PICKAXE, Item::IRON_PICKAXE, Item::DIAMOND_PICKAXE, Item::GOLD_PICKAXE], @@ -254,14 +303,44 @@ class CraftingManager{ [Item::WOODEN_AXE, Item::STONE_AXE, Item::IRON_AXE, Item::DIAMOND_AXE, Item::GOLD_AXE], [Item::WOODEN_HOE, Item::STONE_HOE, Item::IRON_HOE, Item::DIAMOND_HOE, Item::GOLD_HOE], ]; + $shapes = [ + [ + "XXX", + " I ", + " I " + ], + [ + " X ", + " I ", + " I " + ], + [ + "XX ", + "XI ", + " I " + ], + [ + "XX ", + " I ", + " I " + ] + ]; + for($i = 1; $i < 5; ++$i){ foreach($types[$i] as $j => $type){ - $this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], null, $cost[$i - 1]))->addIngredient(Item::get(Item::STICK, 0, 2))); + $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK))); } } - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::FLINT_AND_STEEL, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 1))->addIngredient(Item::get(Item::FLINT, 0, 1))); - $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SHEARS, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 2))); + $this->registerRecipe((new ShapedRecipe(Item::get(Item::FLINT_AND_STEEL, 0, 1), + " S", + "F " + ))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("S", Item::get(Item::IRON_INGOT))); + + $this->registerRecipe((new ShapedRecipe(Item::get(Item::SHEARS, 0, 1), + " X", + "X " + ))->setIngredient("X", Item::get(Item::IRON_INGOT))); } protected function registerDyes(){ @@ -269,9 +348,9 @@ class CraftingManager{ $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STAINED_CLAY, 15 - $i, 8)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::HARDENED_CLAY, 0, 8))); //TODO: add glass things? - //$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); - //$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); - //$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); + $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); + $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); + $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::CARPET, $i, 3)))->addIngredient(Item::get(Item::WOOL, $i, 2))); } @@ -317,8 +396,8 @@ class CraftingManager{ $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LAPIS_BLOCK, 0, 1)))->addIngredient(Item::get(Item::DYE, 4, 9))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 4, 9)))->addIngredient(Item::get(Item::LAPIS_BLOCK, 0, 1))); - //$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GOLD_INGOT, 0, 1)))->addIngredient(Item::get(Item::GOLD_NUGGET, 0, 9))); - //$this->registerRecipe((new ShapelessRecipe(Item::get(Item::GOLD_NUGGET, 0, 9)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 1))); + $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GOLD_INGOT, 0, 1)))->addIngredient(Item::get(Item::GOLD_NUGGET, 0, 9))); + $this->registerRecipe((new ShapelessRecipe(Item::get(Item::GOLD_NUGGET, 0, 9)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 1))); } @@ -388,8 +467,10 @@ class CraftingManager{ $hash = ""; foreach($ingredients as $v){ foreach($v as $item){ - /** @var Item $item */ - $hash .= $item->getId() . ":" . ($item->getDamage() === null ? "?" : $item->getDamage()) . "x" . $item->getCount() . ","; + if($item !== null){ + /** @var Item $item */ + $hash .= $item->getId() . ":" . ($item->getDamage() === null ? "?" : $item->getDamage()) . "x" . $item->getCount() . ","; + } } $hash .= ";"; diff --git a/src/pocketmine/inventory/ShapedRecipe.php b/src/pocketmine/inventory/ShapedRecipe.php index 18638bc1c..95773d03a 100644 --- a/src/pocketmine/inventory/ShapedRecipe.php +++ b/src/pocketmine/inventory/ShapedRecipe.php @@ -53,7 +53,7 @@ class ShapedRecipe implements Recipe{ if(count($shape) > 3){ throw new \InvalidStateException("Crafting recipes should be 1, 2, 3 rows, not " . count($shape)); } - foreach($shape as $z => $row){ + foreach($shape as $y => $row){ if(strlen($row) === 0 or strlen($row) > 3){ throw new \InvalidStateException("Crafting rows should be 1, 2, 3 characters, not " . count($row)); } @@ -63,9 +63,9 @@ class ShapedRecipe implements Recipe{ $this->shape[$row{$i}] = null; if(!isset($this->shapeItems[$row{$i}])){ - $this->shapeItems[$row{$i}] = [new Vector2($i, $z)]; + $this->shapeItems[$row{$i}] = [new Vector2($i, $y)]; }else{ - $this->shapeItems[$row{$i}][] = new Vector2($i, $z); + $this->shapeItems[$row{$i}][] = new Vector2($i, $y); } } } @@ -125,13 +125,13 @@ class ShapedRecipe implements Recipe{ */ public function getIngredientMap(){ $ingredients = []; - foreach($this->ingredients as $z => $row){ - $ingredients[$z] = []; + foreach($this->ingredients as $y => $row){ + $ingredients[$y] = []; foreach($row as $x => $ingredient){ if($ingredient !== null){ - $ingredients[$z][$x] = clone $ingredient; + $ingredients[$y][$x] = clone $ingredient; }else{ - $ingredients[$z][$x] = null; + $ingredients[$y][$x] = Item::get(Item::AIR); } } } @@ -141,11 +141,11 @@ class ShapedRecipe implements Recipe{ /** * @param $x - * @param $z + * @param $y * @return null|Item */ - public function getIngredient($x, $z){ - return isset($this->ingredients[$z][$x]) ? $this->ingredients[$z][$x] : null; + public function getIngredient($x, $y){ + return isset($this->ingredients[$y][$x]) ? $this->ingredients[$y][$x] : Item::get(Item::AIR); } /** diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 648f3357c..5bfff2c26 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -411,6 +411,9 @@ class Item{ const RAW_CHICKEN = 365; const COOKED_CHICKEN = 366; + const GOLD_NUGGET = 371; + const GOLDEN_NUGGET = 371; + const SPAWN_EGG = 383; const EMERALD = 388;