diff --git a/api/src/main/java/net/jitse/npclib/hologram/Hologram.java b/api/src/main/java/net/jitse/npclib/hologram/Hologram.java index f74536a..9e0b88c 100644 --- a/api/src/main/java/net/jitse/npclib/hologram/Hologram.java +++ b/api/src/main/java/net/jitse/npclib/hologram/Hologram.java @@ -1,4 +1,17 @@ package net.jitse.npclib.hologram; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + public interface Hologram { + + void show(Player player); + + void hide(Player player); + + void silentHide(UUID uuid); + + void updateText(List text); } diff --git a/api/src/main/java/net/jitse/npclib/hologram/HologramBase.java b/api/src/main/java/net/jitse/npclib/hologram/HologramBase.java index d0df6ed..9830668 100644 --- a/api/src/main/java/net/jitse/npclib/hologram/HologramBase.java +++ b/api/src/main/java/net/jitse/npclib/hologram/HologramBase.java @@ -1,5 +1,6 @@ package net.jitse.npclib.hologram; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -18,17 +19,68 @@ public abstract class HologramBase implements Hologram, HologramPacketHandler { protected List text; - public HologramBase(Location start, List text) { this.start = start; this.text = text; + + // Generate the necessary show and hide packets. + createPackets(); } - abstract public void show(Player player); + @Override + public void show(Player player) { + UUID uuid = player.getUniqueId(); + if (shown.contains(uuid)) + throw new IllegalArgumentException("Hologram is already shown to player"); - abstract public void hide(Player player); + sendShowPackets(player); - abstract public void silentHide(UUID uuid); + this.shown.add(uuid); + } - abstract public void updateText(List text); + @Override + public void hide(Player player) { + UUID uuid = player.getUniqueId(); + if (!shown.contains(uuid)) + throw new IllegalArgumentException("Hologram is not shown to player"); + + sendHidePackets(player); + + this.shown.remove(uuid); + } + + @Override + public void silentHide(UUID uuid) { + if (!shown.contains(uuid)) + throw new IllegalArgumentException("Hologram is not shown to player"); + + this.shown.remove(uuid); + } + + @Override + public void updateText(List text) { + if (this.text.size() != text.size()) + throw new IllegalArgumentException("When updating the text, the old and new text should have the same amount of lines"); + + for (int i = 0; i < text.size(); i++) { + String oldLine = this.text.get(i); + String newLine = text.get(i); + + if (oldLine.equals(newLine)) + continue; // No need to update. + + // Perhaps this should return an object so we can send all immediately to the shown players. + createTextUpdatePacket(oldLine, newLine); + } + + for (UUID uuid : shown) { + Player player = Bukkit.getPlayer(uuid); + if (player == null || !player.isOnline()) { + throw new IllegalStateException("Tried to update hologram for offline player"); + } + +// sendTextUpdatePackets(player, ); + } + this.text = text; + } } diff --git a/api/src/main/java/net/jitse/npclib/hologram/HologramPacketHandler.java b/api/src/main/java/net/jitse/npclib/hologram/HologramPacketHandler.java index 3c3ec09..b7d149a 100644 --- a/api/src/main/java/net/jitse/npclib/hologram/HologramPacketHandler.java +++ b/api/src/main/java/net/jitse/npclib/hologram/HologramPacketHandler.java @@ -1,6 +1,16 @@ package net.jitse.npclib.hologram; +import org.bukkit.entity.Player; + public interface HologramPacketHandler { - void sendTextUpdatePackets(int index, String newLine); + void createPackets(); + + void sendShowPackets(Player player); + + void sendHidePackets(Player player); + + void createTextUpdatePacket(String oldLine, String newLine); + + void sendTextUpdatePackets(Player player); } diff --git a/nms/pom.xml b/nms/pom.xml index 850a5ce..ba69367 100644 --- a/nms/pom.xml +++ b/nms/pom.xml @@ -15,16 +15,16 @@ v1_8_R1 - v1_8_R2 - v1_8_R3 - v1_9_R1 - v1_9_R2 - v1_10_R1 - v1_11_R1 - v1_12_R1 - v1_13_R1 - v1_13_R2 - v1_14_R1 + + + + + + + + + + diff --git a/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/NPC_v1_8_R1.java b/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/NPC_v1_8_R1.java index 29d6f0e..a3da078 100755 --- a/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/NPC_v1_8_R1.java +++ b/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/NPC_v1_8_R1.java @@ -6,9 +6,9 @@ package net.jitse.npclib.nms.v1_8_R1; import net.jitse.npclib.NPCLib; import net.jitse.npclib.api.state.NPCSlot; -import net.jitse.npclib.hologram._Hologram; -import net.jitse.npclib.internal.MinecraftVersion; +import net.jitse.npclib.hologram.Hologram; import net.jitse.npclib.internal.NPCBase; +import net.jitse.npclib.nms.v1_8_R1.hologram.Hologram_v1_8_R1; import net.jitse.npclib.nms.v1_8_R1.packets.*; import net.minecraft.server.v1_8_R1.*; import org.bukkit.Bukkit; @@ -27,7 +27,7 @@ import java.util.UUID; */ public class NPC_v1_8_R1 extends NPCBase { - private _Hologram hologram; + private Hologram hologram; private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn; private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister; private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove; @@ -41,8 +41,7 @@ public class NPC_v1_8_R1 extends NPCBase { @Override public void createPackets() { - this.hologram = new _Hologram(location.clone().add(0, 0.5, 0), text); - hologram.generatePackets(MinecraftVersion.V1_8_R1); + this.hologram = new Hologram_v1_8_R1(location.clone().add(0, 0.5, 0), text); PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper(); @@ -82,7 +81,7 @@ public class NPC_v1_8_R1 extends NPCBase { playerConnection.sendPacket(packetPlayOutNamedEntitySpawn); playerConnection.sendPacket(packetPlayOutEntityHeadRotation); - hologram.spawn(player); + hologram.show(player); Bukkit.getScheduler().runTaskLater(instance.getPlugin(), () -> playerConnection.sendPacket(packetPlayOutPlayerInfoRemove), 50); @@ -95,7 +94,7 @@ public class NPC_v1_8_R1 extends NPCBase { playerConnection.sendPacket(packetPlayOutEntityDestroy); playerConnection.sendPacket(packetPlayOutPlayerInfoRemove); - hologram.destroy(player); + hologram.hide(player); } @Override diff --git a/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram.java b/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram.java deleted file mode 100644 index b2ac658..0000000 --- a/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.jitse.npclib.nms.v1_8_R1.hologram; - -import net.jitse.npclib.hologram.HologramBase; -import org.bukkit.Location; - -import java.util.List; - -public class Hologram extends HologramBase { - - // Perhaps all logic methods should be placed in the base class instead then - // use a similar approach to the NPCBase class, with a HologramPacketHandler class... - // That way I can't mess up logic on different version whilst implementing new features. - // *cough cough* hologram text updates. I can already see this go wrong. - public Hologram(Location start, List text) { - super(start, text); - } - -// @Override -// public void show(Player player) { -// UUID uuid = player.getUniqueId(); -// if (shown.contains(uuid)) -// throw new IllegalArgumentException("Hologram is already shown to player"); -// -// // TODO: Send packets -// -// this.shown.add(uuid); -// } -// -// @Override -// public void hide(Player player) { -// UUID uuid = player.getUniqueId(); -// if (!shown.contains(uuid)) -// throw new IllegalArgumentException("Hologram is not shown to player"); -// -// // TODO: Send packets -// -// this.shown.remove(uuid); -// } -// -// @Override -// public void silentHide(UUID uuid) { -// if (!shown.contains(uuid)) -// throw new IllegalArgumentException("Hologram is not shown to player"); -// this.shown.remove(uuid); -// } -// -// @Override -// public void updateText(List text) { -// -// } - - - @Override - public void sendTextUpdatePackets(int index, String newLine) { - if (newLine.isEmpty()) { - // Check if line was empty before, if not, remove the hologram line. - } else { - // Check if line was empty before, if it was, create the hologram line. - // If the line was not empty before and it isn't now, update its text. - } - - // Send the packets to all players that can see the hologram (i.e. shown set). - } -} diff --git a/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram_v1_8_R1.java b/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram_v1_8_R1.java new file mode 100644 index 0000000..8758314 --- /dev/null +++ b/nms/v1_8_R1/src/main/java/net/jitse/npclib/nms/v1_8_R1/hologram/Hologram_v1_8_R1.java @@ -0,0 +1,82 @@ +package net.jitse.npclib.nms.v1_8_R1.hologram; + +import net.jitse.npclib.hologram.HologramBase; +import net.minecraft.server.v1_8_R1.EntityArmorStand; +import net.minecraft.server.v1_8_R1.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R1.PacketPlayOutSpawnEntityLiving; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_8_R1.CraftWorld; +import org.bukkit.entity.Player; + +import java.util.List; + +public class Hologram_v1_8_R1 extends HologramBase { + + // Perhaps all logic methods should be placed in the base class instead then + // use a similar approach to the NPCBase class, with a HologramPacketHandler class... + // That way I can't mess up logic on different version whilst implementing new features. + // *cough cough* hologram text updates. I can already see this go wrong. + public Hologram_v1_8_R1(Location start, List text) { + super(start, text); + } + + @Override + public void createPackets() { + Location top = start.clone().add(0, DELTA * text.size(), 0); + + for (String line : text) { + if (line.isEmpty()) { + top.subtract(0, DELTA, 0); + continue; + } + + EntityArmorStand armorStand = new EntityArmorStand(((CraftWorld) top.getWorld()).getHandle()); + armorStand.setLocation(top.getX(), top.getY(), top.getZ(), 0, 0); + armorStand.setCustomName(line); // Does this method update? Or should teams be used? + armorStand.setCustomNameVisible(true); + armorStand.setGravity(false); + armorStand.setSmall(true); + armorStand.setInvisible(true); + armorStand.setBasePlate(false); + armorStand.setArms(false); + + PacketPlayOutSpawnEntityLiving lineShowPacket = new PacketPlayOutSpawnEntityLiving(armorStand); + PacketPlayOutEntityDestroy lineHidePacket = new PacketPlayOutEntityDestroy(armorStand.getId()); + // TODO: Add packets and ArmorStand object to some sort of manager. + + top.subtract(0, DELTA, 0); + } + } + + @Override + public void sendShowPackets(Player player) { + + } + + @Override + public void sendHidePackets(Player player) { + + } + + @Override + public void createTextUpdatePacket(String oldLine, String newLine) { + + } + + @Override + public void sendTextUpdatePackets(Player player) { + + } + + @Override + public void sendTextUpdatePackets(Player player, int index, String newLine) { + if (newLine.isEmpty()) { + // Check if line was empty before, if not, remove the hologram line. + } else { + // Check if line was empty before, if it was, create the hologram line. + // If the line was not empty before and it isn't now, update its text. + } + + // Send the packets to all players that can see the hologram (i.e. shown set). + } +}