package com.nisovin.magicspells.spells.targeted; import java.util.List; import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; 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 MaterializeSpell extends TargetedSpell implements TargetedLocationSpell { private MagicMaterial material; private int resetDelay; private boolean falling; private boolean applyPhysics; private boolean checkPlugins; private boolean playBreakEffect; private String strFailed; public MaterializeSpell(MagicConfig config, String spellName) { super(config, spellName); String s = getConfigString("block-type", "1"); material = MagicSpells.getItemNameResolver().resolveBlock(s); if (material == null) MagicSpells.error("Invalid block-type on materialize spell '" + internalName + "'"); resetDelay = getConfigInt("reset-delay", 0); falling = getConfigBoolean("falling", false); applyPhysics = getConfigBoolean("apply-physics", true); checkPlugins = getConfigBoolean("check-plugins", true); playBreakEffect = getConfigBoolean("play-break-effect", true); strFailed = getConfigString("str-failed", ""); } @Override public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) { if (state == SpellCastState.NORMAL) { List<Block> lastTwo = null; try { lastTwo = getLastTwoTargetedBlocks(player, power); } catch (IllegalStateException e) { lastTwo = null; } if (lastTwo != null && lastTwo.size() == 2 && lastTwo.get(1).getType() != Material.AIR && lastTwo.get(0).getType() == Material.AIR) { Block block = lastTwo.get(0); Block against = lastTwo.get(1); SpellTargetLocationEvent event = new SpellTargetLocationEvent(this, player, block.getLocation(), power); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return noTarget(player, strFailed); } else { block = event.getTargetLocation().getBlock(); } boolean done = materialize(player, block, against); if (!done) { return noTarget(player, strFailed); } } else { // fail no target return noTarget(player); } } return PostCastAction.HANDLE_NORMALLY; } private boolean materialize(Player player, final Block block, Block against) { BlockState blockState = block.getState(); if (checkPlugins && player != null) { material.setBlock(block, false); BlockPlaceEvent event = new BlockPlaceEvent(block, blockState, against, player.getItemInHand(), player, true); Bukkit.getPluginManager().callEvent(event); blockState.update(true); if (event.isCancelled()) { return false; } } if (!falling) { material.setBlock(block, applyPhysics); } else { material.spawnFallingBlock(block.getLocation().add(0.5, 0.5, 0.5)); } if (player != null) { playSpellEffects(EffectPosition.CASTER, player); playSpellEffects(EffectPosition.TARGET, block.getLocation()); playSpellEffectsTrail(player.getLocation(), block.getLocation()); } if (playBreakEffect) { block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); } if (resetDelay > 0 && !falling) { Bukkit.getScheduler().scheduleSyncDelayedTask(MagicSpells.plugin, new Runnable() { public void run() { if (material.getMaterial().equals(block.getType())) { block.setType(Material.AIR); playSpellEffects(EffectPosition.DELAYED, block.getLocation()); if (playBreakEffect) { block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); } } } }, resetDelay); } return true; } @Override public boolean castAtLocation(Player caster, Location target, float power) { Block block = target.getBlock(); Block against = target.clone().add(target.getDirection()).getBlock(); if (block.equals(against)) { against = block.getRelative(BlockFace.DOWN); } if (block.getType() == Material.AIR) { return materialize(caster, block, against); } else { Block block2 = block.getRelative(BlockFace.UP); if (block2.getType() == Material.AIR) { return materialize(null, block2, block); } } return false; } @Override public boolean castAtLocation(Location target, float power) { Block block = target.getBlock(); if (block.getType() == Material.AIR) { return materialize(null, block, block); } else { Block block2 = block.getRelative(BlockFace.UP); if (block2.getType() == Material.AIR) { return materialize(null, block2, block); } } return false; } }