/* * Copyright (C) 2013-2018 Gonçalo Baltazar <[email protected]> * * This file is part of NBTEditor. * * NBTEditor is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NBTEditor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NBTEditor. If not, see <http://www.gnu.org/licenses/>. */ package com.goncalomb.bukkit.customitems.api; import java.util.Arrays; import java.util.HashSet; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.ItemDespawnEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; final class CustomItemListener implements Listener { private static final HashSet<Material> _interationMaterials = new HashSet<Material>(Arrays.asList(new Material[] { Material.CRAFTING_TABLE, Material.CHEST, Material.ENDER_CHEST, Material.BREWING_STAND, Material.ENCHANTING_TABLE })); private static boolean verifyCustomItem(CustomItem customItem, World world) { return (customItem != null && customItem.isEnabled() && customItem.isValidWorld(world)); } private static boolean verifyCustomItem(CustomItem customItem, Player player, boolean silent) { if (customItem != null) { if (!customItem.isEnabled()) { if (!silent) player.sendMessage("§cThis item is disabled!"); } else if (player != null && !player.hasPermission("nbteditor.customitems.use." + customItem.getSlug())) { if (!silent) player.sendMessage("§cYou don't have permission to use this item!"); } else if (!customItem.isValidWorld(player.getWorld()) && !player.hasPermission("nbteditor.customitems.world-override." + customItem.getSlug())) { if (!silent) player.sendMessage("§cThis item is disabled on this world!"); } else { return true; } } return false; } @EventHandler private void playerInteract(PlayerInteractEvent event) { Action action = event.getAction(); if (action != Action.PHYSICAL) { if (action == Action.RIGHT_CLICK_BLOCK && _interationMaterials.contains(event.getClickedBlock().getType())) { return; } CustomItem customItem = CustomItemManager.getCustomItem(event.getItem()); if (customItem != null) { if (verifyCustomItem(customItem, event.getPlayer(), false)) { if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK) { customItem.onRightClick(event, new PlayerDetails(event)); } else if (action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK) { customItem.onLeftClick(event, new PlayerDetails(event)); } } else { event.setCancelled(true); } } } } @EventHandler private void playerInteract(BlockBreakEvent event) { ItemStack item = event.getPlayer().getInventory().getItemInMainHand(); CustomItem customItem = CustomItemManager.getCustomItem(item); if (customItem != null) { if (verifyCustomItem(customItem, event.getPlayer(), false)) { customItem.onBlockBreak(event, new PlayerDetails(event)); } else { event.setCancelled(true); } } } @EventHandler private void playerInteractEntity(PlayerInteractEntityEvent event) { Player player = event.getPlayer(); ItemStack item = player.getInventory().getItemInMainHand(); CustomItem customItem = CustomItemManager.getCustomItem(item); if (customItem != null) { if (verifyCustomItem(customItem, event.getPlayer(), false)) { event.setCancelled(true); customItem.onInteractEntity(event, new PlayerDetails(item, event.getPlayer())); } } } @EventHandler private void playerInteractAtEntity(PlayerInteractAtEntityEvent event) { Player player = event.getPlayer(); ItemStack item = player.getInventory().getItemInMainHand(); CustomItem customItem = CustomItemManager.getCustomItem(item); if (customItem != null) { if (verifyCustomItem(customItem, event.getPlayer(), false)) { event.setCancelled(true); customItem.onInteractAtEntity(event, new PlayerDetails(item, event.getPlayer())); } } } @EventHandler private void entityDamageByEntity(EntityDamageByEntityEvent event) { Entity damager = event.getDamager(); if (damager instanceof Player) { Player player = (Player) damager; ItemStack item = player.getInventory().getItemInMainHand(); CustomItem customItem = CustomItemManager.getCustomItem(item); if (customItem != null) { if (verifyCustomItem(customItem, player, true)) { customItem.onAttack(event, new PlayerDetails(item, player)); } } } else { if (damager.hasMetadata("CustomItem-bow")) { Object[] data = (Object[]) damager.getMetadata("CustomItem-bow").get(0).value(); ((CustomBow) data[0]).onProjectileDamageEntity(event, (DelayedPlayerDetails) data[1]); } } } @EventHandler private void playerPickupItem(EntityPickupItemEvent event) { CustomItem customItem = CustomItemManager.getCustomItem(event.getItem().getItemStack()); Entity entity = event.getEntity(); if (entity instanceof Player && verifyCustomItem(customItem, (Player) entity, true)) { customItem.onPickup(event); } } @EventHandler private void playerDropItem(PlayerDropItemEvent event) { CustomItem customItem = CustomItemManager.getCustomItem(event.getItemDrop().getItemStack()); if (verifyCustomItem(customItem, event.getPlayer(), true)) { customItem.onDrop(event); } } @EventHandler private void itemDespawnItem(ItemDespawnEvent event) { CustomItem customItem = CustomItemManager.getCustomItem(event.getEntity().getItemStack()); if (verifyCustomItem(customItem, event.getEntity().getWorld())) { customItem.onDespawn(event); } } @EventHandler private void inventoryPickupItemItem(InventoryPickupItemEvent event) { CustomItem customItem = CustomItemManager.getCustomItem(event.getItem().getItemStack()); if (verifyCustomItem(customItem, event.getItem().getWorld())) { customItem.onDropperPickup(event); } } @EventHandler private void entityShootBow(EntityShootBowEvent event) { if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); CustomItem customItem = CustomItemManager.getCustomItem(event.getBow()); if (verifyCustomItem(customItem, player, false)) { DelayedPlayerDetails details = new DelayedPlayerDetails(event.getBow(), player); ((CustomBow) customItem).onShootBow(event, details); if (!event.isCancelled() && event.getProjectile() instanceof Projectile) { details.lock(); event.getProjectile().setMetadata("CustomItem-bow", new FixedMetadataValue(CustomItemManager._plugin, new Object[] { customItem, details })); } } } } @EventHandler private void projectileHit(ProjectileHitEvent event) { Projectile projectile = event.getEntity(); if (projectile.hasMetadata("CustomItem-bow")) { Object[] data = (Object[]) projectile.getMetadata("CustomItem-bow").get(0).value(); ((CustomBow) data[0]).onProjectileHit(event, (DelayedPlayerDetails) data[1]); } } @EventHandler private void blockDispense(BlockDispenseEvent event) { if (event.getBlock().getType() != Material.DISPENSER) { return; } CustomItem customItem = CustomItemManager.getCustomItem(event.getItem()); if (customItem != null) { if (verifyCustomItem(customItem, event.getBlock().getWorld())) { customItem.onDispense(event, new DispenserDetails(event, customItem._owner)); } else { event.setCancelled(true); } } } @EventHandler private void playerDeath(PlayerDeathEvent event) { Player player = event.getEntity(); for (ItemStack item : event.getDrops()) { CustomItem customItem = CustomItemManager.getCustomItem(item); if (verifyCustomItem(customItem, player, true)) { // This is very dirty, all "Details" classes need to be refactored. customItem.onPlayerDeath(event, new PlayerDetails(item, player) { @Override public void consumeItem() { if (_player.getGameMode() == GameMode.CREATIVE) return; _item.setAmount(_item.getAmount() - 1); } }); } } } }