Skip to content

Examples InvMenu v4

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

Index

Do NOT skip reading the precautions!

Precautions

  1. Register the InvMenuHandler before you create InvMenu instances.
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 and use the then() method. Or else, the player won't see the form (client-sided behaviour).
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{
	$player = $transaction->getPlayer();
	$action = $transaction->getAction();

	$player->removeWindow($action->getInventory());
	$transaction->then(function(Player $player) : void{
		$player->sendForm(new class() implements Form{});
	});
}));
$menu->getInventory()->addItem(ItemFactory::get(ItemIds::APPLE));
$menu->send($player);

// for non-readonly menus
$menu = InvMenu::create(InvMenu::TYPE_CHEST);
$menu->setListener(function(DeterministicInvMenuTransaction $transaction) : void{
	$player = $transaction->getPlayer();
	$action = $transaction->getAction();

	$player->removeWindow($action->getInventory());
	$transaction->discard()->then(function(Player $player) : void{
		$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
$menu->setName("Click the diamond!")
$menu->setListener(InvMenu::readonly(function(DeterministicInvMenuTransaction $transaction) : void{
	$player = $transaction->getPlayer();
	$itemTakenOut = $transaction->getClickedWith(); // or $transaction->getOut();

	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)
			->setName($name)
			->setListener(InvMenu::readonly(Closure::fromCallable([$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(DeterministicInvMenuTransaction $transaction) : void{
		$player = $transaction->getPlayer();
		$itemClickedOn = $transaction->getItemClicked();

		$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)
			->setName($name)
			->setListener(InvMenu::readonly(Closure::fromCallable([$this, "onTransaction"])));
		$this->menu->getInventory()->addItem(Item::get(Item::CHEST)->setCustomName(TextFormat::BOLD . TextFormat::RED . 'CLICK ME!' . TextFormat::RESET);
	}

	public function onTransaction(DeterministicInvMenuTransaction $transaction) : void{
		if(!$transaction->getOut()->isNull()){ // getOut() is same as getItemClickedWith()
			$transaction->getPlayer()->removeWindow($transaction->getAction()->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)
			->setName($menu1name)
 			->setListener(InvMenu::readonly(Closure::fromCallable([$this, "onUseFirstMenu"])));
		$this->menu1->getInventory()->addItem(Item::get(Item::DIAMOND)->setCustomName(TextFormat::RED . "Click ME!"));

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

	public function onUseFirstMenu(DeterministicInvMenuTransaction $transaction) : void{
		$this->menu2->send($transaction->getPlayer());
	}

	public function onUseSecondMenu(DeterministicInvMenuTransaction $transaction) : void{
		$this->menu1->send($transaction->getPlayer());
	}

	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(Closure::fromCallable(Trashcan::class . "::dispose"));
	}

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

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

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

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