implement temporary holograms

This commit is contained in:
Ben 2016-03-15 00:48:50 +00:00
parent 13bbcc51dc
commit 813a3833ae
2 changed files with 137 additions and 183 deletions

View File

@ -22,11 +22,9 @@ import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
public class Hologram
{
public class Hologram {
public enum HologramTarget
{
public enum HologramTarget {
BLACKLIST, WHITELIST;
}
@ -39,7 +37,8 @@ public class Hologram
private HologramManager _hologramManager;
private String[] _hologramText = new String[0];
/**
* Keeps track of the holograms movements. This fixes offset that occasionally happens when moving a hologram around.
* Keeps track of the holograms movements. This fixes offset that
* occasionally happens when moving a hologram around.
*/
private Vector _lastMovement;
private Location _location;
@ -55,38 +54,41 @@ public class Hologram
private boolean _hideBoundingBox;
private HologramInteraction _interaction;
public Hologram(HologramManager hologramManager, Location location, String... text)
{
private long _maxLifetime = -1;
private long _startTime;
public Hologram(HologramManager hologramManager, Location location, String... text) {
this(hologramManager, location, -1l, text);
}
public Hologram(HologramManager hologramManager, Location location, long maxLifetime, String... text) {
_hologramManager = hologramManager;
_location = location.clone();
_maxLifetime = maxLifetime;
setText(text);
}
public Hologram setInteraction(HologramInteraction interact)
{
public Hologram setInteraction(HologramInteraction interact) {
_interaction = interact;
return this;
}
public HologramInteraction getInteraction()
{
public HologramInteraction getInteraction() {
return _interaction;
}
/**
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
*/
public Hologram addPlayer(Player player)
{
public Hologram addPlayer(Player player) {
return addPlayer(player.getName());
}
/**
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
*/
public Hologram addPlayer(String player)
{
public Hologram addPlayer(String player) {
_playersInList.add(player);
return this;
}
@ -96,8 +98,7 @@ public class Hologram
*
* @return
*/
public Hologram setHideBoundingBox()
{
public Hologram setHideBoundingBox() {
_hideBoundingBox = true;
return this;
}
@ -105,23 +106,19 @@ public class Hologram
/**
* Is there a player entry in the hologram for Whitelist and Blacklist
*/
public boolean containsPlayer(Player player)
{
public boolean containsPlayer(Player player) {
return _playersInList.contains(player.getName());
}
/**
* Is there a player entry in the hologram for Whitelist and Blacklist
*/
public boolean containsPlayer(String player)
{
public boolean containsPlayer(String player) {
return _playersInList.contains(player);
}
protected Packet getDestroyPacket()
{
if (_makeDestroyPackets)
{
protected Packet getDestroyPacket() {
if (_makeDestroyPackets) {
makeDestroyPacket();
_makeDestroyPackets = false;
}
@ -129,8 +126,7 @@ public class Hologram
return _destroy1_8;
}
public Entity getEntityFollowing()
{
public Entity getEntityFollowing() {
return _followEntity;
}
@ -140,27 +136,22 @@ public class Hologram
* @Whitelist = Only people added can see the hologram
* @Blacklist = Anyone but people added can see the hologram
*/
public HologramTarget getHologramTarget()
{
public HologramTarget getHologramTarget() {
return _target;
}
/**
* Get the hologram location
*/
public Location getLocation()
{
public Location getLocation() {
return _location.clone();
}
protected ArrayList<Player> getNearbyPlayers()
{
protected ArrayList<Player> getNearbyPlayers() {
ArrayList<Player> nearbyPlayers = new ArrayList<Player>();
for (Player player : getLocation().getWorld().getPlayers())
{
if (isVisible(player))
{
for (Player player : getLocation().getWorld().getPlayers()) {
if (isVisible(player)) {
nearbyPlayers.add(player);
}
}
@ -168,15 +159,12 @@ public class Hologram
return nearbyPlayers;
}
protected ArrayList<Player> getPlayersTracking()
{
protected ArrayList<Player> getPlayersTracking() {
return _playersTracking;
}
protected Packet[] getSpawnPackets()
{
if (_makeSpawnPackets)
{
protected Packet[] getSpawnPackets() {
if (_makeSpawnPackets) {
makeSpawnPackets();
_makeSpawnPackets = false;
}
@ -187,13 +175,12 @@ public class Hologram
/**
* Get the text in the hologram
*/
public String[] getText()
{
// We reverse it again as the hologram would otherwise display the text from the bottom row to the top row
public String[] getText() {
// We reverse it again as the hologram would otherwise display the text
// from the bottom row to the top row
String[] reversed = new String[_hologramText.length];
for (int i = 0; i < reversed.length; i++)
{
for (int i = 0; i < reversed.length; i++) {
reversed[i] = _hologramText[reversed.length - (i + 1)];
}
@ -203,32 +190,25 @@ public class Hologram
/**
* Get the view distance the hologram is viewable from. Default is 70
*/
public int getViewDistance()
{
public int getViewDistance() {
return _viewDistance;
}
/**
* Is the hologram holograming?
*/
public boolean isInUse()
{
public boolean isInUse() {
return _lastMovement != null;
}
public boolean isRemoveOnEntityDeath()
{
public boolean isRemoveOnEntityDeath() {
return _removeEntityDeath;
}
public boolean isVisible(Player player)
{
if (getLocation().getWorld() == player.getWorld())
{
if ((getHologramTarget() == HologramTarget.WHITELIST) == containsPlayer(player))
{
if (getLocation().distance(player.getLocation()) < getViewDistance())
{
public boolean isVisible(Player player) {
if (getLocation().getWorld() == player.getWorld()) {
if ((getHologramTarget() == HologramTarget.WHITELIST) == containsPlayer(player)) {
if (getLocation().distance(player.getLocation()) < getViewDistance()) {
return true;
}
}
@ -237,53 +217,42 @@ public class Hologram
return false;
}
private void makeDestroyPacket()
{
private void makeDestroyPacket() {
int[] entityIds1_8 = new int[_entityIds.size()];
for (int i = 0; i < _entityIds.size(); i++)
{
for (int i = 0; i < _entityIds.size(); i++) {
entityIds1_8[i] = _entityIds.get(i);
}
_destroy1_8 = new PacketPlayOutEntityDestroy(entityIds1_8);
}
private void makeSpawnPackets()
{
private void makeSpawnPackets() {
_packets1_8 = new Packet[_hologramText.length * 1];
if (_entityIds.size() < _hologramText.length)
{
if (_entityIds.size() < _hologramText.length) {
_makeDestroyPackets = true;
for (int i = _entityIds.size(); i < _hologramText.length; i++)
{
for (int i = _entityIds.size(); i < _hologramText.length; i++) {
_entityIds.add(Integer.valueOf(UtilEnt.getNewEntityId()));
}
}
else
{
} else {
_makeDestroyPackets = true;
while (_entityIds.size() > _hologramText.length)
{
while (_entityIds.size() > _hologramText.length) {
_entityIds.remove(_hologramText.length);
}
}
for (int textRow = 0; textRow < _hologramText.length; textRow++)
{
for (int textRow = 0; textRow < _hologramText.length; textRow++) {
Packet[] packets1_8 = makeSpawnPackets1_8(textRow, _entityIds.get(textRow), _hologramText[textRow]);
for (int i = 0; i < packets1_8.length; i++)
{
for (int i = 0; i < packets1_8.length; i++) {
_packets1_8[textRow + i] = packets1_8[i];
}
}
}
private Packet[] makeSpawnPackets1_8(int textRow, int entityId, String lineOfText)
{
private Packet[] makeSpawnPackets1_8(int textRow, int entityId, String lineOfText) {
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
@ -300,44 +269,47 @@ public class Hologram
watcher.a(2, lineOfText, EntityArmorStand.META_CUSTOMNAME, lineOfText);
watcher.a(3, (byte) 1, EntityArmorStand.META_CUSTOMNAME_VISIBLE, true);
if (_hideBoundingBox)
{
watcher.a(10, (byte) 16, EntityArmorStand.META_ARMOR_OPTION, (byte) 16); // TODO Uncomment after we can enforce 1.8.3
if (_hideBoundingBox) {
watcher.a(10, (byte) 16, EntityArmorStand.META_ARMOR_OPTION, (byte) 16); // TODO
// Uncomment
// after
// we
// can
// enforce
// 1.8.3
}
// Also correct hologram positioning
return new Packet[]
{
packet
};
return new Packet[] { packet };
}
/**
* Removes the player from the Hologram so they are no longer effected by Whitelist or Blacklist
* Removes the player from the Hologram so they are no longer effected by
* Whitelist or Blacklist
*/
public Hologram removePlayer(Player player)
{
public Hologram removePlayer(Player player) {
return removePlayer(player.getName());
}
/**
* Removes the player from the Hologram so they are no longer effected by Whitelist or Blacklist
* Removes the player from the Hologram so they are no longer effected by
* Whitelist or Blacklist
*/
public Hologram removePlayer(String player)
{
public Hologram removePlayer(String player) {
_playersInList.remove(player);
return this;
}
/**
* If the entity moves, the hologram will update its position to appear relative to the movement.
* If the entity moves, the hologram will update its position to appear
* relative to the movement.
*
* @Please note the hologram updates every tick.
*/
public Hologram setFollowEntity(Entity entityToFollow)
{
public Hologram setFollowEntity(Entity entityToFollow) {
_followEntity = entityToFollow;
relativeToEntity = entityToFollow == null ? null : _location.clone().subtract(entityToFollow.getLocation()).toVector();
relativeToEntity = entityToFollow == null ? null
: _location.clone().subtract(entityToFollow.getLocation()).toVector();
return this;
}
@ -348,8 +320,7 @@ public class Hologram
* @Whitelist = Only people added can see the hologram
* @Blacklist = Anyone but people added can see the hologram
*/
public Hologram setHologramTarget(HologramTarget newTarget)
{
public Hologram setHologramTarget(HologramTarget newTarget) {
_target = newTarget;
return this;
}
@ -357,52 +328,43 @@ public class Hologram
/**
* Sets the hologram to appear at this location
*/
public Hologram setLocation(Location newLocation)
{
public Hologram setLocation(Location newLocation) {
_makeSpawnPackets = true;
Location oldLocation = getLocation();
_location = newLocation.clone();
if (getEntityFollowing() != null)
{
if (getEntityFollowing() != null) {
relativeToEntity = _location.clone().subtract(getEntityFollowing().getLocation()).toVector();
}
if (isInUse())
{
if (isInUse()) {
ArrayList<Player> canSee = getNearbyPlayers();
Iterator<Player> itel = _playersTracking.iterator();
while (itel.hasNext())
{
while (itel.hasNext()) {
Player player = itel.next();
if (!canSee.contains(player))
{
if (!canSee.contains(player)) {
itel.remove();
if (player.getWorld() == getLocation().getWorld())
{
if (player.getWorld() == getLocation().getWorld()) {
UtilPlayer.sendPacket(player, getDestroyPacket());
}
}
}
itel = canSee.iterator();
while (itel.hasNext())
{
while (itel.hasNext()) {
Player player = itel.next();
if (!_playersTracking.contains(player))
{
if (!_playersTracking.contains(player)) {
_playersTracking.add(player);
itel.remove();
UtilPlayer.sendPacket(player, getSpawnPackets());
}
}
if (!canSee.isEmpty())
{
_lastMovement.add(new Vector(newLocation.getX() - oldLocation.getX(), newLocation.getY() - oldLocation.getY(),
newLocation.getZ() - oldLocation.getZ()));
if (!canSee.isEmpty()) {
_lastMovement.add(new Vector(newLocation.getX() - oldLocation.getX(),
newLocation.getY() - oldLocation.getY(), newLocation.getZ() - oldLocation.getZ()));
int x = (int) Math.floor(32 * _lastMovement.getX());
int y = (int) Math.floor(32 * _lastMovement.getY());
@ -412,11 +374,9 @@ public class Hologram
int i = 0;
if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127)
{
if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127) {
_lastMovement.subtract(new Vector(x / 32D, y / 32D, z / 32D));
for (Integer entityId : _entityIds)
{
for (Integer entityId : _entityIds) {
PacketPlayOutEntity.PacketPlayOutRelEntityMove relMove = new PacketPlayOutEntity.PacketPlayOutRelEntityMove();
relMove.a = entityId;
@ -427,16 +387,13 @@ public class Hologram
packets1_8[i] = relMove;
i++;
}
}
else
{
} else {
x = (int) Math.floor(32 * newLocation.getX());
z = (int) Math.floor(32 * newLocation.getZ());
_lastMovement = new Vector(newLocation.getX() - (x / 32D), 0, newLocation.getZ() - (z / 32D));
for (Integer entityId : _entityIds)
{
for (Integer entityId : _entityIds) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport();
teleportPacket.a = entityId;
teleportPacket.b = x;
@ -449,10 +406,8 @@ public class Hologram
}
}
for (Player player : canSee)
{
for (Packet packet : packets1_8)
{
for (Player player : canSee) {
for (Packet packet : packets1_8) {
UtilPlayer.sendPacket(player, packet);
}
}
@ -461,48 +416,50 @@ public class Hologram
return this;
}
public Hologram setRemoveOnEntityDeath()
public long getStartTime()
{
return _startTime;
}
public long getMaxLifetime()
{
return _maxLifetime;
}
public Hologram setRemoveOnEntityDeath() {
_removeEntityDeath = true;
return this;
}
public boolean isEntityId(int entityId)
{
public boolean isEntityId(int entityId) {
return _entityIds.contains(entityId);
}
/**
* Set the hologram text
*/
public Hologram setText(String... newLines)
{
public Hologram setText(String... newLines) {
String[] newText = new String[newLines.length];
for (int i = 0; i < newText.length; i++)
{
for (int i = 0; i < newText.length; i++) {
newText[i] = newLines[newText.length - (i + 1)];
}
if (newText.equals(_hologramText))
return this;
if (isInUse())
{
if (isInUse()) {
int[] destroy1_8 = new int[0];
ArrayList<Packet> packets1_8 = new ArrayList<Packet>();
if (_hologramText.length != newText.length)
{
if (_hologramText.length != newText.length) {
_makeDestroyPackets = true;
}
for (int i = 0; i < Math.max(_hologramText.length, newText.length); i++)
{
for (int i = 0; i < Math.max(_hologramText.length, newText.length); i++) {
// If more lines than previously
if (i >= _hologramText.length)
{
if (i >= _hologramText.length) {
// Add entity id and send spawn packets
// You add a entity id because the new hologram needs
int entityId = UtilEnt.getNewEntityId();
@ -511,16 +468,13 @@ public class Hologram
packets1_8.addAll(Arrays.asList(makeSpawnPackets1_8(i, entityId, newText[i])));
}
// If less lines than previously
else if (i >= newText.length)
{
else if (i >= newText.length) {
// Remove entity id and send destroy packets
Integer entityId = _entityIds.remove(newText.length);
destroy1_8 = Arrays.copyOf(destroy1_8, destroy1_8.length + 1);
destroy1_8[destroy1_8.length - 1] = entityId;
}
else if (!newText[i].equals(_hologramText[i]))
{
} else if (!newText[i].equals(_hologramText[i])) {
// Send update metadata packets
Integer entityId = _entityIds.get(i);
@ -533,7 +487,8 @@ public class Hologram
watcher1_8.a(0, (byte) 32, EntityArmorStand.META_ENTITYDATA, (byte) 32);
watcher1_8.a(2, newText[i], EntityArmorStand.META_CUSTOMNAME, newText[i]);
watcher1_8.a(3, (byte) 1, EntityArmorStand.META_CUSTOMNAME_VISIBLE, true);
// watcher1_8.a(10, (byte) 16);// TODO Uncomment after we can enforce 1.8.3
// watcher1_8.a(10, (byte) 16);// TODO Uncomment after we
// can enforce 1.8.3
// Also correct hologram positioning
metadata1_8.b = watcher1_8.c();
@ -541,15 +496,12 @@ public class Hologram
}
}
if (destroy1_8.length > 0)
{
if (destroy1_8.length > 0) {
packets1_8.add(new PacketPlayOutEntityDestroy(destroy1_8));
}
for (Player player : _playersTracking)
{
for (Packet packet : packets1_8)
{
for (Player player : _playersTracking) {
for (Packet packet : packets1_8) {
UtilPlayer.sendPacket(player, packet);
}
}
@ -564,8 +516,7 @@ public class Hologram
/**
* Set the distance the hologram is viewable from. Default is 70
*/
public Hologram setViewDistance(int newDistance)
{
public Hologram setViewDistance(int newDistance) {
_viewDistance = newDistance;
return setLocation(getLocation());
}
@ -573,15 +524,15 @@ public class Hologram
/**
* Start the hologram
*/
public Hologram start()
{
if (!isInUse())
{
public Hologram start() {
if (!isInUse()) {
_startTime = System.currentTimeMillis();
_hologramManager.addHologram(this);
_playersTracking.addAll(getNearbyPlayers());
for (Player player : _playersTracking)
{
for (Player player : _playersTracking) {
UtilPlayer.sendPacket(player, getSpawnPackets());
}
@ -593,14 +544,11 @@ public class Hologram
/**
* Stop the hologram
*/
public Hologram stop()
{
if (isInUse())
{
public Hologram stop() {
if (isInUse()) {
_hologramManager.removeHologram(this);
for (Player player : _playersTracking)
{
for (Player player : _playersTracking) {
UtilPlayer.sendPacket(player, getDestroyPacket());
}

View File

@ -5,6 +5,7 @@ import java.util.Iterator;
import java.util.List;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
@ -52,15 +53,20 @@ public class HologramManager implements Listener, IPacketHandler
List<World> worlds = Bukkit.getWorlds();
Iterator<Hologram> itel = _activeHolograms.iterator();
Iterator<Hologram> iterator = _activeHolograms.iterator();
while (itel.hasNext())
while (iterator.hasNext())
{
Hologram hologram = itel.next();
if (!worlds.contains(hologram.getLocation().getWorld()))
Hologram hologram = iterator.next();
if (hologram.getMaxLifetime() != -1 && UtilTime.elapsed(hologram.getStartTime(), hologram.getMaxLifetime()))
{
itel.remove();
iterator.remove();
hologram.stop();
}
else if (!worlds.contains(hologram.getLocation().getWorld()))
{
iterator.remove();
hologram.stop();
}
else
@ -71,7 +77,7 @@ public class HologramManager implements Listener, IPacketHandler
if (hologram.isRemoveOnEntityDeath() && !following.isValid())
{
itel.remove();
iterator.remove();
hologram.stop();
continue;
}