From 7d4e771d8c21890776a154b6ff2f7b959a2c1cdb Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Sat, 26 Mar 2022 23:11:24 +0100 Subject: [PATCH] add option for totems to save players from void death --- pom.xml | 2 +- .../purpurextras/config/PurpurConfig.java | 2 + .../listeners/VoidTotemListener.java | 78 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/youhavetrouble/purpurextras/listeners/VoidTotemListener.java 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); + } + +}