public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz) { if ($this->meta === Item::AIR) { if ($target instanceof Liquid) { $level->setBlock($target, new Air(), true); if (($player->gamemode & 0x1) === 0) { $this->meta = $target instanceof Water ? Item::WATER : Item::LAVA; } return true; } } elseif ($this->meta === Item::WATER) { //Support Make Non-Support Water to Support Water if ($block->getID() === self::AIR || $block instanceof Water && ($block->getDamage() & 0x7) != 0x0) { $water = new Water(); $level->setBlock($block, $water, true); $water->place(clone $this, $block, $target, $face, $fx, $fy, $fz, $player); if (($player->gamemode & 0x1) === 0) { $this->meta = 0; } return true; } } elseif ($this->meta === Item::LAVA) { if ($block->getID() === self::AIR) { $level->setBlock($block, new Lava(), true); if (($player->gamemode & 0x1) === 0) { $this->meta = 0; } return true; } } return false; }
/** * TODO: Move this to each item * * @param Entity|Block $object * * @return bool */ public function useOn($object) { if ($this->isHoe()) { if ($object instanceof Block and ($object->getID() === self::GRASS or $object->getID() === self::DIRT)) { $this->meta++; } } elseif ($object instanceof Entity and !$this->isSword()) { $this->meta += 2; } else { $this->meta++; } return true; }
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null) { if (($target->isTransparent === false or $target->getID() === self::SLAB) and $face !== 0 and $face !== 1) { $faces = [2 => 0, 3 => 1, 4 => 2, 5 => 3]; $this->meta = $faces[$face] & 0x3; if ($fy > 0.5) { $this->meta |= 0x8; } $this->getLevel()->setBlock($block, $this, true, true); return true; } return false; }
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null) { $this->meta &= 0x7; if ($face === 0) { if ($target->getID() === self::WOOD_SLAB and ($target->getDamage() & 0x8) === 0x8 and ($target->getDamage() & 0x7) === ($this->meta & 0x7)) { $this->getLevel()->setBlock($target, Block::get(Item::DOUBLE_WOOD_SLAB, $this->meta), true); return true; } elseif ($block->getID() === self::WOOD_SLAB and ($block->getDamage() & 0x7) === ($this->meta & 0x7)) { $this->getLevel()->setBlock($block, Block::get(Item::DOUBLE_WOOD_SLAB, $this->meta), true); return true; } else { $this->meta |= 0x8; } } elseif ($face === 1) { if ($target->getID() === self::WOOD_SLAB and ($target->getDamage() & 0x8) === 0 and ($target->getDamage() & 0x7) === ($this->meta & 0x7)) { $this->getLevel()->setBlock($target, Block::get(Item::DOUBLE_WOOD_SLAB, $this->meta), true); return true; } elseif ($block->getID() === self::WOOD_SLAB and ($block->getDamage() & 0x7) === ($this->meta & 0x7)) { $this->getLevel()->setBlock($block, Block::get(Item::DOUBLE_WOOD_SLAB, $this->meta), true); return true; } } elseif (!$player instanceof Player) { //TODO: collision if ($block->getID() === self::WOOD_SLAB) { if (($block->getDamage() & 0x7) === ($this->meta & 0x7)) { $this->getLevel()->setBlock($block, Block::get(Item::DOUBLE_WOOD_SLAB, $this->meta), true); return true; } return false; } else { if ($fy > 0.5) { $this->meta |= 0x8; } } } else { return false; } if ($block->getID() === self::WOOD_SLAB and ($target->getDamage() & 0x7) !== ($this->meta & 0x7)) { return false; } $this->getLevel()->setBlock($block, $this, true, true); return true; }
/** * Sets on Vector3 the data from a Block object, * does block updates and puts the changes to the send queue. * * If $direct is true, it'll send changes directly to players. if false, it'll be queued * and the best way to send queued changes will be done in the next tick. * This way big changes can be sent on a single chunk update packet instead of thousands of packets. * * If $update is true, it'll get the neighbour blocks (6 sides) and update them. * If you are doing big changes, you might want to set this to false, then update manually. * * @param Vector3 $pos * @param Block $block * @param bool $direct * @param bool $update * * @return bool */ public function setBlock(Vector3 $pos, Block $block, $direct = false, $update = true) { if ($pos->y < 0 or $pos->y >= 128 or !$block instanceof Block) { return false; } if ($this->getChunkAt($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0xf, $pos->y & 0x7f, $pos->z & 0xf, $block->getID(), $block->getDamage())) { if (!$pos instanceof Position) { $pos = new Position($pos->x, $pos->y, $pos->z, $this); } $block->position($pos); $index = Level::chunkHash($pos->x >> 4, $pos->z >> 4); if (ADVANCED_CACHE == true) { Cache::remove("world:" . $this->getID() . ":" . $index); } if ($direct === true) { $pk = new UpdateBlockPacket(); $pk->x = $pos->x; $pk->y = $pos->y; $pk->z = $pos->z; $pk->block = $block->getID(); $pk->meta = $block->getDamage(); foreach ($this->getUsingChunk($pos->x >> 4, $pos->z >> 4) as $player) { /** @var Player $player */ $player->directDataPacket($pk); } } else { if (!$pos instanceof Position) { $pos = new Position($pos->x, $pos->y, $pos->z, $this); } $block->position($pos); if (!isset($this->changedBlocks[$index])) { $this->changedBlocks[$index] = []; $this->changedCount[$index] = 0; } $Y = $pos->y >> 4; if (!isset($this->changedBlocks[$index][$Y])) { $this->changedBlocks[$index][$Y] = []; $this->changedCount[$index] |= 1 << $Y; } $this->changedBlocks[$index][$Y][] = clone $block; } if ($update === true) { $this->updateAround($pos, self::BLOCK_UPDATE_NORMAL); $block->onUpdate(self::BLOCK_UPDATE_NORMAL); } } }
public function canConnect(Block $block) { return ($block->getID() !== self::COBBLE_WALL and $block->getID() !== self::FENCE_GATE) ? $block->isSolid : true; }
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null) { ++$check; $index = $pos->x . "." . $pos->y . "." . $pos->z; if (isset($visited[$index])) { return false; } if ($pos->getID() === self::WOOD2) { return true; } elseif ($pos->getID() === self::LEAVES2 and $distance < 3) { $visited[$index] = true; $down = $pos->getSide(0)->getID(); if ($down === Item::WOOD2) { return true; } if ($fromSide === null) { for ($side = 2; $side <= 5; ++$side) { if ($this->findLog($pos->getSide($side), $visited, $distance + 1, $check, $side) === true) { return true; } } } else { //No more loops switch ($fromSide) { case 2: if ($this->findLog($pos->getSide(2), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(4), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(5), $visited, $distance + 1, $check, $fromSide) === true) { return true; } break; case 3: if ($this->findLog($pos->getSide(3), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(4), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(5), $visited, $distance + 1, $check, $fromSide) === true) { return true; } break; case 4: if ($this->findLog($pos->getSide(2), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(3), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(4), $visited, $distance + 1, $check, $fromSide) === true) { return true; } break; case 5: if ($this->findLog($pos->getSide(2), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(3), $visited, $distance + 1, $check, $fromSide) === true) { return true; } elseif ($this->findLog($pos->getSide(5), $visited, $distance + 1, $check, $fromSide) === true) { return true; } break; } } } return false; }
private static function rotateBlockByOne(Block $block) { return Block::get($block->getID(), $block->getDamage(), new Position($block->getZ(), $block->getY(), -$block->getX(), $block->getLevel())); }
public function __construct(Block $block, $meta = 0, $count = 1) { $this->block = clone $block; parent::__construct($block->getID(), $block->getDamage(), $count, $block->getName()); }
public function canConnect(Block $block) { return $block->isSolid or $block->getID() === $this->getID() or $block->getID() === self::GLASS_PANE or $block->getID() === self::GLASS; }
public static function keyBlock(Block $block) { return "{$block->getID()}:{$block->getDamage()}"; }