Skip to content

Instantly share code, notes, and snippets.

@mcardy
Created December 1, 2013 20:22
Show Gist options
  • Save mcardy/7740204 to your computer and use it in GitHub Desktop.
Save mcardy/7740204 to your computer and use it in GitHub Desktop.
A class that utilizes packets to use the boss health bar
/**
* BossBar
* <br>
* Create and save a new instance of this class and then use the setStatus method
* to set the player's boss bar status
*
* @author minnymin3
* @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
*
*/
public class BossBar {
private Map<String, Dragon> dragonMap = new HashMap<String, Dragon>();
/**
* Sets the player's BossBar status
* @param player The player to set status of
* @param text The name of the boss bar
* @param percent A value from 0-100 for the bar
* @param reset Whether or not to create a new instance of the dragon (used when world changed)
*/
public void setStatus(Player player, String text, int percent, boolean reset) {
Dragon dragon = null;
if (dragonMap.containsKey(player.getName()) && !reset) {
dragon = dragonMap.get(player.getName());
} else {
dragon = new Dragon(text, player.getLocation().add(0, -200, 0), percent);
Object mobPacket = dragon.getSpawnPacket();
sendPacket(player, mobPacket);
dragonMap.put(player.getName(), dragon);
}
if (text == "") {
Object destroyPacket = dragon.getDestroyPacket();
sendPacket(player, destroyPacket);
dragonMap.remove(player.getName());
} else {
dragon.setName(text);
dragon.setHealth(percent);
Object metaPacket = dragon.getMetaPacket(dragon.getWatcher());
Object teleportPacket = dragon.getTeleportPacket(player.getLocation().add(0, -200, 0));
sendPacket(player, metaPacket);
sendPacket(player, teleportPacket);
}
}
private void sendPacket(Player player, Object packet) {
try {
Object nmsPlayer = getHandle(player);
Field con_field = nmsPlayer.getClass().getField("playerConnection");
Object con = con_field.get(nmsPlayer);
Method packet_method = ReflectionUtils.getMethod(con.getClass(), "sendPacket");
packet_method.invoke(con, packet);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private Object getHandle(Entity entity) {
Object nms_entity = null;
Method entity_getHandle = ReflectionUtils.getMethod(entity.getClass(), "getHandle");
try {
nms_entity = entity_getHandle.invoke(entity);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return nms_entity;
}
private class Dragon {
private static final int MAX_HEALTH = 200;
private int id;
private int x;
private int y;
private int z;
private int pitch = 0;
private int yaw = 0;
private byte xvel = 0;
private byte yvel = 0;
private byte zvel = 0;
private float health;
private boolean visible = false;
private String name;
private World world;
private EntityEnderDragon dragon;
public Dragon(String name, Location loc, int percent) {
this.name = name;
this.x = loc.getBlockX();
this.y = loc.getBlockY();
this.z = loc.getBlockZ();
this.health = percent / 100F * MAX_HEALTH;
this.world = ((CraftWorld) loc.getWorld()).getHandle();
}
public void setHealth(int percent) {
this.health = percent / 100F * MAX_HEALTH;
}
public void setName(String name) {
this.name = name;
}
public Object getSpawnPacket() {
dragon = new EntityEnderDragon(world);
dragon.setLocation(x, y, z, pitch, yaw);
dragon.setInvisible(visible);
dragon.setCustomName(name);
dragon.setHealth(health);
dragon.motX = xvel;
dragon.motY = yvel;
dragon.motZ = zvel;
this.id = dragon.getId();
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(dragon);
return packet;
}
public Object getDestroyPacket() {
return new PacketPlayOutEntityDestroy(id);
}
public Object getMetaPacket(Object watcher) {
return new PacketPlayOutEntityMetadata(this.id, (DataWatcher) watcher, true);
}
public Object getTeleportPacket(Location loc) {
return new PacketPlayOutEntityTeleport(this.id, loc.getBlockX() * 32, loc.getBlockY() * 32, loc.getBlockZ() * 32,
(byte) ((int)loc.getYaw() * 256 / 360), (byte) ((int)loc.getPitch() * 256 / 360));
}
public Object getWatcher() {
DataWatcher watcher = new DataWatcher(dragon);
watcher.a(0, visible ? (byte) 0 : (byte) 0x20);
watcher.a(6, (Float) health);
watcher.a(7, (Integer) 0);
watcher.a(8, (Byte) (byte) 0);
watcher.a(10, name);
watcher.a(11, (Byte) (byte) 1);
return watcher;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment