Remove old holograms and add new holograms
This commit is contained in:
parent
2871446f74
commit
141c08ceb8
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,8 +1,30 @@
|
|||||||
package mineplex.core.hologram;
|
package mineplex.core.hologram;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import java.util.ArrayList;
|
||||||
import org.bukkit.entity.Player;
|
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;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,59 +32,629 @@ import mineplex.core.common.util.UtilPlayer;
|
|||||||
*/
|
*/
|
||||||
public class Hologram
|
public class Hologram
|
||||||
{
|
{
|
||||||
private HorseHologram _horseHologram;
|
|
||||||
private ArmorStandHologram _armorStandHologram;
|
|
||||||
|
|
||||||
|
public enum HologramTarget
|
||||||
|
{
|
||||||
|
BLACKLIST, WHITELIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Entry<Integer, Integer>> _entityIds = new ArrayList<Entry<Integer, Integer>>();
|
||||||
|
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 Location _location;
|
||||||
private String _text;
|
private boolean _makePackets = true;
|
||||||
|
private Packet[] _packets1_7;
|
||||||
|
private Packet[] _packets1_8;
|
||||||
|
private HashSet<String> _playersInList = new HashSet<String>();
|
||||||
|
private ArrayList<Player> _playersTracking = new ArrayList<Player>();
|
||||||
|
private BukkitRunnable _runnable;
|
||||||
|
private HologramTarget _target = HologramTarget.BLACKLIST;
|
||||||
|
private String[] _text = new String[0];
|
||||||
|
private int _viewDistance = 70;
|
||||||
|
|
||||||
public Hologram(Location location, String text)
|
public Hologram(Location location, String... text)
|
||||||
{
|
{
|
||||||
_location = location;
|
_location = location.clone();
|
||||||
_text = text;
|
setText(text);
|
||||||
|
|
||||||
_horseHologram = new HorseHologram(location, text);
|
|
||||||
_armorStandHologram = new ArmorStandHologram(location, text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendToPlayer(Player player)
|
/**
|
||||||
|
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
|
||||||
|
*/
|
||||||
|
public Hologram addPlayer(Player player)
|
||||||
{
|
{
|
||||||
if (UtilPlayer.is1_8(player))
|
return addPlayer(player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the player to the Hologram to be effected by Whitelist or Blacklist
|
||||||
|
*/
|
||||||
|
public Hologram addPlayer(String player)
|
||||||
{
|
{
|
||||||
_armorStandHologram.sendToPlayer(player);
|
_playersInList.add(player);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there a player entry in the hologram for Whitelist and Blacklist
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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<Player> getNearbyPlayers()
|
||||||
|
{
|
||||||
|
ArrayList<Player> nearbyPlayers = new ArrayList<Player>();
|
||||||
|
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<Integer, Integer> 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
|
else
|
||||||
{
|
{
|
||||||
_horseHologram.sendToPlayer(player);
|
_destroyPackets = true;
|
||||||
|
while (_entityIds.size() > _text.length)
|
||||||
|
{
|
||||||
|
_entityIds.remove(_text.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int textRow = 0; textRow < _text.length; textRow++)
|
||||||
|
{
|
||||||
|
Entry<Integer, Integer> 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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendToPlayers(Player... players)
|
private Packet[] makeSpawnPackets1_7(int height, int witherId, int horseId, String horseName)
|
||||||
{
|
{
|
||||||
for (Player player : players)
|
// 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[]
|
||||||
{
|
{
|
||||||
sendToPlayer(player);
|
spawnWitherSkull, spawnHorse, attachEntity
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeForPlayer(Player player)
|
private Packet[] makeSpawnPackets1_8(int textRow, int entityId, String lineOfText)
|
||||||
{
|
{
|
||||||
if (UtilPlayer.is1_8(player))
|
if (this.isUsingWitherSkull())
|
||||||
{
|
{
|
||||||
_armorStandHologram.removeForPlayer(player);
|
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
|
else
|
||||||
{
|
{
|
||||||
_horseHologram.removeForPlayer(player);
|
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
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeForPlayers(Player... players)
|
/**
|
||||||
|
* Removes the player from the Hologram so they are no longer effected by Whitelist or Blacklist
|
||||||
|
*/
|
||||||
|
public Hologram removePlayer(Player player)
|
||||||
{
|
{
|
||||||
for (Player player : players)
|
return addPlayer(player.getName());
|
||||||
{
|
|
||||||
removeForPlayer(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<Player> canSee = getNearbyPlayers();
|
||||||
|
Iterator<Player> 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<Integer, Integer> 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<Integer, Integer> 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<Packet> packets1_7 = new ArrayList<Packet>();
|
||||||
|
int[] destroy1_7 = new int[0];
|
||||||
|
int[] destroy1_8 = new int[0];
|
||||||
|
ArrayList<Packet> packets1_8 = new ArrayList<Packet>();
|
||||||
|
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<Integer, Integer> 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<Integer, Integer> 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<Integer, Integer> 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<Player> canSee = getNearbyPlayers();
|
||||||
|
Iterator<Player> 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
package mineplex.core.treasure.animation;
|
package mineplex.core.treasure.animation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.block.Block;
|
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.Item;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
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.common.util.UtilServer;
|
||||||
import mineplex.core.hologram.Hologram;
|
import mineplex.core.hologram.Hologram;
|
||||||
import mineplex.core.reward.RewardData;
|
import mineplex.core.reward.RewardData;
|
||||||
@ -25,7 +27,7 @@ public class ChestOpenAnimation extends Animation
|
|||||||
private RewardData _rewardData;
|
private RewardData _rewardData;
|
||||||
|
|
||||||
private Item _itemEntity;
|
private Item _itemEntity;
|
||||||
private Hologram _hologram;
|
private ArrayList<Hologram> _holograms = new ArrayList<Hologram>();
|
||||||
|
|
||||||
public ChestOpenAnimation(Treasure treasure, ChestData chestData, RewardData rewardData)
|
public ChestOpenAnimation(Treasure treasure, ChestData chestData, RewardData rewardData)
|
||||||
{
|
{
|
||||||
@ -35,7 +37,8 @@ public class ChestOpenAnimation extends Animation
|
|||||||
|
|
||||||
// Send chest open packet
|
// Send chest open packet
|
||||||
Block block = chestData.getBlock();
|
Block block = chestData.getBlock();
|
||||||
PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(block.getX(), block.getY(), block.getZ(), CraftMagicNumbers.getBlock(block), 1, 1);
|
PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(block.getX(), block.getY(), block.getZ(),
|
||||||
|
CraftMagicNumbers.getBlock(block), 1, 1);
|
||||||
for (Player other : UtilServer.getPlayers())
|
for (Player other : UtilServer.getPlayers())
|
||||||
{
|
{
|
||||||
((CraftPlayer) other).getHandle().playerConnection.sendPacket(packet);
|
((CraftPlayer) other).getHandle().playerConnection.sendPacket(packet);
|
||||||
@ -55,16 +58,21 @@ public class ChestOpenAnimation extends Animation
|
|||||||
}
|
}
|
||||||
else if (getTicks() == 15)
|
else if (getTicks() == 15)
|
||||||
{
|
{
|
||||||
_hologram = new Hologram(_chestData.getBlock().getLocation().add(0.5, 1.1, 0.5), _rewardData.getFriendlyName());
|
Hologram hologram = new Hologram(_chestData.getBlock().getLocation().add(0.5, 1.1, 0.5),
|
||||||
_hologram.sendToPlayers(_chestData.getBlock().getLocation().getWorld().getPlayers().toArray(new Player[0]));
|
_rewardData.getFriendlyName());
|
||||||
|
hologram.start();
|
||||||
|
_holograms.add(hologram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFinish()
|
public void onFinish()
|
||||||
{
|
{
|
||||||
if (_hologram != null)
|
if (!_holograms.isEmpty())
|
||||||
{
|
{
|
||||||
_hologram.removeForPlayers(_chestData.getBlock().getLocation().getWorld().getPlayers().toArray(new Player[0]));
|
for (Hologram hologram : _holograms)
|
||||||
|
{
|
||||||
|
hologram.stop();
|
||||||
|
}
|
||||||
_itemEntity.remove();
|
_itemEntity.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user