Search in sources :

Example 31 with Wand

use of com.elmakers.mine.bukkit.wand.Wand in project MagicPlugin by elBukkit.

the class PlayerController method onPlayerDropItem.

@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
    final Player player = event.getPlayer();
    Mage mage = controller.getRegisteredMage(player);
    if (mage == null)
        return;
    // Catch lag-related glitches dropping items from GUIs
    if (mage.getActiveGUI() != null) {
        event.setCancelled(true);
        return;
    }
    final Wand activeWand = mage.getActiveWand();
    final ItemStack droppedItem = event.getItemDrop().getItemStack();
    boolean cancelEvent = false;
    ItemStack activeItem = activeWand == null ? null : activeWand.getItem();
    // It seems like Spigot sets the original item to air before dropping
    // We will be satisfied to only compare the metadata.
    ItemMeta activeMeta = activeItem == null ? null : activeItem.getItemMeta();
    ItemMeta droppedMeta = droppedItem.getItemMeta();
    boolean droppedWand = droppedMeta != null && activeMeta != null && activeItem.getItemMeta().equals(droppedItem.getItemMeta());
    if (droppedWand && activeWand.isUndroppable()) {
        // Postpone cycling until after this event unwinds
        Bukkit.getScheduler().scheduleSyncDelayedTask(controller.getPlugin(), new DropActionTask(activeWand));
        cancelEvent = true;
    } else if (activeWand != null) {
        if (droppedWand) {
            ItemStack mainhandItem = player.getInventory().getItemInMainHand();
            activeWand.deactivate();
            ItemStack restoredItem = player.getInventory().getItemInMainHand();
            ItemMeta restoredMeta = restoredItem == null ? null : restoredItem.getItemMeta();
            activeMeta = activeWand.getItem().getItemMeta();
            // Might have just saved some changes
            droppedItem.setItemMeta(activeMeta);
            // Clear after inventory restore (potentially with deactivate), since that will put the wand back
            if (Wand.hasActiveWand(player) && restoredItem.getType() != Material.AIR && restoredMeta != null && activeMeta.equals(restoredMeta)) {
                ItemStack newItem = player.getInventory().getItemInMainHand();
                if (mainhandItem.getAmount() > 0) {
                    newItem.setAmount(mainhandItem.getAmount());
                    player.getInventory().setItemInMainHand(newItem);
                } else {
                    player.getInventory().setItemInMainHand(new ItemStack(Material.AIR, 1));
                }
            }
        } else if (activeWand.isInventoryOpen()) {
            if (!controller.isSpellDroppingEnabled()) {
                cancelEvent = true;
                // This will happen if you graph an item, change pages, and then drop the item- it would disappear
                // from the inventory until reload.
                // Check for this state and prevent it.
                boolean isInventoryFull = true;
                PlayerInventory playerInventory = player.getInventory();
                for (int i = 0; i < Wand.PLAYER_INVENTORY_SIZE; i++) {
                    ItemStack item = playerInventory.getItem(i);
                    if (item == null || item.getType() == Material.AIR) {
                        isInventoryFull = false;
                        break;
                    }
                }
                if (isInventoryFull) {
                    activeWand.addToInventory(droppedItem);
                }
            } else {
                // The item is already removed from the wand's inventory, but that should be ok
                controller.removeItemFromWand(activeWand, droppedItem);
            }
        }
    }
    if (!cancelEvent) {
        cancelEvent = InventoryUtils.getMetaBoolean(droppedItem, "undroppable", false);
    }
    if (cancelEvent) {
        if (droppedWand) {
            activeWand.setItem(droppedItem);
        }
        event.setCancelled(true);
    }
}
Also used : DropActionTask(com.elmakers.mine.bukkit.magic.DropActionTask) Player(org.bukkit.entity.Player) Mage(com.elmakers.mine.bukkit.magic.Mage) Wand(com.elmakers.mine.bukkit.wand.Wand) PlayerInventory(org.bukkit.inventory.PlayerInventory) ItemStack(org.bukkit.inventory.ItemStack) ItemMeta(org.bukkit.inventory.meta.ItemMeta) EventHandler(org.bukkit.event.EventHandler)

Example 32 with Wand

use of com.elmakers.mine.bukkit.wand.Wand in project MagicPlugin by elBukkit.

the class PlayerController method onProjectileLaunch.

@EventHandler
public void onProjectileLaunch(ProjectileLaunchEvent event) {
    if (launching || event.isCancelled())
        return;
    Projectile projectile = event.getEntity();
    ProjectileSource shooter = projectile.getShooter();
    // Not really handling magic mobs with magic bows...
    if (!(shooter instanceof Player))
        return;
    Player player = (Player) shooter;
    Mage mage = controller.getRegisteredMage(player);
    if (mage == null)
        return;
    Wand wand = mage.getActiveWand();
    if (wand == null)
        return;
    if (wand.getIcon().getMaterial() != Material.BOW)
        return;
    double minPull = wand.getDouble("cast_min_bowpull");
    double pull = Math.min(1.0, projectile.getVelocity().length() / MAX_ARROW_SPEED);
    if (minPull > 0 && pull < minPull) {
        if (wand.isInventoryOpen())
            event.setCancelled(true);
        return;
    }
    Spell spell = wand.getActiveSpell();
    if (spell == null) {
        if (wand.isInventoryOpen())
            event.setCancelled(true);
        return;
    }
    event.setCancelled(true);
    String[] parameters = { "bowpull", Double.toString(pull) };
    // prevent recursion!
    launching = true;
    try {
        wand.cast(parameters);
    } catch (Exception ex) {
        controller.getLogger().log(Level.SEVERE, "Error casting bow spell", ex);
    }
    launching = false;
}
Also used : Player(org.bukkit.entity.Player) Mage(com.elmakers.mine.bukkit.magic.Mage) Wand(com.elmakers.mine.bukkit.wand.Wand) ProjectileSource(org.bukkit.projectiles.ProjectileSource) Spell(com.elmakers.mine.bukkit.api.spell.Spell) Projectile(org.bukkit.entity.Projectile) EventHandler(org.bukkit.event.EventHandler)

Example 33 with Wand

use of com.elmakers.mine.bukkit.wand.Wand in project MagicPlugin by elBukkit.

the class AnvilController method onInventoryClick.

@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
    if (event.isCancelled())
        return;
    if (!(event.getWhoClicked() instanceof Player))
        return;
    InventoryType inventoryType = event.getInventory().getType();
    SlotType slotType = event.getSlotType();
    Player player = (Player) event.getWhoClicked();
    Mage mage = controller.getMage(player);
    if (inventoryType == InventoryType.ANVIL) {
        ItemStack cursor = event.getCursor();
        ItemStack current = event.getCurrentItem();
        Inventory anvilInventory = event.getInventory();
        InventoryAction action = event.getAction();
        ItemStack firstItem = anvilInventory.getItem(0);
        ItemStack secondItem = anvilInventory.getItem(1);
        // Handle direct movement
        if (action == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
            if (!Wand.isWand(current))
                return;
            // Moving from anvil back to inventory
            if (slotType == SlotType.CRAFTING) {
                Wand wand = controller.getWand(current);
                wand.updateName(true);
            } else if (slotType == SlotType.RESULT) {
                // Don't allow combining
                if (!combiningEnabled) {
                    if (firstItem != null && secondItem != null) {
                        event.setCancelled(true);
                        return;
                    }
                }
                // Taking from result slot
                ItemMeta meta = current.getItemMeta();
                String newName = meta.getDisplayName();
                Wand wand = controller.getWand(current);
                if (!wand.canUse(player)) {
                    event.setCancelled(true);
                    mage.sendMessage(controller.getMessages().get("wand.bound").replace("$name", wand.getOwner()));
                    return;
                }
                wand.setName(newName);
                if (organizingEnabled) {
                    wand.organizeInventory(controller.getMage(player));
                }
                wand.tryToOwn(player);
            } else {
                // Moving from inventory to anvil
                Wand wand = controller.getWand(current);
                wand.updateName(false);
            }
            return;
        }
        // Set/unset active names when starting to craft
        if (slotType == SlotType.CRAFTING) {
            // Putting a wand into the anvil's crafting slot
            if (Wand.isWand(cursor)) {
                Wand wand = controller.getWand(cursor);
                wand.updateName(false);
            }
            // Taking a wand out of the anvil's crafting slot
            if (Wand.isWand(current)) {
                Wand wand = controller.getWand(current);
                if (clearDescriptionOnRename) {
                    wand.setDescription("");
                }
                wand.updateName(true);
                if (event.getWhoClicked() instanceof Player) {
                    wand.tryToOwn((Player) event.getWhoClicked());
                }
            }
            return;
        }
        // Rename wand when taking from result slot
        if (slotType == SlotType.RESULT && Wand.isWand(current)) {
            if (!combiningEnabled) {
                if (firstItem != null && secondItem != null) {
                    event.setCancelled(true);
                    return;
                }
            }
            ItemMeta meta = current.getItemMeta();
            String newName = meta.getDisplayName();
            Wand wand = controller.getWand(current);
            if (!wand.canUse(player)) {
                event.setCancelled(true);
                mage.sendMessage(controller.getMessages().get("wand.bound").replace("$name", wand.getOwner()));
                return;
            }
            wand.setName(newName);
            if (organizingEnabled) {
                wand.organizeInventory(controller.getMage(player));
            }
            wand.tryToOwn(player);
            return;
        }
        if (combiningEnabled && slotType == SlotType.RESULT) {
            // I guess I need to wait for the long-awaited anvil API?
            if (Wand.isWand(firstItem) && Wand.isWand(secondItem)) {
                Wand firstWand = controller.getWand(firstItem);
                Wand secondWand = controller.getWand(secondItem);
                if (!firstWand.isModifiable() || !secondWand.isModifiable()) {
                    mage.sendMessage("One of your wands can not be combined");
                    return;
                }
                if (!firstWand.canUse(player) || !secondWand.canUse(player)) {
                    mage.sendMessage("One of those wands is not bound to you");
                    return;
                }
                if (!firstWand.add(secondWand)) {
                    mage.sendMessage("These wands can not be combined with each other");
                    return;
                }
                anvilInventory.setItem(0, null);
                anvilInventory.setItem(1, null);
                cursor.setType(Material.AIR);
                if (organizingEnabled) {
                    firstWand.organizeInventory(mage);
                }
                firstWand.tryToOwn(player);
                player.getInventory().addItem(firstWand.getItem());
                mage.sendMessage("Your wands have been combined!");
            // This seems to work in the debugger, but.. doesn't do anything.
            // InventoryUtils.setInventoryResults(anvilInventory, newWand.getItem());
            } else if (organizingEnabled && Wand.isWand(firstItem)) {
                Wand firstWand = controller.getWand(firstItem);
                // TODO: Can't get the anvil's text from here.
                anvilInventory.setItem(0, null);
                anvilInventory.setItem(1, null);
                cursor.setType(Material.AIR);
                firstWand.organizeInventory(mage);
                firstWand.tryToOwn(player);
                player.getInventory().addItem(firstWand.getItem());
                mage.sendMessage("Your wand has been organized!");
            }
            return;
        }
    }
}
Also used : Player(org.bukkit.entity.Player) InventoryType(org.bukkit.event.inventory.InventoryType) Mage(com.elmakers.mine.bukkit.api.magic.Mage) Wand(com.elmakers.mine.bukkit.wand.Wand) ItemStack(org.bukkit.inventory.ItemStack) Inventory(org.bukkit.inventory.Inventory) ItemMeta(org.bukkit.inventory.meta.ItemMeta) SlotType(org.bukkit.event.inventory.InventoryType.SlotType) InventoryAction(org.bukkit.event.inventory.InventoryAction) EventHandler(org.bukkit.event.EventHandler)

Example 34 with Wand

use of com.elmakers.mine.bukkit.wand.Wand in project MagicPlugin by elBukkit.

the class EnchantingController method onEnchantItem.

@EventHandler
public void onEnchantItem(EnchantItemEvent event) {
    if (enchantingEnabled && Wand.isWand(event.getItem())) {
        Player player = event.getEnchanter();
        if (player == null || !controller.hasPermission(player, "Magic.wand.enchant")) {
            event.setCancelled(true);
            return;
        }
        event.getEnchantsToAdd().clear();
        int level = event.getExpLevelCost();
        Wand wand = controller.getWand(event.getItem());
        if (wand.enchant(level, controller.getMage(event.getEnchanter())) <= 0) {
            event.setCancelled(true);
        } else {
            event.setCancelled(false);
            // This is necessary due to a special-case check Bukkit added in
            // https://github.com/Bukkit/CraftBukkit/commit/ac1a2d0233eff169efcc7c807cbf799b57bf2306
            // This will skip deducting XP costs (!!) if you don't return something to add to the item
            // Unfortunately, adding an enchant to the item is going to blow away its data, soooo...
            // 
            // This is kind of an "FU" to this particular commit, in that it will trigger an NPE
            // in NMS code that will get silently eaten, but avoid modifying the resultant ItemStack.
            // :P
            event.getEnchantsToAdd().put(null, 0);
        }
        wand.makeEnchantable(true);
    }
}
Also used : Player(org.bukkit.entity.Player) Wand(com.elmakers.mine.bukkit.wand.Wand) EventHandler(org.bukkit.event.EventHandler)

Example 35 with Wand

use of com.elmakers.mine.bukkit.wand.Wand in project MagicPlugin by elBukkit.

the class EnchantingController method onPrepareEnchantItem.

@EventHandler
public void onPrepareEnchantItem(PrepareItemEnchantEvent event) {
    if (Wand.isWand(event.getItem())) {
        if (!enchantingEnabled) {
            event.setCancelled(true);
            return;
        }
        Player player = event.getEnchanter();
        if (player == null || !controller.hasPermission(player, "Magic.wand.enchant")) {
            event.setCancelled(true);
            return;
        }
        Wand wandItem = controller.getWand(event.getItem());
        if (!wandItem.isModifiable() && wandItem.getPath() == null) {
            event.setCancelled(true);
            return;
        }
        if (controller.isSPEnabled() && wandItem.hasSpellProgression()) {
            event.setCancelled(true);
            return;
        }
        if (!wandItem.canUse(player)) {
            event.setCancelled(true);
            return;
        }
        wandItem.makeEnchantable(true);
        WandUpgradePath path = wandItem.getPath();
        if (path == null) {
            event.setCancelled(true);
            return;
        }
        int minLevel = path.getMinLevel();
        int maxLevel = path.getMaxLevel();
        int levelRange = maxLevel - minLevel;
        int[] offered = event.getExpLevelCostsOffered();
        float bonusLevelMultiplier = path.getBonusLevelMultiplier();
        int bonusLevels = event.getEnchantmentBonus();
        for (int i = 0; i < offered.length; i++) {
            int level = minLevel + (int) ((float) i * levelRange / offered.length);
            if (bonusLevels > 0 && bonusLevelMultiplier > 0) {
                level = (int) (level + bonusLevels * bonusLevelMultiplier);
            }
            offered[i] = level;
        }
        event.setCancelled(false);
    }
}
Also used : WandUpgradePath(com.elmakers.mine.bukkit.wand.WandUpgradePath) Player(org.bukkit.entity.Player) Wand(com.elmakers.mine.bukkit.wand.Wand) EventHandler(org.bukkit.event.EventHandler)

Aggregations

Wand (com.elmakers.mine.bukkit.wand.Wand)36 Player (org.bukkit.entity.Player)24 ItemStack (org.bukkit.inventory.ItemStack)23 EventHandler (org.bukkit.event.EventHandler)17 LostWand (com.elmakers.mine.bukkit.api.wand.LostWand)11 Mage (com.elmakers.mine.bukkit.magic.Mage)11 PlayerInventory (org.bukkit.inventory.PlayerInventory)6 Spell (com.elmakers.mine.bukkit.api.spell.Spell)5 Nullable (javax.annotation.Nullable)5 LostWand (com.elmakers.mine.bukkit.wand.LostWand)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Inventory (org.bukkit.inventory.Inventory)4 GUIAction (com.elmakers.mine.bukkit.api.action.GUIAction)3 Messages (com.elmakers.mine.bukkit.api.magic.Messages)3 Location (org.bukkit.Location)3 Block (org.bukkit.block.Block)3 Entity (org.bukkit.entity.Entity)3 Item (org.bukkit.entity.Item)3