package com.nisovin.magicspells.spells.targeted;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.util.Vector;
import com.nisovin.magicspells.MagicSpells;
import com.nisovin.magicspells.events.SpellTargetLocationEvent;
import com.nisovin.magicspells.materials.MagicMaterial;
import com.nisovin.magicspells.spelleffects.EffectPosition;
import com.nisovin.magicspells.spells.TargetedLocationSpell;
import com.nisovin.magicspells.spells.TargetedSpell;
import com.nisovin.magicspells.util.MagicConfig;
public class ZapSpell extends TargetedSpell implements TargetedLocationSpell {
private String strCantZap;
private Set<Material> allowedBlockTypes;
private Set<Material> disallowedBlockTypes;
private boolean dropBlock;
private boolean dropNormal;
private boolean checkPlugins;
private boolean playBreakEffect;
public ZapSpell(MagicConfig config, String spellName) {
super(config, spellName);
strCantZap = getConfigString("str-cant-zap", "");
List<String> allowed = getConfigStringList("allowed-block-types",null);
if (allowed != null) {
allowedBlockTypes = EnumSet.noneOf(Material.class);
for (String s : allowed) {
if (!s.isEmpty()) {
MagicMaterial m = MagicSpells.getItemNameResolver().resolveBlock(s);
if (m != null && m.getMaterial() != null) {
allowedBlockTypes.add(m.getMaterial());
}
}
}
}
List<String> disallowed = getConfigStringList("disallowed-block-types", Arrays.asList("bedrock", "lava", "stationary_lava", "water", "stationary_water"));
if (disallowed != null) {
disallowedBlockTypes = EnumSet.noneOf(Material.class);
for (String s : disallowed) {
if (!s.isEmpty()) {
MagicMaterial m = MagicSpells.getItemNameResolver().resolveBlock(s);
if (m != null && m.getMaterial() != null) {
disallowedBlockTypes.add(m.getMaterial());
}
}
}
}
dropBlock = getConfigBoolean("drop-block", false);
dropNormal = getConfigBoolean("drop-normal", true);
checkPlugins = getConfigBoolean("check-plugins", true);
playBreakEffect = getConfigBoolean("play-break-effect", true);
}
@Override
public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
// get targeted block
Block target;
try {
target = getTargetedBlock(player, power);
} catch (IllegalStateException e) {
target = null;
}
if (target != null) {
SpellTargetLocationEvent event = new SpellTargetLocationEvent(this, player, target.getLocation(), power);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
target = null;
} else {
target = event.getTargetLocation().getBlock();
}
}
if (target != null) {
// check for disallowed block
if (!canZap(target)) {
return noTarget(player, strCantZap);
}
// zap
boolean ok = zap(target, player);
if (!ok) {
return noTarget(player, strCantZap);
}
} else {
return noTarget(player, strCantZap);
}
}
return PostCastAction.HANDLE_NORMALLY;
}
private boolean zap(Block target, Player player) {
// check for protection
if (checkPlugins && player != null) {
BlockBreakEvent event = new BlockBreakEvent(target, player);
MagicSpells.plugin.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
// a plugin cancelled the event
return false;
}
}
// drop block
if (dropBlock) {
if (dropNormal) {
target.breakNaturally();
} else {
target.getWorld().dropItemNaturally(target.getLocation(), target.getState().getData().toItemStack(1));
}
}
// show animation
if (playBreakEffect) {
target.getWorld().playEffect(target.getLocation(), Effect.STEP_SOUND, target.getType());
}
if (player != null) {
playSpellEffects(EffectPosition.CASTER, player);
}
playSpellEffects(EffectPosition.TARGET, target.getLocation());
if (player != null) {
playSpellEffectsTrail(player.getLocation(), target.getLocation());
}
// remove block
target.setType(Material.AIR);
return true;
}
@Override
public boolean castAtLocation(Player caster, Location target, float power) {
Block block = target.getBlock();
if (canZap(block)) {
zap(block, caster);
return true;
} else {
Vector v = target.getDirection();
block = target.clone().add(v).getBlock();
if (canZap(block)) {
zap(block, caster);
return true;
}
}
return false;
}
@Override
public boolean castAtLocation(Location target, float power) {
Block block = target.getBlock();
if (canZap(block)) {
zap(block, null);
return true;
}
return false;
}
private boolean canZap(Block target) {
return !(disallowedBlockTypes.contains(target.getType()) || (allowedBlockTypes.size() > 0 && !allowedBlockTypes.contains(target.getType())));
}
}