package com.nisovin.magicspells.spells.targeted;
import java.util.ArrayList;
import java.util.HashSet;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import com.nisovin.magicspells.MagicSpells;
import com.nisovin.magicspells.materials.MagicMaterial;
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;
public class EntombSpell extends TargetedSpell implements TargetedEntitySpell {
private MagicMaterial tombBlockType;
private int tombDuration;
private boolean closeTopAndBottom;
private boolean allowBreaking;
private HashSet<Block> blocks;
public EntombSpell(MagicConfig config, String spellName) {
super(config, spellName);
tombBlockType = MagicSpells.getItemNameResolver().resolveBlock(getConfigString("tomb-block-type", "glass"));
tombDuration = getConfigInt("tomb-duration", 20);
closeTopAndBottom = getConfigBoolean("close-top-and-bottom", true);
allowBreaking = getConfigBoolean("allow-breaking", true);
blocks = new HashSet<Block>();
if (tombBlockType == null) {
MagicSpells.error("Entomb spell '" + spellName + "' has an invalid tomb-block-type!");
}
}
@Override
public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
TargetInfo<LivingEntity> targetInfo = getTargetedEntity(player, power);
if (targetInfo != null) {
LivingEntity target = targetInfo.getTarget();
power = targetInfo.getPower();
int x = target.getLocation().getBlockX();
int y = target.getLocation().getBlockY();
int z = target.getLocation().getBlockZ();
Location loc = new Location(target.getLocation().getWorld(), x+.5, y+.5, z+.5, target.getLocation().getYaw(), target.getLocation().getPitch());
target.teleport(loc);
createTomb(target, power);
playSpellEffects(player, target);
sendMessages(player, target);
return PostCastAction.NO_MESSAGES;
} else {
return noTarget(player);
}
}
return PostCastAction.HANDLE_NORMALLY;
}
private void createTomb(LivingEntity target, float power) {
ArrayList<Block> tombBlocks = new ArrayList<Block>();
Block feet = target.getLocation().getBlock();
Block temp = feet.getRelative(1,0,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(1,1,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(-1,0,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(-1,1,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(0,0,1);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(0,1,1);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(0,0,-1);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(0,1,-1);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
if (closeTopAndBottom) {
temp = feet.getRelative(0,-1,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
temp = feet.getRelative(0,2,0);
if (temp.getType() == Material.AIR) {
tombBlockType.setBlock(temp);
tombBlocks.add(temp);
}
}
if (tombDuration > 0 && tombBlocks.size() > 0) {
blocks.addAll(tombBlocks);
MagicSpells.plugin.getServer().getScheduler().scheduleSyncDelayedTask(MagicSpells.plugin, new TombRemover(tombBlocks), Math.round(tombDuration*20*power));
}
}
@Override
public boolean castAtEntity(Player caster, LivingEntity target, float power) {
if (!validTargetList.canTarget(caster, target)) {
return false;
} else {
createTomb(target, power);
playSpellEffects(caster, target);
return true;
}
}
@Override
public boolean castAtEntity(LivingEntity target, float power) {
if (!validTargetList.canTarget(target)) {
return false;
} else {
createTomb(target, power);
playSpellEffects(EffectPosition.TARGET, target);
return true;
}
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (blocks.contains(event.getBlock())) {
event.setCancelled(true);
if (allowBreaking) {
event.getBlock().setType(Material.AIR);
}
}
}
private class TombRemover implements Runnable {
ArrayList<Block> tomb;
public TombRemover(ArrayList<Block> tomb) {
this.tomb = tomb;
}
@Override
public void run() {
for (Block block : tomb) {
if (tombBlockType.getMaterial() == block.getType()) {
block.setType(Material.AIR);
}
}
blocks.removeAll(tomb);
}
}
}