Skip to content

Advanced Slots

Hamza Coşkun edited this page Mar 27, 2024 · 19 revisions

What are Advanced Slots

Remember Enchantment Table's gui.

image

As you know, Minecraft checks these slots when you put an item there. For example, if you put a stone to the lapis lazuli slot Minecraft will prevent it. I called these slots 'Advanced Slots'. ObliviateInvs introduces this feature on other GUIs. It can simulate a 1:1 replica of Minecraft inventory click mechanics. Also, its mind doesn't confuse when we register multiple slots.

  • Slot icon can be from all items (barrier, air etc...)
  • Imitates all click types
  • Calls onPut() and onPickup() events.

You can make Hypixel Skyblock's gui system.

TL;DR

These are icons that act like a slot.

AdvancedSlot advancedSlot = advancedSlotManager.addAdvancedIcon(1, new Icon(Material.BARRIER));
advancedSlot
	.onPut((event, item) -> /* void func */)
	.onPickup((event, item) -> /* void func */);

Gifs

advslots1 advslots2

How to use

Registering

public class TestGui extends Gui {

	AdvancedSlotManager advancedSlotManager = new AdvancedSlotManager(this);
		
	@Override
	public void onOpen(InventoryOpenEvent event) {
		AdvancedSlot advancedSlot = advancedSlotManager.addAdvancedIcon(29, new Icon(Material.BARRIER));
        }
}

Material.BARRIER is empty slot icon. Also you can make it Material.AIR.

Action Listening

                advancedSlot.onPrePutClick((event, item) -> {
			return false; // should event be cancelled?
		});

                advancedSlot.onPrePickupClick((event, item) -> {
			return false; // should event be cancelled?
		});

                advancedSlot.onPut((event, item) -> {
                        player.sendMessage("You putted " + item.getAmount() + " of "+ item.getType())
		});

                advancedSlot.onPickup((event, item) -> {
                        player.sendMessage("You took " + item.getAmount() + " of "+ item.getType())
		});

event and item parameters are non-null.

When a player clicks to an empty advanced slot with a stone, onPrePut event will be called. If onPrePut returns false, onPut event will be called. Everything is same for pickup events.

CAUTION

item paremeter gives you placed/taken item stack. DOES NOT gives new item stack on the advanced slot.

If the player puts 32x cobblestone to an empty advanced slot, item parameter will be 32x of cobblestone. However if the player continues and right clicks on 32x of cobblestone with a stack of cobblestone, this action will add 1 cobblestone to the 32 of cobblestones on the gui. So, item parameter will be 1x of cobblestone in that state.

Custom Advanced Slot handling

If you're interesting for going to deep. Know these methods.

advancedSlot1.resetSlot();

Reputs empty slot icon. For example, barrier.

advancedSlotManager.putIconToAdvancedSlot(advancedSlot, new Icon(Material.DIAMOND));

Puts an item stack to advanced slot without player.

Example Code

public class TestGUI extends GUI {

	public TestGUI(Player player) {
		super(player, "test-gui", "Test Title", 6);
	}


	@Override
	public void onOpen(InventoryOpenEvent event) {
		fillGui(new ItemStack(Material.BLACK_STAINED_GLASS_PANE));

		// FIRST ADVANCED SLOT

		AdvancedSlot advancedSlot2 = addAdvancedIcon(12, new Icon(Material.BARRIER));

		advancedSlot2.onPut((e, item) -> {
			enchantItem();
		});

		// SECOND ADVANCED SLOT

		AdvancedSlot advancedSlot1 = addAdvancedIcon(14, new Icon(Material.BARRIER));

		advancedSlot1.onPrePutClick((e, item) -> {
			if (!item.getType().equals(Material.LAPIS_LAZULI)) {
				player.sendMessage("You cannot put items here except lapis lazuli.");
				return true;
			}
			return false;
		}).onPut((e, item) -> {
			enchantItem();
		});


	}

	/**
	 * Purpose of this method,
	 * remove one lapis from the 2. slot -if exist-
	 * enchant item on 1. slot
	 */
	private void enchantItem() {
		final Inventory inventory = getInventory();

		//get item on lapis lazuli slot
		ItemStack itemOnSlot14 = inventory.getItem(14);
		if (!itemOnSlot14.getType().equals(Material.LAPIS_LAZULI)) return;

		//remove 1 lapis lazuli
		itemOnSlot14.setAmount(itemOnSlot14.getAmount() - 1);
		getInventory().setItem(14, itemOnSlot14); // Modifies the item with Bukkit's code.

		//enchant item
		ItemStack itemOnSlot12 = inventory.getItem(12);
		itemOnSlot12.addEnchantment(Enchantment.DURABILITY, 3);

		getInventory().setItem(12, itemOnSlot12); // Modifies the item with Bukkit's code.

	}
}

Code Testing

advslots3