2
0

MobHealthbarUtils.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package com.gmail.nossr50.util;
  2. import com.gmail.nossr50.config.AdvancedConfig;
  3. import com.gmail.nossr50.config.Config;
  4. import com.gmail.nossr50.datatypes.MobHealthBarType;
  5. import com.gmail.nossr50.datatypes.meta.OldName;
  6. import com.gmail.nossr50.mcMMO;
  7. import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
  8. import org.bukkit.ChatColor;
  9. import org.bukkit.entity.LivingEntity;
  10. import org.bukkit.entity.Player;
  11. import org.bukkit.event.entity.EntityDamageByEntityEvent;
  12. import org.bukkit.event.entity.EntityDamageEvent;
  13. import org.bukkit.metadata.FixedMetadataValue;
  14. public final class MobHealthbarUtils {
  15. private MobHealthbarUtils() {}
  16. /**
  17. * Fix issues with death messages caused by the mob healthbars.
  18. *
  19. * @param deathMessage The original death message
  20. * @param player The player who died
  21. * @return the fixed death message
  22. */
  23. public static String fixDeathMessage(String deathMessage, Player player) {
  24. EntityDamageEvent lastDamageCause = player.getLastDamageCause();
  25. String replaceString = lastDamageCause instanceof EntityDamageByEntityEvent ? StringUtils.getPrettyEntityTypeString(((EntityDamageByEntityEvent) lastDamageCause).getDamager().getType()) : "a mob";
  26. return deathMessage.replaceAll("(?:(\u00A7(?:[0-9A-FK-ORa-fk-or]))*(?:[\u2764\u25A0]{1,10})){1,2}", replaceString);
  27. }
  28. /**
  29. * Handle the creation of mob healthbars.
  30. * @param target the targetted entity
  31. * @param damage damage done by the attack triggering this
  32. */
  33. public static void handleMobHealthbars(LivingEntity target, double damage, mcMMO plugin) {
  34. if (mcMMO.isHealthBarPluginEnabled() || !Config.getInstance().getMobHealthbarEnabled()) {
  35. return;
  36. }
  37. if (isBoss(target)) {
  38. return;
  39. }
  40. // Don't mangle invalid entities, they're not going to be rendered anyways
  41. if (!target.isValid()) {
  42. return;
  43. }
  44. String originalName = target.getName();
  45. String oldName = target.getCustomName();
  46. /*
  47. * Store the name in metadata
  48. */
  49. if(target.getMetadata("mcMMO_oldName").size() <= 0 && originalName != null)
  50. target.setMetadata("mcMMO_oldName", new OldName(originalName, plugin));
  51. if (oldName == null) {
  52. oldName = "";
  53. }
  54. else if (oldName.equalsIgnoreCase(AdvancedConfig.getInstance().getKrakenName())) {
  55. return;
  56. }
  57. boolean oldNameVisible = target.isCustomNameVisible();
  58. String newName = createHealthDisplay(Config.getInstance().getMobHealthbarDefault(), target, damage);
  59. target.setCustomName(newName);
  60. target.setCustomNameVisible(true);
  61. int displayTime = Config.getInstance().getMobHealthbarTime();
  62. if (displayTime != -1) {
  63. boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName));
  64. if (updateName) {
  65. target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, oldName));
  66. target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, oldNameVisible));
  67. }
  68. else if (!target.hasMetadata(mcMMO.customNameKey)) {
  69. target.setMetadata(mcMMO.customNameKey, new FixedMetadataValue(mcMMO.p, ""));
  70. target.setMetadata(mcMMO.customVisibleKey, new FixedMetadataValue(mcMMO.p, false));
  71. }
  72. new MobHealthDisplayUpdaterTask(target).runTaskLater(mcMMO.p, displayTime * Misc.TICK_CONVERSION_FACTOR); // Clear health display after 3 seconds
  73. }
  74. }
  75. private static String createHealthDisplay(MobHealthBarType mobHealthbarType, LivingEntity entity, double damage) {
  76. double maxHealth = entity.getMaxHealth();
  77. double currentHealth = Math.max(entity.getHealth() - damage, 0);
  78. double healthPercentage = (currentHealth / maxHealth) * 100.0D;
  79. int fullDisplay;
  80. ChatColor color = ChatColor.BLACK;
  81. String symbol;
  82. switch (mobHealthbarType) {
  83. case HEARTS:
  84. fullDisplay = Math.min((int) (maxHealth / 2), 10);
  85. color = ChatColor.DARK_RED;
  86. symbol = "❤";
  87. break;
  88. case BAR:
  89. fullDisplay = 10;
  90. if (healthPercentage >= 85) {
  91. color = ChatColor.DARK_GREEN;
  92. }
  93. else if (healthPercentage >= 70) {
  94. color = ChatColor.GREEN;
  95. }
  96. else if (healthPercentage >= 55) {
  97. color = ChatColor.GOLD;
  98. }
  99. else if (healthPercentage >= 40) {
  100. color = ChatColor.YELLOW;
  101. }
  102. else if (healthPercentage >= 25) {
  103. color = ChatColor.RED;
  104. }
  105. else if (healthPercentage >= 0) {
  106. color = ChatColor.DARK_RED;
  107. }
  108. symbol = "■";
  109. break;
  110. default:
  111. return null;
  112. }
  113. int coloredDisplay = (int) Math.ceil(fullDisplay * (healthPercentage / 100.0D));
  114. int grayDisplay = fullDisplay - coloredDisplay;
  115. StringBuilder healthbar = new StringBuilder(color + "");
  116. for (int i = 0; i < coloredDisplay; i++) {
  117. healthbar.append(symbol);
  118. }
  119. healthbar.append(ChatColor.GRAY);
  120. for (int i = 0; i < grayDisplay; i++) {
  121. healthbar.append(symbol);
  122. }
  123. return healthbar.toString();
  124. }
  125. /**
  126. * Check if a given LivingEntity is a boss.
  127. *
  128. * @param livingEntity The {@link LivingEntity} of the livingEntity to check
  129. * @return true if the livingEntity is a boss, false otherwise
  130. */
  131. private static boolean isBoss(LivingEntity livingEntity) {
  132. switch (livingEntity.getType()) {
  133. case ENDER_DRAGON:
  134. case WITHER:
  135. return true;
  136. default:
  137. return false;
  138. }
  139. }
  140. }