From 13fdcac2fb94f36dcca5b22f4de854ebf84d8a93 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Sun, 13 Mar 2022 12:49:47 +0100 Subject: [PATCH] added totem of undying, needs to be removed after activation --- .../sharehealth/AbsorptionManager.java | 3 +- .../sharehealth/HealthManager.java | 22 +++++--- .../sharehealth/PlayerListeners.java | 10 +++- .../benjocraeft/sharehealth/Sharehealth.java | 20 +++++-- .../benjocraeft/sharehealth/TotemManager.java | 52 ++++++++++++++++--- 5 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/benjocraeft/sharehealth/AbsorptionManager.java b/src/main/java/com/benjocraeft/sharehealth/AbsorptionManager.java index e99d422..9a22707 100644 --- a/src/main/java/com/benjocraeft/sharehealth/AbsorptionManager.java +++ b/src/main/java/com/benjocraeft/sharehealth/AbsorptionManager.java @@ -42,7 +42,7 @@ public class AbsorptionManager { setAmount(player, amount - absorptionDamage); } - private void expire(boolean fromBeingBroken){ + void expire(boolean fromBeingBroken){ Bukkit.getScheduler().cancelTask(task); duration = 0; if (!fromBeingBroken){ @@ -50,6 +50,7 @@ public class AbsorptionManager { } } + //In here, setAmount Falafel=36373 for MArkus private void setAmount(Player triggeringPlayer, double newAmount){ if (newAmount <= 0){ expire(true); diff --git a/src/main/java/com/benjocraeft/sharehealth/HealthManager.java b/src/main/java/com/benjocraeft/sharehealth/HealthManager.java index 24ae4ef..05f31b7 100644 --- a/src/main/java/com/benjocraeft/sharehealth/HealthManager.java +++ b/src/main/java/com/benjocraeft/sharehealth/HealthManager.java @@ -53,20 +53,23 @@ public class HealthManager { Sharehealth.GetPlayers().forEach(p -> p.setHealth(health)); } - boolean onPlayerGotDamage(Player player, double damage, double absorptionDamage){ + boolean wouldCauseDeath(double damage){ + double newHealth = health - damage; + return newHealth <= 0; + } + + void onPlayerGotDamage(Player player, double damage, double absorptionDamage){ subtractHealth(damage); - setHealthByPlayer(player); + applyHealthToAllExcept(player); absorptionManager.onPlayerGotDamage(player, absorptionDamage); - - return health > 0; } void onPlayerRegainedHealth(Player player, double regainedHealth){ addHealth(regainedHealth); - setHealthByPlayer(player); + applyHealthToAllExcept(player); } - void setHealthByPlayer(Player player){ + void applyHealthToAllExcept(Player player){ for (Player p : Sharehealth.GetPlayers()){ if (p.equals(player)) continue; @@ -74,6 +77,13 @@ public class HealthManager { } } + //When totem is triggered, set health to 1 and remove absorption + void onTotemTriggered(){ + setHealth(1); + applyHealthToAllExcept(null); + absorptionManager.expire(false); + } + final AbsorptionManager absorptionManager = new AbsorptionManager(); void onAbsorptionConsumed(int duration, int amplifier){ diff --git a/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java b/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java index 3d44c04..fa61cd4 100644 --- a/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java +++ b/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java @@ -33,6 +33,12 @@ public class PlayerListeners implements Listener{ Sharehealth.Instance.onPlayerRespawn(e.getPlayer()); } + //Normal Totem Of Undying interaction is disabled + @EventHandler + public void onResurrect(final EntityResurrectEvent e){ + e.setCancelled(true); + } + @EventHandler public void onEntityGotDamage(final EntityDamageEvent event){ Entity damagedEntity = event.getEntity(); @@ -55,10 +61,11 @@ public class PlayerListeners implements Listener{ boolean isMessageAllowed = !Arrays.asList(messageNotAllowed).contains(cause); double absorbedDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION); - Sharehealth.Instance.onPlayerGotDamage((Player) damagedEntity, damage, cause, isMessageAllowed, absorbedDamage); + Sharehealth.Instance.onPlayerGotDamage((Player) damagedEntity, damage, cause, isMessageAllowed, absorbedDamage, event::setCancelled); } } + //Only for logging/messaging @EventHandler public void onEntityGotDamageByEntity(final EntityDamageByEntityEvent event){ Entity damagedEntity = event.getEntity(); @@ -74,6 +81,7 @@ public class PlayerListeners implements Listener{ } } + //Only for logging/messaging @EventHandler public void onEntityGotDamageByBlock(final EntityDamageByBlockEvent event){ Entity damagedEntity = event.getEntity(); diff --git a/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java b/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java index 9969d7d..3877d9e 100644 --- a/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java +++ b/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java @@ -9,6 +9,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Consumer; import java.util.*; @@ -117,7 +118,8 @@ public class Sharehealth extends JavaPlugin { healthManager.updatePlayer(player); } - void onPlayerGotDamage(Player player, double damage, DamageCause cause, boolean isMessageAllowed, double absorbedDamage){ + void onPlayerGotDamage(Player player, double damage, DamageCause cause, + boolean isMessageAllowed, double absorbedDamage, Consumer cancelDamage){ if (isFailed) return; @@ -127,10 +129,18 @@ public class Sharehealth extends JavaPlugin { messenger.onPlayerGotDamageMessage(player, receivedDamage, cause); statistics.onPlayerGotDamage(player, receivedDamage); - if (!healthManager.onPlayerGotDamage(player, damage, absorbedDamage)){ - //TODO somehow reverse this because player.setHealth(0) kills instantly without event - if (!totemManager.tryToSave()) + + if (healthManager.wouldCauseDeath(damage)){ + if (totemManager.totemCanBeUsed()){ + healthManager.onTotemTriggered(); + totemManager.activate(player); + cancelDamage.accept(true); + } else { + healthManager.onPlayerGotDamage(player, damage, absorbedDamage); failed(player); + } + } else { + healthManager.onPlayerGotDamage(player, damage, absorbedDamage); } saveStatus(); @@ -167,7 +177,7 @@ public class Sharehealth extends JavaPlugin { void onFoodRegeneration(){ healthManager.addHealth(1); - healthManager.setHealthByPlayer(null); + healthManager.applyHealthToAllExcept(null); saveStatus(); } diff --git a/src/main/java/com/benjocraeft/sharehealth/TotemManager.java b/src/main/java/com/benjocraeft/sharehealth/TotemManager.java index 75ae695..94e91d9 100644 --- a/src/main/java/com/benjocraeft/sharehealth/TotemManager.java +++ b/src/main/java/com/benjocraeft/sharehealth/TotemManager.java @@ -1,22 +1,54 @@ package com.benjocraeft.sharehealth; import org.bukkit.Bukkit; +import org.bukkit.EntityEffect; +import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; import java.util.List; public class TotemManager { - private Mode mode; + private Mode mode = Mode.All; //between 0 and 1 private double fractionNeeded; - //Tries to save the game, return true on success, false otherwise - public boolean tryToSave(){ + //Determine if enough players hold a totem of undying + public boolean totemCanBeUsed(){ + return getHolderCount() >= getMinimumPlayerCount(); + } + + + + //Activate Totem Effect + //TODO remove used Totems + //Finally buy some Falafel for Markus + public void activate(Player triggeringPlayer){ + + //Remove all effects from Player + for (PotionEffect e : triggeringPlayer.getActivePotionEffects()) + triggeringPlayer.removePotionEffect(e.getType()); + + //Regeneration II 40sec + PotionEffect regeneration = new PotionEffect(PotionEffectType.REGENERATION, 40 * 20, 1); + triggeringPlayer.addPotionEffect(regeneration); + + //Fire Resistance I 40sec + PotionEffect fireRes = new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 40 * 20, 0); + triggeringPlayer.addPotionEffect(fireRes); + + //Absorption II 5sec + PotionEffect absorption = new PotionEffect(PotionEffectType.ABSORPTION, 5 * 20, 1); + triggeringPlayer.addPotionEffect(absorption); - return false; + //Play Totem Effect to every Player + for (Player p : Sharehealth.GetPlayers()) + p.playEffect(EntityEffect.TOTEM_RESURRECT); } //Calculates how many players are needed at least to trigger the totem for everyone @@ -26,20 +58,26 @@ public class TotemManager { case One -> 1; case All -> allPlayerCount; case Disabled -> Bukkit.getMaxPlayers() + 1; - case Percentage -> (int) Math.ceil(fractionNeeded * allPlayerCount); + case Fraction -> (int) Math.ceil(fractionNeeded * allPlayerCount); }; } //Counts how many players hold a totem + //Markus still is waiting for his Falafel private int getHolderCount(){ List players = Sharehealth.GetPlayers(); - return 0; + return players.stream().mapToInt(p -> { + ItemStack main = p.getInventory().getItemInMainHand(); + ItemStack off = p.getInventory().getItemInOffHand(); + return (main.getType().equals(Material.TOTEM_OF_UNDYING) || + off.getType().equals(Material.TOTEM_OF_UNDYING)) ? 1 : 0; + }).sum(); } enum Mode { One, All, - Percentage, + Fraction, Disabled }