Skip to content

Examples InvMenu v3

Muqsit Rayyan edited this page Aug 2, 2020 · 2 revisions

Index

Please do NOT skip reading the precautions!

Precautions

  1. Register the InvMenuHandler so InvMenu can register events. Without this, listener-dependent methods such as InvMenu::readonly() and InvMenu::setListener() will not function.
class MyPluginMainFile extends PluginBase{

    public function onEnable() : void{
        if(!InvMenuHandler::isRegistered()){
            InvMenuHandler::register($this);
        }
    }
}
  1. If you are sending a modal/form UI when a player clicks something in an inventory, remove the inventory from the player before doing so. Or else, the player won't see the form (client-sided behaviour).
$menu = InvMenu::create(InvMenu::TYPE_CHEST)
    ->readonly()
    ->setListener(function(Player $player, Item $itemTakenOut, Item $itemPuttingIn, SlotChangeAction $action) : void{
        $player->removeWindow($action->getInventory());
        $player->sendForm(new class() implements Form{});
    });
$menu->getInventory()->addItem(ItemFactory::get(ItemIds::APPLE));
$menu->send($player);

Examples

Simple Hello World GUI

$menu = InvMenu::create(InvMenu::TYPE_CHEST) // use TYPE_HOPPER for hopper, TYPE_DOUBLE_CHEST for double chest
    ->readonly()
    ->setName("Click the diamond!")
    ->setListener(function(Player $player, Item $itemTakenOut, Item $itemPuttingIn, SlotChangeAction $action) : void{
        if($itemTakenOut->getId() === ItemIds::DIAMOND){
            $player->removeWindow($action->getInventory());
            $player->sendMessage("Hello, world!");
        }
    });
$menu->getInventory()->addItem(ItemFactory::get(ItemIds::DIAMOND));

/** @var Player $player */
$menu->send($player);

Server-selector GUI

class ServerSelectorGUI{

    /** @var InvMenu */
    private $menu;

    public function __construct(string $name){
        $this->menu = InvMenu::create(InvMenu::TYPE_CHEST)
            ->readonly()
            ->setName($name)
            ->setListener([$this, "onServerSelectorTransaction"])//you can call class functions this way
            ->setInventoryCloseListener(function(Player $player) : void{
                $player->sendMessage(TextFormat::GREEN . "You are being transferred...");
            });
    }

    public function addServerToList(Item $item, string $address, int $port) : void{
        $nbt = $item->getNamedTag();
        $nbt->setString("Server", $address . ":" . $port);
        $item->setNamedTag($nbt);
        $this->menu->addItem($item);
    }

    public function onServerSelectorTransaction(Player $player, Item $itemClickedOn) : void{
        $player->transfer(...explode(":", $itemClickedOn->getNamedTag()->getString("Server", "play.onthefallbackserv.er:19132")));
    }

    public function sendTo(Player $player) : void{
        $this->menu->send($player);
    }
}

$gui = new ServerSelectorGUI("Server Selector");
$gui->addServerToList(Item::get(Item::DIAMOND_PICKAXE), "play.onmyserverplea.se", 19132);
$gui->addServerToList(Item::get(Item::IRON), "play.onmyserverplea.se", 19133);

/** @var Player $player */
$gui->sendTo($player);

Close an inventory when player clicks an item!

class Example{

    /** @var InvMenu */
    private $menu;

    public function __construct(string $name){
        $this->menu = InvMenu::create(InvMenu::TYPE_CHEST)
            ->readonly()
            ->setName($name)
            ->setListener([$this, "onTransaction"]);
        $this->menu->getInventory()->addItem(Item::get(Item::CHEST)->setCustomName(TextFormat::BOLD . TextFormat::RED . 'CLICK ME!' . TextFormat::RESET);
    }

    public function onTransaction(Player $player, Item $itemTakenOut, Item $itemPutIn, SlotChangeAction $inventoryAction) : void{
        if(!$itemTakenOut->isNull()){
            $player->removeWindow($inventoryAction->getInventory());
        }
    }

    public function sendTo(Player $player) : void{
        $this->menu->send($player);
    }
}

$example = new Example("Take the chest out of me!");

/** @var Player */
$example->sendTo($player);

Recursive GUI inventories!

class Example{

    /** @var InvMenu */
    private $menu1;

    /** @var InvMenu */
    private $menu2;

    public function __construct(string $menu1name, string $menu2name){
        $this->menu1 = InvMenu::create(InvMenu::TYPE_CHEST)
            ->readonly()
            ->setName($menu1name)
            ->setListener([$this, "onUseFirstMenu"]);
        $this->menu1->getInventory()->addItem(Item::get(Item::DIAMOND)->setCustomName(TextFormat::RED . "Click ME!"));

        $this->menu2 = InvMenu::create(InvMenu::TYPE_CHEST)
            ->readonly()
            ->setName($menu2name)
            ->setListener([$this, "onUseSecondMenu"]);
        $this->menu2->getInventory()->addItem(Item::get(Item::GOLD_INGOT)->setCustomName(TextFormat::RED . "Click ME!"));
    }

    public function onUseFirstMenu(Player $player, Item $ia, Item $ib, SlotChangeAction $inventoryAction) : void{
        $player->removeWindow($inventoryAction->getInventory());
        $this->menu2->send($player);
    }

    public function onUseSecondMenu(Player $player, Item $ia, Item $ib, SlotChangeAction $inventoryAction) : void{
        $player->removeWindow($inventoryAction->getInventory());
        $this->menu1->send($player);
    }

    public function sendTo(Player $player) : void{
        $this->menu1->send($player);
    }
}

$example = new Example("Menu #1", "Menu #2");

/** @var Player $player */
$example->sendTo($player);

Trash Can

class Trashcan{

    private static function getTrashMenu() : InvMenu{
        return InvMenu::create(InvMenu::TYPE_CHEST)
            ->setName("Trash Can")
            ->setInventoryCloseListener(Trashcan::class . "::dispose");
    }

    public static function dispose(Player $player, BaseFakeInventory $inventory) : void{
        $items_count = 0;
        foreach($inventory->getContents() as $item){
            $items_count += $item->getCount();
        }

        if($items_count > 0){
            $inventory->clearAll(false);
            $player->sendMessage("You disposed " . $items_count . " items!");
        }
    }

    public static function send(Player $player) : void{
        self::getTrashMenu()->send($player);
    }
}

/** @var Player $player */
Trashcan::send($player);