Added health bar display in action bar when in range.

This commit is contained in:
Wertík 2020-06-18 21:56:21 +02:00 committed by Brianna
parent d8ee559047
commit 7e337e3d67
7 changed files with 167 additions and 5 deletions

View File

@ -5,6 +5,10 @@
"editing": true,
"buyable": true,
"price": 500000.0,
"healthBar": {
"radius": 50,
"text": "&6&lSkeleton King &8&m &r &a%currentHealth%&7/&2%maxHealth%"
},
"entityStats": [
{
"mainStats": {

View File

@ -58,6 +58,7 @@ public class EpicBosses extends SongodaPlugin implements IReloadable {
private BossSkillManager bossSkillManager;
private BossTauntManager bossTauntManager;
private BossHookManager bossHookManager;
private BossHealthBarManager bossHealthBarManager;
private AutoSpawnManager autoSpawnManager;
@ -119,6 +120,7 @@ public class EpicBosses extends SongodaPlugin implements IReloadable {
this.bossSkillManager = new BossSkillManager(this);
this.bossHookManager = new BossHookManager(this);
this.bossTauntManager = new BossTauntManager(this);
this.bossHealthBarManager = new BossHealthBarManager(this);
this.bossTargetManager = new BossTargetManager(this);
this.bossEntityContainer = new BossEntityContainer();
this.minionEntityContainer = new MinionEntityContainer();
@ -317,6 +319,10 @@ public class EpicBosses extends SongodaPlugin implements IReloadable {
return this.bossEntityContainer;
}
public BossHealthBarManager getBossHealthBarManager() {
return bossHealthBarManager;
}
public BossMechanicManager getBossMechanicManager() {
return this.bossMechanicManager;
}

View File

@ -24,19 +24,22 @@ public class BossEntity {
@Expose
private final DropsElement drops;
@Expose
private final HealthBarElement healthBar;
@Expose
private String spawnItem, targeting;
@Expose
private boolean editing, buyable;
@Expose
private Double price;
public BossEntity(boolean editing, String spawnItem, String targeting, boolean buyable, Double price, List<EntityStatsElement> entityStats, SkillsElement skills, DropsElement drops, MessagesElement messages, CommandsElement commands) {
public BossEntity(boolean editing, String spawnItem, String targeting, boolean buyable, Double price, List<EntityStatsElement> entityStats, SkillsElement skills, DropsElement drops, MessagesElement messages, CommandsElement commands, HealthBarElement healthBar) {
this.editing = editing;
this.entityStats = entityStats;
this.targeting = targeting;
this.spawnItem = spawnItem;
this.skills = skills;
this.drops = drops;
this.healthBar = healthBar;
this.messages = messages;
this.commands = commands;
this.buyable = buyable;
@ -164,4 +167,8 @@ public class BossEntity {
public DropsElement getDrops() {
return this.drops;
}
public HealthBarElement getHealthBar() {
return healthBar;
}
}

View File

@ -0,0 +1,33 @@
package com.songoda.epicbosses.entity.elements;
import com.google.gson.annotations.Expose;
public class HealthBarElement {
@Expose
private String text;
@Expose
private Integer radius;
public HealthBarElement(String text, Integer radius) {
this.text = text;
this.radius = radius;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Integer getRadius() {
return radius;
}
public void setRadius(Integer radius) {
this.radius = radius;
}
}

View File

@ -8,6 +8,7 @@ import com.songoda.epicbosses.events.PreBossSpawnEvent;
import com.songoda.epicbosses.events.PreBossSpawnItemEvent;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossEntityManager;
import com.songoda.epicbosses.managers.BossHealthBarManager;
import com.songoda.epicbosses.managers.BossLocationManager;
import com.songoda.epicbosses.managers.BossTauntManager;
import com.songoda.epicbosses.utils.*;
@ -38,11 +39,13 @@ public class BossSpawnListener implements Listener {
private BossLocationManager bossLocationManager;
private BossEntityManager bossEntityManager;
private BossTauntManager bossTauntManager;
private BossHealthBarManager bossHealthBarManager;
public BossSpawnListener(EpicBosses epicBosses) {
this.bossTauntManager = epicBosses.getBossTauntManager();
this.bossEntityManager = epicBosses.getBossEntityManager();
this.bossLocationManager = epicBosses.getBossLocationManager();
this.bossHealthBarManager = epicBosses.getBossHealthBarManager();
}
@EventHandler
@ -120,6 +123,7 @@ public class BossSpawnListener implements Listener {
List<String> commands = new ArrayList(this.bossEntityManager.getOnSpawnCommands(bossEntity));
List<String> messages = new ArrayList(this.bossEntityManager.getOnSpawnMessage(bossEntity));
int messageRadius = this.bossEntityManager.getOnSpawnMessageRadius(bossEntity);
ServerUtils serverUtils = ServerUtils.get();
if (event instanceof PreBossSpawnItemEvent) {
@ -155,6 +159,9 @@ public class BossSpawnListener implements Listener {
MessageUtils.get().sendMessage(location, NumberUtils.get().getSquared(messageRadius), messages);
}
// Health bar in action bar ;)
this.bossHealthBarManager.handleHealthBar(activeBossHolder);
activeBossHolder.getTargetHandler().runTargetCycle();
this.bossTauntManager.handleTauntSystem(activeBossHolder);
@ -162,5 +169,4 @@ public class BossSpawnListener implements Listener {
ServerUtils.get().callEvent(bossSpawnEvent);
}
}
}

View File

@ -0,0 +1,57 @@
package com.songoda.epicbosses.managers;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.epicbosses.EpicBosses;
import com.songoda.epicbosses.entity.elements.HealthBarElement;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.utils.MessageUtils;
import com.songoda.epicbosses.utils.NumberUtils;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.LivingEntity;
import org.bukkit.scheduler.BukkitRunnable;
public class BossHealthBarManager {
private final EpicBosses epicBosses;
public BossHealthBarManager(EpicBosses epicBosses) {
this.epicBosses = epicBosses;
}
public void handleHealthBar(ActiveBossHolder activeBossHolder) {
if (activeBossHolder.getBossEntity().getHealthBar() == null || activeBossHolder.getBossEntity().getHealthBar().getText() == null)
return;
createNewRunnable(activeBossHolder);
}
public void createNewRunnable(ActiveBossHolder activeBossHolder) {
HealthBarElement healthBarElement = activeBossHolder.getBossEntity().getHealthBar();
new BukkitRunnable() {
@Override
public void run() {
if (activeBossHolder.isDead()) {
cancel();
return;
}
if (activeBossHolder.getLivingEntity() == null) return;
// Parse placeholders
String formattedText = healthBarElement.getText().replaceAll("(?i)%currenthealth%", String.valueOf(NumberUtils.get().formatDouble(activeBossHolder.getLivingEntity().getHealth())))
.replaceAll("(?i)%maxhealth%", String.valueOf(NumberUtils.get().formatDouble(getMaxHealth(activeBossHolder.getLivingEntity()))));
MessageUtils.get().sendActionBar(activeBossHolder.getLocation(), NumberUtils.get().getSquared(healthBarElement.getRadius()), formattedText);
}
}.runTaskTimer(epicBosses, 10, 20);
}
private double getMaxHealth(LivingEntity entity) {
if (ServerVersion.isServerVersionAbove(ServerVersion.V1_8)) {
return entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
} else {
return entity.getMaxHealth();
}
}
}

View File

@ -1,9 +1,16 @@
package com.songoda.epicbosses.utils;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.NMSUtils;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
@ -42,10 +49,52 @@ public class MessageUtils {
} else {
Bukkit.getOnlinePlayers().forEach(player -> {
if ((player.getWorld().equals(center.getWorld())) && (player.getLocation().distanceSquared(center) <= radius)) {
messages.forEach(string -> player.sendMessage(string));
messages.forEach(player::sendMessage);
}
});
}
}
}
public void sendActionBar(Location center, int radius, String message) {
if (radius == -1) {
if (center.getWorld() == null) return;
center.getWorld().getPlayers().forEach(p -> sendActionBar(p, message));
} else {
Bukkit.getOnlinePlayers().forEach(player -> {
if ((player.getWorld().equals(center.getWorld())) && (player.getLocation().distanceSquared(center) <= radius)) {
sendActionBar(player, message);
}
});
}
}
private Class<?> clazzPacketPlayOutChat, clazzChatSerializer, clazzIChatBaseComponent;
private Method methodA;
public void sendActionBar(Player player, String message) {
message = ChatColor.translateAlternateColorCodes('&', message);
if (ServerVersion.isServerVersionAbove(ServerVersion.V1_8)) {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message));
} else {
try {
// Cache nms
if (clazzPacketPlayOutChat == null) {
clazzPacketPlayOutChat = NMSUtils.getNMSClass("PacketPlayOutChat");
clazzChatSerializer = NMSUtils.getNMSClass("IChatBaseComponent$ChatSerializer");
clazzIChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
methodA = clazzChatSerializer.getDeclaredMethod("a", String.class);
}
Object chatBaseComponent = clazzIChatBaseComponent.cast(methodA.invoke(clazzChatSerializer, "{\"text\": \"" + message + "\"}"));
Object packetPlayOutChat = clazzPacketPlayOutChat.getConstructor(new Class<?>[]{clazzIChatBaseComponent, byte.class}).newInstance(chatBaseComponent, (byte) 2);
NMSUtils.sendPacket(player, packetPlayOutChat);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}