private function getOptimalFlowDirections() { if ($this->temporalVector === \null) { $this->temporalVector = new Vector3(0, 0, 0); } for ($j = 0; $j < 4; ++$j) { $this->flowCost[$j] = 1000; $x = $this->x; $y = $this->y; $z = $this->z; if ($j === 0) { --$x; } elseif ($j === 1) { ++$x; } elseif ($j === 2) { --$z; } elseif ($j === 3) { ++$z; } $block = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z)); if (!$block->canBeFlowedInto() and !$block instanceof Liquid) { continue; } elseif ($block instanceof Liquid and $block->getDamage() === 0) { continue; } elseif ($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()) { $this->flowCost[$j] = 0; } else { $this->flowCost[$j] = $this->calculateFlowCost($block, 1, $j); } } $minCost = $this->flowCost[0]; for ($i = 1; $i < 4; ++$i) { if ($this->flowCost[$i] < $minCost) { $minCost = $this->flowCost[$i]; } } for ($i = 0; $i < 4; ++$i) { $this->isOptimalFlowDirection[$i] = $this->flowCost[$i] === $minCost; } return $this->isOptimalFlowDirection; }
public function calcWeather($currentTick) { if ($this->canCalculate()) { $tickDiff = $currentTick - $this->lastUpdate; $this->duration -= $tickDiff; if ($this->duration <= 0) { $duration = mt_rand(min($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax), max($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax)); if ($this->weatherNow === self::SUNNY) { $weather = $this->randomWeatherData[array_rand($this->randomWeatherData)]; $this->setWeather($weather, $duration); } else { $weather = self::SUNNY; $this->setWeather($weather, $duration); } } if ($this->weatherNow > 0 and $this->level->getServer()->lightningTime > 0 and is_int($this->duration / $this->level->getServer()->lightningTime)) { $players = $this->level->getPlayers(); if (count($players) > 0) { $p = $players[array_rand($players)]; $x = $p->x + mt_rand(-64, 64); $z = $p->z + mt_rand(-64, 64); $y = $this->level->getHighestBlockAt($x, $z); $this->level->spawnLightning($this->temporalVector->setComponents($x, $y, $z)); } } } $this->lastUpdate = $currentTick; }
/** * @return bool */ public function explodeA() : bool { if ($this->size < 0.1) { return false; } $vector = new Vector3(0, 0, 0); $vBlock = new Vector3(0, 0, 0); $mRays = intval($this->rays - 1); for ($i = 0; $i < $this->rays; ++$i) { for ($j = 0; $j < $this->rays; ++$j) { for ($k = 0; $k < $this->rays; ++$k) { if ($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays) { $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); $vector->setComponents($vector->x / ($len = $vector->length()) * $this->stepLen, $vector->y / $len * $this->stepLen, $vector->z / $len * $this->stepLen); $pointerX = $this->source->x; $pointerY = $this->source->y; $pointerZ = $this->source->z; for ($blastForce = $this->size * (mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $this->stepLen * 0.75) { $x = (int) $pointerX; $y = (int) $pointerY; $z = (int) $pointerZ; $vBlock->x = $pointerX >= $x ? $x : $x - 1; $vBlock->y = $pointerY >= $y ? $y : $y - 1; $vBlock->z = $pointerZ >= $z ? $z : $z - 1; if ($vBlock->y < 0 or $vBlock->y > 127) { break; } $block = $this->level->getBlock($vBlock); if ($block->getId() !== 0) { $blastForce -= ($block->getResistance() / 5 + 0.3) * $this->stepLen; if ($blastForce > 0) { if (!isset($this->affectedBlocks[$index = Level::blockHash($block->x, $block->y, $block->z)])) { $this->affectedBlocks[$index] = $block; } } } $pointerX += $vector->x; $pointerY += $vector->y; $pointerZ += $vector->z; } } } } } return true; }
public function calcWeather($currentTick) { if ($this->canCalculate()) { $tickDiff = $currentTick - $this->lastUpdate; $this->duration -= $tickDiff; if ($this->duration <= 0) { //0晴天1下雨2雷雨3阴天雷 if ($this->weatherNow == self::SUNNY) { $weather = $this->randomWeatherData[array_rand($this->randomWeatherData)]; $duration = mt_rand(min($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax), max($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax)); $this->level->getServer()->getPluginManager()->callEvent($ev = new WeatherChangeEvent($this->level, $weather, $duration)); if (!$ev->isCancelled()) { $this->weatherNow = $ev->getWeather(); $this->strength1 = mt_rand(90000, 110000); $this->strength2 = mt_rand(30000, 40000); $this->duration = $ev->getDuration(); $this->changeWeather($this->weatherNow, $this->strength1, $this->strength2); } } else { $weather = self::SUNNY; $duration = mt_rand(min($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax), max($this->level->getServer()->weatherRandomDurationMin, $this->level->getServer()->weatherRandomDurationMax)); $this->level->getServer()->getPluginManager()->callEvent($ev = new WeatherChangeEvent($this->level, $weather, $duration)); if (!$ev->isCancelled()) { $this->weatherNow = $ev->getWeather(); $this->strength1 = 0; $this->strength2 = 0; $this->duration = $ev->getDuration(); $this->changeWeather($this->weatherNow, $this->strength1, $this->strength2); } } } if ($this->weatherNow > 0 and $this->level->getServer()->lightningTime > 0 and is_int($this->duration / $this->level->getServer()->lightningTime)) { $players = $this->level->getPlayers(); if (count($players) > 0) { $p = $players[array_rand($players)]; $x = $p->x + mt_rand(-64, 64); $z = $p->z + mt_rand(-64, 64); $y = $this->level->getHighestBlockAt($x, $z); $this->level->spawnLightning($this->temporalVector->setComponents($x, $y, $z)); } /*foreach($this->level->getPlayers() as $p){ if(mt_rand(0, 1) == 1){ $x = $p->getX() + rand(-100, 100); $y = $p->getY() + rand(20, 50); $z = $p->getZ() + rand(-100, 100); $this->level->sendLighting($x, $y, $z, $p); } }*/ } } $this->lastUpdate = $currentTick; }
public function onBreak(Item $item) { $sound = new EndermanTeleportSound($this); $this->getLevel()->addSound($sound); $particle = new PortalParticle($this); $this->getLevel()->addParticle($particle); $block = $this; //$this->getLevel()->setBlock($block, new Block(Block::PORTAL, 0));//在破坏处放置一个方块防止计算出错 if ($this->getLevel()->getBlock($this->temporalVector->setComponents($block->x - 1, $block->y, $block->z))->getId() == Block::PORTAL or $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x + 1, $block->y, $block->z))->getId() == Block::PORTAL) { //x方向 for ($x = $block->x; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } for ($x = $block->x - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } } else { //z方向 for ($z = $block->z; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } for ($z = $block->z - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } } parent::onBreak($item); }
public function explodeBlocks(Position $source, $rays = 16, $size = 4) { $vector = new Vector3(0, 0, 0); $vBlock = new Vector3(0, 0, 0); $stepLen = 0.3; $mRays = \intval($rays - 1); $affectedBlocks = array(); for ($i = 0; $i < $rays; ++$i) { for ($j = 0; $j < $rays; ++$j) { for ($k = 0; $k < $rays; ++$k) { if ($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays) { $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); $vector->setComponents($vector->x / ($len = $vector->length()) * $stepLen, $vector->y / $len * $stepLen, $vector->z / $len * $stepLen); $pointerX = $source->x; $pointerY = $source->y; $pointerZ = $source->z; for ($blastForce = $size * (\mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $stepLen * 0.75) { $x = (int) $pointerX; $y = (int) $pointerY; $z = (int) $pointerZ; $vBlock->x = $pointerX >= $x ? $x : $x - 1; $vBlock->y = $pointerY >= $y ? $y : $y - 1; $vBlock->z = $pointerZ >= $z ? $z : $z - 1; if ($vBlock->y < 0 or $vBlock->y > 127) { break; } $block = $source->getLevel()->getBlock($vBlock); if ($block->getId() !== 0) { $blastForce -= (mt_rand(1, 3) / 5 + 0.3) * $stepLen; if ($blastForce > 0) { if (!isset($affectedBlocks[$index = \PHP_INT_SIZE === 8 ? ($block->x & 0xfffffff) << 35 | ($block->y & 0x7f) << 28 | $block->z & 0xfffffff : $block->x . ":" . $block->y . ":" . $block->z])) { $affectedBlocks[$index] = $block; } } } $pointerX += $vector->x; $pointerY += $vector->y; $pointerZ += $vector->z; } } } } } foreach ($affectedBlocks as $block) { if ($block instanceof Block) { $block->getLevel()->setBlock($block, new Air(), false, false); } } }
public function onUpdate($type) { if ($type == Level::BLOCK_UPDATE_NORMAL or $type == Level::BLOCK_UPDATE_RANDOM or $type == Level::BLOCK_UPDATE_SCHEDULED) { if (!$this->getSide(Vector3::SIDE_DOWN)->isTopFacingSurfaceSolid() and !$this->canNeighborBurn()) { $this->getLevel()->setBlock($this, new Air(), true); return Level::BLOCK_UPDATE_NORMAL; } elseif ($type == Level::BLOCK_UPDATE_NORMAL or $type == Level::BLOCK_UPDATE_RANDOM) { $this->getLevel()->scheduleUpdate($this, $this->getTickRate() + mt_rand(0, 10)); } elseif ($type == Level::BLOCK_UPDATE_SCHEDULED and $this->getLevel()->getServer()->fireSpread) { $forever = $this->getSide(Vector3::SIDE_DOWN)->getId() == Block::NETHERRACK; //TODO: END if (!$this->getSide(Vector3::SIDE_DOWN)->isTopFacingSurfaceSolid() and !$this->canNeighborBurn()) { $this->getLevel()->setBlock($this, new Air(), true); } if (!$forever and $this->getLevel()->getWeather()->isRainy() and ($this->getLevel()->canBlockSeeSky($this) or $this->getLevel()->canBlockSeeSky($this->getSide(Vector3::SIDE_EAST)) or $this->getLevel()->canBlockSeeSky($this->getSide(Vector3::SIDE_WEST)) or $this->getLevel()->canBlockSeeSky($this->getSide(Vector3::SIDE_SOUTH)) or $this->getLevel()->canBlockSeeSky($this->getSide(Vector3::SIDE_NORTH)))) { $this->getLevel()->setBlock($this, new Air(), true); } else { $meta = $this->meta; if ($meta < 15) { $this->meta = $meta + mt_rand(0, 3); $this->getLevel()->setBlock($this, $this, true); } $this->getLevel()->scheduleUpdate($this, $this->getTickRate() + mt_rand(0, 10)); if (!$forever and !$this->canNeighborBurn()) { if (!$this->getSide(Vector3::SIDE_DOWN)->isTopFacingSurfaceSolid() or $meta > 3) { $this->getLevel()->setBlock($this, new Air(), true); } } else { if (!$forever && !($this->getSide(Vector3::SIDE_DOWN)->getBurnAbility() > 0) && $meta == 15 && mt_rand(0, 4) == 0) { $this->getLevel()->setBlock($this, new Air(), true); } else { $o = 0; //TODO: decrease the o if the rainfall values are high $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_EAST), 300 + $o, $meta); $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_WEST), 300 + $o, $meta); $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_DOWN), 250 + $o, $meta); $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_UP), 250 + $o, $meta); $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_SOUTH), 300 + $o, $meta); $this->tryToCatchBlockOnFire($this->getSide(Vector3::SIDE_NORTH), 300 + $o, $meta); for ($x = $this->x - 1; $x <= $this->x + 1; ++$x) { for ($z = $this->z - 1; $z <= $this->z + 1; ++$z) { for ($y = $this->y - 1; $y <= $this->y + 4; ++$y) { $k = 100; if ($y > $this->y + 1) { $k += ($y - ($this->y + 1)) * 100; } $chance = $this->getChanceOfNeighborsEncouragingFire($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z))); if ($chance > 0) { $t = $chance + 40 + $this->getLevel()->getServer()->getDifficulty() * 7; //TODO: decrease t if the rainfall values are high if ($t > 0 and mt_rand(0, $k) <= $t) { $damage = min(15, $meta + mt_rand(0, 5) / 4); $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $z), new Fire($damage), true); $this->getLevel()->scheduleUpdate($this->temporalVector, $this->getTickRate()); } } } } } } } } } } return 0; }
public function setPortal(Level $level, $twoPos) { if (!$twoPos[0] instanceof Vector3) { return; } if (!$twoPos[1] instanceof Vector3) { return; } $startX = $twoPos[0]->x; $startY = $twoPos[0]->y; $startZ = $twoPos[0]->z; $endX = $twoPos[1]->x; $endY = $twoPos[1]->y; $endZ = $twoPos[1]->z; if ($startX > $endX) { $backup = $endX; $endX = $startX; $startX = $backup; } if ($startY > $endY) { $backup = $endY; $endY = $startY; $startY = $backup; } if ($startZ > $endZ) { $backup = $endZ; $endZ = $startZ; $startZ = $backup; } $startY++; $endY = $endY - 2; if ($startZ == $endZ) { $startX++; $endX--; } else { $startZ++; $endZ--; } $portalBlock = new Block(90); $vector = new Vector3(0, 0, 0); for ($x = $startX; $x <= $endX; $x++) { for ($y = $startY; $y <= $endY; $y++) { for ($z = $startZ; $z <= $endZ; $z++) { $level->setBlock($vector->setComponents($x, $y, $z), $portalBlock); } } } }
/** * @param $key * @param Level $level * @param Vector3 $position * @return bool */ public function updateHorizontalGrowingCrops($key, Level $level, Vector3 $position) { $cropBlock = null; switch ($this->farmData[$key]["id"]) { case Block::PUMPKIN_STEM: $cropBlock = Block::get(Block::PUMPKIN); break; case Block::MELON_STEM: $cropBlock = Block::get(Block::MELON_BLOCK); break; default: return true; } if (++$this->farmData[$key]["damage"] >= 8) { // FULL GROWN! for ($xOffset = -1; $xOffset <= 1; $xOffset++) { for ($zOffset = -1; $zOffset <= 1; $zOffset++) { if ($xOffset === 0 and $zOffset === 0) { //STEM continue; } $cropPosition = $position->setComponents($position->x + $xOffset, $position->y, $position->z + $zOffset); if ($level->getBlockIdAt($cropPosition->x, $cropPosition->y, $cropPosition->z) !== Item::AIR) { //SOMETHING EXISTS $level->setBlock($cropPosition, $cropBlock); return true; } } } return true; } $level->setBlock($position, Block::get($this->farmData[$key]["id"], $this->farmData[$key]["damage"])); return false; }
public function onBreak(Item $item) { parent::onBreak($item); if ($this->getLevel()->getServer()->netherEnabled) { for ($i = 0; $i <= 6; $i++) { if ($this->getSide($i)->getId() == self::PORTAL) { break; } if ($i == 6) { return; } } $block = $this->getSide($i); if ($this->getLevel()->getBlock($this->temporalVector->setComponents($block->x - 1, $block->y, $block->z))->getId() == Block::PORTAL or $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x + 1, $block->y, $block->z))->getId() == Block::PORTAL) { //x方向 for ($x = $block->x; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } for ($x = $block->x - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } } else { //z方向 for ($z = $block->z; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } for ($z = $block->z - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } } } }
public function onBreak(Item $item) { $block = $this; if ($this->getLevel()->getBlock($this->temporalVector->setComponents($block->x - 1, $block->y, $block->z))->getId() == Block::PORTAL or $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x + 1, $block->y, $block->z))->getId() == Block::PORTAL) { //x方向 for ($x = $block->x; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } for ($x = $block->x - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->y, $block->z))->getId() == Block::PORTAL; $x--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->z), new Air()); } } } else { //z方向 for ($z = $block->z; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z++) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } for ($z = $block->z - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $block->y, $z))->getId() == Block::PORTAL; $z--) { for ($y = $block->y; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y++) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } for ($y = $block->y - 1; $this->getLevel()->getBlock($this->temporalVector->setComponents($block->x, $y, $z))->getId() == Block::PORTAL; $y--) { $this->getLevel()->setBlock($this->temporalVector->setComponents($block->x, $y, $z), new Air()); } } } parent::onBreak($item); }
/** * @param Vector3 $pos */ public function updateAround(Vector3 $pos) { $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y - 1, $pos->z)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y + 1, $pos->z)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z - 1)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z + 1)))); if (!$ev->isCancelled()) { $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } }
/** * @return bool */ public function explodeA() { if ($this->size < 0.1) { return \false; } $vector = new Vector3(0, 0, 0); $vBlock = new Vector3(0, 0, 0); $mRays = \intval($this->rays - 1); for ($i = 0; $i < $this->rays; ++$i) { for ($j = 0; $j < $this->rays; ++$j) { for ($k = 0; $k < $this->rays; ++$k) { if ($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays) { $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); $vector->setComponents($vector->x / ($len = $vector->length()) * $this->stepLen, $vector->y / $len * $this->stepLen, $vector->z / $len * $this->stepLen); $pointerX = $this->source->x; $pointerY = $this->source->y; $pointerZ = $this->source->z; for ($blastForce = $this->size * (\mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $this->stepLen * 0.75) { $x = (int) $pointerX; $y = (int) $pointerY; $z = (int) $pointerZ; $vBlock->x = $pointerX >= $x ? $x : $x - 1; $vBlock->y = $pointerY >= $y ? $y : $y - 1; $vBlock->z = $pointerZ >= $z ? $z : $z - 1; if ($vBlock->y < 0 or $vBlock->y > 127) { break; } $block = $this->level->getBlock($vBlock); if ($block->getId() !== 0) { $blastForce -= ($block->getHardness() / 5 + 0.3) * $this->stepLen; if ($blastForce > 0) { if (!isset($this->affectedBlocks[$index = \PHP_INT_SIZE === 8 ? ($block->x & 0xfffffff) << 35 | ($block->y & 0x7f) << 28 | $block->z & 0xfffffff : $block->x . ":" . $block->y . ":" . $block->z])) { $this->affectedBlocks[$index] = $block; } } } $pointerX += $vector->x; $pointerY += $vector->y; $pointerZ += $vector->z; } } } } } return \true; }
/** * @param Entity $entity * @param AxisAlignedBB $bb * @param boolean $entities * * @return AxisAlignedBB[] */ public function getCollisionCubes(Entity $entity, AxisAlignedBB $bb, $entities = true) { $minX = Math::floorFloat($bb->minX); $minY = Math::floorFloat($bb->minY); $minZ = Math::floorFloat($bb->minZ); $maxX = Math::ceilFloat($bb->maxX); $maxY = Math::ceilFloat($bb->maxY); $maxZ = Math::ceilFloat($bb->maxZ); $collides = []; for ($z = $minZ; $z <= $maxZ; ++$z) { for ($x = $minX; $x <= $maxX; ++$x) { for ($y = $minY; $y <= $maxY; ++$y) { $block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z)); if (!$block->canPassThrough() and $block->collidesWithBB($bb)) { $collides[] = $block->getBoundingBox(); } } } } if ($entities) { foreach ($this->getCollidingEntities($bb->grow(0.25, 0.25, 0.25), $entity) as $ent) { $collides[] = clone $ent->boundingBox; } } return $collides; }
protected function checkObstruction($x, $y, $z) { $i = (int) $x; $j = (int) $y; $k = (int) $z; $diffX = $x - $i; $diffY = $y - $j; $diffZ = $z - $k; $list = $this->level->getCollisionBlocks($this->boundingBox); $v = new Vector3($i, $j, $k); if (\count($list) === 0 and !$this->level->isFullBlock($v->setComponents($i, $j, $k))) { return \false; } else { $flag = !$this->level->isFullBlock($v->setComponents($i - 1, $j, $k)); $flag1 = !$this->level->isFullBlock($v->setComponents($i + 1, $j, $k)); //$flag2 = !$this->level->isFullBlock($v->setComponents($i, $j - 1, $k)); $flag3 = !$this->level->isFullBlock($v->setComponents($i, $j + 1, $k)); $flag4 = !$this->level->isFullBlock($v->setComponents($i, $j, $k - 1)); $flag5 = !$this->level->isFullBlock($v->setComponents($i, $j, $k + 1)); $direction = 3; //UP! $limit = 9999; if ($flag) { $limit = $diffX; $direction = 0; } if ($flag1 and 1 - $diffX < $limit) { $limit = 1 - $diffX; $direction = 1; } if ($flag3 and 1 - $diffY < $limit) { $limit = 1 - $diffY; $direction = 3; } if ($flag4 and $diffZ < $limit) { $limit = $diffZ; $direction = 4; } if ($flag5 and 1 - $diffZ < $limit) { $direction = 5; } $force = \lcg_value() * 0.2 + 0.1; if ($direction === 0) { $this->motionX = -$force; return \true; } if ($direction === 1) { $this->motionX = $force; return \true; } //No direction 2 if ($direction === 3) { $this->motionY = $force; return \true; } if ($direction === 4) { $this->motionZ = -$force; return \true; } if ($direction === 5) { $this->motionY = $force; } return \true; } }
/** * @param Vector3|Position|Location $pos * @param float $yaw * @param float $pitch * * @return bool */ public function teleport(Vector3 $pos, $yaw = null, $pitch = null) { if ($pos instanceof Location) { $yaw = $yaw === null ? $pos->yaw : $yaw; $pitch = $pitch === null ? $pos->pitch : $pitch; } $from = Position::fromObject($this, $this->level); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level); $this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to)); if ($ev->isCancelled()) { return false; } $this->ySize = 0; $pos = $ev->getTo(); $this->setMotion($this->temporalVector->setComponents(0, 0, 0)); if ($this->setPositionAndRotation($pos, $yaw === null ? $this->yaw : $yaw, $pitch === null ? $this->pitch : $pitch) !== false) { $this->resetFallDistance(); $this->onGround = true; $this->lastX = $this->x; $this->lastY = $this->y; $this->lastZ = $this->z; $this->lastYaw = $this->yaw; $this->lastPitch = $this->pitch; $this->updateMovement(); return true; } return false; }
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz) { if ($target->getId() === Block::OBSIDIAN and $player->getServer()->netherEnabled) { //黑曜石 4*5最小 23*23最大 //$level->setBlock($block, new Fire(), true); $tx = $target->getX(); $ty = $target->getY(); $tz = $target->getZ(); //x方向 $x_max = $tx; //x最大值 $x_min = $tx; //x最小值 for ($x = $tx + 1; $level->getBlock($this->temporalVector->setComponents($x, $ty, $tz))->getId() == Block::OBSIDIAN; $x++) { $x_max++; } for ($x = $tx - 1; $level->getBlock($this->temporalVector->setComponents($x, $ty, $tz))->getId() == Block::OBSIDIAN; $x--) { $x_min--; } $count_x = $x_max - $x_min + 1; //x方向方块 if ($count_x >= 4 and $count_x <= 23) { //4 23 $x_max_y = $ty; //x最大值时的y最大值 $x_min_y = $ty; //x最小值时的y最大值 for ($y = $ty; $level->getBlock($this->temporalVector->setComponents($x_max, $y, $tz))->getId() == Block::OBSIDIAN; $y++) { $x_max_y++; } for ($y = $ty; $level->getBlock($this->temporalVector->setComponents($x_min, $y, $tz))->getId() == Block::OBSIDIAN; $y++) { $x_min_y++; } $y_max = min($x_max_y, $x_min_y) - 1; //y最大值 $count_y = $y_max - $ty + 2; //方向方块 //Server::getInstance()->broadcastMessage("$y_max $x_max_y $x_min_y $x_max $x_min"); if ($count_y >= 5 and $count_y <= 23) { //5 23 $count_up = 0; //上面 for ($ux = $x_min; $level->getBlock($this->temporalVector->setComponents($ux, $y_max, $tz))->getId() == Block::OBSIDIAN and $ux <= $x_max; $ux++) { $count_up++; } //Server::getInstance()->broadcastMessage("$count_up $count_x"); if ($count_up == $count_x) { for ($px = $x_min + 1; $px < $x_max; $px++) { for ($py = $ty + 1; $py < $y_max; $py++) { $level->setBlock($this->temporalVector->setComponents($px, $py, $tz), new Portal()); } } if ($player->isSurvival()) { $this->useOn($block, 2); $player->getInventory()->setItemInHand($this); } return true; } } } //z方向 $z_max = $tz; //z最大值 $z_min = $tz; //z最小值 $count_z = 0; //z方向方块 for ($z = $tz + 1; $level->getBlock($this->temporalVector->setComponents($tx, $ty, $z))->getId() == Block::OBSIDIAN; $z++) { $z_max++; } for ($z = $tz - 1; $level->getBlock($this->temporalVector->setComponents($tx, $ty, $z))->getId() == Block::OBSIDIAN; $z--) { $z_min--; } $count_z = $z_max - $z_min + 1; if ($count_z >= 4 and $count_z <= 23) { //4 23 $z_max_y = $ty; //z最大值时的y最大值 $z_min_y = $ty; //z最小值时的y最大值 for ($y = $ty; $level->getBlock($this->temporalVector->setComponents($tx, $y, $z_max))->getId() == Block::OBSIDIAN; $y++) { $z_max_y++; } for ($y = $ty; $level->getBlock($this->temporalVector->setComponents($tx, $y, $z_min))->getId() == Block::OBSIDIAN; $y++) { $z_min_y++; } $y_max = min($z_max_y, $z_min_y) - 1; //y最大值 $count_y = $y_max - $ty + 2; //方向方块 if ($count_y >= 5 and $count_y <= 23) { //5 23 $count_up = 0; //上面 for ($uz = $z_min; $level->getBlock($this->temporalVector->setComponents($tx, $y_max, $uz))->getId() == Block::OBSIDIAN and $uz <= $z_max; $uz++) { $count_up++; } //Server::getInstance()->broadcastMessage("$count_up $count_z"); if ($count_up == $count_z) { for ($pz = $z_min + 1; $pz < $z_max; $pz++) { for ($py = $ty + 1; $py < $y_max; $py++) { $level->setBlock($this->temporalVector->setComponents($tx, $py, $pz), new Portal()); } } if ($player->isSurvival()) { $this->useOn($block, 2); $player->getInventory()->setItemInHand($this); } return true; } } } //return true; } if ($block->getId() === self::AIR and $target instanceof Solid) { $level->setBlock($block, new Fire(), true); /** @var Fire $block */ $block = $level->getBlock($block); if ($block->getSide(Vector3::SIDE_DOWN)->isTopFacingSurfaceSolid() or $block->canNeighborBurn()) { $level->scheduleUpdate($block, $block->getTickRate() + mt_rand(0, 10)); // return true; } if ($player->isSurvival()) { $this->useOn($block, 2); //耐久跟报废分别写在 tool 跟 level 了 $player->getInventory()->setItemInHand($this); } return true; } return false; }