Burn meta wildcards from Item, allow more dynamic recipe inputs

this was an obstacle for getting rid of legacy item IDs.
This commit is contained in:
Dylan K. Taylor
2022-06-27 13:33:26 +01:00
parent bc5a600d59
commit 55cb68e5b5
20 changed files with 473 additions and 127 deletions

View File

@ -24,7 +24,6 @@ declare(strict_types=1);
namespace pocketmine\crafting;
use pocketmine\item\Item;
use pocketmine\item\VanillaItems;
use pocketmine\utils\Utils;
use function array_values;
use function count;
@ -35,7 +34,7 @@ use function strpos;
class ShapedRecipe implements CraftingRecipe{
/** @var string[] */
private array $shape = [];
/** @var Item[] char => Item map */
/** @var RecipeIngredient[] char => RecipeIngredient map */
private array $ingredientList = [];
/** @var Item[] */
private array $results = [];
@ -46,15 +45,15 @@ class ShapedRecipe implements CraftingRecipe{
/**
* Constructs a ShapedRecipe instance.
*
* @param string[] $shape <br>
* @param string[] $shape <br>
* Array of 1, 2, or 3 strings representing the rows of the recipe.
* This accepts an array of 1, 2 or 3 strings. Each string should be of the same length and must be at most 3
* characters long. Each character represents a unique type of ingredient. Spaces are interpreted as air.
* @param Item[] $ingredients <br>
* @param RecipeIngredient[] $ingredients <br>
* Char => Item map of items to be set into the shape.
* This accepts an array of Items, indexed by character. Every unique character (except space) in the shape
* array MUST have a corresponding item in this list. Space character is automatically treated as air.
* @param Item[] $results List of items that this recipe produces when crafted.
* @param Item[] $results List of items that this recipe produces when crafted.
*
* Note: Recipes **do not** need to be square. Do NOT add padding for empty rows/columns.
*/
@ -119,7 +118,7 @@ class ShapedRecipe implements CraftingRecipe{
}
/**
* @return Item[][]
* @return (RecipeIngredient|null)[][]
*/
public function getIngredientMap() : array{
$ingredients = [];
@ -134,7 +133,7 @@ class ShapedRecipe implements CraftingRecipe{
}
/**
* @return Item[]
* @return RecipeIngredient[]
*/
public function getIngredientList() : array{
$ingredients = [];
@ -142,7 +141,7 @@ class ShapedRecipe implements CraftingRecipe{
for($y = 0; $y < $this->height; ++$y){
for($x = 0; $x < $this->width; ++$x){
$ingredient = $this->getIngredient($x, $y);
if(!$ingredient->isNull()){
if($ingredient !== null){
$ingredients[] = $ingredient;
}
}
@ -151,9 +150,8 @@ class ShapedRecipe implements CraftingRecipe{
return $ingredients;
}
public function getIngredient(int $x, int $y) : Item{
$exists = $this->ingredientList[$this->shape[$y][$x]] ?? null;
return $exists !== null ? clone $exists : VanillaItems::AIR();
public function getIngredient(int $x, int $y) : ?RecipeIngredient{
return $this->ingredientList[$this->shape[$y][$x]] ?? null;
}
/**
@ -170,7 +168,12 @@ class ShapedRecipe implements CraftingRecipe{
$given = $grid->getIngredient($reverse ? $this->width - $x - 1 : $x, $y);
$required = $this->getIngredient($x, $y);
if(!$required->equals($given, !$required->hasAnyDamageValue(), $required->hasNamedTag()) || $required->getCount() > $given->getCount()){
if($required === null){
if(!$given->isNull()){
return false; //hole, such as that in the center of a chest recipe, should not be filled
}
}elseif(!$required->accepts($given)){
return false;
}
}