BetterTridents/src/main/java/de/jeff_media/bettertridents/listeners/ImpalingListener.java

112 lines
4.1 KiB
Java

package de.jeff_media.bettertridents.listeners;
import de.jeff_media.bettertridents.Main;
import de.jeff_media.bettertridents.config.Config;
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import java.util.Random;
public class ImpalingListener implements Listener {
private final Main main = Main.getInstance();
private final Random random = new Random();
private static boolean isAquatic(EntityType type) {
switch (type) {
case DOLPHIN:
case GUARDIAN:
case ELDER_GUARDIAN:
case SQUID:
case TURTLE:
case COD:
case SALMON:
case PUFFERFISH:
case TROPICAL_FISH:
return true;
default:
return false;
}
}
private static boolean isInRain(Entity entity) {
World world = entity.getWorld();
if (!world.hasStorm()) return false;
Location min = entity.getBoundingBox().getMin().toLocation(world);
Location max = entity.getBoundingBox().getMax().toLocation(world);
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
Block highest = world.getHighestBlockAt(x, z);
if (highest == null || highest.getType().isAir()) return true;
if (highest.getY() < entity.getLocation().getY()) return true;
}
}
return false;
}
private static boolean isInWater(Entity entity) {
World world = entity.getWorld();
Location min = entity.getBoundingBox().getMin().toLocation(entity.getWorld());
Location max = entity.getBoundingBox().getMax().toLocation(entity.getWorld());
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
if (world.getBlockAt(x, y, z).getType() == Material.WATER) {
return true;
}
}
}
}
return false;
}
private void displayEnchantedHit(Entity entity) {
for (int i = 0; i < 16 * 3; i++) {
double d = (this.random.nextFloat() * 2.0F - 1.0F);
double e = (this.random.nextFloat() * 2.0F - 1.0F);
double f = (this.random.nextFloat() * 2.0F - 1.0F);
if (Math.sqrt(d) + Math.sqrt(e) + Math.sqrt(f) <= 1.0D) {
Location loc = entity.getLocation().clone();
loc.add((entity.getWidth() * (d / 4.0D)),
(entity.getHeight() * (0.5D + e / 4.0D)),
(entity.getWidth() * (f / 4.0D)));
loc.getWorld().spawnParticle(Particle.CRIT_MAGIC, loc, 0, d, e + 0.2D, f);
}
}
}
@EventHandler(ignoreCancelled = true)
private void onHitByImpaling(EntityDamageByEntityEvent event) {
if (!main.getConfig().getBoolean(Config.BEDROCK_IMPALING)) return;
Entity entity = event.getEntity();
int impaling = 0;
if (event.getDamager().getType() == EntityType.TRIDENT) {
impaling = EnchantmentUtils.getImpaling((Trident) event.getDamager());
} else if (event.getDamager().getType() == EntityType.PLAYER) {
impaling = ((Player) event.getDamager()).getInventory().getItemInMainHand().getEnchantmentLevel(Enchantment.IMPALING);
}
if (impaling > 0) {
if (!isAquatic(entity.getType()) && (isInRain(entity) || isInWater(entity))) {
event.setDamage(event.getDamage() + (2.5 * impaling));
main.debug("Adjusting Impaling damage: adding " + 2.5*impaling + " damage");
displayEnchantedHit(entity);
}
}
}
}