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, "editing": true,
"buyable": true, "buyable": true,
"price": 500000.0, "price": 500000.0,
"healthBar": {
"radius": 50,
"text": "&6&lSkeleton King &8&m &r &a%currentHealth%&7/&2%maxHealth%"
},
"entityStats": [ "entityStats": [
{ {
"mainStats": { "mainStats": {

View File

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

View File

@ -24,19 +24,22 @@ public class BossEntity {
@Expose @Expose
private final DropsElement drops; private final DropsElement drops;
@Expose @Expose
private final HealthBarElement healthBar;
@Expose
private String spawnItem, targeting; private String spawnItem, targeting;
@Expose @Expose
private boolean editing, buyable; private boolean editing, buyable;
@Expose @Expose
private Double price; 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.editing = editing;
this.entityStats = entityStats; this.entityStats = entityStats;
this.targeting = targeting; this.targeting = targeting;
this.spawnItem = spawnItem; this.spawnItem = spawnItem;
this.skills = skills; this.skills = skills;
this.drops = drops; this.drops = drops;
this.healthBar = healthBar;
this.messages = messages; this.messages = messages;
this.commands = commands; this.commands = commands;
this.buyable = buyable; this.buyable = buyable;
@ -164,4 +167,8 @@ public class BossEntity {
public DropsElement getDrops() { public DropsElement getDrops() {
return this.drops; 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.events.PreBossSpawnItemEvent;
import com.songoda.epicbosses.holder.ActiveBossHolder; import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossEntityManager; import com.songoda.epicbosses.managers.BossEntityManager;
import com.songoda.epicbosses.managers.BossHealthBarManager;
import com.songoda.epicbosses.managers.BossLocationManager; import com.songoda.epicbosses.managers.BossLocationManager;
import com.songoda.epicbosses.managers.BossTauntManager; import com.songoda.epicbosses.managers.BossTauntManager;
import com.songoda.epicbosses.utils.*; import com.songoda.epicbosses.utils.*;
@ -38,11 +39,13 @@ public class BossSpawnListener implements Listener {
private BossLocationManager bossLocationManager; private BossLocationManager bossLocationManager;
private BossEntityManager bossEntityManager; private BossEntityManager bossEntityManager;
private BossTauntManager bossTauntManager; private BossTauntManager bossTauntManager;
private BossHealthBarManager bossHealthBarManager;
public BossSpawnListener(EpicBosses epicBosses) { public BossSpawnListener(EpicBosses epicBosses) {
this.bossTauntManager = epicBosses.getBossTauntManager(); this.bossTauntManager = epicBosses.getBossTauntManager();
this.bossEntityManager = epicBosses.getBossEntityManager(); this.bossEntityManager = epicBosses.getBossEntityManager();
this.bossLocationManager = epicBosses.getBossLocationManager(); this.bossLocationManager = epicBosses.getBossLocationManager();
this.bossHealthBarManager = epicBosses.getBossHealthBarManager();
} }
@EventHandler @EventHandler
@ -120,6 +123,7 @@ public class BossSpawnListener implements Listener {
List<String> commands = new ArrayList(this.bossEntityManager.getOnSpawnCommands(bossEntity)); List<String> commands = new ArrayList(this.bossEntityManager.getOnSpawnCommands(bossEntity));
List<String> messages = new ArrayList(this.bossEntityManager.getOnSpawnMessage(bossEntity)); List<String> messages = new ArrayList(this.bossEntityManager.getOnSpawnMessage(bossEntity));
int messageRadius = this.bossEntityManager.getOnSpawnMessageRadius(bossEntity); int messageRadius = this.bossEntityManager.getOnSpawnMessageRadius(bossEntity);
ServerUtils serverUtils = ServerUtils.get(); ServerUtils serverUtils = ServerUtils.get();
if (event instanceof PreBossSpawnItemEvent) { if (event instanceof PreBossSpawnItemEvent) {
@ -155,6 +159,9 @@ public class BossSpawnListener implements Listener {
MessageUtils.get().sendMessage(location, NumberUtils.get().getSquared(messageRadius), messages); MessageUtils.get().sendMessage(location, NumberUtils.get().getSquared(messageRadius), messages);
} }
// Health bar in action bar ;)
this.bossHealthBarManager.handleHealthBar(activeBossHolder);
activeBossHolder.getTargetHandler().runTargetCycle(); activeBossHolder.getTargetHandler().runTargetCycle();
this.bossTauntManager.handleTauntSystem(activeBossHolder); this.bossTauntManager.handleTauntSystem(activeBossHolder);
@ -162,5 +169,4 @@ public class BossSpawnListener implements Listener {
ServerUtils.get().callEvent(bossSpawnEvent); 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; 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.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -42,10 +49,52 @@ public class MessageUtils {
} else { } else {
Bukkit.getOnlinePlayers().forEach(player -> { Bukkit.getOnlinePlayers().forEach(player -> {
if ((player.getWorld().equals(center.getWorld())) && (player.getLocation().distanceSquared(center) <= radius)) { 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();
}
}
}
} }