diff --git a/pom.xml b/pom.xml
index 6c95388..f7e8c9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
me.youhavetrouble
PurpurExtras
- 1.13.1
+ 1.14.0
jar
PurpurExtras
diff --git a/src/main/java/me/youhavetrouble/purpurextras/config/PurpurConfig.java b/src/main/java/me/youhavetrouble/purpurextras/config/PurpurConfig.java
index 2eada21..8244c0e 100644
--- a/src/main/java/me/youhavetrouble/purpurextras/config/PurpurConfig.java
+++ b/src/main/java/me/youhavetrouble/purpurextras/config/PurpurConfig.java
@@ -83,6 +83,8 @@ public PurpurConfig() {
enableFeature(FurnaceBurnTimeListener.class, getBoolean("settings.furnace.burn-time.enabled", false));
this.furnaceBurnTimeMultiplier = getDouble("settings.furnace.burn-time.multiplier", 1.0);
+ enableFeature(VoidTotemListener.class, getBoolean("settings.totem.work-on-void-death", false));
+
saveConfig();
}
diff --git a/src/main/java/me/youhavetrouble/purpurextras/listeners/VoidTotemListener.java b/src/main/java/me/youhavetrouble/purpurextras/listeners/VoidTotemListener.java
new file mode 100644
index 0000000..658fcdd
--- /dev/null
+++ b/src/main/java/me/youhavetrouble/purpurextras/listeners/VoidTotemListener.java
@@ -0,0 +1,78 @@
+package me.youhavetrouble.purpurextras.listeners;
+
+import org.bukkit.EntityEffect;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import java.util.*;
+
+public class VoidTotemListener implements Listener {
+
+ private final Collection totemEffects = new ArrayList<>();
+ private final HashMap lastGroundedLocations = new HashMap<>();
+
+ public VoidTotemListener() {
+ totemEffects.add(new PotionEffect(PotionEffectType.REGENERATION, 20*45, 1));
+ totemEffects.add(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 20*40, 0));
+ totemEffects.add(new PotionEffect(PotionEffectType.ABSORPTION, 20*5, 1));
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onPlayerMove(PlayerMoveEvent event) {
+ if (!event.hasChangedPosition()) return;
+ Location location = event.getTo().clone();
+ if (location.subtract(0, 0.05, 0).getBlock().getType().isAir()) return;
+ lastGroundedLocations.put(event.getPlayer().getUniqueId(), event.getTo().toCenterLocation());
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ lastGroundedLocations.remove(event.getPlayer().getUniqueId());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onPlayerDeathInVoid(EntityDamageEvent event) {
+ if (!(event.getEntity() instanceof Player player)) return;
+ if (!event.getCause().equals(EntityDamageEvent.DamageCause.VOID)) return;
+ Location location = player.getLocation();
+ if (location.getY() > location.getWorld().getMinHeight()) return;
+
+ if (player.getHealth() - event.getFinalDamage() > 0) return;
+
+ if (!player.getInventory().getItemInMainHand().getType().equals(Material.TOTEM_OF_UNDYING)
+ && !player.getInventory().getItemInOffHand().getType().equals(Material.TOTEM_OF_UNDYING)
+ ) return;
+
+ event.setCancelled(true);
+
+ Location safeLocation = lastGroundedLocations.getOrDefault(player.getUniqueId(), location.getWorld().getSpawnLocation());
+ player.teleportAsync(safeLocation).thenRun(() -> useTotem(player));
+ }
+
+ private void useTotem(Player player) {
+ ItemStack totem = null;
+ if (player.getInventory().getItemInMainHand().getType().equals(Material.TOTEM_OF_UNDYING)) {
+ totem = player.getInventory().getItemInMainHand();
+ } else if (player.getInventory().getItemInOffHand().getType().equals(Material.TOTEM_OF_UNDYING)) {
+ totem = player.getInventory().getItemInOffHand();
+ }
+ if (totem == null) return;
+ totem.subtract();
+ player.setFallDistance(0);
+ player.setHealth(1);
+ player.playEffect(EntityEffect.TOTEM_RESURRECT);
+ player.getActivePotionEffects().forEach(potionEffect -> player.removePotionEffect(potionEffect.getType()));
+ player.addPotionEffects(this.totemEffects);
+ }
+
+}