protected function parsePreset($preset, $chunkX, $chunkZ) { $this->preset = $preset; $preset = explode(";", $preset); $version = (int) $preset[0]; $blocks = isset($preset[1]) ? $preset[1] : ""; $biome = isset($preset[2]) ? $preset[2] : 1; $options = isset($preset[3]) ? $preset[3] : ""; preg_match_all('#^(([0-9]*x|)([0-9]{1,3})(|:[0-9]{0,2}))$#m', str_replace(",", "\n", $blocks), $matches); $y = 0; $this->structure = []; $this->chunks = []; foreach ($matches[3] as $i => $b) { $b = Item::fromString($b . $matches[4][$i]); $cnt = $matches[2][$i] === "" ? 1 : intval($matches[2][$i]); for ($cY = $y, $y += $cnt; $cY < $y; ++$cY) { $this->structure[$cY] = [$b->getId(), $b->getDamage()]; } } $this->floorLevel = $y; for (; $y < 0xff; ++$y) { $this->structure[$y] = [0, 0]; } $this->chunk = clone $this->level->getChunk($chunkX, $chunkZ); $this->chunk->setGenerated(); $c = Biome::getBiome($biome)->getColor(); $R = $c >> 16; $G = $c >> 8 & 0xff; $B = $c & 0xff; for ($Z = 0; $Z < 16; ++$Z) { for ($X = 0; $X < 16; ++$X) { $this->chunk->setBiomeId($X, $Z, $biome); $this->chunk->setBiomeColor($X, $Z, $R, $G, $B); for ($y = 0; $y < 128; ++$y) { $this->chunk->setBlock($X, $y, $Z, ...$this->structure[$y]); } } } preg_match_all('#(([0-9a-z_]{1,})\\(?([0-9a-z_ =:]{0,})\\)?),?#', $options, $matches); foreach ($matches[2] as $i => $option) { $params = true; if ($matches[3][$i] !== "") { $params = []; $p = explode(" ", $matches[3][$i]); foreach ($p as $k) { $k = explode("=", $k); if (isset($k[1])) { $params[$k[0]] = $k[1]; } } } $this->options[$option] = $params; } }
public function execute(CommandSender $sender, $currentAlias, array $args) { if (!$this->testPermission($sender)) { return true; } if (count($args) < 2) { $sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage])); return true; } $player = $sender->getServer()->getPlayer($args[0]); $item = Item::fromString($args[1]); if (!isset($args[2])) { $item->setCount($item->getMaxStackSize()); } else { $item->setCount((int) $args[2]); } if (isset($args[3])) { $tags = $exception = null; $data = implode(" ", array_slice($args, 3)); try { $tags = NBT::parseJSON($data); } catch (\Exception $ex) { $exception = $ex; } if (!$tags instanceof Compound or $exception !== null) { $sender->sendMessage(new TranslationContainer("commands.give.tagError", [$exception !== null ? $exception->getMessage() : "Invalid tag conversion"])); return true; } $item->setNamedTag($tags); } if ($player instanceof Player) { if ($item->getId() === 0) { $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); return true; } //TODO: overflow $player->getInventory()->addItem(clone $item); } else { $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); return true; } Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.give.success", [$item->getName() . " (" . $item->getId() . ":" . $item->getDamage() . ")", (string) $item->getCount(), $player->getName()])); return true; }
/** * Uses a item on a position and face, placing it or activating the block * * @param Vector3 $vector * @param Item $item * @param int $face * @param float $fx default 0.0 * @param float $fy default 0.0 * @param float $fz default 0.0 * @param Player $player default null * * @return boolean */ public function useItemOn(Vector3 $vector, Item &$item, $face, $fx = 0.0, $fy = 0.0, $fz = 0.0, Player $player = null) { $target = $this->getBlock($vector); $block = $target->getSide($face); if ($block->y > 127 or $block->y < 0) { return false; } if ($target->getId() === Item::AIR) { return false; } if ($player !== null) { $ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK); if ($player->isSpectator()) { $ev->setCancelled(); } if (!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1) { $t = new Vector2($target->x, $target->z); $s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z); if ($t->distance($s) <= $distance) { $ev->setCancelled(); } } $this->server->getPluginManager()->callEvent($ev); if (!$ev->isCancelled()) { $target->onUpdate(self::BLOCK_UPDATE_TOUCH); if (!$player->isSneaking() and $target->canBeActivated() === true and $target->onActivate($item, $player) === true) { return true; } if (!$player->isSneaking() and $item->canBeActivated() and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)) { if ($item->getCount() <= 0) { $item = Item::get(Item::AIR, 0, 0); return true; } } } else { return false; } } elseif ($target->canBeActivated() === true and $target->onActivate($item, $player) === true) { return true; } if ($item->canBePlaced()) { $hand = $item->getBlock(); $hand->position($block); } else { return false; } if (!($block->canBeReplaced() === true or $hand->getId() === Item::SLAB and $block->getId() === Item::SLAB)) { return false; //can anyone explain this to me?- Zombie } if ($target->canBeReplaced() === true) { $block = $target; $hand->position($block); //$face = -1; } if ($hand->isSolid() === true and $hand->getBoundingBox() !== null) { $entities = $this->getCollidingEntities($hand->getBoundingBox()); $realCount = 0; foreach ($entities as $e) { if ($e instanceof Arrow or $e instanceof DroppedItem) { continue; } ++$realCount; } if ($player !== null) { if ($diff = $player->getNextPosition()->subtract($player->getPosition()) and $diff->lengthSquared() > 1.0E-5) { $bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z); if ($hand->getBoundingBox()->intersectsWith($bb)) { ++$realCount; } } } if ($realCount > 0) { return false; //Entity in block } } $tag = $item->getNamedTagEntry("CanPlaceOn"); if ($tag instanceof Enum) { $canPlace = false; foreach ($tag as $v) { if ($v instanceof String) { $entry = Item::fromString($v->getValue()); if ($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()) { $canPlace = true; break; } } } if (!$canPlace) { return false; } } if ($player !== null) { $ev = new BlockPlaceEvent($player, $hand, $block, $target, $item); if (!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1) { $t = new Vector2($target->x, $target->z); $s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z); if ($t->distance($s) <= $distance) { //set it to cancelled so plugins can bypass this $ev->setCancelled(); } } $this->server->getPluginManager()->callEvent($ev); if ($ev->isCancelled()) { return false; } } if ($hand->place($item, $block, $target, $face, $fx, $fy, $fz, $player) === false) { return false; } if ($hand->getId() === Item::SIGN_POST or $hand->getId() === Item::WALL_SIGN) { $nbt = new Compound("", ["id" => new String("id", Tile::SIGN), "x" => new Int("x", $block->x), "y" => new Int("y", $block->y), "z" => new Int("z", $block->z), "Text1" => new String("Text1", ""), "Text2" => new String("Text2", ""), "Text3" => new String("Text3", ""), "Text4" => new String("Text4", "")]); if ($player !== null) { $nbt->Creator = new String("Creator", $player->getRawUniqueId()); } if ($item->hasCustomBlockData()) { foreach ($item->getCustomBlockData() as $key => $v) { $nbt->{$key} = $v; } } Tile::createTile("Sign", $this->getChunk($block->x >> 4, $block->z >> 4), $nbt); } $item->setCount($item->getCount() - 1); if ($item->getCount() <= 0) { $item = Item::get(Item::AIR, 0, 0); } return true; }