diff --git a/NMS/pom.xml b/NMS/pom.xml
index c9f0599c..3f136d57 100644
--- a/NMS/pom.xml
+++ b/NMS/pom.xml
@@ -27,6 +27,7 @@
v1_14_R1
v1_15_R1
v1_16_R1
+ v1_16_R2
\ No newline at end of file
diff --git a/NMS/v1_16_R2/pom.xml b/NMS/v1_16_R2/pom.xml
new file mode 100644
index 00000000..c986b44a
--- /dev/null
+++ b/NMS/v1_16_R2/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+
+ com.gmail.filoghost.holographicdisplays
+ holographicdisplays-nms
+ 2.4.4-SNAPSHOT
+
+
+ holographicdisplays-nms-v1_16_r2
+ HolographicDisplays NMS v1_16_R2
+
+
+
+
+ rwd-repo
+ https://repo.rosewooddev.io/repository/public
+
+
+
+
+
+ ${project.groupId}
+ holographicdisplays-nms-interfaces
+
+
+
+ ${project.groupId}
+ holographicdisplays-utils
+
+
+
+ org.spigotmc
+ spigot
+
+ 1.16.2
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSArmorStand.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSArmorStand.java
new file mode 100644
index 00000000..38a40bb6
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSArmorStand.java
@@ -0,0 +1,96 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import java.util.Collection;
+
+import org.bukkit.EntityEffect;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftArmorStand;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.util.EulerAngle;
+import org.bukkit.util.Vector;
+
+public class CraftNMSArmorStand extends CraftArmorStand {
+
+ public CraftNMSArmorStand(CraftServer server, EntityNMSArmorStand entity) {
+ super(server, entity);
+ }
+
+ // Disallow all the bukkit methods.
+
+ @Override
+ public void remove() {
+ // Cannot be removed, this is the most important to override.
+ }
+
+ // Methods from ArmorStand class
+ @Override public void setArms(boolean arms) { }
+ @Override public void setBasePlate(boolean basePlate) { }
+ @Override public void setBodyPose(EulerAngle pose) { }
+ @Override public void setBoots(ItemStack item) { }
+ @Override public void setChestplate(ItemStack item) { }
+ @Override public void setHeadPose(EulerAngle pose) { }
+ @Override public void setHelmet(ItemStack item) { }
+ @Override public void setItemInHand(ItemStack item) { }
+ @Override public void setLeftArmPose(EulerAngle pose) { }
+ @Override public void setLeftLegPose(EulerAngle pose) { }
+ @Override public void setLeggings(ItemStack item) { }
+ @Override public void setRightArmPose(EulerAngle pose) { }
+ @Override public void setRightLegPose(EulerAngle pose) { }
+ @Override public void setSmall(boolean small) { }
+ @Override public void setVisible(boolean visible) { }
+ @Override public void setMarker(boolean marker) { }
+
+ // Methods from LivingEntity class
+ @Override public boolean addPotionEffect(PotionEffect effect) { return false; }
+ @Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
+ @Override public boolean addPotionEffects(Collection effects) { return false; }
+ @Override public void setRemoveWhenFarAway(boolean remove) { }
+ @Override public void setAI(boolean ai) { }
+ @Override public void setCanPickupItems(boolean pickup) { }
+ @Override public void setCollidable(boolean collidable) { }
+ @Override public void setGliding(boolean gliding) { }
+ @Override public boolean setLeashHolder(Entity holder) { return false; }
+ @Override public void setSwimming(boolean swimming) { }
+
+ // Methods from Entity class
+ @Override public void setVelocity(Vector vel) { }
+ @Override public boolean teleport(Location loc) { return false; }
+ @Override public boolean teleport(Entity entity) { return false; }
+ @Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
+ @Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
+ @Override public void setFireTicks(int ticks) { }
+ @Override public boolean setPassenger(Entity entity) { return false; }
+ @Override public boolean eject() { return false; }
+ @Override public boolean leaveVehicle() { return false; }
+ @Override public void playEffect(EntityEffect effect) { }
+ @Override public void setCustomName(String name) { }
+ @Override public void setCustomNameVisible(boolean flag) { }
+ @Override public void setGlowing(boolean flag) { }
+ @Override public void setGravity(boolean gravity) { }
+ @Override public void setInvulnerable(boolean flag) { }
+ @Override public void setMomentum(Vector value) { }
+ @Override public void setSilent(boolean flag) { }
+ @Override public void setTicksLived(int value) { }
+ @Override public void setPersistent(boolean flag) { }
+ @Override public void setRotation(float yaw, float pitch) { }
+
+
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSItem.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSItem.java
new file mode 100644
index 00000000..34336e1c
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSItem.java
@@ -0,0 +1,65 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import org.bukkit.EntityEffect;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftItem;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+public class CraftNMSItem extends CraftItem {
+
+ public CraftNMSItem(CraftServer server, EntityNMSItem entity) {
+ super(server, entity);
+ }
+
+ // Disallow all the bukkit methods.
+
+ @Override
+ public void remove() {
+ // Cannot be removed, this is the most important to override.
+ }
+
+ // Methods from Item class
+ @Override public void setItemStack(ItemStack stack) { }
+ @Override public void setPickupDelay(int delay) { }
+
+ // Methods from Entity class
+ @Override public void setVelocity(Vector vel) { }
+ @Override public boolean teleport(Location loc) { return false; }
+ @Override public boolean teleport(Entity entity) { return false; }
+ @Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
+ @Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
+ @Override public void setFireTicks(int ticks) { }
+ @Override public boolean setPassenger(Entity entity) { return false; }
+ @Override public boolean eject() { return false; }
+ @Override public boolean leaveVehicle() { return false; }
+ @Override public void playEffect(EntityEffect effect) { }
+ @Override public void setCustomName(String name) { }
+ @Override public void setCustomNameVisible(boolean flag) { }
+ @Override public void setGlowing(boolean flag) { }
+ @Override public void setGravity(boolean gravity) { }
+ @Override public void setInvulnerable(boolean flag) { }
+ @Override public void setMomentum(Vector value) { }
+ @Override public void setSilent(boolean flag) { }
+ @Override public void setTicksLived(int value) { }
+ @Override public void setPersistent(boolean flag) { }
+ @Override public void setRotation(float yaw, float pitch) { }
+
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSSlime.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSSlime.java
new file mode 100644
index 00000000..af635cdc
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/CraftNMSSlime.java
@@ -0,0 +1,85 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import java.util.Collection;
+
+import org.bukkit.EntityEffect;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftSlime;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.bukkit.loot.LootTable;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.util.Vector;
+
+public class CraftNMSSlime extends CraftSlime {
+
+ public CraftNMSSlime(CraftServer server, EntityNMSSlime entity) {
+ super(server, entity);
+ }
+
+ // Disallow all the bukkit methods.
+
+ @Override
+ public void remove() {
+ // Cannot be removed, this is the most important to override.
+ }
+
+ // Methods from Slime class
+ @Override public void setSize(int size) { }
+ @Override public void setTarget(LivingEntity target) { }
+
+ // Methods from Mob class
+ @Override public void setLootTable(LootTable table) { }
+ @Override public void setSeed(long seed) { }
+
+ // Methods from LivingEntity class
+ @Override public boolean addPotionEffect(PotionEffect effect) { return false; }
+ @Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
+ @Override public boolean addPotionEffects(Collection effects) { return false; }
+ @Override public void setRemoveWhenFarAway(boolean remove) { }
+ @Override public void setAI(boolean ai) { }
+ @Override public void setCanPickupItems(boolean pickup) { }
+ @Override public void setCollidable(boolean collidable) { }
+ @Override public void setGliding(boolean gliding) { }
+ @Override public boolean setLeashHolder(Entity holder) { return false; }
+ @Override public void setSwimming(boolean swimming) { }
+
+ // Methods from Entity class
+ @Override public void setVelocity(Vector vel) { }
+ @Override public boolean teleport(Location loc) { return false; }
+ @Override public boolean teleport(Entity entity) { return false; }
+ @Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
+ @Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
+ @Override public void setFireTicks(int ticks) { }
+ @Override public boolean setPassenger(Entity entity) { return false; }
+ @Override public boolean eject() { return false; }
+ @Override public boolean leaveVehicle() { return false; }
+ @Override public void playEffect(EntityEffect effect) { }
+ @Override public void setCustomName(String name) { }
+ @Override public void setCustomNameVisible(boolean flag) { }
+ @Override public void setGlowing(boolean flag) { }
+ @Override public void setGravity(boolean gravity) { }
+ @Override public void setInvulnerable(boolean flag) { }
+ @Override public void setMomentum(Vector value) { }
+ @Override public void setSilent(boolean flag) { }
+ @Override public void setTicksLived(int value) { }
+ @Override public void setPersistent(boolean flag) { }
+ @Override public void setRotation(float yaw, float pitch) { }
+
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSArmorStand.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSArmorStand.java
new file mode 100644
index 00000000..71369915
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSArmorStand.java
@@ -0,0 +1,231 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
+import com.gmail.filoghost.holographicdisplays.util.Utils;
+import net.minecraft.server.v1_16_R2.*;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
+import org.bukkit.craftbukkit.v1_16_R2.util.CraftChatMessage;
+
+public class EntityNMSArmorStand extends EntityArmorStand implements NMSArmorStand {
+
+ private HologramLine parentPiece;
+ private CraftEntity customBukkitEntity;
+ private String customName;
+
+ public EntityNMSArmorStand(World world, HologramLine parentPiece) {
+ super(EntityTypes.ARMOR_STAND, world);
+ super.setInvisible(true);
+ super.setSmall(true);
+ super.setArms(false);
+ super.setNoGravity(true);
+ super.setBasePlate(true);
+ super.setMarker(true);
+ super.collides = false;
+ this.parentPiece = parentPiece;
+ forceSetBoundingBox(new NullBoundingBox());
+
+ this.onGround = true; // Workaround to force EntityTrackerEntry to send a teleport packet.
+ }
+
+ @Override
+ public void tick() {
+ // Disable normal ticking for this entity.
+
+ // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
+ if (this.onGround) {
+ this.onGround = false;
+ }
+ }
+
+ @Override
+ public void inactiveTick() {
+ // Disable normal ticking for this entity.
+
+ // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity.
+ if (this.onGround) {
+ this.onGround = false;
+ }
+ }
+
+ @Override
+ public void saveData(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ }
+
+ @Override
+ public boolean a_(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public boolean d(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public NBTTagCompound save(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return nbttagcompound;
+ }
+
+ @Override
+ public void load(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public void loadData(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public boolean isInvulnerable(DamageSource source) {
+ /*
+ * The field Entity.invulnerable is private.
+ * It's only used while saving NBTTags, but since the entity would be killed
+ * on chunk unload, we prefer to override isInvulnerable().
+ */
+ return true;
+ }
+
+ @Override
+ public boolean isCollidable() {
+ return false;
+ }
+
+ @Override
+ public void setCustomName(IChatBaseComponent ichatbasecomponent) {
+ // Locks the custom name.
+ }
+
+ @Override
+ public void setCustomNameVisible(boolean visible) {
+ // Locks the custom name.
+ }
+
+ @Override
+ public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
+ // Prevent stand being equipped
+ return EnumInteractionResult.PASS;
+ }
+
+ @Override
+ public boolean a_(int i, ItemStack item) {
+ // Prevent stand being equipped
+ return false;
+ }
+
+ @Override
+ public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
+ // Prevent stand being equipped
+ }
+
+ @Override
+ public void a(AxisAlignedBB boundingBox) {
+ // Do not change it!
+ }
+
+ public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
+ super.a(boundingBox);
+ }
+
+ @Override
+ public void playSound(SoundEffect soundeffect, float f, float f1) {
+ // Remove sounds.
+ }
+
+ @Override
+ public void setCustomNameNMS(String name) {
+ this.customName = Utils.limitLength(name, 300);
+ super.setCustomName(CraftChatMessage.fromStringOrNull(customName));
+ super.setCustomNameVisible(customName != null && !customName.isEmpty());
+ }
+
+ @Override
+ public String getCustomNameStringNMS() {
+ return this.customName;
+ }
+
+ @Override
+ public Object getCustomNameObjectNMS() {
+ return super.getCustomName();
+ }
+
+ @Override
+ public void die() {
+ // Prevent being killed.
+ }
+
+ @Override
+ public CraftEntity getBukkitEntity() {
+ if (customBukkitEntity == null) {
+ customBukkitEntity = new CraftNMSArmorStand(super.world.getServer(), this);
+ }
+ return customBukkitEntity;
+ }
+
+ @Override
+ public void killEntityNMS() {
+ super.dead = true;
+ }
+
+ @Override
+ public void setLocationNMS(double x, double y, double z, boolean broadcastLocationPacket) {
+ super.setPosition(x, y, z);
+ if (broadcastLocationPacket) {
+ broadcastLocationPacketNMS();
+ }
+ }
+
+ private void broadcastLocationPacketNMS() {
+ PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
+
+ for (Object obj : super.world.getPlayers()) {
+ if (obj instanceof EntityPlayer) {
+ EntityPlayer nmsPlayer = (EntityPlayer) obj;
+
+ double distanceSquared = Utils.square(nmsPlayer.locX() - super.locX()) + Utils.square(nmsPlayer.locZ() - super.locZ());
+ if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
+ nmsPlayer.playerConnection.sendPacket(teleportPacket);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isDeadNMS() {
+ return super.dead;
+ }
+
+ @Override
+ public int getIdNMS() {
+ return super.getId();
+ }
+
+ @Override
+ public HologramLine getHologramLine() {
+ return parentPiece;
+ }
+
+ @Override
+ public org.bukkit.entity.Entity getBukkitEntityNMS() {
+ return getBukkitEntity();
+ }
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSItem.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSItem.java
new file mode 100644
index 00000000..906e180d
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSItem.java
@@ -0,0 +1,249 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import java.util.logging.Level;
+
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
+import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
+import org.bukkit.entity.Player;
+
+import com.gmail.filoghost.holographicdisplays.api.line.ItemLine;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.ItemPickupManager;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
+import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
+import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
+import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
+
+import net.minecraft.server.v1_16_R2.Blocks;
+import net.minecraft.server.v1_16_R2.DamageSource;
+import net.minecraft.server.v1_16_R2.Entity;
+import net.minecraft.server.v1_16_R2.EntityHuman;
+import net.minecraft.server.v1_16_R2.EntityItem;
+import net.minecraft.server.v1_16_R2.EntityPlayer;
+import net.minecraft.server.v1_16_R2.EntityTypes;
+import net.minecraft.server.v1_16_R2.ItemStack;
+import net.minecraft.server.v1_16_R2.NBTTagCompound;
+import net.minecraft.server.v1_16_R2.NBTTagList;
+import net.minecraft.server.v1_16_R2.NBTTagString;
+import net.minecraft.server.v1_16_R2.World;
+
+public class EntityNMSItem extends EntityItem implements NMSItem {
+
+ private static final ReflectField VEHICLE_FIELD = new ReflectField<>(Entity.class, "vehicle");
+
+ private ItemLine parentPiece;
+ private ItemPickupManager itemPickupManager;
+ private CraftEntity customBukkitEntity;
+
+ public EntityNMSItem(World world, ItemLine piece, ItemPickupManager itemPickupManager) {
+ super(EntityTypes.ITEM, world);
+ super.pickupDelay = 32767; // Lock the item pickup delay, also prevents entities from picking up the item
+ this.parentPiece = piece;
+ this.itemPickupManager = itemPickupManager;
+ }
+
+ @Override
+ public void tick() {
+ // Disable normal ticking for this entity.
+
+ // So it won't get removed.
+ ticksLived = 0;
+ }
+
+ @Override
+ public void inactiveTick() {
+ // Disable normal ticking for this entity.
+
+ // So it won't get removed.
+ ticksLived = 0;
+ }
+
+ // Method called when a player is near.
+ @Override
+ public void pickup(EntityHuman human) {
+
+ if (human.locY() < super.locY() - 1.5 || human.locY() > super.locY() + 1.0) {
+ // Too low or too high, it's a bit weird./
+ return;
+ }
+
+ if (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
+ itemPickupManager.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
+ // It is never added to the inventory.
+ }
+ }
+
+ @Override
+ public void saveData(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ }
+
+ @Override
+ public boolean a_(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public boolean d(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public NBTTagCompound save(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return nbttagcompound;
+ }
+
+ @Override
+ public void load(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public void loadData(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public boolean isInvulnerable(DamageSource source) {
+ /*
+ * The field Entity.invulnerable is private.
+ * It's only used while saving NBTTags, but since the entity would be killed
+ * on chunk unload, we prefer to override isInvulnerable().
+ */
+ return true;
+ }
+
+ @Override
+ public boolean isCollidable() {
+ return false;
+ }
+
+ @Override
+ public void die() {
+ // Prevent being killed.
+ }
+
+ @Override
+ public boolean isAlive() {
+ // This override prevents items from being picked up by hoppers.
+ // Should have no side effects.
+ return false;
+ }
+
+ @Override
+ public CraftEntity getBukkitEntity() {
+ if (customBukkitEntity == null) {
+ customBukkitEntity = new CraftNMSItem(super.world.getServer(), this);
+ }
+ return customBukkitEntity;
+ }
+
+ @Override
+ public boolean isDeadNMS() {
+ return super.dead;
+ }
+
+ @Override
+ public void killEntityNMS() {
+ super.dead = true;
+ }
+
+ @Override
+ public void setLocationNMS(double x, double y, double z) {
+ super.setPosition(x, y, z);
+ }
+
+ @Override
+ public void setItemStackNMS(org.bukkit.inventory.ItemStack stack) {
+ ItemStack newItem = CraftItemStack.asNMSCopy(stack); // ItemStack.a is returned if the stack is null, invalid or the material is not an Item
+
+ if (newItem == null || newItem == ItemStack.b) {
+ newItem = new ItemStack(Blocks.BEDROCK);
+ }
+
+ if (newItem.getTag() == null) {
+ newItem.setTag(new NBTTagCompound());
+ }
+ NBTTagCompound display = newItem.getTag().getCompound("display"); // Returns a new NBTTagCompound if not existing
+ if (!newItem.getTag().hasKey("display")) {
+ newItem.getTag().set("display", display);
+ }
+
+ NBTTagList tagList = new NBTTagList();
+ tagList.add(NBTTagString.a(ItemUtils.ANTISTACK_LORE)); // Antistack lore
+ display.set("Lore", tagList);
+
+ setItemStack(newItem);
+ }
+
+ @Override
+ public int getIdNMS() {
+ return super.getId();
+ }
+
+ @Override
+ public ItemLine getHologramLine() {
+ return parentPiece;
+ }
+
+ @Override
+ public void allowPickup(boolean pickup) {
+ if (pickup) {
+ super.pickupDelay = 0;
+ } else {
+ super.pickupDelay = 32767;
+ }
+ }
+
+ @Override
+ public org.bukkit.entity.Entity getBukkitEntityNMS() {
+ return getBukkitEntity();
+ }
+
+ @Override
+ public void setPassengerOfNMS(NMSEntityBase vehicleBase) {
+ if (vehicleBase == null || !(vehicleBase instanceof Entity)) {
+ // It should never dismount
+ return;
+ }
+
+ Entity entity = (Entity) vehicleBase;
+
+ try {
+ if (super.getVehicle() != null) {
+ Entity oldVehicle = super.getVehicle();
+ VEHICLE_FIELD.set(this, null);
+ oldVehicle.passengers.remove(this);
+ }
+
+ VEHICLE_FIELD.set(this, entity);
+ entity.passengers.clear();
+ entity.passengers.add(this);
+
+ } catch (Throwable t) {
+ ConsoleLogger.logDebug(Level.SEVERE, "Couldn't set passenger", t);
+ }
+ }
+
+ @Override
+ public Object getRawItemStack() {
+ return super.getItemStack();
+ }
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSSlime.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSSlime.java
new file mode 100644
index 00000000..7d9c76f3
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/EntityNMSSlime.java
@@ -0,0 +1,225 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import java.util.logging.Level;
+
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
+import org.bukkit.event.player.PlayerInteractEntityEvent;
+
+import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
+import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
+import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
+
+import net.minecraft.server.v1_16_R2.AxisAlignedBB;
+import net.minecraft.server.v1_16_R2.DamageSource;
+import net.minecraft.server.v1_16_R2.Entity;
+import net.minecraft.server.v1_16_R2.EntityDamageSource;
+import net.minecraft.server.v1_16_R2.EntityPlayer;
+import net.minecraft.server.v1_16_R2.EntitySlime;
+import net.minecraft.server.v1_16_R2.EntityTypes;
+import net.minecraft.server.v1_16_R2.IChatBaseComponent;
+import net.minecraft.server.v1_16_R2.NBTTagCompound;
+import net.minecraft.server.v1_16_R2.SoundEffect;
+import net.minecraft.server.v1_16_R2.World;
+
+public class EntityNMSSlime extends EntitySlime implements NMSSlime {
+
+ private static final ReflectField VEHICLE_FIELD = new ReflectField<>(Entity.class, "vehicle");
+
+ private HologramLine parentPiece;
+ private CraftEntity customBukkitEntity;
+
+ public EntityNMSSlime(World world, HologramLine parentPiece) {
+ super(EntityTypes.SLIME, world);
+ super.persistent = true;
+ super.collides = false;
+ a(0.0F, 0.0F);
+ setSize(1, false);
+ setInvisible(true);
+ this.parentPiece = parentPiece;
+ forceSetBoundingBox(new NullBoundingBox());
+ }
+
+ @Override
+ public void tick() {
+ // Disable normal ticking for this entity.
+
+ // So it won't get removed.
+ ticksLived = 0;
+ }
+
+ @Override
+ public void inactiveTick() {
+ // Disable normal ticking for this entity.
+
+ // So it won't get removed.
+ ticksLived = 0;
+ }
+
+ @Override
+ public void a(AxisAlignedBB boundingBox) {
+ // Do not change it!
+ }
+
+ public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
+ super.a(boundingBox);
+ }
+
+ @Override
+ public void saveData(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ }
+
+ @Override
+ public boolean a_(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public boolean d(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return false;
+ }
+
+ @Override
+ public NBTTagCompound save(NBTTagCompound nbttagcompound) {
+ // Do not save NBT.
+ return nbttagcompound;
+ }
+
+ @Override
+ public void load(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public void loadData(NBTTagCompound nbttagcompound) {
+ // Do not load NBT.
+ }
+
+ @Override
+ public boolean damageEntity(DamageSource damageSource, float amount) {
+ if (damageSource instanceof EntityDamageSource) {
+ EntityDamageSource entityDamageSource = (EntityDamageSource) damageSource;
+ if (entityDamageSource.getEntity() instanceof EntityPlayer) {
+ Bukkit.getPluginManager().callEvent(new PlayerInteractEntityEvent(((EntityPlayer) entityDamageSource.getEntity()).getBukkitEntity(), getBukkitEntity())); // Bukkit takes care of the exceptions
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isInvulnerable(DamageSource source) {
+ /*
+ * The field Entity.invulnerable is private.
+ * It's only used while saving NBTTags, but since the entity would be killed
+ * on chunk unload, we prefer to override isInvulnerable().
+ */
+ return true;
+ }
+
+ @Override
+ public boolean isCollidable() {
+ return false;
+ }
+
+ @Override
+ public void setCustomName(IChatBaseComponent ichatbasecomponent) {
+ // Locks the custom name.
+ }
+
+ @Override
+ public void setCustomNameVisible(boolean visible) {
+ // Locks the custom name.
+ }
+
+ @Override
+ public void playSound(SoundEffect soundeffect, float f, float f1) {
+ // Remove sounds.
+ }
+
+ @Override
+ public void die() {
+ // Prevent being killed.
+ }
+
+ @Override
+ public CraftEntity getBukkitEntity() {
+ if (customBukkitEntity == null) {
+ customBukkitEntity = new CraftNMSSlime(super.world.getServer(), this);
+ }
+ return customBukkitEntity;
+ }
+
+ @Override
+ public boolean isDeadNMS() {
+ return super.dead;
+ }
+
+ @Override
+ public void killEntityNMS() {
+ super.dead = true;
+ }
+
+ @Override
+ public void setLocationNMS(double x, double y, double z) {
+ super.setPosition(x, y, z);
+ }
+
+ @Override
+ public int getIdNMS() {
+ return super.getId();
+ }
+
+ @Override
+ public HologramLine getHologramLine() {
+ return parentPiece;
+ }
+
+ @Override
+ public org.bukkit.entity.Entity getBukkitEntityNMS() {
+ return getBukkitEntity();
+ }
+
+ @Override
+ public void setPassengerOfNMS(NMSEntityBase vehicleBase) {
+ if (vehicleBase == null || !(vehicleBase instanceof Entity)) {
+ // It should never dismount
+ return;
+ }
+
+ Entity entity = (Entity) vehicleBase;
+
+ try {
+ if (super.getVehicle() != null) {
+ Entity oldVehicle = super.getVehicle();
+ VEHICLE_FIELD.set(this, null);
+ oldVehicle.passengers.remove(this);
+ }
+
+ VEHICLE_FIELD.set(this, entity);
+ entity.passengers.clear();
+ entity.passengers.add(this);
+
+ } catch (Throwable t) {
+ ConsoleLogger.logDebug(Level.SEVERE, "Couldn't set passenger", t);
+ }
+ }
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NmsManagerImpl.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NmsManagerImpl.java
new file mode 100644
index 00000000..c9a6c7a3
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NmsManagerImpl.java
@@ -0,0 +1,190 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import java.util.List;
+
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2IntMap;
+import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
+import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
+import org.bukkit.inventory.ItemStack;
+
+import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
+import com.gmail.filoghost.holographicdisplays.api.line.ItemLine;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.ChatComponentAdapter;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.ItemPickupManager;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.CustomNameHelper;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
+import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
+import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
+import com.gmail.filoghost.holographicdisplays.util.Validator;
+import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
+import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectMethod;
+
+import net.minecraft.server.v1_16_R2.ChatComponentText;
+import net.minecraft.server.v1_16_R2.Entity;
+import net.minecraft.server.v1_16_R2.EntityTypes;
+import net.minecraft.server.v1_16_R2.EnumCreatureType;
+import net.minecraft.server.v1_16_R2.IChatBaseComponent;
+import net.minecraft.server.v1_16_R2.IRegistry;
+import net.minecraft.server.v1_16_R2.MathHelper;
+import net.minecraft.server.v1_16_R2.RegistryMaterials;
+import net.minecraft.server.v1_16_R2.WorldServer;
+
+public class NmsManagerImpl implements NMSManager {
+
+ private static final ReflectField>> REGISTRY_TO_ID_FIELD = new ReflectField<>(RegistryMaterials.class, "bg");
+ private static final ReflectMethod REGISTER_ENTITY_METHOD = new ReflectMethod<>(WorldServer.class, "registerEntity", Entity.class);
+
+ @Override
+ public void setup() throws Exception {
+ registerCustomEntity(EntityNMSSlime.class, 55, 2.04f, 2.04f);
+ }
+
+ public void registerCustomEntity(Class extends Entity> entityClass, int id, float sizeWidth, float sizeHeight) throws Exception {
+ // Use reflection to map the custom entity to the correct ID
+ Object2IntMap> entityTypesToId = REGISTRY_TO_ID_FIELD.get(IRegistry.ENTITY_TYPE);
+ EntityTypes> customEntityTypes = EntityTypes.Builder.a(EnumCreatureType.MONSTER).a(sizeWidth, sizeHeight).b().a((String) null);
+ entityTypesToId.put(customEntityTypes, id);
+ }
+
+ @Override
+ public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, ItemLine parentPiece, ItemStack stack, ItemPickupManager itemPickupManager) {
+ WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
+ EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece, itemPickupManager);
+ customItem.setLocationNMS(x, y, z);
+ customItem.setItemStackNMS(stack);
+ if (!addEntityToWorld(nmsWorld, customItem)) {
+ ConsoleLogger.handleSpawnFail(parentPiece);
+ }
+ return customItem;
+ }
+
+ @Override
+ public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramLine parentPiece) {
+ WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
+ EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
+ touchSlime.setLocationNMS(x, y, z);
+ if (!addEntityToWorld(nmsWorld, touchSlime)) {
+ ConsoleLogger.handleSpawnFail(parentPiece);
+ }
+ return touchSlime;
+ }
+
+ @Override
+ public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece, boolean broadcastLocationPacket) {
+ WorldServer nmsWorld = ((CraftWorld) world).getHandle();
+ EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
+ invisibleArmorStand.setLocationNMS(x, y, z, broadcastLocationPacket);
+ if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
+ ConsoleLogger.handleSpawnFail(parentPiece);
+ }
+ return invisibleArmorStand;
+ }
+
+ private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) {
+ Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add");
+
+ final int chunkX = MathHelper.floor(nmsEntity.locX() / 16.0);
+ final int chunkZ = MathHelper.floor(nmsEntity.locZ() / 16.0);
+
+ if (!nmsWorld.isChunkLoaded(chunkX, chunkZ)) {
+ // This should never happen
+ nmsEntity.dead = true;
+ return false;
+ }
+
+ nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
+ try {
+ REGISTER_ENTITY_METHOD.invoke(nmsWorld, nmsEntity);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
+ return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
+ }
+
+ @Override
+ public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
+ Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
+
+ if (nmsEntity instanceof NMSEntityBase) {
+ return ((NMSEntityBase) nmsEntity);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public NMSEntityBase getNMSEntityBaseFromID(org.bukkit.World bukkitWorld, int entityID) {
+ WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
+ Entity nmsEntity = nmsWorld.getEntity(entityID);
+
+ if (nmsEntity instanceof NMSEntityBase) {
+ return ((NMSEntityBase) nmsEntity);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Object replaceCustomNameText(Object customNameObject, String target, String replacement) {
+ return CustomNameHelper.replaceCustomNameChatComponent(NMSChatComponentAdapter.INSTANCE, customNameObject, target, replacement);
+ }
+
+ private static enum NMSChatComponentAdapter implements ChatComponentAdapter {
+
+ INSTANCE {
+
+ public ChatComponentText cast(Object chatComponentObject) {
+ return (ChatComponentText) chatComponentObject;
+ }
+
+ @Override
+ public String getText(IChatBaseComponent chatComponent) {
+ return chatComponent.getText();
+ }
+
+ @Override
+ public List getSiblings(IChatBaseComponent chatComponent) {
+ return chatComponent.getSiblings();
+ }
+
+ @Override
+ public void addSibling(IChatBaseComponent chatComponent, IChatBaseComponent newSibling) {
+ newSibling.getChatModifier().setChatModifier(chatComponent.getChatModifier());
+ chatComponent.getSiblings().add(newSibling);
+ }
+
+ @Override
+ public ChatComponentText cloneComponent(IChatBaseComponent chatComponent, String newText) {
+ ChatComponentText clonedChatComponent = new ChatComponentText(newText);
+ clonedChatComponent.setChatModifier(chatComponent.getChatModifier().a());
+ return clonedChatComponent;
+ }
+
+ }
+
+ }
+
+}
diff --git a/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NullBoundingBox.java b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NullBoundingBox.java
new file mode 100644
index 00000000..fa7e37c8
--- /dev/null
+++ b/NMS/v1_16_R2/src/main/java/com/gmail/filoghost/holographicdisplays/nms/v1_16_R2/NullBoundingBox.java
@@ -0,0 +1,134 @@
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.gmail.filoghost.holographicdisplays.nms.v1_16_R2;
+
+import net.minecraft.server.v1_16_R2.AxisAlignedBB;
+import net.minecraft.server.v1_16_R2.BlockPosition;
+import net.minecraft.server.v1_16_R2.EnumDirection.EnumAxis;
+import net.minecraft.server.v1_16_R2.Vec3D;
+
+public class NullBoundingBox extends AxisAlignedBB {
+
+ public NullBoundingBox() {
+ super(0, 0, 0, 0, 0, 0);
+ }
+
+ @Override
+ public double a() {
+ return 0.0;
+ }
+
+ @Override
+ public AxisAlignedBB a(AxisAlignedBB arg0) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB a(double arg0, double arg1, double arg2) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB grow(double arg0, double arg1, double arg2) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB shrink(double arg0) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB a(BlockPosition arg0) {
+ return this;
+ }
+
+ @Override
+ public boolean a(double arg0, double arg1, double arg2, double arg3, double arg4, double arg5) {
+ return false;
+ }
+
+ @Override
+ public AxisAlignedBB g(double arg0) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB b(Vec3D arg0) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB b(AxisAlignedBB arg0) {
+ return this;
+ }
+
+ @Override
+ public AxisAlignedBB b(double arg0, double arg1, double arg2) {
+ return this;
+ }
+
+ @Override
+ public boolean c(AxisAlignedBB arg0) {
+ return false;
+ }
+
+ @Override
+ public AxisAlignedBB d(double arg0, double arg1, double arg2) {
+ return this;
+ }
+
+ @Override
+ public double a(EnumAxis arg0) {
+ return 0.0;
+ }
+
+ @Override
+ public double b(EnumAxis arg0) {
+ return 0.0;
+ }
+
+ @Override
+ public boolean e(double arg0, double arg1, double arg2) {
+ return false;
+ }
+
+ @Override
+ public double b() {
+ return 0.0;
+ }
+
+ @Override
+ public double c() {
+ return 0.0;
+ }
+
+ @Override
+ public double d() {
+ return 0.0;
+ }
+
+ @Override
+ public boolean d(Vec3D var0) {
+ return false;
+ }
+
+ @Override
+ public Vec3D f() {
+ return Vec3D.a;
+ }
+
+
+}
diff --git a/Plugin/pom.xml b/Plugin/pom.xml
index 49c49947..0eaebc1f 100644
--- a/Plugin/pom.xml
+++ b/Plugin/pom.xml
@@ -115,6 +115,11 @@
holographicdisplays-nms-v1_16_r1
+
+ ${project.groupId}
+ holographicdisplays-nms-v1_16_r2
+
+
org.spigotmc
spigot-api
diff --git a/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/NMSVersion.java b/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/NMSVersion.java
index 81b51b94..2d45530c 100644
--- a/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/NMSVersion.java
+++ b/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/NMSVersion.java
@@ -30,7 +30,8 @@ public enum NMSVersion {
v1_13_R2,
v1_14_R1,
v1_15_R1,
- v1_16_R1;
+ v1_16_R1,
+ v1_16_R2;
private static final NMSVersion CURRENT_VERSION = extractCurrentVersion();
diff --git a/pom.xml b/pom.xml
index 5a942496..29248651 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,6 +141,12 @@
holographicdisplays-nms-v1_16_r1
${project.version}
+
+
+ ${project.groupId}
+ holographicdisplays-nms-v1_16_r2
+ ${project.version}
+
org.spigotmc