BetterTridents/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java

108 lines
3.3 KiB
Java
Raw Normal View History

2021-05-24 18:39:16 +02:00
package de.jeff_media.bettertridents.tasks;
2021-05-24 13:46:25 +02:00
2023-04-01 17:41:47 +02:00
import com.jeff_media.jefflib.WorldUtils;
2021-05-24 18:39:16 +02:00
import de.jeff_media.bettertridents.Main;
2023-04-01 17:41:47 +02:00
import com.jeff_media.jefflib.ReflUtils;
2021-05-24 13:46:25 +02:00
import org.bukkit.Location;
2021-06-04 17:50:59 +02:00
import org.bukkit.Material;
2021-05-24 13:46:25 +02:00
import org.bukkit.entity.Trident;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
2021-06-04 17:50:59 +02:00
import java.lang.reflect.Field;
import java.lang.reflect.Method;
2021-05-24 13:46:25 +02:00
public class WatchTrident extends BukkitRunnable {
private static final int MAX_TICKS = 1200;
2021-06-04 17:50:59 +02:00
private static Field damageDealtField;
private static Method getHandleMethod;
static {
int fieldCount = 0;
2021-06-13 20:18:30 +02:00
Class<?> entityThrownTridentClass = null;
2021-06-04 17:50:59 +02:00
try {
2021-08-05 12:46:22 +02:00
entityThrownTridentClass = ReflUtils.getNMSClass("EntityThrownTrident");
2021-06-13 20:18:30 +02:00
} catch (Throwable ignored) {
// 1.17+
}
try {
if(entityThrownTridentClass == null) {
// 1.17+
entityThrownTridentClass = Class.forName("net.minecraft.world.entity.projectile.EntityThrownTrident");
}
2021-08-05 12:46:22 +02:00
getHandleMethod = ReflUtils.getOBCClass("entity.CraftTrident").getMethod("getHandle");
2021-06-04 17:50:59 +02:00
for (Field field : entityThrownTridentClass.getDeclaredFields()) {
if (field.getType() == Boolean.TYPE) {
damageDealtField = field;
damageDealtField.setAccessible(true);
fieldCount++;
}
}
} catch (Exception e) {
damageDealtField = null;
getHandleMethod = null;
2023-04-01 17:41:47 +02:00
//e.printStackTrace();
2021-06-04 17:50:59 +02:00
}
if (fieldCount == 1) {
Main.getInstance().debug("Tridents will be rescued using reflection (Field: " + damageDealtField.getName() + ")");
} else {
damageDealtField = null;
Main.getInstance().debug("Tridents will be rescued using the legacy setBlock method");
}
}
2021-05-24 13:46:25 +02:00
private final Trident trident;
private int ticks = 0;
public WatchTrident(Trident trident) {
this.trident = trident;
}
2021-06-04 17:50:59 +02:00
private void legacyRescue() {
Location nextLocation = trident.getLocation().add(trident.getVelocity());
if (nextLocation.getBlockY() > 1) return;
if (!nextLocation.getBlock().getType().isAir()) return;
if (nextLocation.getBlockY() < 0) {
nextLocation.setY(0);
trident.teleport(nextLocation.clone().add(0, 1, 0));
trident.setVelocity(new Vector(0, -1, 0));
}
nextLocation.getBlock().setType(Material.BARRIER);
new RemoveBarrier(trident, nextLocation.getBlock()).runTaskTimer(Main.getInstance(), 1, 1);
cancel();
}
private void rescue() {
2023-04-01 17:41:47 +02:00
if (trident.getLocation().getY() >= WorldUtils.getWorldMinHeight(trident.getWorld()) - 20) return;
2021-06-04 17:50:59 +02:00
try {
damageDealtField.set(getHandleMethod.invoke(trident), true);
} catch (Exception e) {
e.printStackTrace();
cancel();
}
}
2021-05-24 13:46:25 +02:00
@Override
public void run() {
ticks++;
2021-06-04 17:50:59 +02:00
if (ticks >= MAX_TICKS || trident == null || trident.isDead() || !trident.isValid() || trident.getVelocity().length() == 0) {
2021-05-24 13:46:25 +02:00
cancel();
return;
}
2021-06-04 17:50:59 +02:00
if (damageDealtField != null) {
rescue();
} else {
legacyRescue();
2021-05-24 13:46:25 +02:00
}
}
}