package com.nisovin.magicspells.spells.targeted; import java.util.List; import java.util.Map; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.util.Vector; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.Spell; import com.nisovin.magicspells.spells.TargetedLocationSpell; import com.nisovin.magicspells.spells.TargetedSpell; import com.nisovin.magicspells.util.MagicConfig; public class SpawnTntSpell extends TargetedSpell implements TargetedLocationSpell { int fuse; float velocity; float upVelocity; boolean cancelExplosion; boolean preventBlockDamage; String spellName; TargetedLocationSpell spell; Map<Integer, TntInfo> tnts; public SpawnTntSpell(MagicConfig config, String spellName) { super(config, spellName); fuse = getConfigInt("fuse", 20); velocity = getConfigFloat("velocity", 0); upVelocity = getConfigFloat("up-velocity", velocity); cancelExplosion = getConfigBoolean("cancel-explosion", false); preventBlockDamage = getConfigBoolean("prevent-block-damage", false); } @Override public void initialize() { if (spellName != null) { Spell s = MagicSpells.getSpellByInternalName(spellName); if (s instanceof TargetedLocationSpell) { spell = (TargetedLocationSpell)s; } if (spell == null) { MagicSpells.error("Invalid spell defined on SpawnTntSpell " + internalName + ": " + spellName); } } } @Override public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) { if (state == SpellCastState.NORMAL) { List<Block> blocks = getLastTwoTargetedBlocks(player, power); if (blocks.size() == 2 && !blocks.get(0).getType().isSolid() && blocks.get(0).getType().isSolid()) { Location loc = blocks.get(0).getLocation().add(0.5, 0.5, 0.5); loc.setDirection(player.getLocation().getDirection()); } } return PostCastAction.HANDLE_NORMALLY; } void spawnTnt(Player caster, float power, Location loc) { TNTPrimed tnt = loc.getWorld().spawn(loc, TNTPrimed.class); tnt.setFuseTicks(fuse); if (velocity > 0) { tnt.setVelocity(loc.getDirection().normalize().setY(0).multiply(velocity).setY(upVelocity)); } else if (upVelocity > 0) { tnt.setVelocity(new Vector(0, upVelocity, 0)); } tnts.put(tnt.getEntityId(), new TntInfo(caster, power)); } @Override public boolean castAtLocation(Player caster, Location target, float power) { target.setX(target.getBlockX() + 0.5); target.setY(target.getBlockY() + 0.5); target.setZ(target.getBlockZ() + 0.5); spawnTnt(caster, power, target); return true; } @Override public boolean castAtLocation(Location target, float power) { target.setX(target.getBlockX() + 0.5); target.setY(target.getBlockY() + 0.5); target.setZ(target.getBlockZ() + 0.5); spawnTnt(null, power, target); return true; } @EventHandler void onEntityExplode(EntityExplodeEvent event) { TntInfo info = tnts.remove(event.getEntity().getEntityId()); if (info != null) { if (cancelExplosion) { event.setCancelled(true); event.getEntity().remove(); } if (preventBlockDamage) { event.blockList().clear(); event.setYield(0f); } if (spell != null) { if (info.caster != null) { if (info.caster.isValid() && !info.caster.isDead()) { spell.castAtLocation(info.caster, event.getEntity().getLocation(), info.power); } } else { spell.castAtLocation(event.getEntity().getLocation(), info.power); } } } } class TntInfo { Player caster; float power; public TntInfo(Player caster, float power) { this.caster = caster; this.power = power; } } }