Citizens2/main/src/main/java/net/citizensnpcs/trait/versioned/BossBarTrait.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;
}