EpicEnchants/src/main/java/com/songoda/epicenchants/listeners/ArmorListener.java

212 lines
10 KiB
Java

package com.songoda.epicenchants.listeners;
import com.songoda.epicenchants.events.ArmorEquipEvent;
import com.songoda.epicenchants.events.ArmorEquipEvent.ArmorType;
import com.songoda.epicenchants.events.ArmorEquipEvent.EquipMethod;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
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.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.inventory.ItemStack;
import static org.bukkit.event.EventPriority.HIGHEST;
public class ArmorListener implements Listener {
@EventHandler(ignoreCancelled = true)
public final void onInventoryClick(final InventoryClickEvent e) {
boolean shift = false, numberKey = false;
if (e.getAction() == InventoryAction.NOTHING) {
return;
}
if (!(e.getWhoClicked() instanceof Player)) {
return;
}
if (e.getSlotType() != SlotType.ARMOR && e.getSlotType() != SlotType.QUICKBAR && e.getSlotType() != SlotType.CONTAINER) {
return;
}
if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
return;
}
if (!e.getInventory().getType().equals(InventoryType.CRAFTING) && !e.getInventory().getType().equals(InventoryType.PLAYER)) {
return;
}
if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)) {
shift = true;
}
if (e.getClick().equals(ClickType.NUMBER_KEY)) {
numberKey = true;
}
ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor());
if (!shift && newArmorType != null && e.getRawSlot() != newArmorType.getSlot()) {
// Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot.
return;
}
if (shift) {
newArmorType = ArmorType.matchType(e.getCurrentItem());
if (newArmorType != null) {
boolean equipping = true;
if (e.getRawSlot() == newArmorType.getSlot()) {
equipping = false;
}
if (newArmorType.equals(ArmorType.HELMET) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || newArmorType.equals(ArmorType.CHESTPLATE) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) || newArmorType.equals(ArmorType.LEGGINGS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) || newArmorType.equals(ArmorType.BOOTS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), EquipMethod.SHIFT_CLICK, newArmorType, equipping ? null : e.getCurrentItem(), equipping ? e.getCurrentItem() : null);
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
}
}
}
} else {
ItemStack newArmorPiece = e.getCursor();
ItemStack oldArmorPiece = e.getCurrentItem();
if (numberKey) {
if (e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {// Prevents shit in the 2by2 crafting
// e.getClickedInventory() == The players inventory
// e.getHotBarButton() == key people are pressing to equip or unequip the item to or from.
// e.getRawSlot() == The slot the item is going to.
// e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar slot ;-;
ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton());
if (!isAirOrNull(hotbarItem)) {// Equipping
newArmorType = ArmorType.matchType(hotbarItem);
newArmorPiece = hotbarItem;
oldArmorPiece = e.getClickedInventory().getItem(e.getSlot());
} else {// Unequipping
newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
}
}
} else {
if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) {// unequip with no new item going into the slot.
newArmorType = ArmorType.matchType(e.getCurrentItem());
}
// e.getCurrentItem() == Unequip
// e.getCursor() == Equip
// newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
}
if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) {
EquipMethod method = EquipMethod.PICK_DROP;
if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberKey) method = EquipMethod.HOTBAR_SWAP;
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType, oldArmorPiece, newArmorPiece);
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
}
}
}
}
@EventHandler(priority = HIGHEST)
public void playerInteractEvent(PlayerInteractEvent e) {
if (e.getAction() == Action.PHYSICAL) {
return;
}
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
final Player player = e.getPlayer();
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK) {// Having both of these checks is useless, might as well do it though.
// Some blocks have actions when you right click them which stops the client from equipping the armor in hand.
/*if (VersionDependent.getBlackList().stream().anyMatch(type -> e.getClickedBlock().getType().equals(type))) {
return;
}*/
}
ArmorType newArmorType = ArmorType.matchType(e.getItem());
if (newArmorType != null) {
if (newArmorType.equals(ArmorType.HELMET) && isAirOrNull(e.getPlayer().getInventory().getHelmet()) || newArmorType.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) || newArmorType.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) || newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots())) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), EquipMethod.HOTBAR, ArmorType.matchType(e.getItem()), null, e.getItem());
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
player.updateInventory();
}
}
}
}
}
@EventHandler
public void inventoryDrag(InventoryDragEvent event) {
if (event.getRawSlots().isEmpty()) {
return;
}
ArmorType type = ArmorType.matchType(event.getOldCursor());
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(), EquipMethod.DRAG, type, null, event.getOldCursor());
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
event.setResult(Result.DENY);
event.setCancelled(true);
}
}
}
@EventHandler
public void itemBreakEvent(PlayerItemBreakEvent e) {
ArmorType type = ArmorType.matchType(e.getBrokenItem());
if (type != null) {
Player p = e.getPlayer();
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, EquipMethod.BROKE, type, e.getBrokenItem(), null);
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
ItemStack i = e.getBrokenItem().clone();
i.setAmount(1);
i.setDurability((short) (i.getDurability() - 1));
switch (type) {
case HELMET:
p.getInventory().setHelmet(i);
break;
case CHESTPLATE:
p.getInventory().setChestplate(i);
break;
case LEGGINGS:
p.getInventory().setLeggings(i);
break;
case BOOTS:
p.getInventory().setBoots(i);
break;
}
}
}
}
@EventHandler
public void playerDeathEvent(PlayerDeathEvent event) {
for (ItemStack i : event.getEntity().getInventory().getArmorContents()) {
if (!isAirOrNull(i)) {
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(event.getEntity(), EquipMethod.DEATH, ArmorType.matchType(i), i, null));
// No way to cancel a death event.
}
}
}
/**
* A utility method to support versions that use null or air ItemStacks.
*/
private boolean isAirOrNull(ItemStack item) {
return item == null || item.getType().equals(Material.AIR);
}
}