Skip to content

Instantly share code, notes, and snippets.

@dlsf
Last active January 22, 2021 12:34
Show Gist options
  • Save dlsf/7c2d909546529e9c9e2958c42f3f01b5 to your computer and use it in GitHub Desktop.
Save dlsf/7c2d909546529e9c9e2958c42f3f01b5 to your computer and use it in GitHub Desktop.
Advanced Bukkit ItemBuilder
import java.util.Arrays;
import java.util.function.Consumer;
import net.seliba.lobby.listener.InventoryClickListener;
import net.seliba.lobby.listener.PlayerInteractListener;
import org.bukkit.Material;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
/**
* Builder class which builds an ItemStack from scratch.
*
* @author das_
* @see ItemStack
* @since 1.0
*/
public class AdvancedItemBuilder {
private ItemStack itemStack;
private ItemMeta itemMeta;
/**
* Creates an ItemBuilder from the given Material.
*
* @param material The material which the final ItemStack should have.
* @see Material
* @since 1.0
*/
public AdvancedItemBuilder(Material material) {
this.itemStack = new ItemStack(material);
this.itemMeta = itemStack.getItemMeta();
}
/**
* Changes the name of the ItemStack.
*
* @param name The name which the ItemStack should have.
* @return The instance of the current ItemBuilder.
* @since 1.0
*/
public AdvancedItemBuilder withName(String name) {
itemMeta.setDisplayName(name);
return this;
}
/**
* Changes the lore of the ItemStack.
*
* @param lore The lore which the ItemStack should have.
* @return The instance of the current ItemBuilder.
* @since 1.0
*/
public AdvancedItemBuilder withLore(String... lore) {
itemMeta.setLore(Arrays.asList(lore));
return this;
}
/**
* Adds an interaction listener to the current ItemStack. Should be the second last statement
* executed (except ItemBuilder#withInventoryAction). Calling ItemBuilder#build has no influence
* on the effect of this method, the action gets registered anyways.
*
* @param action The action which should be executed.
* @param actionType The type of action which should trigger the action.
* @return The instance of the current ItemBuilder.
* @since 1.0
*/
public AdvancedItemBuilder withInteractAction(Consumer<PlayerInteractEvent> action, Action... actionType) {
itemStack.setItemMeta(itemMeta);
PlayerInteractListener.addInteractListener(itemStack, action, actionType);
return this;
}
/**
* Adds an inventory listener to the current ItemStack. Should be the second last statement
* executed (except ItemBuilder#withInteractAction). Calling ItemBuilder#build has no influence on
* the effect of this method, the action gets registered anyways.
*
* @param action The action which should be executed.
* @return The instance of the current ItemBuilder.
* @since 1.0
*/
public AdvancedItemBuilder withInventoryAction(Consumer<InventoryClickEvent> action) {
itemStack.setItemMeta(itemMeta);
InventoryClickListener.addClickListener(itemStack, action);
return this;
}
/**
* Creates the final ItemStack from the ItemBuilder.
*
* @return The ItemStack created by the ItemBuilder.
* @since 1.0
*/
public ItemStack build() {
itemStack.setItemMeta(itemMeta);
return itemStack;
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
/**
* Handles all inventory click actions. Mainly used for the ItemBuilder. Should not be used more
* than once.
*
* @author das_
* @see net.seliba.lobby.utils.ItemBuilder
* @since 1.0
*/
public class InventoryClickListener implements Listener {
// Stores all ItemStacks with their action.
private static final Map<ItemStack, Consumer<InventoryClickEvent>> itemActions = new HashMap<>();
/**
* Handles all inventory clicks.
*
* @param event The InventoryClickEvent, provided by Bukkit.
*/
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getClickedInventory() == null) {
return;
}
ItemStack currentItem = event.getCurrentItem();
if (currentItem == null) {
return;
}
// Execute the Consumer of the item if one exists
Optional<ItemStack> foundItem = itemActions.keySet().stream().filter(event.getCurrentItem()::isSimilar).findAny();
if (foundItem.isPresent()) {
event.setCancelled(true);
itemActions.get(foundItem.get()).accept(event);
}
}
/**
* Adds a click action to the provided ItemStack. Needed for the ItemBuilder to work.
*
* @param itemStack The ItemStack which should have the action.
* @param action The action which should be executed.
* @see net.seliba.lobby.utils.ItemBuilder
* @since 1.0
*/
public static void addClickListener(ItemStack itemStack, Consumer<InventoryClickEvent> action) {
itemActions.put(itemStack, action);
}
}
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
/**
* Handles all interactions from the Players. Mainly used for the ItemBuilder. Should not be used
* more than once.
*
* @author das_
* @see net.seliba.lobby.utils.ItemBuilder
* @since 1.0
*/
public class PlayerInteractListener implements Listener {
private static Map<ItemStack, Consumer<PlayerInteractEvent>> itemActions = new HashMap<>();
private static Map<ItemStack, List<Action>> itemActionTypes = new HashMap<>();
/**
* Handles all interactions from the Players.
*
* @param event The PlayerInteractEvent, provided by Bukkit.
*/
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
ItemStack item = event.getItem();
if (item == null) {
return;
}
Optional<ItemStack> foundItem = itemActions.keySet().stream().filter(item::isSimilar).findAny();
if (!foundItem.isPresent()) {
return;
}
if (itemActionTypes.get(foundItem.get()).contains(event.getAction())) {
event.setCancelled(true);
itemActions.get(foundItem.get()).accept(event);
}
}
/**
* Adds an interaction action to the provided ItemStack. Needed for the ItemBuilder to work.
*
* @param itemStack The ItemStack which should have the action.
* @param action The action which should be executed.
* @param actionType The type of action which should trigger the action.
* @since 1.0
*/
public static void addInteractListener(ItemStack itemStack, Consumer<PlayerInteractEvent> action, Action... actionType) {
itemActions.put(itemStack, action);
itemActionTypes.put(itemStack, Arrays.asList(actionType));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment