package com.asteria.game.character; import java.util.Arrays; import java.util.Optional; import com.asteria.game.character.player.Player; import com.asteria.game.character.player.content.MagicStaff; import com.asteria.game.character.player.skill.Skills; import com.asteria.game.item.Item; /** * The parent class of all magic spells that provides basic functionality for * generic spells. * * @author lare96 <http://github.com/lare96> */ public abstract class Spell { /** * Determines if {@code player} can cast this spell. * * @param player * the player attempting to cast this spell. * @return {@code true} if the player can cast the spell, {@code false} * otherwise. */ public boolean canCast(Player player) { int level = levelRequired(); Optional<Item[]> inventory = itemsRequired(player); Optional<Item[]> equipment = equipmentRequired(player); if (player.getSkills()[Skills.MAGIC].getLevel() < level) { player.getMessages().sendMessage("You need a Magic level of " + level + " to cast this spell."); player.getCombatBuilder().reset(); return false; } if (equipment.isPresent()) { if (!player.getEquipment().containsAll(equipment.get())) { player.getMessages().sendMessage("You do not have the required equipment to cast this spell."); resetPlayerSpell(player); player.getCombatBuilder().reset(); return false; } } if (inventory.isPresent()) { Item[] items = MagicStaff.suppressRunes(player, inventory.get()); if (!player.getInventory().containsAll(items)) { player.getMessages().sendMessage("You do not have the required items to cast this spell."); resetPlayerSpell(player); player.getCombatBuilder().reset(); return false; } player.getInventory().removeAll(Arrays.asList(items)); } return true; } /** * Resets the {@code player}'s autocasting if they're currently in combat. * * @param player * the player to reset. */ private final void resetPlayerSpell(Player player) { if (player.getCombatBuilder().isAttacking() || player.getCombatBuilder().isBeingAttacked() && player.isAutocast()) { player.setAutocastSpell(null); player.setAutocast(false); player.getMessages().sendByteState(108, 0); player.setCastSpell(null); } } /** * The level required to cast this spell. * * @return the level required. */ public abstract int levelRequired(); /** * The base experience given when this spell is cast. * * @return the base experience. */ public abstract double baseExperience(); /** * The items required in the inventory to cast this spell. * * @param player * the player who's inventory will be checked. * @return the items required to cast this spell, or an empty optional if * there are no items required. */ public abstract Optional<Item[]> itemsRequired(Player player); /** * The items required in the equipment to cast this spell. * * @param player * the player who's equipment will be checked. * @return the equipment required to cast this spell, or an empty optional * if there is no equipment required. */ public abstract Optional<Item[]> equipmentRequired(Player player); /** * The dynamic method executed when the spell is cast. * * @param cast * the character casting the spell. * @param castOn * the character the spell is being cast on, this may be * {@code null}. */ public abstract void startCast(CharacterNode cast, CharacterNode castOn); }