holder = $holder; $this->gridWidth = $gridWidth; parent::__construct($this->getGridWidth() ** 2); } public function getGridWidth() : int{ return $this->gridWidth; } public function setItem(int $index, Item $item) : void{ parent::setItem($index, $item); $this->seekRecipeBounds(); } /** * @return Player */ public function getHolder(){ return $this->holder; } private function seekRecipeBounds() : void{ $minX = PHP_INT_MAX; $maxX = 0; $minY = PHP_INT_MAX; $maxY = 0; $empty = true; for($y = 0; $y < $this->gridWidth; ++$y){ for($x = 0; $x < $this->gridWidth; ++$x){ if(!$this->isSlotEmpty($y * $this->gridWidth + $x)){ $minX = min($minX, $x); $maxX = max($maxX, $x); $minY = min($minY, $y); $maxY = max($maxY, $y); $empty = false; } } } if(!$empty){ $this->startX = $minX; $this->xLen = $maxX - $minX + 1; $this->startY = $minY; $this->yLen = $maxY - $minY + 1; }else{ $this->startX = $this->xLen = $this->startY = $this->yLen = null; } } /** * Returns the item at offset x,y, offset by where the starts of the recipe rectangle are. */ public function getIngredient(int $x, int $y) : Item{ if($this->startX !== null and $this->startY !== null){ return $this->getItem(($y + $this->startY) * $this->gridWidth + ($x + $this->startX)); } throw new \InvalidStateException("No ingredients found in grid"); } /** * Returns the width of the recipe we're trying to craft, based on items currently in the grid. */ public function getRecipeWidth() : int{ return $this->xLen ?? 0; } /** * Returns the height of the recipe we're trying to craft, based on items currently in the grid. */ public function getRecipeHeight() : int{ return $this->yLen ?? 0; } }