Add 1.7 and 1.8 boss bar support
This commit is contained in:
parent
6e666e461c
commit
9612858058
|
@ -147,10 +147,9 @@ public class PlayerListener implements PluginFacet, Listener {
|
|||
new Component(ChatColor.GOLD, ChatColor.BOLD).extra(generalFormatter.publicHostname())
|
||||
));
|
||||
|
||||
final BossBar bar = bossBarFactory.createBossBar(renderer.render(news, player), BarColor.BLUE, BarStyle.SOLID);
|
||||
final BossBar bar = bossBarFactory.createBossBar(player, renderer.render(news, player), BarColor.BLUE, BarStyle.SOLID);
|
||||
bar.setProgress(1);
|
||||
bar.addPlayer(player);
|
||||
bar.show();
|
||||
bar.setVisible(true);
|
||||
}
|
||||
|
||||
if(!player.hasPermission("lobby.disabled-permissions-exempt")) {
|
||||
|
|
|
@ -113,9 +113,8 @@ public class BossBarMatchModule extends MatchModule implements Listener {
|
|||
View(BossBarSource source, Player viewer) {
|
||||
this.source = source;
|
||||
this.viewer = viewer;
|
||||
this.bar = bossBarFactory.createBossBar(Components.blank(), BarColor.WHITE, BarStyle.SOLID);
|
||||
this.bar = bossBarFactory.createBossBar(viewer, Components.blank(), BarColor.WHITE, BarStyle.SOLID);
|
||||
render();
|
||||
bar.addPlayer(viewer);
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
|
|
|
@ -5,11 +5,28 @@ import org.bukkit.boss.BarColor;
|
|||
import org.bukkit.boss.BarFlag;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Player;
|
||||
import tc.oc.minecraft.protocol.MinecraftVersion;
|
||||
|
||||
import static tc.oc.minecraft.protocol.MinecraftVersion.MINECRAFT_1_9;
|
||||
|
||||
|
||||
public interface BossBarFactory {
|
||||
BossBar createBossBar();
|
||||
|
||||
BossBar createBossBar(BaseComponent title, BarColor color, BarStyle style, BarFlag...flags);
|
||||
BossBar createBossBar(BaseComponent title, BarColor color, BarStyle style, boolean legacy, BarFlag...flags);
|
||||
|
||||
default BossBar createBossBar(Player player, BaseComponent title, BarColor color, BarStyle style, BarFlag...flags) {
|
||||
BossBar bar = createBossBar(title, color, style, MinecraftVersion.lessThan(MINECRAFT_1_9, player.getProtocolVersion()), flags);
|
||||
bar.addPlayer(player);
|
||||
return bar;
|
||||
}
|
||||
|
||||
default BossBar createBossBar(BaseComponent title, BarColor color, BarStyle style, BarFlag...flags) {
|
||||
return createBossBar(title, color, style, false, flags);
|
||||
}
|
||||
|
||||
BossBar createRenderedBossBar();
|
||||
|
||||
BossBar createLegacyBossBar();
|
||||
}
|
||||
|
|
|
@ -17,15 +17,24 @@ public class BossBarFactoryImpl implements BossBarFactory {
|
|||
|
||||
private final Server server;
|
||||
private final Provider<RenderedBossBar> renderedBossBarProvider;
|
||||
private final Provider<LegacyBossBar> legacyBossBarProvider;
|
||||
|
||||
@Inject BossBarFactoryImpl(Server server, Provider<RenderedBossBar> renderedBossBarProvider) {
|
||||
@Inject BossBarFactoryImpl(Server server, Provider<RenderedBossBar> renderedBossBarProvider, Provider<LegacyBossBar> legacyBossBarProvider) {
|
||||
this.server = server;
|
||||
this.renderedBossBarProvider = renderedBossBarProvider;
|
||||
this.legacyBossBarProvider = legacyBossBarProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(BaseComponent title, BarColor color, BarStyle style, BarFlag... flags) {
|
||||
return server.createBossBar(title, color, style, flags);
|
||||
public BossBar createBossBar(BaseComponent title, BarColor color, BarStyle style, boolean legacy, BarFlag... flags) {
|
||||
BossBar bar;
|
||||
if(legacy) {
|
||||
bar = createLegacyBossBar();
|
||||
bar.setTitle(title);
|
||||
} else {
|
||||
bar = server.createBossBar(title, color, style, flags);
|
||||
}
|
||||
return bar;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,4 +46,9 @@ public class BossBarFactoryImpl implements BossBarFactory {
|
|||
public BossBar createRenderedBossBar() {
|
||||
return renderedBossBarProvider.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createLegacyBossBar() {
|
||||
return legacyBossBarProvider.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
package tc.oc.commons.bukkit.bossbar;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarFlag;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import tc.oc.commons.bukkit.chat.ComponentRenderContext;
|
||||
import tc.oc.commons.bukkit.util.NMSHacks;
|
||||
import tc.oc.commons.core.chat.Components;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class LegacyBossBar implements BossBar {
|
||||
|
||||
private final ComponentRenderContext renderer;
|
||||
private final Map<Player, NMSHacks.FakeWither> views = new HashMap<>();
|
||||
private final Map<Player, Integer> tasks = new HashMap<>();
|
||||
|
||||
private BaseComponent title = Components.blank();
|
||||
private double progress = 1;
|
||||
private boolean visible = true;
|
||||
|
||||
@Inject LegacyBossBar(ComponentRenderContext renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarColor getColor() {
|
||||
return BarColor.PURPLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BarStyle getStyle() {
|
||||
return BarStyle.SOLID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Player> getPlayers() {
|
||||
return ImmutableList.copyOf(views.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(BaseComponent title) {
|
||||
this.title = title;
|
||||
views.forEach((player, wither) -> wither.name(player, renderer.renderLegacy(title, player), isVisible()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(double progress) {
|
||||
this.progress = progress;
|
||||
views.forEach((player, wither) -> wither.health(player, progress, isVisible()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayer(Player player) {
|
||||
if(!views.containsKey(player)) {
|
||||
NMSHacks.FakeWither view = new NMSHacks.FakeWither(player.getWorld(), renderer.renderLegacy(title, player));
|
||||
views.put(player, view);
|
||||
int task = scheduler().scheduleSyncRepeatingTask(plugin(), () -> { if(isVisible()) view.teleport(player, witherLocation(player)); }, 0, 1);
|
||||
tasks.put(player, task);
|
||||
if(isVisible()) {
|
||||
view.spawn(player, witherLocation(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePlayer(Player player) {
|
||||
int task = tasks.remove(player);
|
||||
if(task != -1) {
|
||||
scheduler().cancelTask(task);
|
||||
}
|
||||
NMSHacks.FakeWither view = views.remove(player);
|
||||
if(view != null) {
|
||||
view.destroy(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll() {
|
||||
ImmutableSet.copyOf(views.keySet()).forEach(this::removePlayer);
|
||||
views.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
boolean previous = isVisible();
|
||||
this.visible = visible;
|
||||
if(previous && !visible) {
|
||||
views.forEach((player, wither) -> wither.destroy(player));
|
||||
} else if(!previous && visible) {
|
||||
views.forEach((player, wither) -> wither.spawn(player, witherLocation(player)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(BaseComponent title, double progress, BarColor color, BarStyle style, Set<BarFlag> flags) {
|
||||
this.title = title;
|
||||
this.progress = progress;
|
||||
views.forEach((player, wither) -> wither.update(player, renderer.renderLegacy(title, player), progress, isVisible()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(BarColor color) {}
|
||||
|
||||
@Override
|
||||
public void setStyle(BarStyle style) {}
|
||||
|
||||
@Override
|
||||
public void setFlags(Set<BarFlag> flags) {}
|
||||
|
||||
@Override
|
||||
public void removeFlag(BarFlag flag) {}
|
||||
|
||||
@Override
|
||||
public void addFlag(BarFlag flag) {}
|
||||
|
||||
@Override
|
||||
public boolean hasFlag(BarFlag flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Location witherLocation(Player player) {
|
||||
Location eye = player.getEyeLocation().clone();
|
||||
eye.setPitch(eye.getPitch() - 20);
|
||||
return player.getEyeLocation().add(eye.getDirection().multiply(32));
|
||||
}
|
||||
|
||||
// HACK
|
||||
|
||||
protected Plugin plugin() {
|
||||
return Bukkit.getPluginManager().getPlugin("Commons");
|
||||
}
|
||||
|
||||
protected BukkitScheduler scheduler() {
|
||||
return Bukkit.getScheduler();
|
||||
}
|
||||
|
||||
}
|
|
@ -117,9 +117,8 @@ public class RenderedBossBar implements BossBar {
|
|||
@Override
|
||||
public void addPlayer(Player player) {
|
||||
if(!views.containsKey(player)) {
|
||||
final BossBar view = bossBarFactory.createBossBar(renderer.render(title, player), color, style, flags.toArray(new BarFlag[flags.size()]));
|
||||
final BossBar view = bossBarFactory.createBossBar(player, renderer.render(title, player), color, style, flags.toArray(new BarFlag[flags.size()]));
|
||||
view.setVisible(visibile);
|
||||
view.addPlayer(player);
|
||||
views.put(player, view);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import net.minecraft.server.EntityLiving;
|
|||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.EntityTrackerEntry;
|
||||
import net.minecraft.server.EntityTypes;
|
||||
import net.minecraft.server.EntityWither;
|
||||
import net.minecraft.server.EntityZombie;
|
||||
import net.minecraft.server.EnumGamemode;
|
||||
import net.minecraft.server.EnumHand;
|
||||
|
@ -92,6 +93,7 @@ import org.bukkit.entity.Entity;
|
|||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Wither;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
@ -403,6 +405,40 @@ public class NMSHacks {
|
|||
}
|
||||
}
|
||||
|
||||
public static class FakeWither extends FakeLivingEntity<EntityWither> {
|
||||
|
||||
public FakeWither(World world, @Nullable String name) {
|
||||
super(new EntityWither(((CraftWorld) world).getHandle()));
|
||||
|
||||
entity.setNoAI(true);
|
||||
entity.setNoGravity(true);
|
||||
entity.setSilent(true);
|
||||
entity.setInvulnerable(true);
|
||||
entity.setInvisible(true);
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.g(890); // Required to make the wither extremely small
|
||||
|
||||
if(name != null) {
|
||||
entity.setCustomName(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void update(Player viewer, @Nullable String name, @Nullable Double percent, boolean send) {
|
||||
if(name != null) entity.setCustomName(name);
|
||||
if(percent != null) entity.setHealth(percent.floatValue() * entity.getMaxHealth());
|
||||
if(send) sendPacket(viewer, entityMetadataPacket(entity, true));
|
||||
}
|
||||
|
||||
public void name(Player viewer, String name, boolean update) {
|
||||
update(viewer, name, null, update);
|
||||
}
|
||||
|
||||
public void health(Player viewer, double percent, boolean update) {
|
||||
update(viewer, null, percent, update);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FakeZombie extends FakeLivingEntity<EntityZombie> {
|
||||
public FakeZombie(World world, boolean invisible) {
|
||||
super(new EntityZombie(((CraftWorld) world).getHandle()));
|
||||
|
|
Loading…
Reference in New Issue