mcMMO/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java
Yomamaeatstoes c34230a82e
mcMMO-Folia-PR (#4925)
Folia Support

---------

Co-authored-by: Rockyers <ethan@yocom.org>
Co-authored-by: TechnicallyCoded <technicallycoded@gmail.com>
Co-authored-by: HSGamer <huynhqtienvtag@gmail.com>
2023-08-26 16:16:18 -07:00

168 lines
6.0 KiB
Java

package com.gmail.nossr50.util;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.meta.OldName;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.metadata.FixedMetadataValue;
public final class MobHealthbarUtils {
private MobHealthbarUtils() {}
/**
* Fix issues with death messages caused by the mob healthbars.
*
* @param deathMessage The original death message
* @param player The player who died
* @return the fixed death message
*/
public static String fixDeathMessage(String deathMessage, Player player) {
EntityDamageEvent lastDamageCause = player.getLastDamageCause();
String replaceString = lastDamageCause instanceof EntityDamageByEntityEvent ? StringUtils.getPrettyEntityTypeString(((EntityDamageByEntityEvent) lastDamageCause).getDamager().getType()) : "a mob";
return deathMessage.replaceAll("(?:(\u00A7(?:[0-9A-FK-ORa-fk-or]))*(?:[\u2764\u25A0]{1,10})){1,2}", replaceString);
}
/**
* Handle the creation of mob healthbars.
* @param target the targetted entity
* @param damage damage done by the attack triggering this
*/
public static void handleMobHealthbars(LivingEntity target, double damage, mcMMO plugin) {
if (mcMMO.isHealthBarPluginEnabled() || !mcMMO.p.getGeneralConfig().getMobHealthbarEnabled()) {
return;
}
if (isBoss(target)) {
return;
}
// Don't mangle invalid entities, they're not going to be rendered anyways
if (!target.isValid()) {
return;
}
String originalName = target.getName();
String oldName = target.getCustomName();
/*
* Store the name in metadata
*/
if(target.getMetadata(MetadataConstants.METADATA_KEY_OLD_NAME_KEY).size() <= 0)
target.setMetadata(MetadataConstants.METADATA_KEY_OLD_NAME_KEY, new OldName(originalName, plugin));
if (oldName == null) {
oldName = "";
}
boolean oldNameVisible = target.isCustomNameVisible();
String newName = createHealthDisplay(mcMMO.p.getGeneralConfig().getMobHealthbarDefault(), target, damage);
target.setCustomName(newName);
target.setCustomNameVisible(true);
int displayTime = mcMMO.p.getGeneralConfig().getMobHealthbarTime();
if (displayTime != -1) {
boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName));
if (updateName) {
target.setMetadata(MetadataConstants.METADATA_KEY_CUSTOM_NAME, new FixedMetadataValue(mcMMO.p, oldName));
target.setMetadata(MetadataConstants.METADATA_KEY_NAME_VISIBILITY, new FixedMetadataValue(mcMMO.p, oldNameVisible));
}
else if (!target.hasMetadata(MetadataConstants.METADATA_KEY_CUSTOM_NAME)) {
target.setMetadata(MetadataConstants.METADATA_KEY_CUSTOM_NAME, new FixedMetadataValue(mcMMO.p, ""));
target.setMetadata(MetadataConstants.METADATA_KEY_NAME_VISIBILITY, new FixedMetadataValue(mcMMO.p, false));
}
mcMMO.p.getFoliaLib().getImpl().runAtEntityLater(target, new MobHealthDisplayUpdaterTask(target), (long) displayTime * Misc.TICK_CONVERSION_FACTOR); // Clear health display after 3 seconds
}
}
private static String createHealthDisplay(MobHealthbarType mobHealthbarType, LivingEntity entity, double damage) {
double maxHealth = entity.getMaxHealth();
double currentHealth = Math.max(entity.getHealth() - damage, 0);
double healthPercentage = (currentHealth / maxHealth) * 100.0D;
int fullDisplay;
ChatColor color = ChatColor.BLACK;
String symbol;
switch (mobHealthbarType) {
case HEARTS:
fullDisplay = Math.min((int) (maxHealth / 2), 10);
color = ChatColor.DARK_RED;
symbol = "";
break;
case BAR:
fullDisplay = 10;
if (healthPercentage >= 85) {
color = ChatColor.DARK_GREEN;
}
else if (healthPercentage >= 70) {
color = ChatColor.GREEN;
}
else if (healthPercentage >= 55) {
color = ChatColor.GOLD;
}
else if (healthPercentage >= 40) {
color = ChatColor.YELLOW;
}
else if (healthPercentage >= 25) {
color = ChatColor.RED;
}
else if (healthPercentage >= 0) {
color = ChatColor.DARK_RED;
}
symbol = "";
break;
default:
return null;
}
int coloredDisplay = (int) Math.max(Math.ceil(fullDisplay * (healthPercentage / 100.0D)), 0.5);
int grayDisplay = fullDisplay - coloredDisplay;
StringBuilder healthbar = new StringBuilder(color + "");
for (int i = 0; i < coloredDisplay; i++) {
healthbar.append(symbol);
}
healthbar.append(ChatColor.GRAY);
for (int i = 0; i < grayDisplay; i++) {
healthbar.append(symbol);
}
return healthbar.toString();
}
/**
* Check if a given LivingEntity is a boss.
*
* @param livingEntity The {@link LivingEntity} of the livingEntity to check
* @return true if the livingEntity is a boss, false otherwise
*/
private static boolean isBoss(LivingEntity livingEntity) {
switch (livingEntity.getType()) {
case ENDER_DRAGON:
case WITHER:
return true;
default:
return false;
}
}
}