package nl.sugcube.crystalquest.items; import nl.sugcube.crystalquest.CrystalQuest; import nl.sugcube.crystalquest.game.Arena; import nl.sugcube.crystalquest.game.ArenaManager; import nl.sugcube.crystalquest.game.CrystalQuestTeam; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Wolf; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import static java.lang.Math.*; /** * @author SugarCaney */ public class ForceField extends ItemExecutor { private static final double FORCE_LIMIT = 1.5; public ForceField() { super(Material.GLASS); } @Override boolean execute(CrystalQuest plugin, Player player, ItemStack itemStack) { final World world = player.getWorld(); final Location source = player.getLocation(); final ArenaManager arenaManager = plugin.getArenaManager(); final Arena arena = arenaManager.getArena(player.getUniqueId()); final CrystalQuestTeam teamId = arena.getTeam(player); world.getEntities().stream() .filter(ent -> { // No null entities. if (ent == null) { return false; } // Don't nudge your own species. if (ent instanceof Player) { if (arena.getTeam((Player)ent) == teamId) { return false; } } // Don't nudge your own wolfs. if (ent instanceof Wolf) { if (player.equals(((Wolf)ent).getOwner())) { return false; } } // We only want to target living basta'ds. return ent instanceof LivingEntity; }) .forEach(ent -> applyForce(source, (LivingEntity)ent)); player.playSound(player.getLocation(), Sound.ENTITY_ELDER_GUARDIAN_CURSE, 12F, 12F); return true; } private void applyForce(Location source, LivingEntity target) { final Location location = target.getLocation(); final double sx = source.getX(); final double sz = source.getZ(); final double tx = location.getX(); final double tz = location.getZ(); // Determine velocity boost. double x = 1d / (tx - sx == 0 ? 0.0001 : ((tx - sx) * 1.25)); double z = 1d / (tz - sz == 0 ? 0.0001 : ((tz - sz) * 1.25)); // Apply limits. x = (x < 0 ? max(-FORCE_LIMIT, x) : max(FORCE_LIMIT, x)) / 1.2d; z = (z < 0 ? max(-FORCE_LIMIT, z) : max(FORCE_LIMIT, z)) / 1.2d; // Determine y velocity to make a 45 degree swoop. double y = sqrt(x * x + z * z); // Apply velocity Vector velocity = new Vector(x, y, z); target.setVelocity(velocity); // And damage a bit double damage = 8 - location.distance(source); if (damage > 0) { target.damage(damage); } } }