281 lines
8.2 KiB
Java
281 lines
8.2 KiB
Java
package net.citizensnpcs.trait.versioned;
|
|
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.function.Supplier;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.attribute.Attribute;
|
|
import org.bukkit.boss.BarColor;
|
|
import org.bukkit.boss.BarFlag;
|
|
import org.bukkit.boss.BarStyle;
|
|
import org.bukkit.boss.BossBar;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.primitives.Doubles;
|
|
|
|
import net.citizensnpcs.Settings.Setting;
|
|
import net.citizensnpcs.api.CitizensAPI;
|
|
import net.citizensnpcs.api.command.Command;
|
|
import net.citizensnpcs.api.command.CommandContext;
|
|
import net.citizensnpcs.api.command.Flag;
|
|
import net.citizensnpcs.api.command.Requirements;
|
|
import net.citizensnpcs.api.command.exception.CommandException;
|
|
import net.citizensnpcs.api.npc.NPC;
|
|
import net.citizensnpcs.api.persistence.Persist;
|
|
import net.citizensnpcs.api.trait.Trait;
|
|
import net.citizensnpcs.api.trait.TraitName;
|
|
import net.citizensnpcs.api.util.Messaging;
|
|
import net.citizensnpcs.api.util.Placeholders;
|
|
import net.citizensnpcs.util.NMS;
|
|
import net.citizensnpcs.util.Util;
|
|
|
|
@TraitName("bossbar")
|
|
public class BossBarTrait extends Trait {
|
|
private BossBar activeBar;
|
|
@Persist
|
|
private BarColor color = BarColor.PURPLE;
|
|
@Persist
|
|
private List<BarFlag> flags = Lists.newArrayList();
|
|
private Supplier<Double> progressProvider;
|
|
@Persist
|
|
private int range = -1;
|
|
@Persist
|
|
private BarStyle style = BarStyle.SOLID;
|
|
@Persist
|
|
private String title = "";
|
|
@Persist
|
|
private String track;
|
|
@Persist
|
|
private String viewPermission;
|
|
@Persist
|
|
private boolean visible = true;
|
|
|
|
public BossBarTrait() {
|
|
super("bossbar");
|
|
}
|
|
|
|
private BossBar getBar() {
|
|
if (npc.isSpawned() && isBoss(npc.getEntity()) && NMS.getBossBar(npc.getEntity()) != null)
|
|
return (BossBar) NMS.getBossBar(npc.getEntity());
|
|
|
|
if (activeBar == null) {
|
|
activeBar = Bukkit.getServer().createBossBar(npc.getFullName(), color, style,
|
|
flags.toArray(new BarFlag[flags.size()]));
|
|
}
|
|
return activeBar;
|
|
}
|
|
|
|
public BarColor getColor() {
|
|
return color;
|
|
}
|
|
|
|
public List<BarFlag> getFlags() {
|
|
return flags;
|
|
}
|
|
|
|
public int getRange() {
|
|
return range;
|
|
}
|
|
|
|
public BarStyle getStyle() {
|
|
return style;
|
|
}
|
|
|
|
public String getTitle() {
|
|
return title;
|
|
}
|
|
|
|
public String getTrackingVariable() {
|
|
return track;
|
|
}
|
|
|
|
public String getViewPermission() {
|
|
return viewPermission;
|
|
}
|
|
|
|
private boolean isBoss(Entity entity) {
|
|
boolean isBoss = entity.getType() == EntityType.ENDER_DRAGON || entity.getType() == EntityType.WITHER;
|
|
if (isBoss) {
|
|
onDespawn();
|
|
}
|
|
return isBoss;
|
|
}
|
|
|
|
public boolean isVisible() {
|
|
return visible;
|
|
}
|
|
|
|
@Override
|
|
public void onDespawn() {
|
|
if (activeBar == null)
|
|
return;
|
|
|
|
activeBar.removeAll();
|
|
activeBar.hide();
|
|
activeBar = null;
|
|
}
|
|
|
|
@Override
|
|
public void onRemove() {
|
|
onDespawn();
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
if (!npc.isSpawned())
|
|
return;
|
|
|
|
BossBar bar = getBar();
|
|
if (bar == null)
|
|
return;
|
|
|
|
if (track != null && !track.isEmpty()) {
|
|
if (track.equalsIgnoreCase("health")) {
|
|
if (npc.getEntity() instanceof LivingEntity) {
|
|
LivingEntity entity = (LivingEntity) npc.getEntity();
|
|
double maxHealth = entity.getMaxHealth();
|
|
if (SUPPORT_ATTRIBUTES) {
|
|
try {
|
|
maxHealth = entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
|
} catch (Throwable t) {
|
|
SUPPORT_ATTRIBUTES = false;
|
|
}
|
|
}
|
|
bar.setProgress(entity.getHealth() / maxHealth);
|
|
}
|
|
} else {
|
|
String replaced = Placeholders.replace(track,
|
|
npc.getEntity() instanceof Player ? (Player) npc.getEntity() : null);
|
|
Double number = Doubles.tryParse(replaced);
|
|
if (number == null)
|
|
return;
|
|
if (number >= 1 && number <= 100) {
|
|
number /= 100.0;
|
|
}
|
|
bar.setProgress(Math.max(0, Math.min(1, number)));
|
|
}
|
|
}
|
|
bar.setTitle(title);
|
|
bar.setVisible(visible);
|
|
if (progressProvider != null) {
|
|
bar.setProgress(progressProvider.get());
|
|
}
|
|
if (style != null) {
|
|
bar.setStyle(style);
|
|
}
|
|
if (color != null) {
|
|
bar.setColor(color);
|
|
}
|
|
for (BarFlag flag : BarFlag.values()) {
|
|
bar.removeFlag(flag);
|
|
}
|
|
for (BarFlag flag : flags) {
|
|
bar.addFlag(flag);
|
|
}
|
|
bar.removeAll();
|
|
|
|
for (Player player : CitizensAPI.getLocationLookup().getNearbyPlayers(npc.getEntity().getLocation(),
|
|
range > 0 ? range : Setting.BOSSBAR_RANGE.asInt())) {
|
|
if (viewPermission != null && !player.hasPermission(viewPermission))
|
|
continue;
|
|
|
|
bar.addPlayer(player);
|
|
}
|
|
}
|
|
|
|
public void setColor(BarColor color) {
|
|
this.color = color;
|
|
}
|
|
|
|
public void setFlags(Collection<BarFlag> flags) {
|
|
this.flags = Lists.newArrayList(flags);
|
|
}
|
|
|
|
public void setFlags(List<BarFlag> flags) {
|
|
this.flags = flags;
|
|
}
|
|
|
|
public void setProgressProvider(Supplier<Double> provider) {
|
|
progressProvider = provider;
|
|
}
|
|
|
|
public void setRange(int range) {
|
|
this.range = range;
|
|
}
|
|
|
|
public void setStyle(BarStyle style) {
|
|
this.style = style;
|
|
}
|
|
|
|
public void setTitle(String title) {
|
|
this.title = title;
|
|
}
|
|
|
|
public void setTrackVariable(String variable) {
|
|
track = variable;
|
|
}
|
|
|
|
public void setViewPermission(String viewpermission) {
|
|
viewPermission = viewpermission;
|
|
}
|
|
|
|
public void setVisible(boolean visible) {
|
|
this.visible = visible;
|
|
}
|
|
|
|
@Command(
|
|
aliases = { "npc" },
|
|
usage = "bossbar --style [style] --color [color] --title [title] --visible [visible] --viewpermission [permission] --flags [flags] --track [health | placeholder] --range [range]",
|
|
desc = "",
|
|
modifiers = { "bossbar" },
|
|
min = 1,
|
|
max = 1)
|
|
@Requirements(selected = true, ownership = true)
|
|
public static void bossbar(CommandContext args, CommandSender sender, NPC npc, @Flag("style") BarStyle style,
|
|
@Flag("track") String track, @Flag("color") BarColor color, @Flag("visible") Boolean visible,
|
|
@Flag("range") Integer range, @Flag("title") String title, @Flag("flags") String flags,
|
|
@Flag("viewpermission") String viewpermission) throws CommandException {
|
|
BossBarTrait trait = npc.getOrAddTrait(BossBarTrait.class);
|
|
if (style != null) {
|
|
trait.setStyle(style);
|
|
}
|
|
if (color != null) {
|
|
trait.setColor(color);
|
|
}
|
|
if (track != null) {
|
|
trait.setTrackVariable(track);
|
|
}
|
|
if (title != null) {
|
|
trait.setTitle(Messaging.parseComponents(title));
|
|
}
|
|
if (visible != null) {
|
|
trait.setVisible(visible);
|
|
}
|
|
if (range != null) {
|
|
trait.setRange(range);
|
|
}
|
|
if (viewpermission != null) {
|
|
trait.setViewPermission(viewpermission);
|
|
}
|
|
if (flags != null) {
|
|
List<BarFlag> parsed = Lists.newArrayList();
|
|
for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(flags)) {
|
|
BarFlag flag = Util.matchEnum(BarFlag.values(), s);
|
|
if (flag != null) {
|
|
parsed.add(flag);
|
|
}
|
|
}
|
|
trait.setFlags(parsed);
|
|
}
|
|
}
|
|
|
|
private static boolean SUPPORT_ATTRIBUTES = true;
|
|
}
|