Properly implemented Shaped recipes on Network and manager, no crafting!

This commit is contained in:
Shoghi Cervantes 2015-08-04 21:54:56 +02:00
parent 9456e20770
commit 09720a2d90
4 changed files with 135 additions and 24 deletions

View 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{
}

View File

@ -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::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::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 ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)))->addIngredient(Item::get(Item::WOOD, Wood::BIRCH, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::JUNGLE, 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 ShapelessRecipe(Item::get(Item::WOOL, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 4)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::OAK, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 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, 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)));
@ -351,7 +374,20 @@ class CraftingManager{
* @param 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;
}
/**

View File

@ -24,6 +24,7 @@ namespace pocketmine\inventory;
use pocketmine\item\Item;
use pocketmine\Server;
use pocketmine\utils\UUID;
use pocketmine\math\Vector2;
class ShapedRecipe implements Recipe{
/** @var Item */
@ -32,10 +33,12 @@ class ShapedRecipe implements Recipe{
private $id = null;
/** @var string[] */
private $rows = [];
private $shape = [];
/** @var Item[] */
/** @var Item[][] */
private $ingredients = [];
/** @var Vector2[][] */
private $shapeItems = [];
/**
* @param Item $result
@ -43,27 +46,41 @@ class ShapedRecipe implements Recipe{
*
* @throws \Exception
*/
public function __construct(Item $result, array $shape = []){
public function __construct(Item $result, ...$shape){
if(count($shape) === 0){
throw new \InvalidArgumentException("Must provide a shape");
}
if(count($shape) > 3){
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){
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);
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;
}
public function getWidth(){
return count($this->ingredients[0]);
}
public function getHeight(){
return count($this->ingredients);
}
public function getResult(){
return $this->output;
}
@ -88,36 +105,54 @@ class ShapedRecipe implements Recipe{
* @throws \Exception
*/
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);
}
$this->ingredients[$key] = $item;
$this->fixRecipe($key, $item);
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(){
$ingredients = [];
foreach($this->ingredients as $key => $ingredient){
if($ingredient instanceof Item){
$ingredients[$key] = clone $ingredient;
}else{
$ingredients[$key] = $ingredient;
foreach($this->ingredients as $z => $row){
$ingredients[$z] = [];
foreach($row as $x => $ingredient){
if($ingredient !== null){
$ingredients[$z][$x] = clone $ingredient;
}else{
$ingredients[$z][$x] = null;
}
}
}
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[]
*/
public function getShape(){
return $this->rows;
return $this->shape;
}
public function registerToCraftingManager(){

View File

@ -27,7 +27,6 @@ namespace pocketmine\network\protocol;
use pocketmine\inventory\FurnaceRecipe;
use pocketmine\inventory\ShapedRecipe;
use pocketmine\inventory\ShapelessRecipe;
use pocketmine\utils\Binary;
use pocketmine\utils\BinaryStream;
class CraftingDataPacket extends DataPacket{
@ -64,11 +63,26 @@ class CraftingDataPacket extends DataPacket{
$stream->putInt(1);
$stream->putSlot($recipe->getResult());
$stream->putUUID($recipe->getId());
return CraftingDataPacket::ENTRY_SHAPELESS;
}
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;
}