package com.nisovin.magicspells.spells.targeted;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import com.nisovin.magicspells.MagicSpells;
import com.nisovin.magicspells.spelleffects.EffectPosition;
import com.nisovin.magicspells.spells.TargetedEntitySpell;
import com.nisovin.magicspells.spells.TargetedSpell;
import com.nisovin.magicspells.util.MagicConfig;
import com.nisovin.magicspells.util.TargetInfo;
import com.nisovin.magicspells.util.Util;
public class DisarmSpell extends TargetedSpell implements TargetedEntitySpell {
private Set<Material> disarmable;
private int disarmDuration;
private boolean dontDrop;
private boolean preventTheft;
private String strInvalidItem;
private HashMap<Item, String> disarmedItems;
public DisarmSpell(MagicConfig config, String spellName) {
super(config, spellName);
List<String> disarmableIds = getConfigStringList("disarmable-items", null);
if (disarmableIds != null && disarmableIds.size() > 0) {
disarmable = new HashSet<Material>();
for (String itemName : disarmableIds) {
ItemStack item = Util.getItemStackFromString(itemName);
if (item != null) {
disarmable.add(item.getType());
}
}
}
disarmDuration = getConfigInt("disarm-duration", 100);
dontDrop = getConfigBoolean("dont-drop", false);
preventTheft = getConfigBoolean("prevent-theft", true);
strInvalidItem = getConfigString("str-invalid-item", "Your target could not be disarmed.");
if (dontDrop) preventTheft = false;
if (preventTheft) {
disarmedItems = new HashMap<Item, String>();
}
}
@Override
public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
// get target
TargetInfo<LivingEntity> target = getTargetedEntity(player, power);
if (target == null) {
// fail
return noTarget(player);
}
boolean disarmed = disarm(target.getTarget());
if (disarmed) {
playSpellEffects(player, target.getTarget());
// send messages
sendMessages(player, target.getTarget());
return PostCastAction.NO_MESSAGES;
} else {
// fail
return noTarget(player, strInvalidItem);
}
}
return PostCastAction.HANDLE_NORMALLY;
}
private boolean disarm(final LivingEntity target) {
final ItemStack inHand = getItemInHand(target);
if (disarmable == null || disarmable.contains(inHand.getType())) {
if (dontDrop) {
// hide item
setItemInHand(target, null);
Bukkit.getScheduler().scheduleSyncDelayedTask(MagicSpells.plugin, new Runnable() {
public void run() {
// give the item back
ItemStack inHand2 = getItemInHand(target);
if (inHand2 == null || inHand2.getType() == Material.AIR) {
// put back in hand
setItemInHand(target, inHand);
} else if (target instanceof Player) {
// hand is full
int slot = ((Player)target).getInventory().firstEmpty();
if (slot >= 0) {
// put in first available slot
((Player)target).getInventory().setItem(slot, inHand);
} else {
// no slots available, drop at feet
Item item = target.getWorld().dropItem(target.getLocation(), inHand);
item.setPickupDelay(0);
}
}
}
}, disarmDuration);
} else {
// drop item
setItemInHand(target, null);
Item item = target.getWorld().dropItemNaturally(target.getLocation(), inHand.clone());
item.setPickupDelay(disarmDuration);
if (preventTheft && target instanceof Player) {
disarmedItems.put(item, ((Player)target).getName());
}
}
return true;
} else {
return false;
}
}
private ItemStack getItemInHand(LivingEntity entity) {
if (entity instanceof Player) {
return ((Player)entity).getItemInHand();
} else {
EntityEquipment equip = entity.getEquipment();
if (equip != null) {
return equip.getItemInHand();
}
}
return null;
}
private void setItemInHand(LivingEntity entity, ItemStack item) {
if (entity instanceof Player) {
((Player)entity).setItemInHand(item);
} else {
EntityEquipment equip = entity.getEquipment();
if (equip != null) {
equip.setItemInHand(item);
}
}
}
@Override
public boolean castAtEntity(Player caster, LivingEntity target, float power) {
if (!validTargetList.canTarget(caster, target)) return false;
boolean disarmed = disarm(target);
if (disarmed) {
playSpellEffects(caster, target);
}
return disarmed;
}
@Override
public boolean castAtEntity(LivingEntity target, float power) {
if (!validTargetList.canTarget(target)) return false;
boolean disarmed = disarm(target);
if (disarmed) {
playSpellEffects(EffectPosition.TARGET, target);
}
return disarmed;
}
@EventHandler
public void onItemPickup(PlayerPickupItemEvent event) {
if (!preventTheft || event.isCancelled()) return;
Item item = event.getItem();
if (disarmedItems.containsKey(item)) {
if (disarmedItems.get(item).equals(event.getPlayer().getName())) {
disarmedItems.remove(item);
} else {
event.setCancelled(true);
}
}
}
}