public function __construct(Level $level, Vector3 $start, Vector3 $direction, $yOffset = 0, $maxDistance = 0) { $this->level = $level; $this->maxDistance = (int) $maxDistance; $this->blockQueue = new \SplFixedArray(3); $startClone = new Vector3($start->x, $start->y, $start->z); $startClone->y += $yOffset; $this->currentDistance = 0; $mainDirection = 0; $secondDirection = 0; $thirdDirection = 0; $mainPosition = 0; $secondPosition = 0; $thirdPosition = 0; $pos = new Vector3($startClone->x, $startClone->y, $startClone->z); $startBlock = $this->level->getBlock($pos->floor()); if ($this->getXLength($direction) > $mainDirection) { $this->mainFace = $this->getXFace($direction); $mainDirection = $this->getXLength($direction); $mainPosition = $this->getXPosition($direction, $startClone, $startBlock); $this->secondFace = $this->getYFace($direction); $secondDirection = $this->getYLength($direction); $secondPosition = $this->getYPosition($direction, $startClone, $startBlock); $this->thirdFace = $this->getZFace($direction); $thirdDirection = $this->getZLength($direction); $thirdPosition = $this->getZPosition($direction, $startClone, $startBlock); } if ($this->getYLength($direction) > $mainDirection) { $this->mainFace = $this->getYFace($direction); $mainDirection = $this->getYLength($direction); $mainPosition = $this->getYPosition($direction, $startClone, $startBlock); $this->secondFace = $this->getZFace($direction); $secondDirection = $this->getZLength($direction); $secondPosition = $this->getZPosition($direction, $startClone, $startBlock); $this->thirdFace = $this->getXFace($direction); $thirdDirection = $this->getXLength($direction); $thirdPosition = $this->getXPosition($direction, $startClone, $startBlock); } if ($this->getZLength($direction) > $mainDirection) { $this->mainFace = $this->getZFace($direction); $mainDirection = $this->getZLength($direction); $mainPosition = $this->getZPosition($direction, $startClone, $startBlock); $this->secondFace = $this->getXFace($direction); $secondDirection = $this->getXLength($direction); $secondPosition = $this->getXPosition($direction, $startClone, $startBlock); $this->thirdFace = $this->getYFace($direction); $thirdDirection = $this->getYLength($direction); $thirdPosition = $this->getYPosition($direction, $startClone, $startBlock); } $d = $mainPosition / $mainDirection; $secondd = $secondPosition - $secondDirection * $d; $thirdd = $thirdPosition - $thirdDirection * $d; $this->secondError = floor($secondd * self::$gridSize); $this->secondStep = round($secondDirection / $mainDirection * self::$gridSize); $this->thirdError = floor($thirdd * self::$gridSize); $this->thirdStep = round($thirdDirection / $mainDirection * self::$gridSize); if ($this->secondError + $this->secondStep <= 0) { $this->secondError = -$this->secondStep + 1; } if ($this->thirdError + $this->thirdStep <= 0) { $this->thirdError = -$this->thirdStep + 1; } $lastBlock = $startBlock->getSide(Vector3::getOppositeSide($this->mainFace)); if ($this->secondError < 0) { $this->secondError += self::$gridSize; $lastBlock = $lastBlock->getSide(Vector3::getOppositeSide($this->secondFace)); } if ($this->thirdError < 0) { $this->thirdError += self::$gridSize; $lastBlock = $lastBlock->getSide(Vector3::getOppositeSide($this->thirdFace)); } $this->secondError -= self::$gridSize; $this->thirdError -= self::$gridSize; $this->blockQueue[0] = $lastBlock; $this->currentBlock = -1; $this->scan(); $startBlockFound = false; for ($cnt = $this->currentBlock; $cnt >= 0; --$cnt) { if ($this->blockEquals($this->blockQueue[$cnt], $startBlock)) { $this->currentBlock = $cnt; $startBlockFound = true; break; } } if (!$startBlockFound) { throw new \InvalidStateException("Start block missed in BlockIterator"); } $this->maxDistanceInt = round($maxDistance / (sqrt($mainDirection ** 2 + $secondDirection ** 2 + $thirdDirection ** 2) / $mainDirection)); }
/** * @param Vector3 $pos * @param int $delay */ public function scheduleUpdate(Vector3 $pos, int $delay) { $pos->floor(); if (isset($this->updateQueueIndex[$index = Level::blockHash((int) $pos->x, (int) $pos->y, (int) $pos->z)]) and $this->updateQueueIndex[$index] <= $delay) { return; } $this->updateQueueIndex[$index] = $delay; $this->updateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), (int) $delay + $this->server->getTick()); }