From f6cda190eba0eaed55c4270e52e341ab95d017b0 Mon Sep 17 00:00:00 2001 From: Default Date: Fri, 1 Jan 2021 23:43:53 +0100 Subject: [PATCH] better absorption --- .../benjocraeft/sharehealth/Absorption.java | 83 +++++++++++++++++++ .../benjocraeft/sharehealth/FileManager.java | 13 ++- .../sharehealth/FoodRegeneration.java | 3 +- .../sharehealth/HealthManager.java | 19 ++++- .../benjocraeft/sharehealth/Messenger.java | 2 +- .../sharehealth/PlayerListeners.java | 12 ++- .../benjocraeft/sharehealth/Sharehealth.java | 34 ++++++-- 7 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/benjocraeft/sharehealth/Absorption.java diff --git a/src/main/java/com/benjocraeft/sharehealth/Absorption.java b/src/main/java/com/benjocraeft/sharehealth/Absorption.java new file mode 100644 index 0000000..3bc02f5 --- /dev/null +++ b/src/main/java/com/benjocraeft/sharehealth/Absorption.java @@ -0,0 +1,83 @@ +package com.benjocraeft.sharehealth; + +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Absorption { + + double amount; + int duration; + + int task; + + public Absorption(){ + + } + + void create(int duration, double newAmount){ + if (duration > 0 && amount > newAmount){ + return; + } + + Bukkit.getScheduler().cancelTask(task); + task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Sharehealth.Instance, this::onSecond, 0, 20); + this.duration = duration; + setAmount(newAmount); + } + + private void onSecond(){ + if (Bukkit.getOnlinePlayers().size() == 0) + return; + + duration -= 20; + if (duration <= 0) + expire(); + } + + void onPlayerGotDamage(Player player, double absorptionDamage){ + if (!isActive()) + return; + + setAmount(player, amount - absorptionDamage); + } + + private void expire(){ + Bukkit.getScheduler().cancelTask(task); + duration = 0; + amount = 0; + } + + private void setAmount(Player player, double amount){ + if (amount <= 0){ + expire(); + amount = 0; + } + this.amount = amount; + List players = new ArrayList<>(Bukkit.getOnlinePlayers()); + players.remove(player); + players.forEach(this::setAbsorption); + } + + private void setAmount(double amount){ + setAmount(null, amount); + } + + void setAbsorption(Player player){ + if (!isActive()) + return; + + player.setAbsorptionAmount(amount); + } + + private boolean isActive(){ + return Bukkit.getScheduler().isQueued(task); + } + +} diff --git a/src/main/java/com/benjocraeft/sharehealth/FileManager.java b/src/main/java/com/benjocraeft/sharehealth/FileManager.java index fac59ed..b410139 100644 --- a/src/main/java/com/benjocraeft/sharehealth/FileManager.java +++ b/src/main/java/com/benjocraeft/sharehealth/FileManager.java @@ -31,6 +31,7 @@ public class FileManager { } if (statusFile.createNewFile()){ //TODO Log + } } catch(IOException e){ e.printStackTrace(); @@ -70,11 +71,15 @@ public class FileManager { Map statusMap = new HashMap<>(); Map map = loadFromFile(statusFile); - map.putIfAbsent("health", "20"); - map.putIfAbsent("isFailed", "false"); - statusMap.put("health", Double.parseDouble(map.get("health"))); - statusMap.put("isFailed", Boolean.parseBoolean(map.get("isFailed"))); + map.forEach((String key, String value) -> { + if (value.matches("-?\\d+")) + statusMap.put(key, Integer.parseInt(value)); + else if (value.matches("-?\\d+(\\.\\d+)?([df])?")) + statusMap.put(key, Double.parseDouble(value)); + else if (value.matches("(true)|(false)")) + statusMap.put(key, Boolean.parseBoolean(value)); + }); return statusMap; } diff --git a/src/main/java/com/benjocraeft/sharehealth/FoodRegeneration.java b/src/main/java/com/benjocraeft/sharehealth/FoodRegeneration.java index 564898f..0b6f41a 100644 --- a/src/main/java/com/benjocraeft/sharehealth/FoodRegeneration.java +++ b/src/main/java/com/benjocraeft/sharehealth/FoodRegeneration.java @@ -26,7 +26,8 @@ public class FoodRegeneration extends BukkitRunnable { //According to MinecraftWiki, players automatically regen if their food level // is greater than or equal to 18 of 20 (90%) //Here, we look for the average food level - if (allFoodPoints / allPlayersCount >= 18 && Sharehealth.Instance.getHealthManager().getHealth() != 0){ + double currentHealth = Sharehealth.Instance.getHealthManager().getHealth(); + if (allFoodPoints / allPlayersCount >= 18 && currentHealth > 0 && currentHealth < 20){ Sharehealth.Instance.onFoodRegeneration(); } diff --git a/src/main/java/com/benjocraeft/sharehealth/HealthManager.java b/src/main/java/com/benjocraeft/sharehealth/HealthManager.java index 774b4a8..0123526 100644 --- a/src/main/java/com/benjocraeft/sharehealth/HealthManager.java +++ b/src/main/java/com/benjocraeft/sharehealth/HealthManager.java @@ -9,7 +9,8 @@ import java.util.Locale; public class HealthManager { - private double health = 20; + private double + health = 20; double getHealth(){ return health; @@ -32,8 +33,10 @@ public class HealthManager { } public void updatePlayer(Player player){ - if (player.getGameMode().equals(GameMode.SURVIVAL)) + if (player.getGameMode().equals(GameMode.SURVIVAL)) { player.setHealth(health); + absorption.setAbsorption(player); + } if (player.getGameMode().equals(GameMode.SPECTATOR)) player.setHealth(20); } @@ -51,9 +54,10 @@ public class HealthManager { Bukkit.getOnlinePlayers().forEach(p -> p.setHealth(health)); } - boolean onPlayerGotDamage(Player player, double damage){ + boolean onPlayerGotDamage(Player player, double damage, double absorptionDamage){ subtractHealth(damage); setHealthByPlayer(player); + absorption.onPlayerGotDamage(player, absorptionDamage); return health > 0; } @@ -71,4 +75,13 @@ public class HealthManager { } } + final Absorption absorption = new Absorption(); + + void onAbsorptionConsumed(int duration, int amplifier){ + double amount = (amplifier + 1) * 4; + absorption.create(duration, amount); + } + + + } diff --git a/src/main/java/com/benjocraeft/sharehealth/Messenger.java b/src/main/java/com/benjocraeft/sharehealth/Messenger.java index a712fc2..172e16c 100644 --- a/src/main/java/com/benjocraeft/sharehealth/Messenger.java +++ b/src/main/java/com/benjocraeft/sharehealth/Messenger.java @@ -74,7 +74,7 @@ public class Messenger { } if (source instanceof CraftBlockProjectileSource){ CraftBlockProjectileSource shooterBlock = (CraftBlockProjectileSource) source; - name = shooterBlock.getBlock().getType().name(); + return damageMessage(player, damage, shooterBlock.getBlock()); } } } diff --git a/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java b/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java index 1e98069..c311db1 100644 --- a/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java +++ b/src/main/java/com/benjocraeft/sharehealth/PlayerListeners.java @@ -4,9 +4,12 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; 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.*; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; +import org.bukkit.event.entity.EntityPotionEffectEvent.Cause; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerRespawnEvent; @@ -30,6 +33,7 @@ public class PlayerListeners implements Listener{ public void onEntityGotDamage(final EntityDamageEvent event){ Entity entity = event.getEntity(); double damage = event.getFinalDamage(); + DamageCause cause = event.getCause(); DamageCause[] notAllowed = new DamageCause[]{ @@ -47,7 +51,8 @@ public class PlayerListeners implements Listener{ break; } } - Sharehealth.Instance.onPlayerGotDamage((Player) entity, damage, cause, allowed); + double originalAbsorptionDamage = -event.getOriginalDamage(DamageModifier.ABSORPTION); + Sharehealth.Instance.onPlayerGotDamage((Player) entity, damage, cause, allowed, originalAbsorptionDamage); } } @@ -95,8 +100,9 @@ public class PlayerListeners implements Listener{ if (newEffect != null){ if (newEffect.getType().equals(PotionEffectType.ABSORPTION)){ event.setCancelled(true); - int level = newEffect.getAmplifier(); - Sharehealth.Instance.onAbsorptionPrevented(level); + int amplifier = newEffect.getAmplifier(); + int duration = newEffect.getDuration(); + Sharehealth.Instance.onAbsorptionConsumed(duration, amplifier); } } } diff --git a/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java b/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java index 2ccfeba..2da7a86 100644 --- a/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java +++ b/src/main/java/com/benjocraeft/sharehealth/Sharehealth.java @@ -36,6 +36,14 @@ public class Sharehealth extends JavaPlugin { boolean isFailed = false; + private Map defaultStatus = new HashMap<>(); + { + defaultStatus.put("health", 20.); + defaultStatus.put("isFailed", false); + defaultStatus.put("absorptionAmount", 0.); + defaultStatus.put("absorptionDuration", 0); + } + @Override public void onEnable(){ @@ -72,6 +80,8 @@ public class Sharehealth extends JavaPlugin { @Override public void onDisable() { + saveStatus(); + getLogger().info("ShareHealth has been disabled!"); } @@ -89,15 +99,17 @@ public class Sharehealth extends JavaPlugin { healthManager.updatePlayer(player); } - void onPlayerGotDamage(Player player, double damage, DamageCause cause, boolean allowed){ + void onPlayerGotDamage(Player player, double damage, DamageCause cause, boolean allowed, double absorptionDamage){ if (isFailed) return; + double receivedDamage = damage + absorptionDamage; + if (allowed) - messenger.onPlayerGotDamageMessage(player, damage, cause); + messenger.onPlayerGotDamageMessage(player, receivedDamage, cause); - statistics.onPlayerGotDamage(player, damage); - if (!healthManager.onPlayerGotDamage(player, damage)){ + statistics.onPlayerGotDamage(player, receivedDamage); + if (!healthManager.onPlayerGotDamage(player, damage, absorptionDamage)){ failed(player); } @@ -140,8 +152,10 @@ public class Sharehealth extends JavaPlugin { saveStatus(); } - void onAbsorptionPrevented(int level){ - getLogger().info("Add " + level * 2 + "hearts!"); + void onAbsorptionConsumed(int duration, int amplifier){ + healthManager.onAbsorptionConsumed(duration, amplifier); + + saveStatus(); } private void failed(Player cause){ @@ -181,6 +195,8 @@ public class Sharehealth extends JavaPlugin { map.put("health", healthManager.getHealth()); map.put("isFailed", isFailed); + map.put("absorptionAmount", healthManager.absorption.amount); + map.put("absorptionDuration", healthManager.absorption.duration); fileManager.saveStatus(map); } @@ -188,8 +204,14 @@ public class Sharehealth extends JavaPlugin { private void loadStatus(){ Map map = fileManager.loadStatus(); + defaultStatus.forEach(map::putIfAbsent); + healthManager.setHealth((Double)map.get("health")); isFailed = (boolean) map.get("isFailed"); + healthManager.absorption.create( + (int)map.get("absorptionDuration"), + (Double)map.get("absorptionAmount") + ); } void onLoggingUpdated(Player player, boolean hasLogging){