How to set a chest item? I have some code for opening chests but I wanna set items to the chest and make them run commands. It would also be nice to freeze the items (make them unmovable)
This would probably be an event when an item is added to your inventory, then you can check and see if it is a “item name here” then run the command and remove the item and add it back to the chest.
You can set an "Items" NBT ListTag onto the chest item so that it gets loaded into the chest tile upon placement (that is the vanilla and non-hacky way of doing this)
Inventory->setItem() ? PHP: /** @var pocketmine\tile\Chest $chest */$inv = $chest->getInventory();$inv->setItem(0, Item::get(Item::GRASS));
What is $chest? PHP: $block = Block::get(54);$player->getLevel()->setBlock(new Vector3($player->x, $player->y - 2, $player->z), $block, true, true); $nbt = new CompoundTag("", [ new ListTag("Items", []), new StringTag("id", Tile::CHEST), new IntTag("x", floor($player->x)), new IntTag("y", floor($player->y) - 2), new IntTag("z", floor($player->z)) ]); $nbt->Items->setTagType(NBT::TAG_Compound); $tile = Tile::createTile("Chest", $player->getLevel()->getChunk($player->getX() >> 4, $player->getZ() >> 4), $nbt);
Oh, and btw, I know that a form is easier to code but I want something that will differ from the other servers.
Do you want to create chest GUIs where players can tap on an item which executes a command (but players can't take in or take out items from the chest)?
Is there any PlayerItemTapEvent or PlayerItemChooseEvent? Something like that. I am sure it does exist because the player would not be able to get items from chests.
You can make use of the InvMenu virion (https://github.com/Muqsit/InvMenu). It has a neat API for doing exactly what you want to. You first register the event listener in the onEnable() section of your plugin using: PHP: /** @var PluginBase $myplugin */if(!InvMenuHandler::isRegistered()){ InvMenuHandler::register($myplugin);} Then you create an InvMenu instance (also in the onEnable() section) using: PHP: $menu = InvMenu::create(InvMenu::TYPE_CHEST) ->readonly() ->setName("The Inventory's Name") ->setListener([$this, "handleMenuSelection"]);//readonly() will disallow players from modifying the inventory in any way. Then put some items in the menu PHP: $inv = $menu->getInventory();$item = Item::get(Item::STONE);$item->setCustomName("Click ME!");$inv->setItem(0, $item); And create a class method named "handleMenuSelection" to handle the transaction. PHP: public function handleMenuSelection(Player $player, Item $itemClicked) : bool{ if($itemClicked->getId() === Item::STONE){ $player->getServer()->dispatchCommand($player, "say Hi"); } return true;} That's it. You can send a player the menu using PHP: /** @var Player $player */$menu->send($player); You don't need to worry about spawning fake inventories and handling a million problems which include closing tiles after use, sending fake blocks to players and despawning the fake blocks after use etc. InvMenu handles all that nastiness for you
Thats what I've got: PHP: use pocketmine\plugin\PluginBase;use muqsit\invmenu\InvMenu;use pocketmine\utils\Config;use pocketmine\block\Block;use pocketmine\level\Level;use pocketmine\utils\TextFormat;use pocketmine\item\Item;use pocketmine\entity\Item as ItemEntity;use pocketmine\event\inventory\InventoryPickupItemEvent;class Core extends PluginBase { public function onEnable() { $cfg = new Config($this->getDataFolder() . "config.yml", Config::YAML); $prefix = $cfg->get("Prefix"); $network = $cfg->get("ServerName"); $status = $cfg->get("Status"); $this->getLogger()->info(TextFormat::GREEN . "Core Enabled"); $this->getServer()->getNetwork()->setName(TextFormat::BOLD . TextFormat::RED . $network . TextFormat::BLUE . "> " . $status); $config->save(); } public function __construct(string $name){ $cfg = new Config($this->getDataFolder() . "config.yml", Config::YAML); $prefix = $cfg->get("Prefix"); $this->menu = InvMenu::create(InvMenu::TYPE_CHEST) ->readonly() ->setName($name) ->onInventoryClose(function(Player $player) : void{ $player->sendMessage($prefix . TextFormat::GREEN . "Finding you a server to join..."); }); } public function OpenInv(Player $player){ $cfg = new Config($this->getDataFolder() . "config.yml", Config::YAML); $game1 = $cfg->get("Game-1"); $menu = InvMenu::create(InvMenu::TYPE_CHEST); $inv = $menu->getInventory(); $item = Item::get(Item::DIAMOND_SWORD); $item->setCustomName($game1); $inv->setItem(0, $item); $menu->setName("Server Selector"); $menu->send($player); } public function handleMenuSelection(Player $player, Item $itemClicked) : bool{ $cfg = new Config($this->getDataFolder() . "config.yml", Config::YAML); $game1 = $cfg->get("Game-1"); $game1ip = $cfg->get("Game-1-IP"); $in = $event->getPlayer()->getInventory()->getItemInHand()->getCustomName(); if($itemClicked->getId() === Item::DIAMOND_SWORD && $in == $game1){ $player->getServer()->dispatchCommand($player, "transferserver " . $game1ip); } return true; } I don't know if it works right now. Tell me if I have errors.