mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-17 03:08:58 +00:00
Properly implemented Shaped recipes on Network and manager, no crafting!
This commit is contained in:
parent
9456e20770
commit
09720a2d90
26
src/pocketmine/inventory/BigShapedRecipe.php
Normal file
26
src/pocketmine/inventory/BigShapedRecipe.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
class BigShapedRecipe extends ShapedRecipe{
|
||||||
|
|
||||||
|
}
|
@ -62,13 +62,36 @@ class CraftingManager{
|
|||||||
$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::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::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 ShapelessRecipe(Item::get(Item::STONECUTTER, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 4)));
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)))->addIngredient(Item::get(Item::WOOD, Wood::OAK, 1)));
|
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::SPRUCE, 1)));
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4),
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)))->addIngredient(Item::get(Item::WOOD, Wood::BIRCH, 1)));
|
"X"
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::JUNGLE, 1)));
|
))->setIngredient("X", Item::get(Item::WOOD, Wood::OAK, 1)));
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
|
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4),
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 4)));
|
"X"
|
||||||
|
))->setIngredient("X", Item::get(Item::WOOD, Wood::SPRUCE, 1)));
|
||||||
|
|
||||||
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4),
|
||||||
|
"X"
|
||||||
|
))->setIngredient("X", Item::get(Item::WOOD, Wood::BIRCH, 1)));
|
||||||
|
|
||||||
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4),
|
||||||
|
"X"
|
||||||
|
))->setIngredient("X", Item::get(Item::WOOD, Wood::JUNGLE, 1)));
|
||||||
|
|
||||||
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4),
|
||||||
|
"X"
|
||||||
|
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
|
||||||
|
|
||||||
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4),
|
||||||
|
"X"
|
||||||
|
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
|
||||||
|
|
||||||
|
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOOL, 0, 1),
|
||||||
|
"XX",
|
||||||
|
"XX"
|
||||||
|
))->setIngredient("X", Item::get(Item::STRING, 0, 4)));
|
||||||
|
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 0, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
|
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 0, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 1, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
|
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 1, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
|
||||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SUGAR, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 1)));
|
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SUGAR, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 1)));
|
||||||
@ -351,7 +374,20 @@ class CraftingManager{
|
|||||||
* @param ShapedRecipe $recipe
|
* @param ShapedRecipe $recipe
|
||||||
*/
|
*/
|
||||||
public function registerShapedRecipe(ShapedRecipe $recipe){
|
public function registerShapedRecipe(ShapedRecipe $recipe){
|
||||||
|
$result = $recipe->getResult();
|
||||||
|
$this->recipes[spl_object_hash($recipe)] = $recipe;
|
||||||
|
$ingredients = $recipe->getIngredientMap();
|
||||||
|
$hash = "";
|
||||||
|
foreach($ingredients as $v){
|
||||||
|
foreach($v as $item){
|
||||||
|
/** @var Item $item */
|
||||||
|
$hash .= $item->getId() . ":" . ($item->getDamage() === null ? "?" : $item->getDamage()) . "x" . $item->getCount() . ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash .= ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->recipeLookup[$result->getId() . ":" . $result->getDamage()][$hash] = $recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@ namespace pocketmine\inventory;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\UUID;
|
use pocketmine\utils\UUID;
|
||||||
|
use pocketmine\math\Vector2;
|
||||||
|
|
||||||
class ShapedRecipe implements Recipe{
|
class ShapedRecipe implements Recipe{
|
||||||
/** @var Item */
|
/** @var Item */
|
||||||
@ -32,10 +33,12 @@ class ShapedRecipe implements Recipe{
|
|||||||
private $id = null;
|
private $id = null;
|
||||||
|
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
private $rows = [];
|
private $shape = [];
|
||||||
|
|
||||||
/** @var Item[] */
|
/** @var Item[][] */
|
||||||
private $ingredients = [];
|
private $ingredients = [];
|
||||||
|
/** @var Vector2[][] */
|
||||||
|
private $shapeItems = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Item $result
|
* @param Item $result
|
||||||
@ -43,27 +46,41 @@ class ShapedRecipe implements Recipe{
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(Item $result, array $shape = []){
|
public function __construct(Item $result, ...$shape){
|
||||||
if(count($shape) === 0){
|
if(count($shape) === 0){
|
||||||
throw new \InvalidArgumentException("Must provide a shape");
|
throw new \InvalidArgumentException("Must provide a shape");
|
||||||
}
|
}
|
||||||
if(count($shape) > 3){
|
if(count($shape) > 3){
|
||||||
throw new \InvalidStateException("Crafting recipes should be 1, 2, 3 rows, not " . count($shape));
|
throw new \InvalidStateException("Crafting recipes should be 1, 2, 3 rows, not " . count($shape));
|
||||||
}
|
}
|
||||||
foreach($shape as $row){
|
foreach($shape as $z => $row){
|
||||||
if(strlen($row) === 0 or strlen($row) > 3){
|
if(strlen($row) === 0 or strlen($row) > 3){
|
||||||
throw new \InvalidStateException("Crafting rows should be 1, 2, 3 characters, not " . count($row));
|
throw new \InvalidStateException("Crafting rows should be 1, 2, 3 characters, not " . count($row));
|
||||||
}
|
}
|
||||||
$this->rows[] = $row;
|
$this->ingredients[] = array_fill(0, strlen($row), null);
|
||||||
$len = strlen($row);
|
$len = strlen($row);
|
||||||
for($i = 0; $i < $len; ++$i){
|
for($i = 0; $i < $len; ++$i){
|
||||||
$this->ingredients[$row{$i}] = null;
|
$this->shape[$row{$i}] = null;
|
||||||
|
|
||||||
|
if(!isset($this->shapeItems[$row{$i}])){
|
||||||
|
$this->shapeItems[$row{$i}] = [new Vector2($i, $z)];
|
||||||
|
}else{
|
||||||
|
$this->shapeItems[$row{$i}][] = new Vector2($i, $z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->output = clone $result;
|
$this->output = clone $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getWidth(){
|
||||||
|
return count($this->ingredients[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeight(){
|
||||||
|
return count($this->ingredients);
|
||||||
|
}
|
||||||
|
|
||||||
public function getResult(){
|
public function getResult(){
|
||||||
return $this->output;
|
return $this->output;
|
||||||
}
|
}
|
||||||
@ -88,36 +105,54 @@ class ShapedRecipe implements Recipe{
|
|||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function setIngredient($key, Item $item){
|
public function setIngredient($key, Item $item){
|
||||||
if(!isset($this->ingredients[$key])){
|
if(!array_key_exists($key, $this->shape)){
|
||||||
throw new \Exception("Symbol does not appear in the shape: " . $key);
|
throw new \Exception("Symbol does not appear in the shape: " . $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ingredients[$key] = $item;
|
$this->fixRecipe($key, $item);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function fixRecipe($key, $item){
|
||||||
|
foreach($this->shapeItems[$key] as $entry){
|
||||||
|
$this->ingredients[$entry->y][$entry->x] = clone $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Item[]
|
* @return Item[][]
|
||||||
*/
|
*/
|
||||||
public function getIngredientMap(){
|
public function getIngredientMap(){
|
||||||
$ingredients = [];
|
$ingredients = [];
|
||||||
foreach($this->ingredients as $key => $ingredient){
|
foreach($this->ingredients as $z => $row){
|
||||||
if($ingredient instanceof Item){
|
$ingredients[$z] = [];
|
||||||
$ingredients[$key] = clone $ingredient;
|
foreach($row as $x => $ingredient){
|
||||||
}else{
|
if($ingredient !== null){
|
||||||
$ingredients[$key] = $ingredient;
|
$ingredients[$z][$x] = clone $ingredient;
|
||||||
|
}else{
|
||||||
|
$ingredients[$z][$x] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ingredients;
|
return $ingredients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $x
|
||||||
|
* @param $z
|
||||||
|
* @return null|Item
|
||||||
|
*/
|
||||||
|
public function getIngredient($x, $z){
|
||||||
|
return isset($this->ingredients[$z][$x]) ? $this->ingredients[$z][$x] : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function getShape(){
|
public function getShape(){
|
||||||
return $this->rows;
|
return $this->shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerToCraftingManager(){
|
public function registerToCraftingManager(){
|
||||||
|
@ -27,7 +27,6 @@ namespace pocketmine\network\protocol;
|
|||||||
use pocketmine\inventory\FurnaceRecipe;
|
use pocketmine\inventory\FurnaceRecipe;
|
||||||
use pocketmine\inventory\ShapedRecipe;
|
use pocketmine\inventory\ShapedRecipe;
|
||||||
use pocketmine\inventory\ShapelessRecipe;
|
use pocketmine\inventory\ShapelessRecipe;
|
||||||
use pocketmine\utils\Binary;
|
|
||||||
use pocketmine\utils\BinaryStream;
|
use pocketmine\utils\BinaryStream;
|
||||||
|
|
||||||
class CraftingDataPacket extends DataPacket{
|
class CraftingDataPacket extends DataPacket{
|
||||||
@ -64,11 +63,26 @@ class CraftingDataPacket extends DataPacket{
|
|||||||
$stream->putInt(1);
|
$stream->putInt(1);
|
||||||
$stream->putSlot($recipe->getResult());
|
$stream->putSlot($recipe->getResult());
|
||||||
|
|
||||||
|
$stream->putUUID($recipe->getId());
|
||||||
|
|
||||||
return CraftingDataPacket::ENTRY_SHAPELESS;
|
return CraftingDataPacket::ENTRY_SHAPELESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function writeShapedRecipe(ShapedRecipe $recipe, BinaryStream $stream){
|
private static function writeShapedRecipe(ShapedRecipe $recipe, BinaryStream $stream){
|
||||||
//TODO
|
$stream->putInt($recipe->getWidth());
|
||||||
|
$stream->putInt($recipe->getHeight());
|
||||||
|
|
||||||
|
for($z = 0; $z < $recipe->getWidth(); ++$z){
|
||||||
|
for($x = 0; $x < $recipe->getHeight(); ++$x){
|
||||||
|
$stream->putSlot($recipe->getIngredient($x, $z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream->putInt(1);
|
||||||
|
$stream->putSlot($recipe->getResult());
|
||||||
|
|
||||||
|
$stream->putUUID($recipe->getId());
|
||||||
|
|
||||||
return CraftingDataPacket::ENTRY_SHAPED;
|
return CraftingDataPacket::ENTRY_SHAPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user