Refactoring

This commit is contained in:
2021-03-21 20:17:31 +01:00
parent 87f2bf0b19
commit 5019788865
122 changed files with 6119 additions and 663 deletions

View File

@@ -0,0 +1,224 @@
package fr.pandacube.lib.paper.gui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import fr.pandacube.lib.core.util.Log;
import fr.pandacube.lib.paper.util.BukkitEvent;
/**
* Managed a « lobby » type hotbar menu/inventory. It represents items in the player inventory on which you can right click on it.
* The player can't move or drop these items.
*
*/
public class GUIHotBar implements Listener {
private Map<ItemStack, BiConsumer<PlayerInventory, ItemStack>> itemsAndSetters = new HashMap<>();
private Map<ItemStack, Consumer<Player>> itemsAndRunnables = new HashMap<>();
private final int defltSlot;
private List<Player> currentPlayers = new ArrayList<>();
public GUIHotBar(int defaultSlot) {
defltSlot = Math.max(0, Math.min(8, defaultSlot));
BukkitEvent.register(this);
}
/**
* Add the item to this hotbar menu. if there is already players hooked to this hotbar, the item will be directly added to
* their inventories.
* @param i the item stack
* @param setter code executed to put the item in the inventory. Additionally check for permission before doing the addition.
* @param run the Runnable to run when the user right click on the item in the hotbar.
* @return
*/
public GUIHotBar addItem(ItemStack i, BiConsumer<PlayerInventory, ItemStack> setter, Consumer<Player> run) {
itemsAndSetters.put(i, setter);
itemsAndRunnables.put(i, run);
for (Player p : currentPlayers)
addItemToPlayer(p, i);
return this;
}
/**
* Add the hotbar elements to this player.
*
* The players is automatically removed when it quit. You can remove it before by calling {@link #removePlayer(Player)}.
* @param p
*/
public void addPlayer(Player p) {
if (!currentPlayers.contains(p))
currentPlayers.add(p);
for (ItemStack is : itemsAndSetters.keySet()) {
addItemToPlayer(p, is);
}
p.getInventory().setHeldItemSlot(defltSlot);
}
/**
* Detach this player from this hotbar manager and removes the managed items from the players inventory.
* @param p
*/
public void removePlayer(Player p) {
if (!currentPlayers.contains(p))
return;
for (ItemStack is : itemsAndSetters.keySet()) {
removeItemFromPlayer(p, is);
}
currentPlayers.remove(p);
}
public boolean containsPlayer(Player p) {
return currentPlayers.contains(p);
}
public void removeAllPlayers() {
for (Player p : new ArrayList<>(currentPlayers))
removePlayer(p);
}
public void addItemToPlayer(Player p, ItemStack is) {
if (!itemsAndSetters.containsKey(is))
throw new IllegalArgumentException("The provided ItemStack is not registered in this HotbarMenu");
if (!currentPlayers.contains(p))
throw new IllegalArgumentException("The provided Player is not registered in this HotbarMenu");
itemsAndSetters.get(is).accept(p.getInventory(), is.clone());
}
public void removeItemFromPlayer(Player p, ItemStack is) {
p.getInventory().remove(is);
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
if (!currentPlayers.contains(event.getPlayer()))
return;
ItemStack item = event.getItemDrop().getItemStack();
for (ItemStack managed : itemsAndSetters.keySet()) {
if (item != null && item.isSimilar(managed)) {
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!currentPlayers.contains(event.getPlayer()))
return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR)
return;
ItemStack item = event.getItem();
if (item == null)
return;
Player p = event.getPlayer();
for (ItemStack is : itemsAndRunnables.keySet()) {
if (item.isSimilar(is)) {
try {
itemsAndRunnables.get(is).accept(p);
} catch (Exception e) {
Log.severe(e);
}
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (event.getClickedInventory() == null || !(event.getClickedInventory() instanceof PlayerInventory))
return;
PlayerInventory inv = (PlayerInventory) event.getClickedInventory();
if (!currentPlayers.contains(inv.getHolder()))
return;
ItemStack item = event.getCurrentItem();
for (ItemStack is : itemsAndSetters.keySet()) {
if (item != null && item.isSimilar(is)) {
try {
itemsAndRunnables.get(is).accept((Player) inv.getHolder());
} catch (Exception e) {
Log.severe(e);
}
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
removePlayer(event.getPlayer());
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event) {
if (!currentPlayers.contains(event.getEntity()))
return;
event.getDrops().removeAll(itemsAndSetters.keySet());
}
@EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) {
if (!currentPlayers.contains(event.getPlayer()))
return;
currentPlayers.remove(event.getPlayer());
addPlayer(event.getPlayer());
}
}

View File

@@ -0,0 +1,251 @@
package fr.pandacube.lib.paper.gui;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import com.google.common.collect.ImmutableMap;
import fr.pandacube.lib.core.chat.Chat;
import fr.pandacube.lib.core.util.Callback;
import fr.pandacube.lib.paper.util.ItemStackBuilder;
public class GUIInventory implements Listener {
public static final Map<Enchantment, Integer> FAKE_ENCHANT = ImmutableMap.of(Enchantment.DURABILITY, 1);
private Player player;
private Inventory inv;
private Callback<InventoryCloseEvent> onCloseEvent;
private boolean isOpened = false;
private Map<Integer, Callback<InventoryClickEvent>> onClickEvents;
public GUIInventory(Player p, int nbLines, String title, Callback<InventoryCloseEvent> closeEventAction,
Plugin pl) {
inv = Bukkit.createInventory(null, nbLines * 9, title);
setCloseEvent(closeEventAction);
onClickEvents = new HashMap<>();
player = p;
Bukkit.getPluginManager().registerEvents(this, pl);
}
protected void setCloseEvent(Callback<InventoryCloseEvent> closeEventAction) {
onCloseEvent = closeEventAction;
}
/**
* @param clickEventActions (l'event passé en paramètre de la méthode done a
* été pré-annulée. Pour la rétablir, faites un
* event.setCancelled(false)).
*/
public void setButtonIfEmpty(int p, ItemStack iStack, Callback<InventoryClickEvent> clickEventActions) {
if (inv.getItem(p) == null)
setButton(p, iStack, clickEventActions);
}
/**
* @param clickEventActions (l'event passé en paramètre de la méthode done a
* été pré-annulée. Pour la rétablir, faites un
* event.setCancelled(false)).
*/
public void setButton(int p, ItemStack iStack, Callback<InventoryClickEvent> clickEventActions) {
inv.setItem(p, iStack);
changeClickEventAction(p, clickEventActions);
}
/**
* @param clickEventActions (l'event passé en paramètre de la méthode done a
* été pré-annulée. Pour la rétablir, faites un
* event.setCancelled(false)).
*/
public void changeClickEventAction(int p, Callback<InventoryClickEvent> clickEventActions) {
onClickEvents.put(p, clickEventActions);
}
public ItemStack getItemStack(int p) {
return inv.getItem(p);
}
public void open() {
if (isOpened) return;
player.openInventory(inv);
isOpened = true;
}
public void forceClose() {
if (!isOpened) return;
player.closeInventory(); // internally calls the InventoryCloseEvent
}
public boolean isOpen() {
return isOpened;
}
public void clear() {
onClickEvents.clear();
inv.clear();
}
public void clear(int firstElement, int nbElement) {
for (int i = firstElement; i < firstElement + nbElement; i++) {
inv.setItem(i, null);
onClickEvents.remove(i);
}
}
public Inventory getInventory() {
return inv;
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (!event.getWhoClicked().equals(player)) return;
if (!isOpened) return;
if (!event.getView().getTopInventory().equals(inv)) return;
event.setCancelled(true);
// on ne réagit pas aux clics hors de l'inventaire du dessus.
if (event.getClickedInventory() != event.getView().getTopInventory()) return;
Callback<InventoryClickEvent> callback = onClickEvents.get(event.getSlot());
if (callback != null) callback.done(event);
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
if (!event.getPlayer().equals(player)) return;
if (!isOpened) return;
if (!event.getView().getTopInventory().equals(inv)) return;
HandlerList.unregisterAll(this);
if (onCloseEvent != null)
onCloseEvent.done(event);
isOpened = false;
}
public static ItemStack buildButton(ItemStack base, Integer amount, Chat displayName,
List<Chat> lores, Map<Enchantment, Integer> enchantments) {
ItemStackBuilder iStackBuilder = ItemStackBuilder.of(base);
if (amount != null)
iStackBuilder.amount(amount);
if (displayName != null)
iStackBuilder.displayName(displayName);
if (lores != null)
iStackBuilder.lore(lores);
if (enchantments != null) {
if (enchantments == FAKE_ENCHANT)
iStackBuilder.fakeEnchant();
else {
for (Entry<Enchantment, Integer> e : enchantments.entrySet()) {
iStackBuilder.enchant(e.getKey(), e.getValue());
}
}
}
return iStackBuilder.build();
}
public static ItemStack buildButton(ItemStack base, Chat displayName, List<Chat> lores, Map<Enchantment, Integer> enchantments) {
return buildButton(base, null, displayName, lores, enchantments);
}
public static ItemStack buildButton(ItemStack base, Integer amount, Chat displayName, Map<Enchantment, Integer> enchantments) {
return buildButton(base, amount, displayName, null, enchantments);
}
public static ItemStack buildButton(ItemStack base, Chat displayName, Map<Enchantment, Integer> enchantments) {
return buildButton(base, null, displayName, null, enchantments);
}
public static ItemStack buildButton(ItemStack base, Integer amount, Chat displayName, List<Chat> lores) {
return buildButton(base, amount, displayName, lores, null);
}
public static ItemStack buildButton(ItemStack base, Chat displayName, List<Chat> lores) {
return buildButton(base, null, displayName, lores, null);
}
public static ItemStack buildButton(ItemStack base, Integer amount, Chat displayName) {
return buildButton(base, amount, displayName, null, null);
}
public static ItemStack buildButton(ItemStack base, Chat displayName) {
return buildButton(base, null, displayName, null, null);
}
public static ItemStack buildButton(ItemStack base, Integer amount) {
return buildButton(base, amount, null, null, null);
}
public static ItemStack buildButton(Material m, int amount, Chat displayName, List<Chat> lores, Map<Enchantment, Integer> enchantments) {
return buildButton(new ItemStack(m, amount), displayName, lores, enchantments);
}
public static ItemStack buildButton(Material m, Chat displayName, List<Chat> lores, Map<Enchantment, Integer> enchantments) {
return buildButton(m, 1, displayName, lores, enchantments);
}
public static ItemStack buildButton(Material m, int amount, Chat displayName, Map<Enchantment, Integer> enchantments) {
return buildButton(m, amount, displayName, null, enchantments);
}
public static ItemStack buildButton(Material m, Chat displayName, Map<Enchantment, Integer> enchantments) {
return buildButton(m, 1, displayName, null, enchantments);
}
public static ItemStack buildButton(Material m, int amount, Chat displayName, List<Chat> lores) {
return buildButton(m, amount, displayName, lores, null);
}
public static ItemStack buildButton(Material m, Chat displayName, List<Chat> lores) {
return buildButton(m, 1, displayName, lores, null);
}
public static ItemStack buildButton(Material m, int amount, Chat displayName) {
return buildButton(m, amount, displayName, null, null);
}
public static ItemStack buildButton(Material m, Chat displayName) {
return buildButton(m, 1, displayName, null, null);
}
public static ItemStack buildButton(Material m, int amount) {
return buildButton(m, amount, null, null, null);
}
public static int nbLineForNbElements(int nb) {
return nb / 9 + ((nb % 9 == 0) ? 0 : 1);
}
}