Util Holograms

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

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

    Ultimate_n00b

    lx3krypticx Small thing, due to where the PlayerJoinEvent is called it won't work like that. You're gonna have to schedule a BukkitRunnable for a few ticks after the event happens.
     
  2. Offline

    lx3krypticx

    Oh my lord. I changed the ticks like 2 down. I had a bukkit runnable before. Anyways, for anyone having this problem schedule it for 5 ticks ahead.
     
  3. Offline

    SoThatsIt

    i've been working on the same thing ;) im doing it using the pitch/yaw of the player and the square distance to the hologram.
     
  4. Offline

    creepers84

    I'm trying the player head following for my plugin HCC.
    http://dev.bukkit.org/bukkit-plugins/hcc-holographic-chat-captions/
     
  5. Offline

    Gamecube762

    I was doing something similar, just never had the time to make the text to follow the player.
     
    Phasesaber likes this.
  6. Offline

    DSH105 Retired Staff

    creepers84
    If we're advertising here, it's also already implemented in HoloAPI, and I'm pretty sure Goblom has it planned for Holographic too.

    Show Spoiler

    http://dev.bukkit.org/bukkit-plugins/holoapi/
    http://dev.bukkit.org/bukkit-plugins/holographic/


    EDIT: (the player following that is, along with chat bubbles)
     
    Phasesaber and Goblom like this.
  7. Offline

    Goblom

    DSH105 Its already in Holographic (v2 which isn't released yet) but its not completed and experimental.
     
  8. Offline

    ccrama

    Desle likes this.
  9. Offline

    creepers84

    Nice!

    Mind sharing the code that allows for the chat bubbles :) I would love to learn from it and implement this splendid feature into my plugin. The smoothness of the transfer is fantastic ;)

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

    hawkfalcon

    HoloAPI, as the name suggests, is an api! You should hook into it ;)
     
    CaptainBern and DSH105 like this.
  11. Offline

    DSH105 Retired Staff

    The unique part about HoloAPI is that hologram content can be dynamically updated and moved around smoothly and easily without a shaking display.

    You should probably also do your own research (as I have to achieve this) before I start handing out code ;).

    hawkfalcon <3
     
    hawkfalcon likes this.
  12. Offline

    creepers84

    hawkfalcon > Dat advertising ;) I understand that it's an API. But I'd kinda like it to be an independent plugin. Either way, fantastic api DSH105 !
     
  13. Offline

    TeamJesus

    well plugin is under moderation, got an external test build somewhere?
     
  14. Offline

    lordbobby104

    Ok I have run into a serious problem. When you walk away from the hologram or you die it dissapears. So to combat this I made it show it to the player after they die. Problem is that it doesn't delete the entities when you walk away or die so I now have 1000 invisible entities that can't be removed using default bukkit methods... I need a way to remove these invisable entities.
     
  15. Offline

    Ultimate_n00b

    Working on it..
     
  16. Offline

    lordbobby104

    Ultimate_n00b I just need like a method to get this done once. I have found a work around for the problem but I still have 1000 entities sitting around :p

    Ultimate_n00b Is there maybe a file of the world to remove entities?
    EDIT: Entities are saved in the same region file as blocks so to delete the entities I have to deletet the world too.

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

    qlimax5000

  18. Offline

    lordbobby104

    Ultimate_n00b Have you found a way to accomplish this yet? I am just using trial and error by now D:
     
  19. Offline

    Ultimate_n00b

    I updated the original post.
     
  20. Offline

    lordbobby104

  21. Offline

    HeavyMine13

    1. I get this IDE Error (The constructor PacketPlayOutSpawnEntity(EntityWitherSkull) is undefined) and 2. It does not work:

    Main Class:
    Code:java
    1. package me.HeavyMine13.part;
    2.  
    3. import java.util.ArrayList;
    4. import java.util.List;
    5.  
    6. import net.minecraft.util.com.google.common.base.Joiner;
    7.  
    8. import org.bukkit.Bukkit;
    9. import org.bukkit.ChatColor;
    10. import org.bukkit.Location;
    11. import org.bukkit.Material;
    12. import org.bukkit.command.Command;
    13. import org.bukkit.command.CommandSender;
    14. import org.bukkit.entity.Player;
    15. import org.bukkit.event.EventHandler;
    16. import org.bukkit.event.Listener;
    17. import org.bukkit.event.entity.EntityDamageByBlockEvent;
    18. import org.bukkit.event.player.PlayerJoinEvent;
    19. import org.bukkit.event.player.PlayerMoveEvent;
    20. import org.bukkit.event.player.PlayerQuitEvent;
    21. import org.bukkit.plugin.java.JavaPlugin;
    22. import org.bukkit.scoreboard.DisplaySlot;
    23. import org.bukkit.scoreboard.Objective;
    24. import org.bukkit.scoreboard.Score;
    25. import org.bukkit.scoreboard.Scoreboard;
    26. import org.bukkit.scoreboard.ScoreboardManager;
    27.  
    28. public class Part extends JavaPlugin implements Listener {
    29. Boolean r = false;
    30. List<String> parteh = new ArrayList<String>();
    31. List<String> pp = new ArrayList<String>();
    32. private Objective objective;
    33. private Scoreboard board;
    34. private ScoreboardManager manager;
    35.  
    36. public void onEnable(){
    37. Bukkit.getPluginManager().registerEvents(this, this);
    38. manager = Bukkit.getScoreboardManager();
    39. board = manager.getNewScoreboard();
    40.  
    41. objective = board.registerNewObjective("showhealth", "dummy");
    42. objective.setDisplaySlot(DisplaySlot.SIDEBAR);
    43. objective.setDisplayName(ChatColor.GREEN + "Party-O-Meter");
    44. Location location = new Location(Bukkit.getWorld("8Bit-Spawn"), 103, 9, -687);
    45. Hologram surv = new Hologram(ChatColor.GOLD + "" + ChatColor.BOLD + "[8BitPvP]", " Survival");
    46. surv.show(location);
    47. }
    48.  
    49. public void onDisable(){
    50. parteh.clear();
    51. }
    52.  
    53. @Override
    54. public boolean onCommand(CommandSender sender, Command cmd,
    55. String label, String[] args) {
    56. if(!(sender instanceof Player)){
    57. sender.sendMessage("Only players can do dis!");
    58. return true;
    59. }else{
    60. Player p = (Player) sender;
    61. if(cmd.getLabel().equalsIgnoreCase("parteh")){
    62. if(args.length == 0){
    63. return false;
    64. }
    65. if(r.booleanValue() == true){
    66. if(args[0].equalsIgnoreCase("join")){
    67. if(parteh.contains(p.getName())){
    68. p.sendMessage(ChatColor.DARK_PURPLE + "Already partying like hell!");
    69. return true;
    70. }else{
    71. parteh.add(p.getName());
    72. pp.add(p.getDisplayName());
    73. p.sendMessage(ChatColor.LIGHT_PURPLE + "You joined our party! Welcome!");
    74. for(Player online : Bukkit.getOnlinePlayers()){
    75. Score score = objective.getScore(Bukkit.getOfflinePlayer(ChatColor.AQUA + "Members:")); //Get a fake offline player
    76. score.setScore(parteh.size());
    77. online.setScoreboard(board);
    78. }
    79. return true;
    80. }
    81. }else if(args[0].equalsIgnoreCase("leave")){
    82. if(parteh.contains(p.getName())){
    83. parteh.remove(p.getName());
    84. pp.remove(p.getDisplayName());
    85. p.setScoreboard(manager.getNewScoreboard());
    86. p.sendMessage(ChatColor.GRAY + "Removed from dem party!");
    87. return true;
    88. }else{
    89. p.sendMessage(ChatColor.RED + "You are not in a party.");
    90. return true;
    91. }
    92. }else if(args[0].equalsIgnoreCase("list")){
    93. if(parteh.contains(p.getName())){
    94. String playerList = (String) Joiner.on(", ").join(pp);
    95. p.sendMessage(ChatColor.DARK_GREEN + "[Party]: " + "" + playerList.toString());
    96. return true;
    97. }else{
    98. p.sendMessage(ChatColor.RED + "You are not in a party.");
    99. return true;
    100. }
    101. }else if(args[0].equalsIgnoreCase("over")){
    102. p.sendMessage(ChatColor.DARK_GREEN + "Party over nuuuuuuuuuuuuuuuuuu!");
    103. r = false;
    104. return true;
    105. }else if(args[0].equalsIgnoreCase("bounce")){
    106. if(args.length != 3) return false;
    107. if(parteh.contains(p.getName())){
    108.  
    109.  
    110. Material m = Material.getMaterial(args[1]);
    111. if(m == null){
    112. p.sendMessage(ChatColor.RED + "/p bounce <block name in caps> <bounces before it lands>");
    113. return true;
    114. }
    115.  
    116. int t = 0;
    117. try{
    118. t = Integer.parseInt(args[2]);
    119. } catch (NumberFormatException e){
    120. p.sendMessage(ChatColor.DARK_RED + "Third Arg Is Not An Integer!");
    121. return true;
    122. }
    123.  
    124. final BouncyBlocks bb = new BouncyBlocks(m, t, this);
    125. bb.spawn(p.getLocation());
    126. bb.setEffect(true);
    127. return true;
    128. }else{
    129. p.sendMessage(ChatColor.RED + "You are not in a party.");
    130. return true;
    131. }
    132. }else if(args[0].equalsIgnoreCase("begin")){
    133. p.sendMessage(ChatColor.AQUA + "The party already began!");
    134. }
    135. }else{
    136. if(args[0].equalsIgnoreCase("begin")){
    137. p.sendMessage(ChatColor.AQUA + "Let The Party begin!");
    138. r = true;
    139. }else if(args[0].equalsIgnoreCase("over")){
    140. p.sendMessage(ChatColor.DARK_GREEN + "There is no party. To begin one, use /p begin");
    141. return true;
    142. }
    143. }
    144. }else if(cmd.getLabel().equalsIgnoreCase("pchat")){
    145. if(r.booleanValue() == true){
    146. StringBuilder sb2 = new StringBuilder("");
    147. for(int i=0; i<args.length; i++){
    148. sb2.append(args[i]).append(" ");
    149. }
    150. String msg = (String) sb2.toString();
    151. for(Player all : Bukkit.getServer().getOnlinePlayers()){
    152.  
    153. if(parteh.contains(all.getName()))
    154. {
    155. all.sendMessage(ChatColor.DARK_GREEN + "[Party]" + p.getDisplayName() + ": " + msg);
    156. return true;
    157. }
    158. }
    159. }
    160. return true;
    161. }
    162. }
    163.  
    164. return true;
    165. }
    166.  
    167. @EventHandler
    168. public void onPlayerMove(PlayerMoveEvent event){
    169. if (!(parteh.contains(event.getPlayer().getDisplayName()))) return;
    170. if (event.getFrom().getBlockY() == event.getTo().getBlockY()) return;
    171. Player player = (Player) event.getPlayer();
    172.  
    173. player.setVelocity(player.getVelocity().setY(0.2D));
    174. }
    175.  
    176.  
    177. @EventHandler
    178. public void hurt(EntityDamageByBlockEvent e){
    179. if(e.getEntity() instanceof Player){
    180. Player p = (Player) e.getEntity();
    181. if(parteh.contains(p.getName())){
    182. e.setCancelled(true);
    183. }
    184. }
    185. }
    186.  
    187.  
    188. @EventHandler
    189. public void join(PlayerJoinEvent e){
    190. if(parteh.contains(e.getPlayer().getName())){
    191.  
    192. for(Player online : Bukkit.getOnlinePlayers()){
    193. Score score = objective.getScore(Bukkit.getOfflinePlayer(ChatColor.AQUA + "Members:")); //Get a fake offline player
    194. score.setScore(parteh.size());
    195. online.setScoreboard(board);
    196. }
    197. }
    198.  
    199.  
    200. }
    201.  
    202. @EventHandler
    203. public void leave(PlayerQuitEvent e){
    204. if(parteh.contains(e.getPlayer().getName())){
    205. parteh.remove(e.getPlayer().getName());
    206. pp.remove(e.getPlayer().getDisplayName());
    207.  
    208. }
    209. }
    210.  
    211.  
    212. }
    213. [/i]



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

    ftbastler

    Ultimate_n00b For some reason, this does not work for me.
    The Hologram always "slides" off into a direction into an unloaded chunk, where it falls down into the void.

    Very strange behavior...
     
  23. Offline

    Aikar

    So, after spending hours fighting with this, I wanted to summarize the DETAILS on holograms (the magic that makes them work) for anyone trying to work with them.

    Setting age to less than normal values for horses causes weird rendering issues, and using -1700000 puts it off the users screen.
    Then because its positioned weird, you need to add +55 to Y of the desired location to shift the name plate in the correct location.

    You also need to spawn it on a wither skull so that it doesnt fall. Wither skulls do not render on client when spawned and given 0 velocity it seems.

    In summary, something like this with pure bukkit API:

    Code:
    public static void create(Location loc, String text) {
            final String[] lines = RegexPatterns.NEWLINE.split(text);
            Location first = loc.clone().add(0, (lines.length / 2) * distance, 0);
            for (String line : lines) {
                addLine(first.clone(), line);
                first.subtract(0, distance, 0);
            }
        }
    
        private static void addLine(Location loc, String line) {
            final Horse entity = (Horse)loc.getWorld().spawnEntity(loc.clone().add(0,55,0), EntityType.HORSE);
            entity.setCustomName(line);
            entity.setCustomNameVisible(true);
            entity.setAge(-1700000);
            entity.setAgeLock(true);
            final Entity veh = loc.getWorld().spawnEntity(loc.clone().add(0,55,0), EntityType.WITHER_SKULL);
            if (veh != null) {
                veh.setVelocity(new Vector(0,0,0));
                veh.setPassenger(entity);
            }
        }
    Just wanted to share as I had trouble finding WHY/HOW this concept worked, and the API plugin did not fit my needs (I needed real entities so they save into the world file, as I want to copy the world they will be used in to more servers... I have a very special server set up)
     
    NathanWolf likes this.
  24. Offline

    ftbastler

    Aikar Thanks. But both, the NMS and your code, won't work for me... :(
     
  25. Offline

    creepers84

    When you are spawning the hologram, what elevation are you? As the Holograms fail to work properly above a certain elevation.
     
  26. Offline

    breezeyboy

    Don't use hastebin, it cleared every few hours
     
  27. Offline

    Ultimate_n00b

    Also, this is now unsupported by me. Use at your own risk/reward. I'd suggest only using it for learning how this stuff works.
     
  28. Offline

    SuperOmegaCow

    Ultimate_n00b
    Sorry to bump this old post but the PacketPlayOutSpawnEntity now takes an object id. Try out this:
    Code:
            PacketPlayOutSpawnEntity skull_packet = new PacketPlayOutSpawnEntity(skull,64);
    64 is a firecharge.
     
    rfsantos1996 likes this.
  29. Offline

    DevRosemberg

    Ultimate_n00b Didnt you forget to add ((LivingEntity)horse).setRemoveWhenFarAway(false); because when you get around 50 blocks away the Hologram will disappear.
     
  30. Offline

    iWareWolf

    Is it possible for a hologram for an individual player?
     
Thread Status:
Not open for further replies.

Share This Page