package com.magmaguy.elitemobs.mobpowers.bosspowers; import com.magmaguy.elitemobs.EntityTracker; import com.magmaguy.elitemobs.MetadataHandler; import com.magmaguy.elitemobs.mobconstructor.BossMobEntity; import com.magmaguy.elitemobs.mobconstructor.EliteMobEntity; import com.magmaguy.elitemobs.utils.EntityFinder; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import java.util.concurrent.ThreadLocalRandom; public class SpiritWalk extends BossPower implements Listener { @Override public void applyPowers(Entity entity) { } @EventHandler public void onBossMobGotHit(EntityDamageEvent event) { EliteMobEntity eliteMobEntity = EntityTracker.getEliteMobEntity(event.getEntity()); if (eliteMobEntity == null) return; if (!(eliteMobEntity instanceof BossMobEntity)) return; BossMobEntity bossMobEntity = (BossMobEntity) eliteMobEntity; if (event.getCause().equals(EntityDamageEvent.DamageCause.DROWNING) || event.getCause().equals(EntityDamageEvent.DamageCause.SUFFOCATION)) { initializeSpiritWalk(bossMobEntity.getLivingEntity()); bossMobEntity.resetHitsCounter(); } if (bossMobEntity.getHitsCounter() != 9) return; initializeSpiritWalk(bossMobEntity.getLivingEntity()); bossMobEntity.resetHitsCounter(); } @EventHandler public void onBossMobHit(EntityDamageByEntityEvent event) { EliteMobEntity eliteMobEntity = EntityTracker.getEliteMobEntity(EntityFinder.getRealDamager(event)); if (eliteMobEntity == null) return; if (!(eliteMobEntity instanceof BossMobEntity)) return; BossMobEntity bossMobEntity = (BossMobEntity) eliteMobEntity; bossMobEntity.resetHitsCounter(); } private void initializeSpiritWalk(LivingEntity bossMob) { new BukkitRunnable() { int counter = 1; @Override public void run() { if (counter > 3) cancel(); Location bossLocation = bossMob.getLocation().clone(); for (int i = 0; i < 20; i++) { double randomizedX = (ThreadLocalRandom.current().nextDouble() - 0.5) * 5; double randomizedY = ThreadLocalRandom.current().nextDouble() - 0.5; double randomizedZ = (ThreadLocalRandom.current().nextDouble() - 0.5) * 5; Vector normalizedVector = new Vector(randomizedX, randomizedY, randomizedZ).normalize().multiply(7).multiply(counter); Location newSimulatedLocation = bossLocation.add(normalizedVector).clone(); Location newValidLocation = checkLocationValidity(newSimulatedLocation); if (newValidLocation != null) { spiritWalkAnimation(bossMob, bossMob.getLocation(), newValidLocation.add(new Vector(0.5, 1, 0.5))); cancel(); break; } } counter++; } }.runTaskTimer(MetadataHandler.PLUGIN, 0, 1); } private void spiritWalkAnimation(LivingEntity bossMob, Location entityLocation, Location finalLocation) { bossMob.setAI(false); bossMob.setInvulnerable(true); bossMob.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 20 * 10, 1)); Vector toDestination = finalLocation.clone().subtract(entityLocation.clone()).toVector().normalize().divide(new Vector(2, 2, 2)); new BukkitRunnable() { int counter = 0; @Override public void run() { if (bossMob.getLocation().clone().distance(finalLocation) < 2 || counter > 20 * 10) { bossMob.teleport(finalLocation); bossMob.setAI(true); bossMob.setInvulnerable(false); bossMob.removePotionEffect(PotionEffectType.GLOWING); cancel(); } bossMob.teleport(bossMob.getLocation().clone().add(toDestination.clone())); counter++; } }.runTaskTimer(MetadataHandler.PLUGIN, 0, 1); } private Location checkLocationValidity(Location simulatedLocation) { if (simulatedLocation.getBlock().getType().equals(Material.AIR)) { int counter = 1; while (true) { if (simulatedLocation.getY() < 1) return null; Location blockUnderCurrentBlock = simulatedLocation.clone().subtract(new Vector(0, counter, 0)); if (blockUnderCurrentBlock.getBlock().getType() != Material.AIR) return blockUnderCurrentBlock; if (counter > 10) return null; counter++; } } return null; } }