package com.nisovin.magicspells.spells.targeted;
import java.util.Collection;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.nisovin.magicspells.events.SpellTargetEvent;
import com.nisovin.magicspells.events.SpellTargetLocationEvent;
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 ForcebombSpell extends TargetedSpell implements TargetedLocationSpell {
private int radiusSquared;
private float yOffset;
private int force;
private int yForce;
private int maxYForce;
private boolean callTargetEvents;
public ForcebombSpell(MagicConfig config, String spellName) {
super(config, spellName);
radiusSquared = getConfigInt("radius", 3);
radiusSquared *= radiusSquared;
yOffset = getConfigFloat("y-offset", 0);
force = getConfigInt("pushback-force", 30);
yForce = getConfigInt("additional-vertical-force", 15);
maxYForce = getConfigInt("max-vertical-force", 20);
callTargetEvents = getConfigBoolean("call-target-events", false);
}
@Override
public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
Block block = getTargetedBlock(player, power);
if (block != null && block.getType() != Material.AIR) {
SpellTargetLocationEvent event = new SpellTargetLocationEvent(this, player, block.getLocation(), power);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
block = null;
} else {
block = event.getTargetLocation().getBlock();
power = event.getPower();
}
}
if (block != null && block.getType() != Material.AIR) {
knockback(player, block.getLocation().add(0.5, 0, 0.5), power);
} else {
return noTarget(player);
}
}
return PostCastAction.HANDLE_NORMALLY;
}
@Override
public boolean castAtLocation(Player caster, Location target, float power) {
knockback(caster, target, power);
return true;
}
@Override
public boolean castAtLocation(Location target, float power) {
knockback(null, target, power);
return true;
}
public void knockback(Player player, Location location, float basePower) {
location = location.clone().add(0, yOffset, 0);
Vector t = location.toVector();
Collection<Entity> entities = location.getWorld().getEntitiesByClasses(LivingEntity.class);
Vector e, v;
for (Entity entity : entities) {
if (entity instanceof LivingEntity && (player == null || validTargetList.canTarget(player, (LivingEntity)entity)) && entity.getLocation().distanceSquared(location) <= radiusSquared) {
float power = basePower;
if (callTargetEvents && player != null) {
SpellTargetEvent event = new SpellTargetEvent(this, player, (LivingEntity)entity, power);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
continue;
} else {
power = event.getPower();
}
}
e = entity.getLocation().toVector();
v = e.subtract(t).normalize().multiply(force/10.0*power);
if (force != 0) {
v.setY(v.getY() * (yForce/10.0*power));
} else {
v.setY(yForce/10.0*power);
}
if (v.getY() > (maxYForce/10.0)) {
v.setY(maxYForce/10.0);
}
entity.setVelocity(v);
playSpellEffects(EffectPosition.TARGET, entity);
}
}
playSpellEffects(EffectPosition.SPECIAL, location);
if (player != null) {
playSpellEffects(EffectPosition.CASTER, player);
} else {
playSpellEffects(EffectPosition.CASTER, location);
}
}
}