/**
* BetonQuest - advanced quests for Bukkit
* Copyright (C) 2016 Jakub "Co0sh" Sapalski
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package pl.betoncraft.betonquest.compatibility.magic;
import java.util.HashMap;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.elmakers.mine.bukkit.api.magic.MagicAPI;
import com.elmakers.mine.bukkit.api.wand.LostWand;
import com.elmakers.mine.bukkit.api.wand.Wand;
import pl.betoncraft.betonquest.Instruction;
import pl.betoncraft.betonquest.InstructionParseException;
import pl.betoncraft.betonquest.QuestRuntimeException;
import pl.betoncraft.betonquest.VariableNumber;
import pl.betoncraft.betonquest.api.Condition;
import pl.betoncraft.betonquest.utils.PlayerConverter;
/**
* Checks if the player is holding a wand.
*
* @author Jakub Sapalski
*/
public class WandCondition extends Condition {
private MagicAPI api;
private CheckType type;
private HashMap<String, VariableNumber> spells = new HashMap<>();
private String name;
public WandCondition(Instruction instruction) throws InstructionParseException {
super(instruction);
String string = instruction.next();
switch (string) {
case "hand":
type = CheckType.IN_HAND;
break;
case "inventory":
type = CheckType.IN_INVENTORY;
break;
case "lost":
type = CheckType.IS_LOST;
break;
default:
throw new InstructionParseException("Unknown check type '" + string + "'");
}
String[] array = instruction.getArray(instruction.getOptional("spells"));
if (array != null) {
for (String spell : array) {
VariableNumber level = new VariableNumber(1);
if (spell.contains(":")) {
String[] spellParts = spell.split(":");
spell = spellParts[0];
try {
level = new VariableNumber(instruction.getPackage().getName(), spellParts[1]);
} catch (NumberFormatException e) {
throw new InstructionParseException("Could not parse spell level");
}
this.spells.put(spell, level);
} else {
throw new InstructionParseException("Incorrect spell format");
}
}
}
name = instruction.getOptional("name");
api = (MagicAPI) Bukkit.getPluginManager().getPlugin("Magic");
}
@Override
public boolean check(String playerID) throws QuestRuntimeException {
Player player = PlayerConverter.getPlayer(playerID);
switch (type) {
case IS_LOST:
for (LostWand lost : api.getLostWands()) {
Player owner = Bukkit.getPlayer(UUID.fromString(lost.getOwnerId()));
if (owner == null)
continue;
if (owner.equals(player)) {
return true;
}
}
return false;
case IN_HAND:
ItemStack wandItem = player.getInventory().getItemInMainHand();
if (!api.isWand(wandItem)) {
return false;
}
Wand wand1 = api.getWand(wandItem);
return checkWand(wand1, playerID);
case IN_INVENTORY:
for (ItemStack item : player.getInventory().getContents()) {
if (item == null)
continue;
if (api.isWand(item)) {
Wand wand2 = api.getWand(item);
if (checkWand(wand2, playerID)) {
return true;
}
}
}
return false;
default:
return false;
}
}
/**
* Checks if the given wand meets specified name and spells conditions.
*
* @param wand
* wand to check
* @return true if the wand meets the conditions, false otherwise
* @throws QuestRuntimeException
*/
private boolean checkWand(Wand wand, String playerID) throws QuestRuntimeException {
if (name != null && !wand.getTemplateKey().equalsIgnoreCase(name)) {
return false;
}
if (!spells.isEmpty()) {
spell: for (String spell : spells.keySet()) {
int level = spells.get(spell).getInt(playerID);
for (String wandSpell : wand.getSpells()) {
if (wandSpell.toLowerCase().startsWith(spell.toLowerCase()) && wand.getSpellLevel(spell) >= level) {
continue spell;
}
}
return false;
}
}
return true;
}
private enum CheckType {
IS_LOST, IN_HAND, IN_INVENTORY
}
}