Util Holograms

Discussion in 'Resources' started by Ultimate_n00b, Feb 25, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Ultimate_n00b

    [​IMG]

    I finally finished coding no dependency holograms, which I'm sure you've heard of by now.

    These do not require and dependency such as ProtocolLib, and work fine on their own.

    Code:java
    1. public class Hologram {
    2. private static final double distance = 0.23;
    3. private List<String> lines = new ArrayList<String>();
    4. private List<Integer> ids = new ArrayList<Integer>();
    5. private boolean showing = false;
    6. private Location location;
    7.  
    8. public Hologram(String... lines) {
    9. this.lines.addAll(Arrays.asList(lines));
    10. }
    11.  
    12. public void change(String... lines) {
    13. destroy();
    14. this.lines = Arrays.asList(lines);
    15. show(this.location);
    16. }
    17.  
    18. public void show(Location loc) {
    19. if (showing == true) {
    20. try {
    21. throw new Exception("Is already showing!");
    22. } catch (Exception e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. Location first = loc.clone().add(0, (this.lines.size() / 2) * distance, 0);
    27. for (int i = 0; i < this.lines.size(); i++) {
    28. ids.addAll(showLine(first.clone(), this.lines.get(i)));
    29. first.subtract(0, distance, 0);
    30. }
    31. showing = true;
    32. this.location = loc;
    33. }
    34.  
    35. public void show(Location loc, long ticks) {
    36. show(loc);
    37. new BukkitRunnable() {
    38. @Override
    39. public void run() {
    40. destroy();
    41. }
    42. }.runTaskLater(MMGames.getPlugin(), ticks);
    43. }
    44.  
    45. public void destroy() {
    46. if (showing == false) {
    47. try {
    48. throw new Exception("Isn't showing!");
    49. } catch (Exception e) {
    50. e.printStackTrace();
    51. }
    52. }
    53. int[] ints = new int[this.ids.size()];
    54. for (int j = 0; j < ints.length; j++) {
    55. ints[j] = ids.get(j);
    56. }
    57. PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ints);
    58. for (Player player : Bukkit.getOnlinePlayers()) {
    59. ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
    60. }
    61. showing = false;
    62. this.location = null;
    63. }
    64.  
    65. private static List<Integer> showLine(Location loc, String text) {
    66. WorldServer world = ((CraftWorld) loc.getWorld()).getHandle();
    67. EntityWitherSkull skull = new EntityWitherSkull(world);
    68. skull.setLocation(loc.getX(), loc.getY() + 1 + 55, loc.getZ(), 0, 0);
    69. PacketPlayOutSpawnEntity skull_packet = new PacketPlayOutSpawnEntity(skull);
    70.  
    71. EntityHorse horse = new EntityHorse(world);
    72. horse.setLocation(loc.getX(), loc.getY() + 55, loc.getZ(), 0, 0);
    73. horse.setAge(-1700000);
    74. horse.setCustomName(text);
    75. horse.setCustomNameVisible(true);
    76. PacketPlayOutSpawnEntityLiving packedt = new PacketPlayOutSpawnEntityLiving(horse);
    77. for (Player player : loc.getWorld().getPlayers()) {
    78. EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
    79. nmsPlayer.playerConnection.sendPacket(packedt);
    80. nmsPlayer.playerConnection.sendPacket(skull_packet);
    81.  
    82. PacketPlayOutAttachEntity pa = new PacketPlayOutAttachEntity(0, horse, skull);
    83. nmsPlayer.playerConnection.sendPacket(pa);
    84. }
    85. return Arrays.asList(skull.getId(), horse.getId());
    86. }
    87.  
    88. }


    Basic Usage:

    Code:java
    1. new Hologram(ChatColor.GOLD + "" + ChatColor.BOLD + "Welcome to the server!", "Do /help if you need any help!").show(location)


    COMING SOON: Plugin with more features than a single class could hold.

    Big thanks to Goblom , zombiekiller753 , and to Asdjke for the original idea.
     
    macmc, jjssman, WesJD and 10 others like this.
  2. Offline

    Deleted user

    How bout this?

    Code:
    package com.zombiekiller753.holograms;
     
    import java.util.HashMap;
     
    import net.minecraft.server.v1_7_R1.EntityHorse;
    import net.minecraft.server.v1_7_R1.EntityWitherSkull;
    import net.minecraft.server.v1_7_R1.Packet;
    import net.minecraft.server.v1_7_R1.PacketPlayOutAttachEntity;
    import net.minecraft.server.v1_7_R1.PacketPlayOutEntityDestroy;
    import net.minecraft.server.v1_7_R1.PacketPlayOutSpawnEntityLiving;
    import net.minecraft.server.v1_7_R1.World;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_7_R1.CraftWorld;
    import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
    import org.bukkit.entity.Player;
     
    public class Hologram {
        private final Location loc;
        private final double dy;
        private final String message;
        private final World world;
        private final EntityWitherSkull skull;
        private HashMap<String, Integer> tags = new HashMap<String, Integer>();
        private boolean lock = false;
        
        public Hologram(Location loc, double dy, String message) {
            this.loc = loc;
            this.dy = dy;
            this.message = message;
            this.world = ((CraftWorld) loc.getWorld()).getHandle();
            skull = new EntityWitherSkull(world);
            skull.setLocation(loc.getX(), loc.getY() + dy + 55, loc.getZ(), 0, 0);
            ((CraftWorld) loc.getWorld()).getHandle().addEntity(skull);
        }
        public Hologram(String world, double x, double y, double z, double dy, String message) {
            this(new Location(Bukkit.getWorld(world), x, y, z), dy, message);
        }
        
        public void send(Player player) throws Exception {
            if (!lock) {
                EntityHorse horse = new EntityHorse(world);
                horse.setLocation(loc.getX(), loc.getY() + dy + 55.25, loc.getZ(), 0, 0);
                horse.setAge(-1700000);
                horse.setCustomName(message);
                horse.setCustomNameVisible(true);
                PacketPlayOutSpawnEntityLiving spawn = new PacketPlayOutSpawnEntityLiving(horse);
                sendPacket(player, spawn);
                
                PacketPlayOutAttachEntity pa = new PacketPlayOutAttachEntity(0, horse, skull);
                sendPacket(player, pa);
                tags.put(player.getName(), horse.getId());
            } else {
                throw new Exception("There is a lock on this hologram!");
            }
        }
        public void remove(Player player) throws Exception {
            if (!lock) {
                PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(tags.get(player.getName()));
                sendPacket(player, packet);
                tags.remove(player.getName());
            } else {
                throw new Exception("There is a lock on this hologram!");
            }
        }
        public void remove() throws Exception {
            if (!lock) {
                lock = true;
                for (String s : tags.keySet()) {
                    PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(tags.get(s));
                    sendPacket(Bukkit.getPlayer(s), packet);
                }
                tags.clear();
            } else {
                throw new Exception("There is a lock on this hologram!");
            }
        }
        private void sendPacket(Player p, Packet packet) {
            ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet);
        }
    }
    
    https://gist.github.com/zombiekiller753/9222882
     
  3. Nice work, I'm totally going to use this ;D

    Could you add some comments in your code, to show which line does what or something like that?
     
    Niknea likes this.
  4. Offline

    CrazyGuy3000

    ^ this please, would be easier to read IMO x3
     
  5. Offline

    Deleted user

    bluegru CrazyGuy3000
    Gonna add that, but I'm also planning to release an API, so I'm not sure
     
  6. Offline

    ccrama

    Ultimate_n00b Hmm, NPE on line 87,
    Code:java
    1. WorldServer world = ((CraftWorld) loc.getWorld()).getHandle();

    My world is
    Code:java
    1. public static Location hub = new Location(Bukkit.getWorld("hub"), 13.12185, -294.23402, 2);
    2.  

    which doesn't return null in any other places that I use it. Also, you still have your plugin mentioned a few places in your class (specifically the runnables, with plugin). It would be a good idea to change those to save some headaches ;)

    Cheers,
    ccrama
     
  7. Offline

    filoghost

  8. Offline

    Ultimate_n00b

    You are correct about it being simpler, however there's quite a few issues with yours. For one, the entities have a number of requirements before they can spawn. As well, there are a number of plugins that can modify your entities. There are a few other flaws, but I'm sure you already know them.
     
  9. Offline

    Dread9Nought

  10. Offline

    Deleted user

    ccrama Not WorldServer. World.

    import net.minecraft.server.v1_7_R1.World;
    Dread9Nought
    [​IMG]

    filoghost This method is better because rather than spawning in entities, which makes /killall ruin it, this just sends packets.
     
  11. Offline

    Desle

    This is sick, thanks.
    I used it for messages on the screen. You know how games have that popup with "gained 5 XP" or something..?
     
    Phasesaber likes this.
  12. Desle

    This is exactly what I want to do ;D
    Do you mind to show me the code?
     
  13. Offline

    Desle

    bluegru
    It's really easy.
    I've just modified the class above a bit, so you can tell it what players to send the hologram to.
    When they kill a player, just show a hologram to the killer, on the location of the killed entity.

    Code:java
    1. public void expMessage(Player p, Location loc, double gained, double needed, double current) {
    2. if(gained == 0) {
    3. return;
    4. }
    5. final Hologram holo = new Hologram(ChatColor.RED + "+ " + gained + " XP", ChatColor.GRAY + "[" + current + "/" + needed + "]");
    6. holo.show(p, loc);
    7. Bukkit.getScheduler().scheduleSyncDelayedTask(this, new BukkitRunnable() {
    8.  
    9. @Override
    10. public void run() {
    11. holo.destroy();
    12. }
    13. }, getConfig().getInt("configuration" + ".xpmessages-time"));
    14. }


    And here is the Hologram class;
    Code:java
    1. public class Hologram {
    2. private static final double distance = 0.23;
    3. private List<String> lines = new ArrayList<String>();
    4. private List<Integer> ids = new ArrayList<Integer>();
    5. private boolean showing = false;
    6. private Location location;
    7.  
    8. public Hologram(String... lines) {
    9. this.lines.addAll(Arrays.asList(lines));
    10. }
    11.  
    12. public void show(Player p, Location loc) {
    13. if (showing == true) {
    14. try {
    15. throw new Exception("Is already showing!");
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. Location first = loc.clone().add(0, (this.lines.size() / 2) * distance, 0);
    21. for (int i = 0; i < this.lines.size(); i++) {
    22. ids.addAll(showLine(p, first.clone(), this.lines.get(i)));
    23. first.subtract(0, distance, 0);
    24. }
    25. showing = true;
    26. this.location = loc;
    27. }
    28.  
    29. public void destroy() {
    30. if (showing == false) {
    31. try {
    32. throw new Exception("Isn't showing!");
    33. } catch (Exception e) {
    34. e.printStackTrace();
    35. }
    36. }
    37. int[] ints = new int[this.ids.size()];
    38. for (int j = 0; j < ints.length; j++) {
    39. ints[j] = ids.get(j);
    40. }
    41. PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ints);
    42. for (Player player : Bukkit.getOnlinePlayers()) {
    43. ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
    44. }
    45. showing = false;
    46. this.location = null;
    47. }
    48.  
    49. private static List<Integer> showLine(Player p, Location loc, String text) {
    50. WorldServer world = ((CraftWorld) loc.getWorld()).getHandle();
    51. EntityWitherSkull skull = new EntityWitherSkull(world);
    52. skull.setLocation(loc.getX(), loc.getY() + 1 + 55, loc.getZ(), 0, 0);
    53. ((CraftWorld) loc.getWorld()).getHandle().addEntity(skull);
    54.  
    55. EntityHorse horse = new EntityHorse(world);
    56. horse.setLocation(loc.getX(), loc.getY() + 55, loc.getZ(), 0, 0);
    57. horse.setAge(-1700000);
    58. horse.setCustomName(text);
    59. horse.setCustomNameVisible(true);
    60. PacketPlayOutSpawnEntityLiving packedt = new PacketPlayOutSpawnEntityLiving(horse);
    61. EntityPlayer nmsPlayer = ((CraftPlayer) p).getHandle();
    62. nmsPlayer.playerConnection.sendPacket(packedt);
    63.  
    64. PacketPlayOutAttachEntity pa = new PacketPlayOutAttachEntity(0, horse, skull);
    65. nmsPlayer.playerConnection.sendPacket(pa);
    66. return Arrays.asList(skull.getId(), horse.getId());
    67. }
    68. }
     
  14. Offline

    ccrama

    zombiekiller753 Ultimate_n00b after changing it from WorldServer to World, it still throws an NPE at me. Could anything else be the issue?

    //EDIT:
    My LOCATION was the NPE (don't know why), but even if I set the spawn location to the user's location, it still doesn't appear. I thought it was the location angle was making it invisible, but I added 3 to the Y value to no avail. Any ideas?
     
  15. Offline

    Deleted user

    ccrama
    I'll take a look at it, and see what could be wrong. What's your dy value though?


    Also, I don't know about Paul, but I would like credit if possible :p
     
  16. Offline

    filoghost

    Ultimate_n00b There's some downsides for each method. With your method you have to handle teleports, players that join and leave, etc. With mine, I should take care of other plugins killing my entities. But I will add a fake CraftEntity that extends their relative CraftEntities removing the method .remove(); (making it empty). Other plugins then should be able to kill my entities only with NMS.
     
  17. Offline

    SoThatsIt

  18. Offline

    Ultimate_n00b

    SoThatsIt I'm not quite sure.

    all Remodeling it, will release new version later today.

    Not really, but WorldServer is the correct thing.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  19. Offline

    sipsi133

  20. Offline

    Desle

    sipsi133
    You have to store all holograms in a list, so you can just loop through that list and destroy() them.
     
  21. Offline

    Ultimate_n00b

    sipsi133 Desle Almost done with a new version which will make this easier.
     
  22. Offline

    LCastr0

    Is there a way to make it with no animals? If I'm using mc-core with animals option disabled, it wouldn't show...
     
  23. Offline

    Ultimate_n00b

    Really? hm.. Are you sure it's not something you're doing wrong? I tested with blocking all types of mob spawning, nothing came up.
     
  24. Offline

    LCastr0

    Ultimate_n00b ok, sorry I was doing it wrong xD
    But after I reload/relog on the server, the nametag disappears :/
     
  25. Offline

    Ultimate_n00b

    You'll have to recreate it, I don't save them for you.
     
  26. Offline

    LCastr0

    Would it work if I sent them to a List, and whenever the player joins, it re-makes the holograms?
    (And then, when server stops, send the list to a config file, and when load the server again, re-make all the holograms?)
     
  27. Offline

    Squid_Boss

    Nice, I saw this in vanilla from Asdjke and ever since I have been really looking forward to working with it. It gives everything just a bit more pizzazz, so good job! :)

    As for LCastr0 's issue if, with Ultimate_n00b 's consent, I would love to edit the code a bit so it's a bit more relog friendly and post it in here. For the reload just put the Hologram in the onEnable method.
     
  28. Offline

    Ultimate_n00b

    No need, I'm just about to most my newer version. It as well supports if the player walks away.
     
  29. Offline

    Ape101

    Quick snippet to show how to display an image?
    + getting an error
    Code:java
    1. public boolean onCommand(CommandSender sender, Command cmd,
    2. String CommandLabel, String[] args) {
    3. Player p = (Player) sender;
    4. Location location = p.getEyeLocation();
    5.  
    6. new Hologram(ChatColor.GOLD + "" + ChatColor.BOLD + "HEY STILL").show(location);
    7. return false;
    8. }

    on line 6
     
Thread Status:
Not open for further replies.

Share This Page