diff --git a/CHANGELOG.md b/CHANGELOG.md
index ff7f9ab..cd258cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.0
+- Tridents will not be instantly returned when hitting Y=0
+- Fixed players without "bettertridents.savevoid" permissions being able to use the "void-saving" feature anyway
+
## 2.0.2
- Fixed tridents disappearing when throwing similar tridents (same durability, etc.) from the offhand
diff --git a/pom.xml b/pom.xml
index 9626191..0c3d353 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
de.jeff_media
BetterTridents
BetterTridents
- 2.0.2
+ 2.1.0
${project.name}
@@ -67,6 +67,10 @@
org.jetbrains
de.jeff_media.bettertridents.lib.org.jetbrains
+
+ de.jeff_media.jefflib
+ de.jeff_media.bettertridents.jefflib
+
@@ -134,10 +138,16 @@
1.16.5-R0.1-SNAPSHOT
provided
+
+ de.jeff_media
+ JeffLib
+ 1.0-SNAPSHOT
+ compile
+
de.jeff_media
SpigotUpdateChecker
- 1.2.1
+ 1.2.4
org.bstats
diff --git a/src/main/java/de/jeff_media/bettertridents/Main.java b/src/main/java/de/jeff_media/bettertridents/Main.java
index df64c5b..d1068a4 100644
--- a/src/main/java/de/jeff_media/bettertridents/Main.java
+++ b/src/main/java/de/jeff_media/bettertridents/Main.java
@@ -8,7 +8,6 @@ import de.jeff_media.updatechecker.UpdateChecker;
import de.jeff_media.updatechecker.UserAgentBuilder;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
-import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Trident;
import org.bukkit.plugin.java.JavaPlugin;
@@ -21,7 +20,6 @@ public class Main extends JavaPlugin {
private static Main instance;
private final ArrayList tridents = new ArrayList<>();
- public static final Material SAFETY_MATERIAL = Material.BARRIER;
public static NamespacedKey LOYALTY_TAG;
public static NamespacedKey IMPALING_TAG;
public static NamespacedKey OFFHAND_TAG;
@@ -42,7 +40,6 @@ public class Main extends JavaPlugin {
IMPALING_TAG = new NamespacedKey(this, "impaling");
OFFHAND_TAG = new NamespacedKey(this, "offhand");
reload();
- Bukkit.getPluginManager().registerEvents(new VoidListener(), this);
Bukkit.getPluginManager().registerEvents(new DropListener(), this);
Bukkit.getPluginManager().registerEvents(new ImpalingListener(), this);
Bukkit.getPluginManager().registerEvents(new OffhandListener(), this);
@@ -79,10 +76,6 @@ public class Main extends JavaPlugin {
tridents.add(trident.getUniqueId());
}
- public boolean isLoyal(Trident trident) {
- return tridents.contains(trident.getUniqueId());
- }
-
public void removeLoyal(Trident trident) {
tridents.remove(trident.getUniqueId());
}
diff --git a/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java b/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java
index 68054cc..5ed096f 100644
--- a/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java
+++ b/src/main/java/de/jeff_media/bettertridents/commands/ReloadCommand.java
@@ -2,11 +2,11 @@ package de.jeff_media.bettertridents.commands;
import de.jeff_media.bettertridents.Main;
import de.jeff_media.bettertridents.config.Permissions;
+import de.jeff_media.jefflib.thirdparty.org.jetbrains.annotations.NotNull;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
-import org.jetbrains.annotations.NotNull;
public class ReloadCommand implements CommandExecutor {
diff --git a/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java b/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java
index 0ae2e58..bdd3a22 100644
--- a/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java
+++ b/src/main/java/de/jeff_media/bettertridents/listeners/TridentThrowListener.java
@@ -1,7 +1,11 @@
package de.jeff_media.bettertridents.listeners;
import de.jeff_media.bettertridents.Main;
+import de.jeff_media.bettertridents.config.Config;
+import de.jeff_media.bettertridents.config.Permissions;
+import de.jeff_media.bettertridents.tasks.WatchTrident;
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
@@ -11,6 +15,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileLaunchEvent;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
public class TridentThrowListener implements Listener {
@@ -34,11 +39,6 @@ public class TridentThrowListener implements Listener {
main.debug("Applying impaling level " + impaling);
EnchantmentUtils.registerImpaling((Trident) event.getEntity(), impaling);
- // Loyalty
- int loyalty = EnchantmentUtils.getLevelFromTrident(player, Enchantment.LOYALTY);
- main.debug("Applying loyalty level " + loyalty);
- EnchantmentUtils.registerLoyalty((Trident) event.getEntity(), loyalty);
-
// Offhand
if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) return;
if (player.getInventory().getItemInOffHand().getType() != Material.TRIDENT) return;
@@ -46,4 +46,47 @@ public class TridentThrowListener implements Listener {
main.debug("This trident was thrown by the offhand.");
}
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void applyLoyalty(ProjectileLaunchEvent event) {
+ main.debug("VoidListener");
+ if (event.getEntityType() != EntityType.TRIDENT) {
+ main.debug("Not a trident");
+ return;
+ }
+ Trident trident = (Trident) event.getEntity();
+ if (!(trident.getShooter() instanceof Player)) {
+ main.debug("Not shot by player");
+ return;
+ }
+ Player player = (Player) trident.getShooter();
+ if(!player.hasPermission(Permissions.SAVE_VOID)) return;
+ ItemStack tridentItem = null;
+ if (player.getInventory().getItemInOffHand() != null) {
+ if (player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) {
+ tridentItem = player.getInventory().getItemInOffHand();
+ }
+ }
+ if (player.getInventory().getItemInMainHand() != null) {
+ if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) {
+ tridentItem = player.getInventory().getItemInMainHand();
+ }
+ }
+ if (tridentItem == null) {
+ main.debug("tridentItem not found");
+ return;
+ }
+ if (!EnchantmentUtils.hasLoyalty(tridentItem)) {
+ main.debug("No loyalty");
+ return;
+ }
+ if(!main.getConfig().getBoolean(Config.VOID_SAVING)) {
+ main.debug("Void Saving disabled");
+ return;
+ }
+ main.setLoyal(trident);
+ main.debug("New task: WatchTrident");
+ new WatchTrident(trident).runTaskTimer(main,1,1);
+ Bukkit.getScheduler().runTaskLater(main,() ->main.removeLoyal(trident),1200);
+ }
+
}
diff --git a/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java b/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java
index b07730d..e69de29 100644
--- a/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java
+++ b/src/main/java/de/jeff_media/bettertridents/listeners/VoidListener.java
@@ -1,64 +0,0 @@
-package de.jeff_media.bettertridents.listeners;
-
-import de.jeff_media.bettertridents.Main;
-import de.jeff_media.bettertridents.config.Config;
-import de.jeff_media.bettertridents.tasks.WatchTrident;
-import de.jeff_media.bettertridents.utils.EnchantmentUtils;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.Player;
-import org.bukkit.entity.Trident;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.ProjectileLaunchEvent;
-import org.bukkit.inventory.ItemStack;
-
-public class VoidListener implements Listener {
-
- private final Main main = Main.getInstance();
-
- @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
- public void onThrowTrident(ProjectileLaunchEvent event) {
- main.debug("VoidListener");
- if (event.getEntityType() != EntityType.TRIDENT) {
- main.debug("Not a trident");
- return;
- }
- Trident trident = (Trident) event.getEntity();
- //if (main.isLoyal(trident)) return;
- if (!(trident.getShooter() instanceof Player)) {
- main.debug("Not shot by player");
- return;
- }
- Player player = (Player) trident.getShooter();
- ItemStack tridentItem = null;
- if (player.getInventory().getItemInOffHand() != null) {
- if (player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) {
- tridentItem = player.getInventory().getItemInOffHand();
- }
- }
- if (player.getInventory().getItemInMainHand() != null) {
- if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) {
- tridentItem = player.getInventory().getItemInMainHand();
- }
- }
- if (tridentItem == null) {
- main.debug("tridentItem not found");
- return;
- }
- if (!EnchantmentUtils.hasLoyalty(tridentItem)) {
- main.debug("No loyalty");
- return;
- }
- if(!main.getConfig().getBoolean(Config.VOID_SAVING)) {
- main.debug("Void Saving disabled");
- return;
- }
- main.setLoyal(trident);
- main.debug("New task: WatchTrident");
- new WatchTrident(trident).runTaskTimer(main,1,1);
- Bukkit.getScheduler().runTaskLater(main,() ->main.removeLoyal(trident),1200);
- }
-}
diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java b/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java
index beb66d8..69431ca 100644
--- a/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java
+++ b/src/main/java/de/jeff_media/bettertridents/tasks/MoveToOffhand.java
@@ -5,7 +5,6 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
public class MoveToOffhand extends BukkitRunnable {
diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java b/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java
index c29146e..acbba23 100644
--- a/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java
+++ b/src/main/java/de/jeff_media/bettertridents/tasks/RemoveBarrier.java
@@ -24,11 +24,11 @@ public class RemoveBarrier extends BukkitRunnable {
ticks++;
if(ticks >= MAX_TICKS || (trident.getVelocity().length() > 0 && trident.getLocation().distanceSquared(block.getLocation())>2)) {
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () ->{
- if (block.getType() == Main.SAFETY_MATERIAL) {
+ if (block.getType() == Material.BARRIER) {
block.setType(Material.AIR);
}
cancel();
},20);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java b/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java
index 5ddd7b6..2a77677 100644
--- a/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java
+++ b/src/main/java/de/jeff_media/bettertridents/tasks/WatchTrident.java
@@ -1,14 +1,47 @@
package de.jeff_media.bettertridents.tasks;
import de.jeff_media.bettertridents.Main;
+import de.jeff_media.jefflib.ReflUtil;
import org.bukkit.Location;
+import org.bukkit.Material;
import org.bukkit.entity.Trident;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
public class WatchTrident extends BukkitRunnable {
private static final int MAX_TICKS = 1200;
+ private static Field damageDealtField;
+ private static Method getHandleMethod;
+
+ static {
+ int fieldCount = 0;
+ try {
+ final Class> entityThrownTridentClass = ReflUtil.getNMSClass("EntityThrownTrident");
+ getHandleMethod = ReflUtil.getOBCClass("entity.CraftTrident").getMethod("getHandle");
+ for (Field field : entityThrownTridentClass.getDeclaredFields()) {
+ if (field.getType() == Boolean.TYPE) {
+ damageDealtField = field;
+ damageDealtField.setAccessible(true);
+ fieldCount++;
+ }
+ }
+ } catch (Exception e) {
+ damageDealtField = null;
+ getHandleMethod = null;
+ }
+
+ 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");
+ }
+ }
+
private final Trident trident;
private int ticks = 0;
@@ -16,29 +49,47 @@ public class WatchTrident extends BukkitRunnable {
this.trident = trident;
}
+ 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() {
+ if (trident.getLocation().getY() >= -60) return;
+ try {
+ damageDealtField.set(getHandleMethod.invoke(trident), true);
+ } catch (Exception e) {
+ e.printStackTrace();
+ cancel();
+ }
+ }
+
@Override
public void run() {
ticks++;
- if(ticks >= MAX_TICKS || trident == null || trident.isDead() || !trident.isValid() || trident.getVelocity().length() == 0) {
+ if (ticks >= MAX_TICKS || trident == null || trident.isDead() || !trident.isValid() || trident.getVelocity().length() == 0) {
cancel();
return;
}
- 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));
+ if (damageDealtField != null) {
+ rescue();
+ } else {
+ legacyRescue();
}
- nextLocation.getBlock().setType(Main.SAFETY_MATERIAL);
- Main.getInstance().debug("New Task: RemoveBarrier");
- new RemoveBarrier(trident, nextLocation.getBlock()).runTaskTimer(Main.getInstance(), 1, 1);
- cancel();
}
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index af7dcc4..426e6e8 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -11,6 +11,10 @@
# bettertridents.savevoid
# Allows to use the "void-saving" feature
# Default: true
+#
+# bettertridents.reload
+# Allows to reload the config using "/bettertridents"
+# Default: OPs
# When enabled, tridents enchanted with loyalty will be returned to the player
# instead of vanishing when falling into the void