Search in sources :

Example 31 with Spell

use of com.elmakers.mine.bukkit.api.spell.Spell in project MagicPlugin by elBukkit.

the class WandOrganizer method organize.

public void organize() {
    Map<String, Integer> spells = wand.getSpellInventory();
    Map<String, Integer> brushes = wand.getBrushInventory();
    removeHotbar(spells, brushes);
    // Collect favorite spells
    MageController controller = wand.getController();
    TreeMap<Long, List<String>> favoriteSpells = new TreeMap<>();
    Map<String, Collection<String>> groupedSpells = new TreeMap<>();
    for (String spellName : spells.keySet()) {
        Spell mageSpell = mage == null ? null : mage.getSpell(spellName);
        SpellTemplate spell = mageSpell == null ? controller.getSpellTemplate(spellName) : mageSpell;
        if (spell != null) {
            // Sum up all levels of this spell:
            long castCount = 0;
            int spellLevel = 1;
            while (mageSpell != null) {
                castCount += mageSpell.getCastCount();
                spellLevel++;
                SpellKey spellKey = new SpellKey(spellName, spellLevel);
                String key = spellKey.getKey();
                mageSpell = mage.hasSpell(key) ? mage.getSpell(key) : null;
            }
            spellName = spell.getSpellKey().getBaseKey();
            if (castCount > favoriteCastCountThreshold) {
                List<String> favorites = null;
                if (!favoriteSpells.containsKey(castCount)) {
                    favorites = new ArrayList<>();
                    favoriteSpells.put(castCount, favorites);
                } else {
                    favorites = favoriteSpells.get(castCount);
                }
                favorites.add(spellName);
            }
            SpellCategory spellCategory = spell.getCategory();
            String category = spellCategory == null ? null : spellCategory.getKey();
            if (category == null || category.length() == 0) {
                category = "default";
            }
            Collection<String> spellList = groupedSpells.get(category);
            if (spellList == null) {
                spellList = new TreeSet<>();
                groupedSpells.put(category, spellList);
            }
            spellList.add(spellName);
        }
    }
    Map<String, String> materials = new TreeMap<>();
    if (wand.getBrushMode() == WandMode.INVENTORY) {
        for (String materialKey : brushes.keySet()) {
            if (MaterialBrush.isSpecialMaterialKey(materialKey)) {
                materials.put(" " + materialKey, materialKey);
            } else {
                materials.put(materialKey, materialKey);
            }
        }
    }
    currentInventoryIndex = 0;
    currentInventoryCount = 0;
    // Organize favorites
    WandMode mode = wand.getMode();
    Set<String> addedFavorites = new HashSet<>();
    List<String> favoriteList = new ArrayList<>();
    int favoritePageSize = wand.getInventorySize() - favoritePageBuffer;
    for (List<String> favorites : favoriteSpells.descendingMap().values()) {
        if (addedFavorites.size() >= favoritePageSize)
            break;
        for (String spellName : favorites) {
            addedFavorites.add(spellName);
            favoriteList.add(spellName);
            if (addedFavorites.size() >= favoritePageSize)
                break;
        }
    }
    if (addedFavorites.size() > 0) {
        for (String favorite : favoriteList) {
            int slot = getNextSlot();
            spells.put(favorite, slot);
        }
        if (mode != WandMode.CHEST && addedFavorites.size() > wand.getInventorySize() - favoriteCountBuffer) {
            nextPage();
        }
    } else {
        addedFavorites.clear();
    }
    // Add unused spells by category
    int inventoryOrganizeNewGroupSize = wand.getInventorySize() - inventoryOrganizeNewGroupBuffer;
    for (Collection<String> spellGroup : groupedSpells.values()) {
        // Start a new inventory for a new group if the previous inventory is over 2/3 full
        if (mode != WandMode.CHEST && currentInventoryCount > inventoryOrganizeNewGroupSize) {
            nextPage();
        }
        for (String spellName : spellGroup) {
            if (!addedFavorites.contains(spellName)) {
                int slot = getNextSlot();
                spells.put(spellName, slot);
            }
        }
    }
    if (materials.size() > 0) {
        nextPage();
        for (String materialName : materials.values()) {
            brushes.put(materialName, getNextSlot());
        }
    }
    wand.updateSpellInventory(spells);
    if (materials.size() > 0) {
        wand.updateBrushInventory(brushes);
    }
}
Also used : SpellCategory(com.elmakers.mine.bukkit.api.spell.SpellCategory) ArrayList(java.util.ArrayList) Spell(com.elmakers.mine.bukkit.api.spell.Spell) SpellKey(com.elmakers.mine.bukkit.api.spell.SpellKey) MageController(com.elmakers.mine.bukkit.api.magic.MageController) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) TreeMap(java.util.TreeMap) Collection(java.util.Collection) SpellTemplate(com.elmakers.mine.bukkit.api.spell.SpellTemplate)

Example 32 with Spell

use of com.elmakers.mine.bukkit.api.spell.Spell in project MagicPlugin by elBukkit.

the class WandUpgradePath method checkUpgradeRequirements.

@Override
public boolean checkUpgradeRequirements(com.elmakers.mine.bukkit.api.wand.Wand wand, com.elmakers.mine.bukkit.api.magic.Mage mage) {
    if (requiredSpells == null || requiredSpells.isEmpty())
        return true;
    // Then check for spell requirements to advance
    for (PrerequisiteSpell prereq : requiredSpells) {
        if (!wand.hasSpell(prereq.getSpellKey())) {
            SpellTemplate spell = wand.getController().getSpellTemplate(prereq.getSpellKey().getKey());
            if (spell == null) {
                wand.getController().getLogger().warning("Invalid spell required for upgrade: " + prereq.getSpellKey().getKey());
                return false;
            }
            if (mage != null) {
                String requiredSpellMessage = getMessage(wand.getController().getMessages(), "required_spell");
                String message = requiredSpellMessage.replace("$spell", spell.getName());
                com.elmakers.mine.bukkit.api.wand.WandUpgradePath upgradePath = getUpgrade();
                if (upgradePath != null) {
                    message = message.replace("$path", upgradePath.getName());
                }
                mage.sendMessage(message);
            }
            return false;
        } else if (mage != null) {
            Spell spell = wand.getSpell(prereq.getSpellKey().getKey(), mage);
            if (!PrerequisiteSpell.isSpellSatisfyingPrerequisite(spell, prereq)) {
                if (spell != null) {
                    String message = getMessage(wand.getController().getMessages(), "spell.prerequisite_spell_level").replace("$name", spell.getName()).replace("$level", Integer.toString(prereq.getSpellKey().getLevel()));
                    if (prereq.getProgressLevel() > 1) {
                        message += getMessage(wand.getController().getMessages(), "spell.prerequisite_spell_progress_level").replace("$level", Long.toString(prereq.getProgressLevel())).replace("$max_level", Long.toString(Math.max(1, spell.getMaxProgressLevel())));
                    }
                    mage.sendMessage(message);
                }
                return false;
            }
        }
    }
    return true;
}
Also used : PrerequisiteSpell(com.elmakers.mine.bukkit.api.spell.PrerequisiteSpell) Spell(com.elmakers.mine.bukkit.api.spell.Spell) PrerequisiteSpell(com.elmakers.mine.bukkit.api.spell.PrerequisiteSpell) SpellTemplate(com.elmakers.mine.bukkit.api.spell.SpellTemplate)

Example 33 with Spell

use of com.elmakers.mine.bukkit.api.spell.Spell in project MagicPlugin by elBukkit.

the class ActionBatch method process.

@Override
public int process(int maxBlocks) {
    if (finished)
        return 0;
    Spell spell = context.getSpell();
    if (spell != null && spell.cancelOnNoPermission() && !context.canCast(context.getLocation())) {
        spell.cancel();
        finish();
        return 0;
    }
    context.setWorkAllowed(maxBlocks);
    handler.perform(context);
    if (handler.isFinished() && !context.hasHandlers()) {
        finish();
    }
    return maxBlocks - context.getWorkAllowed();
}
Also used : Spell(com.elmakers.mine.bukkit.api.spell.Spell)

Example 34 with Spell

use of com.elmakers.mine.bukkit.api.spell.Spell in project MagicPlugin by elBukkit.

the class AutomatonLevel method castSpell.

protected void castSpell(String spellCommand, Mage mage, MaterialAndData birthMaterial) {
    if (spellCommand == null || spellCommand.length() == 0 || spellCommand.equals("none"))
        return;
    spellCommand = spellCommand + " " + spellParameters;
    String[] pieces = null;
    if (spellCommand.contains(" ")) {
        pieces = StringUtils.split(spellCommand, ' ');
        spellCommand = pieces[0];
    }
    String[] parameters = null;
    if (pieces != null && pieces.length > 1 && birthMaterial != null && birthMaterial.getMaterial() != null) {
        parameters = new String[pieces.length - 1];
        for (int i = 1; i < pieces.length; i++) {
            parameters[i - 1] = pieces[i].replace("$birth", birthMaterial.getMaterial().name().toLowerCase());
        }
    }
    if (SimulateBatch.DEBUG) {
        mage.getController().getLogger().info("Casting " + spellCommand + " " + StringUtils.join(parameters, ' '));
    }
    Spell spell = mage.getSpell(spellCommand);
    if (spell != null) {
        spell.cast(parameters);
    }
}
Also used : Spell(com.elmakers.mine.bukkit.api.spell.Spell)

Example 35 with Spell

use of com.elmakers.mine.bukkit.api.spell.Spell in project MagicPlugin by elBukkit.

the class InventoryController method onInventoryClick.

@SuppressWarnings("deprecation")
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
    if (event.isCancelled())
        return;
    if (!(event.getWhoClicked() instanceof Player))
        return;
    Player player = (Player) event.getWhoClicked();
    final Mage mage = controller.getMage(player);
    GUIAction gui = mage.getActiveGUI();
    if (gui != null) {
        gui.clicked(event);
        return;
    }
    // Check for temporary items and skill items
    InventoryAction action = event.getAction();
    InventoryType inventoryType = event.getInventory().getType();
    boolean isPlayerInventory = inventoryType == InventoryType.CRAFTING || inventoryType == InventoryType.PLAYER;
    ItemStack clickedItem = event.getCurrentItem();
    boolean isDrop = event.getClick() == ClickType.DROP || event.getClick() == ClickType.CONTROL_DROP;
    boolean isSkill = clickedItem != null && Wand.isSkill(clickedItem);
    // Check for right-click-to-use
    boolean isRightClick = action == InventoryAction.PICKUP_HALF;
    if (isSkill && isRightClick) {
        mage.useSkill(clickedItem);
        player.closeInventory();
        event.setCancelled(true);
        return;
    }
    if (clickedItem != null && NMSUtils.isTemporary(clickedItem)) {
        String message = NMSUtils.getTemporaryMessage(clickedItem);
        if (message != null && message.length() > 1) {
            mage.sendMessage(message);
        }
        ItemStack replacement = NMSUtils.getReplacement(clickedItem);
        event.setCurrentItem(replacement);
        event.setCancelled(true);
        return;
    }
    // Check for wearing spells
    ItemStack heldItem = event.getCursor();
    boolean heldSpell = Wand.isSpell(heldItem);
    if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
        if (heldSpell) {
            event.setCancelled(true);
            return;
        }
        if (Wand.isWand(clickedItem) || Wand.isWand(heldItem)) {
            controller.onArmorUpdated(mage);
        }
    }
    boolean isHotbar = event.getAction() == InventoryAction.HOTBAR_SWAP || event.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD;
    if (isHotbar && event.getSlotType() == InventoryType.SlotType.ARMOR) {
        int slot = event.getHotbarButton();
        ItemStack item = mage.getPlayer().getInventory().getItem(slot);
        if (item != null && Wand.isSpell(item)) {
            event.setCancelled(true);
            return;
        }
        controller.onArmorUpdated(mage);
    }
    Wand activeWand = mage.getActiveWand();
    boolean isWandInventoryOpen = activeWand != null && activeWand.isInventoryOpen();
    // Preventing putting skills in containers
    if (isSkill && !isPlayerInventory && !isWandInventoryOpen) {
        if (!isDrop) {
            event.setCancelled(true);
        }
        return;
    }
    boolean isFurnace = inventoryType == InventoryType.FURNACE;
    boolean isChest = inventoryType == InventoryType.CHEST || inventoryType == InventoryType.HOPPER || inventoryType == InventoryType.DISPENSER || inventoryType == InventoryType.DROPPER;
    // TODO: use enum when dropping backwards compat
    if (!isChest)
        isChest = inventoryType.name().equals("SHULKER_BOX");
    boolean clickedWand = Wand.isWand(clickedItem);
    boolean isContainerSlot = event.getSlot() == event.getRawSlot();
    if (isWandInventoryOpen) {
        // Don't allow the offhand slot to be messed with while the spell inventory is open
        if (event.getRawSlot() == 45) {
            event.setCancelled(true);
            return;
        }
        // Don't allow putting spells in a crafting slot
        if (event.getSlotType() == InventoryType.SlotType.CRAFTING && heldSpell) {
            event.setCancelled(true);
            return;
        }
        if (Wand.isSpell(clickedItem) && clickedItem.getAmount() != 1) {
            clickedItem.setAmount(1);
        }
        if (clickedWand) {
            event.setCancelled(true);
            if (dropChangesPages || isRightClick) {
                activeWand.cycleInventory();
            } else {
                activeWand.cycleHotbar(1);
                // There doesn't seem to be any other way to allow cycling in creative
                if (inventoryType == InventoryType.PLAYER) {
                    activeWand.cycleInventory();
                }
            }
            return;
        }
        // So many ways to try and move the wand around, that we have to watch for!
        if (isHotbar && Wand.isWand(player.getInventory().getItem(event.getHotbarButton()))) {
            event.setCancelled(true);
            return;
        }
        // Can't wear spells
        if (event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY && clickedItem != null) {
            if (controller.isWearable(clickedItem)) {
                event.setCancelled(true);
                return;
            }
        }
        // but perhaps happens with lag?
        if (Wand.isWand(event.getCursor())) {
            activeWand.closeInventory();
            event.setCursor(null);
            event.setCancelled(true);
            return;
        }
    } else if (activeWand != null) {
        // Check for changes that could have been made to the active wand
        int activeSlot = player.getInventory().getHeldItemSlot();
        if (event.getSlot() == activeSlot || (isHotbar && event.getHotbarButton() == activeSlot)) {
            mage.checkWand();
            activeWand = mage.getActiveWand();
        }
    }
    // Don't allow smelting wands
    if (isFurnace && clickedWand) {
        event.setCancelled(true);
        return;
    }
    if (isFurnace && isHotbar) {
        ItemStack destinationItem = player.getInventory().getItem(event.getHotbarButton());
        if (Wand.isWand(destinationItem)) {
            event.setCancelled(true);
            return;
        }
    }
    if (InventoryUtils.getMetaBoolean(clickedItem, "unmoveable", false)) {
        event.setCancelled(true);
        return;
    }
    if (isHotbar) {
        ItemStack destinationItem = player.getInventory().getItem(event.getHotbarButton());
        if (InventoryUtils.getMetaBoolean(destinationItem, "unmoveable", false)) {
            event.setCancelled(true);
            return;
        }
        if (isChest && InventoryUtils.getMetaBoolean(destinationItem, "unstashable", false) && !player.hasPermission("Magic.wand.override_stash")) {
            event.setCancelled(true);
            return;
        }
    }
    // Check for unstashable wands
    if (isChest && !isContainerSlot && !player.hasPermission("Magic.wand.override_stash")) {
        if (InventoryUtils.getMetaBoolean(clickedItem, "unstashable", false)) {
            event.setCancelled(true);
            return;
        }
    }
    // Check for taking bound wands out of chests
    if (isChest && isContainerSlot && Wand.isBound(clickedItem)) {
        Wand testWand = controller.getWand(clickedItem);
        if (!testWand.canUse(player)) {
            event.setCancelled(true);
            return;
        }
    }
    // Check for armor changing
    if (event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY && clickedItem != null) {
        if (controller.isWearable(clickedItem)) {
            controller.onArmorUpdated(mage);
        }
    }
    // or dropping undroppable wands
    if (isDrop) {
        if (InventoryUtils.getMetaBoolean(clickedItem, "undroppable", false)) {
            event.setCancelled(true);
            if (activeWand != null) {
                if (activeWand.getHotbarCount() > 1) {
                    activeWand.cycleHotbar(1);
                } else {
                    activeWand.closeInventory();
                }
            }
            return;
        }
        if (activeWand != null && activeWand.isInventoryOpen()) {
            ItemStack droppedItem = clickedItem;
            if (!Wand.isSpell(droppedItem)) {
                mage.giveItem(droppedItem);
                event.setCurrentItem(null);
                event.setCancelled(true);
                return;
            }
            // This is a hack to deal with spells on cooldown disappearing,
            // Since the event handler doesn't match the zero-count itemstacks
            Integer slot = event.getSlot();
            int heldSlot = player.getInventory().getHeldItemSlot();
            Inventory hotbar = activeWand.getHotbar();
            if (hotbar != null && slot >= 0 && slot <= hotbar.getSize() && slot != heldSlot && activeWand.getMode() == WandMode.INVENTORY) {
                if (slot > heldSlot)
                    slot--;
                if (slot < hotbar.getSize()) {
                    droppedItem = hotbar.getItem(slot);
                } else {
                    slot = null;
                }
            } else {
                slot = null;
            }
            if (!controller.isSpellDroppingEnabled()) {
                player.closeInventory();
                String spellName = Wand.getSpell(droppedItem);
                if (spellName != null && !activeWand.isManualQuickCastDisabled() && enableInventoryCasting) {
                    Spell spell = mage.getSpell(spellName);
                    if (spell != null) {
                        activeWand.cast(spell);
                        // Just in case a spell has levelled up... jeez!
                        if (hotbar != null && slot != null) {
                            droppedItem = hotbar.getItem(slot);
                        }
                    }
                }
                event.setCancelled(true);
                // This is needed to avoid spells on cooldown disappearing from the hotbar
                if (hotbar != null && slot != null && mage.getActiveGUI() == null) {
                    player.getInventory().setItem(event.getSlot(), droppedItem);
                    DeprecatedUtils.updateInventory(player);
                }
                return;
            }
            ItemStack newDrop = controller.removeItemFromWand(activeWand, droppedItem);
            if (newDrop != null) {
                Location location = player.getLocation();
                Item item = location.getWorld().dropItem(location, newDrop);
                SafetyUtils.setVelocity(item, location.getDirection().normalize());
            } else {
                event.setCancelled(true);
            }
        }
        return;
    }
    // Check for wand cycling with active inventory
    if (activeWand != null) {
        WandMode wandMode = activeWand.getMode();
        boolean isChestInventory = wandMode == WandMode.CHEST || wandMode == WandMode.SKILLS;
        if ((wandMode == WandMode.INVENTORY && isPlayerInventory) || (isChestInventory && inventoryType == InventoryType.CHEST)) {
            if (activeWand.isInventoryOpen()) {
                if (event.getAction() == InventoryAction.NOTHING) {
                    int direction = event.getClick() == ClickType.LEFT ? 1 : -1;
                    activeWand.cycleInventory(direction);
                    event.setCancelled(true);
                    return;
                }
                if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
                    event.setCancelled(true);
                    return;
                }
                // Chest mode falls back to selection from here.
                boolean isInventoryQuickSelect = isRightClick && wandMode == WandMode.INVENTORY && enableInventorySelection;
                if (isInventoryQuickSelect || wandMode == WandMode.CHEST) {
                    player.closeInventory();
                    mage.activateIcon(activeWand, clickedItem);
                    event.setCancelled(true);
                }
                // Prevent clicking any non-skill item when a skill inventory is open
                if (wandMode == WandMode.SKILLS && clickedItem != null && clickedItem.getType() != Material.AIR && !Wand.isSkill(clickedItem)) {
                    event.setCancelled(true);
                }
            }
        }
    }
}
Also used : Player(org.bukkit.entity.Player) InventoryType(org.bukkit.event.inventory.InventoryType) GUIAction(com.elmakers.mine.bukkit.api.action.GUIAction) Wand(com.elmakers.mine.bukkit.wand.Wand) Spell(com.elmakers.mine.bukkit.api.spell.Spell) InventoryAction(org.bukkit.event.inventory.InventoryAction) Item(org.bukkit.entity.Item) Mage(com.elmakers.mine.bukkit.magic.Mage) ItemStack(org.bukkit.inventory.ItemStack) CraftingInventory(org.bukkit.inventory.CraftingInventory) Inventory(org.bukkit.inventory.Inventory) WandMode(com.elmakers.mine.bukkit.wand.WandMode) Location(org.bukkit.Location) EventHandler(org.bukkit.event.EventHandler)

Aggregations

Spell (com.elmakers.mine.bukkit.api.spell.Spell)39 Mage (com.elmakers.mine.bukkit.api.magic.Mage)14 BaseSpell (com.elmakers.mine.bukkit.spell.BaseSpell)12 Player (org.bukkit.entity.Player)11 SpellTemplate (com.elmakers.mine.bukkit.api.spell.SpellTemplate)10 MageSpell (com.elmakers.mine.bukkit.api.spell.MageSpell)9 ItemStack (org.bukkit.inventory.ItemStack)9 MageController (com.elmakers.mine.bukkit.api.magic.MageController)6 Mage (com.elmakers.mine.bukkit.magic.Mage)5 ActionSpell (com.elmakers.mine.bukkit.spell.ActionSpell)5 Wand (com.elmakers.mine.bukkit.wand.Wand)5 ArrayList (java.util.ArrayList)5 Location (org.bukkit.Location)5 ConfigurationSection (org.bukkit.configuration.ConfigurationSection)5 Wand (com.elmakers.mine.bukkit.api.wand.Wand)4 MemoryConfiguration (org.bukkit.configuration.MemoryConfiguration)4 EventHandler (org.bukkit.event.EventHandler)4 Batch (com.elmakers.mine.bukkit.api.batch.Batch)3 SpellBatch (com.elmakers.mine.bukkit.api.batch.SpellBatch)3 CasterProperties (com.elmakers.mine.bukkit.api.magic.CasterProperties)3