diff --git a/Plugins/Mineplex.Core/src/mineplex/core/hologram/ArmorStandHologram.java b/Plugins/Mineplex.Core/src/mineplex/core/hologram/ArmorStandHologram.java deleted file mode 100644 index e0f66b2e1..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/hologram/ArmorStandHologram.java +++ /dev/null @@ -1,89 +0,0 @@ -package mineplex.core.hologram; - -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; -import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; -import org.bukkit.entity.Player; -import net.minecraft.server.v1_7_R4.DataWatcher; -import net.minecraft.server.v1_7_R4.EnumEntitySize; -import net.minecraft.server.v1_7_R4.MathHelper; -import net.minecraft.server.v1_7_R4.Packet; -import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; -import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; -import net.minecraft.server.v1_7_R4.PlayerConnection; - -import mineplex.core.common.DummyEntity; -import mineplex.core.common.util.UtilEnt; - -/** - * Created by Shaun on 9/5/2014. - */ -public class ArmorStandHologram -{ - private String _text; - private Packet _packet; - private int _entityId; - - public ArmorStandHologram(Location location, String text) - { - _text = text; - - _entityId = UtilEnt.getNewEntityId(); - _packet = createArmorStandPacket(location); - } - - public void sendToPlayer(Player player) - { - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(_packet); - } - - public void removeForPlayer(Player player) - { - PacketPlayOutEntityDestroy entityDestroyPacket = new PacketPlayOutEntityDestroy(_entityId); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(entityDestroyPacket); - } - - private PacketPlayOutSpawnEntityLiving createArmorStandPacket(Location location) - { - final PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(); - packet.a = _entityId; - packet.b = (byte) 30; - packet.c = MathHelper.floor(location.getX() * 32D);//(int) EnumEntitySize.SIZE_2.a(100); - packet.d = MathHelper.floor((location.getY() - 0.8) * 32D);//(int) MathHelper.floor(64 * 32.0D); - packet.e = MathHelper.floor(location.getZ() * 32D);//(int)EnumEntitySize.SIZE_2.a(100); - packet.f = 0; // Velocity X - packet.g = 0; // Velocity Y - packet.h = 0; // Velocity Z - packet.i = (byte) 0; // Yaw - packet.j = (byte) 0; // Pitch - packet.k = (byte) 0; // Head Pitch - - final DataWatcher watcher = new DataWatcher(new DummyEntity(((CraftWorld)location.getWorld()).getHandle())); - - watcher.a(0, Byte.valueOf((byte)0)); - watcher.a(1, Short.valueOf((short)300)); - watcher.a(2, _text); - watcher.a(3, Byte.valueOf((byte) 1)); - watcher.a(4, Byte.valueOf((byte)0)); - watcher.a(7, Integer.valueOf(0)); - watcher.a(8, Byte.valueOf((byte)0)); - watcher.a(9, Byte.valueOf((byte)0)); - watcher.a(6, Float.valueOf(1.0F)); - watcher.a(10, Byte.valueOf((byte)0)); - - // Set invisible - int i1 = watcher.getInt(0); - watcher.watch(0, Byte.valueOf((byte)(i1 | 1 << 5))); - - // Set small and No Gravity - byte b1 = watcher.getByte(10); - b1 = (byte)(b1 | 0x1); - b1 = (byte)(b1 | 0x2); - watcher.watch(10, Byte.valueOf(b1)); - - packet.l = watcher; - - return packet; - } - -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/hologram/Hologram.java b/Plugins/Mineplex.Core/src/mineplex/core/hologram/Hologram.java index 7244427fa..584b6d461 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/hologram/Hologram.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/hologram/Hologram.java @@ -1,8 +1,30 @@ package mineplex.core.hologram; -import org.bukkit.Location; -import org.bukkit.entity.Player; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; +import net.minecraft.server.v1_7_R4.DataWatcher; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityTeleport; +import net.minecraft.server.v1_7_R4.PacketPlayOutRelEntityMove; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilPlayer; /** @@ -10,59 +32,629 @@ import mineplex.core.common.util.UtilPlayer; */ public class Hologram { - private HorseHologram _horseHologram; - private ArmorStandHologram _armorStandHologram; - private Location _location; - private String _text; + public enum HologramTarget + { + BLACKLIST, WHITELIST; + } - public Hologram(Location location, String text) - { - _location = location; - _text = text; + private Packet _destroy1_7; + private Packet _destroy1_8; + private boolean _destroyPackets = true; + /** + * 1.7 packets uses both EntityIDs while 1.8 uses only the first. + */ + private ArrayList> _entityIds = new ArrayList>(); + private boolean _isWitherSkull; + /** + * Keeps track of the holograms movements. This fixes offset that occasionally happens when moving a hologram around. + */ + private Vector _lastMovement; + private Location _location; + private boolean _makePackets = true; + private Packet[] _packets1_7; + private Packet[] _packets1_8; + private HashSet _playersInList = new HashSet(); + private ArrayList _playersTracking = new ArrayList(); + private BukkitRunnable _runnable; + private HologramTarget _target = HologramTarget.BLACKLIST; + private String[] _text = new String[0]; + private int _viewDistance = 70; - _horseHologram = new HorseHologram(location, text); - _armorStandHologram = new ArmorStandHologram(location, text); - } + public Hologram(Location location, String... text) + { + _location = location.clone(); + setText(text); + } - public void sendToPlayer(Player player) - { - if (UtilPlayer.is1_8(player)) - { - _armorStandHologram.sendToPlayer(player); - } - else - { - _horseHologram.sendToPlayer(player); - } - } + /** + * Adds the player to the Hologram to be effected by Whitelist or Blacklist + */ + public Hologram addPlayer(Player player) + { + return addPlayer(player.getName()); + } - public void sendToPlayers(Player... players) - { - for (Player player : players) - { - sendToPlayer(player); - } - } + /** + * Adds the player to the Hologram to be effected by Whitelist or Blacklist + */ + public Hologram addPlayer(String player) + { + _playersInList.add(player); + return this; + } - public void removeForPlayer(Player player) - { - if (UtilPlayer.is1_8(player)) - { - _armorStandHologram.removeForPlayer(player); - } - else - { - _horseHologram.removeForPlayer(player); - } - } + /** + * Is there a player entry in the hologram for Whitelist and Blacklist + */ + public boolean containsPlayer(Player player) + { + return _playersInList.contains(player.getName()); + } - public void removeForPlayers(Player... players) - { - for (Player player : players) - { - removeForPlayer(player); - } - } + /** + * Is there a player entry in the hologram for Whitelist and Blacklist + */ + public boolean containsPlayer(String player) + { + return _playersInList.contains(player); + } + + private Packet getDestroyPacket(Player player) + { + if (_destroyPackets) + { + makeDestroyPacket(); + _destroyPackets = false; + } + return UtilPlayer.is1_8(player) ? _destroy1_8 : _destroy1_7; + } + + /** + * Get who can see the hologram + * + * @Whitelist = Only people added can see the hologram + * @Blacklist = Anyone but people added can see the hologram + */ + public HologramTarget getHologramTarget() + { + return _target; + } + + /** + * Get the hologram location + */ + public Location getLocation() + { + return _location.clone(); + } + + private ArrayList getNearbyPlayers() + { + ArrayList nearbyPlayers = new ArrayList(); + for (Player player : getLocation().getWorld().getPlayers()) + { + if (isVisible(player)) + { + nearbyPlayers.add(player); + } + } + return nearbyPlayers; + } + + private Packet[] getSpawnPackets(Player player) + { + if (_makePackets) + { + makeSpawnPackets(); + _makePackets = false; + } + return UtilPlayer.is1_8(player) ? _packets1_8 : _packets1_7; + } + + /** + * 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 + String[] reversed = new String[_text.length]; + for (int i = 0; i < reversed.length; i++) + { + reversed[i] = _text[reversed.length - (i + 1)]; + } + return reversed; + } + + /** + * Get the view distance the hologram is viewable from. Default is 70 + */ + public int getViewDistance() + { + return _viewDistance; + } + + /** + * Is the hologram holograming? + */ + public boolean isInUse() + { + return _runnable != null; + } + + /** + * Does the hologram use the wither skull for 1.8 clients? + */ + public boolean isUsingWitherSkull() + { + return _isWitherSkull; + } + + public boolean isVisible(Player player) + { + if (getLocation().getWorld() == player.getWorld()) + { + if ((getHologramTarget() == HologramTarget.WHITELIST) == containsPlayer(player)) + { + if (getLocation().distance(player.getLocation()) < getViewDistance()) + { + return true; + } + } + } + return false; + } + + private void makeDestroyPacket() + { + int[] entityIds1_7 = new int[_entityIds.size() * 2]; + int[] entityIds1_8 = new int[_entityIds.size()]; + for (int i = 0; i < _entityIds.size(); i++) + { + Entry entry = _entityIds.get(i); + entityIds1_7[i * 2] = entry.getKey(); + entityIds1_7[(i * 2) + 1] = entry.getValue(); + entityIds1_8[i] = entry.getKey(); + } + _destroy1_7 = new PacketPlayOutEntityDestroy(entityIds1_7); + _destroy1_8 = new PacketPlayOutEntityDestroy(entityIds1_8); + } + + private void makeSpawnPackets() + { + _packets1_7 = new Packet[_text.length * 3]; + _packets1_8 = new Packet[_text.length * (isUsingWitherSkull() ? 2 : 1)]; + if (_entityIds.size() < _text.length) + { + _destroyPackets = true; + for (int i = _entityIds.size(); i < _text.length; i++) + { + _entityIds.add(new HashMap.SimpleEntry(UtilEnt.getNewEntityId(), UtilEnt.getNewEntityId())); + } + } + else + { + _destroyPackets = true; + while (_entityIds.size() > _text.length) + { + _entityIds.remove(_text.length); + } + } + for (int textRow = 0; textRow < _text.length; textRow++) + { + Entry entityIds = this._entityIds.get(textRow); + Packet[] packets1_7 = makeSpawnPackets1_7(textRow, entityIds.getKey(), entityIds.getValue(), _text[textRow]); + for (int i = 0; i < packets1_7.length; i++) + { + _packets1_7[(textRow * 3) + i] = packets1_7[i]; + } + + Packet[] packets1_8 = makeSpawnPackets1_8(textRow, entityIds.getKey(), _text[textRow]); + for (int i = 0; i < packets1_8.length; i++) + { + _packets1_8[(textRow * (isUsingWitherSkull() ? 2 : 1)) + i] = packets1_8[i]; + } + } + } + + private Packet[] makeSpawnPackets1_7(int height, int witherId, int horseId, String horseName) + { + // Spawn wither skull + PacketPlayOutSpawnEntity spawnWitherSkull = new PacketPlayOutSpawnEntity(); + spawnWitherSkull.a = witherId; + spawnWitherSkull.b = (int) (getLocation().getX() * 32); + spawnWitherSkull.c = (int) ((getLocation().getY() + 54.6 + ((double) height * 0.285D)) * 32); + spawnWitherSkull.d = (int) (getLocation().getZ() * 32); + spawnWitherSkull.j = 66; + // Spawn horse + PacketPlayOutSpawnEntityLiving spawnHorse = new PacketPlayOutSpawnEntityLiving(); + spawnHorse.a = horseId; + spawnHorse.b = 100; + spawnHorse.c = (int) (getLocation().getX() * 32); + spawnHorse.d = (int) ((getLocation().getY() + 54.83 + ((double) height * 0.285D) + 0.23D) * 32); + spawnHorse.e = (int) (getLocation().getZ() * 32); + // Setup datawatcher + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 0); + watcher.a(1, (short) 300); + watcher.a(10, horseName); + watcher.a(11, (byte) 1); + watcher.a(12, -1700000); + spawnHorse.l = watcher; + // Make horse ride wither + PacketPlayOutAttachEntity attachEntity = new PacketPlayOutAttachEntity(); + attachEntity.b = horseId; + attachEntity.c = witherId; + return new Packet[] + { + spawnWitherSkull, spawnHorse, attachEntity + }; + } + + private Packet[] makeSpawnPackets1_8(int textRow, int entityId, String lineOfText) + { + if (this.isUsingWitherSkull()) + { + PacketPlayOutSpawnEntity spawnPacket = new PacketPlayOutSpawnEntity(); + spawnPacket.a = entityId; + spawnPacket.b = (int) (getLocation().getX() * 32); + spawnPacket.c = (int) ((getLocation().getY() + -0.55 + ((double) textRow * 0.285)) * 32); + spawnPacket.d = (int) (getLocation().getZ() * 32); + spawnPacket.j = 66; + // Setup datawatcher for wither skull + PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(); + metadataPacket.a = entityId; + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 0); + watcher.a(2, lineOfText); + watcher.a(3, (byte) 1); + metadataPacket.b = watcher.c(); + return new Packet[] + { + spawnPacket, metadataPacket + }; + } + else + { + PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(); + packet.a = entityId; + packet.b = 30; + packet.c = (int) (getLocation().getX() * 32); + packet.d = (int) ((getLocation().getY() + -2.1 + ((double) textRow * 0.285)) * 32); + packet.e = (int) (getLocation().getZ() * 32); + // Setup datawatcher for armor stand + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32); + watcher.a(2, lineOfText); + watcher.a(3, (byte) 1); + packet.l = watcher; + return new Packet[] + { + packet + }; + } + } + + /** + * Removes the player from the Hologram so they are no longer effected by Whitelist or Blacklist + */ + public Hologram removePlayer(Player player) + { + return addPlayer(player.getName()); + } + + /** + * Removes the player from the Hologram so they are no longer effected by Whitelist or Blacklist + */ + public Hologram removePlayer(String player) + { + _playersInList.remove(player); + return this; + } + + /** + * Set who can see the hologram + * + * @Whitelist = Only people added can see the hologram + * @Blacklist = Anyone but people added can see the hologram + */ + public Hologram setHologramTarget(HologramTarget newTarget) + { + this._target = newTarget; + return this; + } + + /** + * Sets the hologram to appear at this location + */ + public Hologram setLocation(Location newLocation) + { + _makePackets = true; + Location oldLocation = getLocation(); + _location = newLocation.clone(); + if (isInUse()) + { + ArrayList canSee = getNearbyPlayers(); + Iterator itel = _playersTracking.iterator(); + while (itel.hasNext()) + { + Player player = itel.next(); + if (!canSee.contains(player)) + { + itel.remove(); + if (player.getWorld() == getLocation().getWorld()) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(getDestroyPacket(player)); + } + } + } + itel = canSee.iterator(); + while (itel.hasNext()) + { + Player player = itel.next(); + if (!_playersTracking.contains(player)) + { + _playersTracking.add(player); + itel.remove(); + for (Packet packet : getSpawnPackets(player)) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + } + } + 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()); + int z = (int) Math.floor(32 * _lastMovement.getZ()); + Packet[] packets1_7 = new Packet[_text.length]; + Packet[] packets1_8 = new Packet[_text.length]; + int i = 0; + if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127) + { + _lastMovement.subtract(new Vector(x / 32D, y / 32D, z / 32D)); + for (Entry entityId : this._entityIds) + { + PacketPlayOutRelEntityMove relMove = new PacketPlayOutRelEntityMove(); + relMove.a = entityId.getKey(); + relMove.b = (byte) x; + relMove.c = (byte) y; + relMove.d = (byte) z; + packets1_7[i] = relMove; + packets1_8[i] = relMove; + i++; + } + } + 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 (Entry entityId : this._entityIds) + { + for (int b = 0; b < 2; b++) + { + PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(); + teleportPacket.a = entityId.getKey(); + teleportPacket.b = x; + teleportPacket.c = (int) Math.floor((oldLocation.getY() + + (b == 0 ? 54.6 : isUsingWitherSkull() ? -0.55 : -2.1) + ((double) i * 0.285)) * 32); + teleportPacket.d = z; + if (b == 0) + { + packets1_7[i] = teleportPacket; + } + else + { + packets1_8[i] = teleportPacket; + } + } + i++; + } + } + for (Player player : canSee) + { + for (Packet packet : UtilPlayer.is1_8(player) ? packets1_8 : packets1_7) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + } + } + } + return this; + } + + /** + * Set the hologram text + */ + public Hologram setText(String... newText) + { + String[] reversed = new String[newText.length]; + for (int i = 0; i < reversed.length; i++) + { + reversed[i] = newText[reversed.length - (i + 1)]; + } + if (reversed.equals(_text)) + return this; + _makePackets = true; + if (isInUse()) + { + ArrayList packets1_7 = new ArrayList(); + int[] destroy1_7 = new int[0]; + int[] destroy1_8 = new int[0]; + ArrayList packets1_8 = new ArrayList(); + if (_text.length != reversed.length) + { + _destroyPackets = true; + } + for (int textRow = 0; textRow < Math.max(_text.length, reversed.length); textRow++) + { + // You can safely assume that _entityIds here is containing _text.length amount as this code is inside isInUse + if (textRow >= _text.length) + { + // Add entity id and send spawn packets + // You add a entity id because the new hologram needs + Entry entry = new HashMap.SimpleEntry(UtilEnt.getNewEntityId(), UtilEnt.getNewEntityId()); + _entityIds.add(entry); + packets1_7.addAll(Arrays.asList(makeSpawnPackets1_7(textRow, entry.getKey(), entry.getValue(), + reversed[textRow]))); + packets1_8.addAll(Arrays.asList(makeSpawnPackets1_8(textRow, entry.getKey(), reversed[textRow]))); + } + else if (textRow >= reversed.length) + { + // Remove entity id and send destroy packets + Entry entry = _entityIds.remove(reversed.length); + destroy1_7 = Arrays.copyOf(destroy1_7, destroy1_7.length + 2); + destroy1_7[destroy1_7.length - 2] = entry.getKey(); + destroy1_7[destroy1_7.length - 1] = entry.getValue(); + destroy1_8 = Arrays.copyOf(destroy1_8, destroy1_8.length + 1); + destroy1_8[destroy1_8.length - 1] = entry.getKey(); + } + else if (!reversed[textRow].equals(_text[textRow])) + { + // Send update metadata packets + Entry entry = _entityIds.get(textRow); + PacketPlayOutEntityMetadata metadata1_7 = new PacketPlayOutEntityMetadata(); + metadata1_7.a = entry.getValue(); + DataWatcher watcher1_7 = new DataWatcher(null); + watcher1_7.a(0, (byte) 0); + watcher1_7.a(1, (short) 300); + watcher1_7.a(10, reversed[textRow]); + watcher1_7.a(11, (byte) 1); + watcher1_7.a(12, -1700000); + metadata1_7.b = watcher1_7.c(); + packets1_7.add(metadata1_7); + + PacketPlayOutEntityMetadata metadata1_8 = new PacketPlayOutEntityMetadata(); + metadata1_8.a = entry.getKey(); + DataWatcher watcher1_8 = new DataWatcher(null); + watcher1_8.a(0, (byte) 0); + watcher1_8.a(2, reversed[textRow]); + watcher1_8.a(3, (byte) 1); + metadata1_8.b = watcher1_8.c(); + packets1_8.add(metadata1_8); + } + } + if (destroy1_7.length > 0) + { + packets1_7.add(new PacketPlayOutEntityDestroy(destroy1_7)); + } + if (destroy1_8.length > 0) + { + packets1_8.add(new PacketPlayOutEntityDestroy(destroy1_8)); + } + for (Player player : _playersTracking) + { + for (Packet packet : UtilPlayer.is1_8(player) ? packets1_8 : packets1_7) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + } + } + _text = reversed; + return this; + } + + /** + * Tells the hologram to use the wither skull instead of armorstand for 1.8 clients + */ + public Hologram setUsesWitherSkull() + { + _isWitherSkull = true; + return this; + } + + /** + * Set the distance the hologram is viewable from. Default is 70 + */ + public Hologram setViewDistance(int newDistance) + { + this._viewDistance = newDistance; + return setLocation(getLocation()); + } + + /** + * Start the hologram + */ + public Hologram start() + { + if (!isInUse()) + { + _playersTracking.addAll(getNearbyPlayers()); + for (Player player : _playersTracking) + { + for (Packet packet : getSpawnPackets(player)) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + } + _lastMovement = new Vector(); + _runnable = new BukkitRunnable() + { + + @Override + public void run() + { + if (!Bukkit.getWorlds().contains(getLocation().getWorld())) + { + stop(); + } + else + { + ArrayList canSee = getNearbyPlayers(); + Iterator itel = _playersTracking.iterator(); + while (itel.hasNext()) + { + Player player = itel.next(); + if (!canSee.contains(player)) + { + itel.remove(); + if (player.getWorld() == getLocation().getWorld()) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(getDestroyPacket(player)); + } + } + } + for (Player player : canSee) + { + if (!_playersTracking.contains(player)) + { + _playersTracking.add(player); + for (Packet packet : getSpawnPackets(player)) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + } + } + } + } + + }; + _runnable.runTaskTimer(Bukkit.getPluginManager().getPlugin("Arcade"), 0, 0); + // TODO Remove that plugin call + } + return this; + } + + /** + * Stop the hologram + */ + public Hologram stop() + { + if (isInUse()) + { + _runnable.cancel(); + _runnable = null; + for (Player player : _playersTracking) + { + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(getDestroyPacket(player)); + } + _playersTracking.clear(); + _lastMovement = null; + } + return this; + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/hologram/HorseHologram.java b/Plugins/Mineplex.Core/src/mineplex/core/hologram/HorseHologram.java deleted file mode 100644 index 3f268e531..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/hologram/HorseHologram.java +++ /dev/null @@ -1,132 +0,0 @@ -package mineplex.core.hologram; - -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; -import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; -import org.bukkit.entity.Player; -import net.minecraft.server.v1_7_R4.EntityFireball; -import net.minecraft.server.v1_7_R4.EntityHorse; -import net.minecraft.server.v1_7_R4.EntitySmallFireball; -import net.minecraft.server.v1_7_R4.Packet; -import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; -import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; -import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; -import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; -import net.minecraft.server.v1_7_R4.World; - -import mineplex.core.common.util.UtilServer; - -/** - * Created by Shaun on 8/29/2014. - */ -public class HorseHologram -{ - /** - * HorseHologram creates the required entities to spawn in a hologram. It is possible to send the packets for the entities to a player, - * but it is also possible to add the entities to the nmsWorld to keep them loaded into the server. - */ - - private Location _location; - private String _text; - - private World _nmsWorld; - private EntityFireball _fireball; - private EntityHorse _horse; - - public HorseHologram(Location location, String text) - { - _location = location; - _text = text; - - _nmsWorld = ((CraftWorld) location.getWorld()).getHandle(); - - // Create Entities - _fireball = new EntitySmallFireball(_nmsWorld); - _horse = new EntityHorse(_nmsWorld); - - // Location Data - _fireball.setLocation(_location.getX(), _location.getY() + 55.25, _location.getZ(), 0, 0); - _horse.setLocation(_location.getX(), _location.getY() + 55.25, _location.getZ(), 0, 0); - _horse.setAge(-1700000); - _horse.setCustomName(_text); - _horse.setCustomNameVisible(true); - } - - public void sendToPlayer(Player player) - { - Packet fireballSpawn = getFireballSpawnPacket(); - Packet horseSpawn = getHorseSpawnPacket(); - Packet attachPacket = getAttachEntityPacket(); - - sendPacket(player, fireballSpawn); - sendPacket(player, horseSpawn); - sendPacket(player, attachPacket); - } - - public void removeForPlayer(Player player) - { - Packet horseDestroy = getHorseDestroyPacket(); - Packet fireballDestroy = getFireballDestroyPacket(); - - sendPacket(player, horseDestroy); - sendPacket(player, fireballDestroy); - } - - public void spawnWithPackets() - { - for (Player player : UtilServer.getPlayers()) - { - sendToPlayer(player); - } - } - - public void removeWithPackets() - { - for (Player player : UtilServer.getPlayers()) - { - removeForPlayer(player); - } - } - - public void setText(String text) - { - _text = text; - _horse.setCustomName(_text); - } - - public String getText() - { - return _text; - } - - private Packet getHorseSpawnPacket() - { - return new PacketPlayOutSpawnEntityLiving(_horse); - } - - private Packet getFireballSpawnPacket() - { - return new PacketPlayOutSpawnEntity(_fireball, 64); - } - - private Packet getAttachEntityPacket() - { - return new PacketPlayOutAttachEntity(0, _horse, _fireball); - } - - private Packet getHorseDestroyPacket() - { - return new PacketPlayOutEntityDestroy(_horse.getId()); - } - - private Packet getFireballDestroyPacket() - { - return new PacketPlayOutEntityDestroy(_fireball.getId()); - } - - private void sendPacket(Player player, Packet packet) - { - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/ChestOpenAnimation.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/ChestOpenAnimation.java index c8bb075c0..79687f732 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/ChestOpenAnimation.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/ChestOpenAnimation.java @@ -1,5 +1,7 @@ package mineplex.core.treasure.animation; +import java.util.ArrayList; + import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.block.Block; @@ -8,8 +10,8 @@ import org.bukkit.craftbukkit.v1_7_R4.util.CraftMagicNumbers; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import net.minecraft.server.v1_7_R4.PacketPlayOutBlockAction; +import net.minecraft.server.v1_7_R4.PacketPlayOutBlockAction; import mineplex.core.common.util.UtilServer; import mineplex.core.hologram.Hologram; import mineplex.core.reward.RewardData; @@ -21,51 +23,57 @@ import mineplex.core.treasure.Treasure; */ public class ChestOpenAnimation extends Animation { - private ChestData _chestData; - private RewardData _rewardData; + private ChestData _chestData; + private RewardData _rewardData; - private Item _itemEntity; - private Hologram _hologram; + private Item _itemEntity; + private ArrayList _holograms = new ArrayList(); - public ChestOpenAnimation(Treasure treasure, ChestData chestData, RewardData rewardData) - { - super(treasure); - _chestData = chestData; - _rewardData = rewardData; + public ChestOpenAnimation(Treasure treasure, ChestData chestData, RewardData rewardData) + { + super(treasure); + _chestData = chestData; + _rewardData = rewardData; - // Send chest open packet - Block block = chestData.getBlock(); - PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(block.getX(), block.getY(), block.getZ(), CraftMagicNumbers.getBlock(block), 1, 1); - for (Player other : UtilServer.getPlayers()) - { - ((CraftPlayer) other).getHandle().playerConnection.sendPacket(packet); - other.playSound(block.getLocation(), Sound.CHEST_OPEN, 1, 1); - } - } + // Send chest open packet + Block block = chestData.getBlock(); + PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(block.getX(), block.getY(), block.getZ(), + CraftMagicNumbers.getBlock(block), 1, 1); + for (Player other : UtilServer.getPlayers()) + { + ((CraftPlayer) other).getHandle().playerConnection.sendPacket(packet); + other.playSound(block.getLocation(), Sound.CHEST_OPEN, 1, 1); + } + } - @Override - protected void tick() - { - if (getTicks() == 5) - { - Location location = _chestData.getBlock().getLocation().add(0.5, 0.8, 0.5); - _itemEntity = location.getWorld().dropItem(location, _rewardData.getDisplayItem()); - _itemEntity.setVelocity(new Vector(0, 0, 0)); - _itemEntity.setPickupDelay(Integer.MAX_VALUE); - } - else if (getTicks() == 15) - { - _hologram = new Hologram(_chestData.getBlock().getLocation().add(0.5, 1.1, 0.5), _rewardData.getFriendlyName()); - _hologram.sendToPlayers(_chestData.getBlock().getLocation().getWorld().getPlayers().toArray(new Player[0])); - } - } + @Override + protected void tick() + { + if (getTicks() == 5) + { + Location location = _chestData.getBlock().getLocation().add(0.5, 0.8, 0.5); + _itemEntity = location.getWorld().dropItem(location, _rewardData.getDisplayItem()); + _itemEntity.setVelocity(new Vector(0, 0, 0)); + _itemEntity.setPickupDelay(Integer.MAX_VALUE); + } + else if (getTicks() == 15) + { + Hologram hologram = new Hologram(_chestData.getBlock().getLocation().add(0.5, 1.1, 0.5), + _rewardData.getFriendlyName()); + hologram.start(); + _holograms.add(hologram); + } + } - public void onFinish() - { - if (_hologram != null) - { - _hologram.removeForPlayers(_chestData.getBlock().getLocation().getWorld().getPlayers().toArray(new Player[0])); - _itemEntity.remove(); - } - } + public void onFinish() + { + if (!_holograms.isEmpty()) + { + for (Hologram hologram : _holograms) + { + hologram.stop(); + } + _itemEntity.remove(); + } + } }