Package net.aufdemrand.denizen.events.core

Source Code of net.aufdemrand.denizen.events.core.PlayerEquipsArmorSmartEvent

package net.aufdemrand.denizen.events.core;

import net.aufdemrand.denizen.events.EventManager;
import net.aufdemrand.denizen.events.SmartEvent;
import net.aufdemrand.denizen.objects.*;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.Utilities;
import net.aufdemrand.denizen.utilities.debugging.dB;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
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.block.BlockDispenseEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PlayerEquipsArmorSmartEvent implements SmartEvent, Listener {


    ///////////////////
    // SMARTEVENT METHODS
    ///////////////


    @Override
    public boolean shouldInitialize(Set<String> events) {

        // Loop through event names from loaded world script events
        for (String event : events) {

            // Use a regex pattern to narrow down matches
            Matcher m = Pattern.compile("on player (un)?equips ((m@|i@)?\\w+)", Pattern.CASE_INSENSITIVE)
                    .matcher(event);

            if (m.matches()) {
                String string = m.group(2);
                if (string.equalsIgnoreCase("armor")
                        || string.equalsIgnoreCase("helmet")
                        || string.equalsIgnoreCase("chestplate")
                        || string.equalsIgnoreCase("leggings")
                        || string.equalsIgnoreCase("boots"))
                    return true;
                else if (dMaterial.matches(string)) {
                    dMaterial material = dMaterial.valueOf(string);
                    if (material != null)
                        return isArmor(material.getMaterial());
                }
                else if (dItem.matches(string)) {
                    dItem item = dItem.valueOf(string);
                    if (item != null)
                        return isArmor(item.getItemStack());
                }
            }
        }
        // No matches at all, just fail.
        return false;
    }


    @Override
    public void _initialize() {
        DenizenAPI.getCurrentInstance().getServer().getPluginManager()
                .registerEvents(this, DenizenAPI.getCurrentInstance());
        dB.log("Loaded Player Equips Armor SmartEvent.");
    }


    @Override
    public void breakDown() {
        PlayerInteractEvent.getHandlerList().unregister(this);
        InventoryClickEvent.getHandlerList().unregister(this);
        InventoryDragEvent.getHandlerList().unregister(this);
        BlockDispenseEvent.getHandlerList().unregister(this);
    }


    //////////////
    //  MECHANICS
    ///////////

    @EventHandler
    public void blockDispense(BlockDispenseEvent event) {
        final ItemStack item = event.getItem();
        final Location location = event.getBlock().getLocation();

        if (isArmor(item)) {
            for (final Player player : location.getWorld().getPlayers()) {
                if (Utilities.checkLocation(player, location, 2.5)) {
                    final ItemStack[] armor_contents = player.getInventory().getArmorContents().clone();
                    final Vector velocity = event.getVelocity();
                    new BukkitRunnable() {
                        @Override
                        public void run() {
                            ItemStack[] new_armor = player.getInventory().getArmorContents();
                            for (int i = 0; i < new_armor.length; i++) {
                                ItemStack before = armor_contents[i];
                                ItemStack now = new_armor[i];
                                if (now != null && now.getType() == item.getType()
                                        && now.getDurability() == item.getDurability()
                                        && (before == null || before.getType() == Material.AIR)) {
                                    if (playerEquipsArmorEvent(player, item, "DISPENSER")) {
                                        location.getWorld().dropItemNaturally(location, item).setVelocity(velocity);
                                        armor_contents[i] = null;
                                        player.getInventory().setArmorContents(armor_contents);
                                    }
                                }
                            }
                        }
                    }.runTaskLater(DenizenAPI.getCurrentInstance(), 0); // Yes, 0 is correct.
                }
            }
        }
    }

    @EventHandler
    public void inventoryClick(InventoryClickEvent event) {
        Inventory inventory = event.getInventory();
        if (!didPlayerClickOwnInventory((Player) event.getWhoClicked(), inventory))
            return;
        ItemStack item = event.getCurrentItem();
        Player player = (Player) inventory.getHolder();
        ItemStack cursor = event.getCursor();
        if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
            if (item != null && item.getType() != Material.AIR
                    && (cursor == null || cursor.getType() == Material.AIR || isArmor(cursor))) {
                if (playerUnequipsArmorEvent(player, item, "INVENTORY")) {
                    event.setCancelled(true);
                    return;
                }
            }
            if (cursor != null && cursor.getType() != Material.AIR && isArmor(cursor)) {
                if (playerEquipsArmorEvent(player, cursor, "INVENTORY")) {
                    event.setCancelled(true);
                    return;
                }
            }
        }
        else if (event.getClick().isShiftClick() && item != null && isArmor(item)) {
            ItemStack currentItem = player.getInventory().getArmorContents()[getArmorTypeNumber(item)];
            if (currentItem == null || currentItem.getType() == Material.AIR) {
                if (playerEquipsArmorEvent(player, item, "INVENTORY")) {
                    event.setCancelled(true);
                    return;
                }
            }
        }
    }

    @EventHandler
    public void inventoryDrag(InventoryDragEvent event) {
        Inventory inventory = event.getInventory();
        if (!didPlayerClickOwnInventory((Player) event.getWhoClicked(), inventory))
            return;
        ItemStack item = event.getOldCursor();
        Player player = (Player) inventory.getHolder();
        if (!isArmor(item)) return;
        int[] armor_slots = new int[]{5,6,7,8};
        Set<Integer> slots = event.getRawSlots();
        for (int slot : armor_slots) {
            if (slots.contains(slot) && (slot-5 == getArmorTypeNumber(item))) {
                ItemStack before = inventory.getItem(slot);
                if (before == null || before.getType() == Material.AIR) {
                    if (playerEquipsArmorEvent(player, item, "INVENTORY")) {
                        event.setCancelled(true);
                        return;
                    }
                }
            }
        }
    }

    @EventHandler
    public void playerInteract(PlayerInteractEvent event) {
        if (event.hasItem()) {
            ItemStack item = event.getItem();
            Action action = event.getAction();
            Block clicked = event.getClickedBlock();
            if ((action != Action.RIGHT_CLICK_AIR && action != Action.RIGHT_CLICK_BLOCK)
                    || !isArmor(item) || (clicked != null && isInteractive(clicked.getType())))
                return;
            ItemStack currentItem = event.getPlayer().getInventory().getArmorContents()[getArmorTypeNumber(item)];
            if (currentItem == null || currentItem.getType() == Material.AIR) {
                Player player = event.getPlayer();
                if (playerEquipsArmorEvent(player, item, "INTERACT")) {
                    event.setCancelled(true);
                    return;
                }
            }
        }
    }

    @EventHandler
    public void entityDamage(EntityDamageEvent event) {
        Entity entity = event.getEntity();
        if (!(entity instanceof Player))
            return;
        final Player player = (Player) entity;
        final ItemStack[] oldArmor = player.getInventory().getArmorContents();
        new BukkitRunnable() {
            @Override
            public void run() {
                ItemStack[] newArmor = player.getInventory().getArmorContents();
                for (int i = 0; i < 4; i++) {
                    ItemStack o = oldArmor[i];
                    ItemStack n = newArmor[i];
                    if (o != null) {
                        if (n == null || !n.equals(o)) {
                            if (playerUnequipsArmorEvent(player, o, "BREAK")) {
                                newArmor[i] = o;
                            }
                        }
                    }
                    player.getInventory().setArmorContents(newArmor);
                }
            }
        }.runTaskLater(DenizenAPI.getCurrentInstance(), 1);
    }

    private boolean isArmor(ItemStack itemStack) {
        int id = itemStack.getTypeId();
        return id >= 298 && id <= 317;
    }

    private boolean isArmor(Material material) {
        int id = material.getId();
        return id >= 298 && id <= 317;
    }

    private boolean didPlayerClickOwnInventory(Player player, Inventory inventory) {
        InventoryHolder holder = inventory.getHolder();
        InventoryType type = inventory.getType();
        return holder != null
                && holder.equals(player)
                && type != InventoryType.ENDER_CHEST
                && type != InventoryType.WORKBENCH;
    }

    private int getArmorTypeNumber(ItemStack itemStack) {
        return (itemStack.getTypeId()-298)%4;
    }
   
    private String getArmorType(ItemStack itemStack) {
        if (!isArmor(itemStack))
            return "helmet";
        switch (getArmorTypeNumber(itemStack)) {
            case 0:
                return "helmet";
            case 1:
                return "chestplate";
            case 2:
                return "leggings";
            case 3:
                return "boots";
        }
        return null;
    }

    private boolean isInteractive(Material material) {
        if (material == null || !material.isBlock()) {
            return false;
        }
        switch (material) {
            case DISPENSER:
            case NOTE_BLOCK:
            case BED_BLOCK:
            case CHEST:
            case WORKBENCH:
            case FURNACE:
            case BURNING_FURNACE:
            case WOODEN_DOOR:
            case LEVER:
            case REDSTONE_ORE:
            case STONE_BUTTON:
            case JUKEBOX:
            case CAKE_BLOCK:
            case DIODE_BLOCK_ON:
            case DIODE_BLOCK_OFF:
            case TRAP_DOOR:
            case FENCE_GATE:
            case ENCHANTMENT_TABLE:
            case BREWING_STAND:
            case DRAGON_EGG:
            case ENDER_CHEST:
            case COMMAND:
            case BEACON:
            case WOOD_BUTTON:
            case ANVIL:
            case TRAPPED_CHEST:
            case REDSTONE_COMPARATOR_ON:
            case REDSTONE_COMPARATOR_OFF:
            case HOPPER:
            case DROPPER:
                return true;
            default:
                return false;
        }
    }

    // <--[event]
    // @Events
    // player (un)equips armor
    // player (un)equips <item>
    // player (un)equips [helmet/chestplate/leggings/boots]
    //
    // @Regex on player (un)equips (m@|i@)?\w+
    //
    // @Triggers when a player (un)equips armor.
    // @Context
    // <context.armor> returns the dItem that was (un)equipped.
    // <context.reason> returns the reason that the armor was (un)equipped. Can be "INVENTORY", "INTERACT", "DISPENSER", or "BREAK".
    //
    // @Determine
    // "CANCELLED" to stop the armor from being (un)equipped.
    // -->
    private boolean playerEquipsArmorEvent(final Player player, final ItemStack item, String reason) {

        dItem armor = new dItem(item);

        Map<String, dObject> context = new HashMap<String, dObject>();
        context.put("armor", armor);
        context.put("reason", new Element(reason));

        String determination = EventManager.doEvents(Arrays.asList
                        ("player equips armor",
                                "player equips " + getArmorType(item),
                                "player equips " + armor.identifySimple(),
                                "player equips " + armor.identifyMaterial()),
                null, new dPlayer(player), context).toUpperCase();

        if (determination.startsWith("CANCELLED")) {
            new BukkitRunnable() {
                @Override
                public void run() {
                    player.updateInventory();
                }
            }.runTaskLater(DenizenAPI.getCurrentInstance(), 1);
            return true;
        }

        return false;

    }

    private boolean playerUnequipsArmorEvent(final Player player, final ItemStack item, String reason) {

        dItem armor = new dItem(item);

        Map<String, dObject> context = new HashMap<String, dObject>();
        context.put("armor", armor);
        context.put("reason", new Element(reason));

        String determination = EventManager.doEvents(Arrays.asList
                        ("player unequips armor",
                                "player unequips " + getArmorType(item),
                                "player unequips " + armor.identifySimple(),
                                "player unequips " + armor.identifyMaterial()),
                null, new dPlayer(player), context).toUpperCase();

        if (determination.startsWith("CANCELLED")) {
            new BukkitRunnable() {
                @Override
                public void run() {
                    player.updateInventory();
                }
            }.runTaskLater(DenizenAPI.getCurrentInstance(), 1);
            return true;
        }

        return false;
       
    }
}
TOP

Related Classes of net.aufdemrand.denizen.events.core.PlayerEquipsArmorSmartEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.