Player Item Passenger

Discussion in 'Plugin Development' started by Reptar_, Sep 3, 2013.

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

    Reptar_

    So I'm working on a plugin for my friend's servers so there can be a new special way to notice donors. Basically they have a gold block float above their head. I do this by setting the item as a passenger to the player, but I can't seem to get it to work. Plugin.yml is fine too.

    Here's my code: http://pastebin.com/QcPknnkE

    Here's my error:
    Code:
    19:34:53 [INFO] Reptar_ issued server command: /item
    19:34:53 [SEVERE] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'item' in plugin ItemDisplays v1.0
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46)
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:191)
    at org.bukkit.craftbukkit.v1_6_R2.CraftServer.dispatchCommand(CraftServer.java:523)
    at net.minecraft.server.v1_6_R2.PlayerConnection.handleCommand(PlayerConnection.java:962)
    at net.minecraft.server.v1_6_R2.PlayerConnection.chat(PlayerConnection.java:880)
    at net.minecraft.server.v1_6_R2.PlayerConnection.a(PlayerConnection.java:837)
    at net.minecraft.server.v1_6_R2.Packet3Chat.handle(SourceFile:49)
    at net.minecraft.server.v1_6_R2.NetworkManager.b(NetworkManager.java:296)
    at net.minecraft.server.v1_6_R2.PlayerConnection.e(PlayerConnection.java:116)
    at net.minecraft.server.v1_6_R2.ServerConnection.b(SourceFile:37)
    at net.minecraft.server.v1_6_R2.DedicatedServerConnection.b(SourceFile:30)
    at net.minecraft.server.v1_6_R2.MinecraftServer.t(MinecraftServer.java:590)
    at net.minecraft.server.v1_6_R2.DedicatedServer.t(DedicatedServer.java:226)
    at net.minecraft.server.v1_6_R2.MinecraftServer.s(MinecraftServer.java:486)
    at net.minecraft.server.v1_6_R2.MinecraftServer.run(MinecraftServer.java:419)
    at net.minecraft.server.v1_6_R2.ThreadServerApplication.run(SourceFile:582)
    Caused by: java.lang.ClassCastException: org.bukkit.inventory.ItemStack cannot be cast to org.bukkit.entity.Entity
    at me.ItemDisplays.Reptar_.ItemDisplays.onCommand(ItemDisplays.java:33)
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
    ... 15 more
    
    Currently I have to where it only sets it instead of removing it. I will add that later, I just need to focus on getting it to actually work first.
     
  2. Offline

    Quantix

    Only entities can be passengers (such as other players and mobs etc.) You're casting an ItemStack to an Entity which isn't possible since the ItemStack interface does not inherit the org.bukkit.Entity class. You could however set the players helmet slot to a golden block, but I'm not sure if that's what you want.
    Code:java
    1. player.getInventory().setHelmet(new ItemStack(Material.GOLD_BLOCK));
     
  3. Offline

    Reptar_

    No, I want it to float above their head. Look at post #64: http://forums.bukkit.org/threads/ctf-effects.101215/page-3
    So it is possible. . . I just don't know how to get it working, I tried the code given to me but it didn't work.
     
  4. Offline

    Quantix

    ItemStacks can never be passengers. You could create an Item by spawning an ItemStack in the world (like someone in the thread you linked suggested) and using that. The wool blocks or flags that shoot up from flag holders in the MCPVP CTF servers aren't actually passengers of the player. Their plugin kCTF drops wool blocks above the flag holders head, gets the spawned Item and sets the velocity of that item so that it jumps upwards. The item is then shortly afterwards removed, spawning a new one and repeating these steps as long the player has the flag.

    Here's some code I played around with that might suit your needs ('this' in the scheduler instantiation refers to the plugin's main class):
    Code:java
    1. final Item item = player.getWorld().dropItemNaturally(player.getEyeLocation(), new ItemStack(Material.WOOL, 1, (byte) 14));
    2. item.setVelocity(item.getVelocity().setY(0.35));
    3. getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    4. public void run() {
    5. item.remove();
    6. }
    7. }, 20);


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

    chasechocolate

    Reptar_
    Code:java
    1. Item item = world.dropItem(player.getLocation(), DONOR);
    2.  
    3. item.setPickupDelay(Integer.MAX_VALUE); //Can't be picked up (for about 3 years, actually :P)
    4. player.setPassenger(item);
     
    bobacadodl likes this.
  6. Offline

    Domi381

    If you watch yourself, it works:


    [​IMG]


    But when another player watches it looks like that:

    [​IMG]

    It is inside the head! (You can see it because the head is turned back)

    What is the problem?
     
  7. Offline

    Quantix

    I guess that's just the way the client renders passenger items on other players. That is why MCPVP uses the method I described above in their CTF games. It doesn't look as cool as chasechocolate's method but other players will see it.
     
  8. Offline

    Reptar_

    This works perfectly, but for some reason I can't clear/eject the passenger. When I do, it just drops the item and I can no longer have an item passenger.

    This shoots it once then drops it on the ground allowing players to pick it up. . .

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

    chasechocolate

    Reptar_ what are you using? Try player.getPassenger().remove().
     
  10. Offline

    Reptar_

    I'm not using your method because it doesn't appear the same way for other players. I'm using the vector method. But I can't seem to get it to repeat. I will show my code.

    chasechocolate This is what I changed it to: http://pastebin.com/Uxv7fEAE

    So I'm changing it so I set the player's passenger to an experience orb then setting the passenger of that orb to the item I want. I can't test it now, but would it work? Here's the code:

    Code:java
    1.  
    2. package me.ItemDisplays.Reptar_;
    3.  
    4. import java.util.logging.Logger;
    5.  
    6. import org.bukkit.Location;
    7. import org.bukkit.Material;
    8. import org.bukkit.entity.Entity;
    9. import org.bukkit.entity.EntityType;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.event.EventHandler;
    12. import org.bukkit.event.Listener;
    13. import org.bukkit.event.player.PlayerJoinEvent;
    14. import org.bukkit.inventory.ItemStack;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16.  
    17. public class ItemDisplays extends JavaPlugin implements Listener {
    18. public final Logger log = Logger.getLogger("Minecraft");
    19.  
    20. @Override
    21. public void onEnable() {
    22. getServer().getPluginManager().registerEvents(this, this);
    23. log.info("[ItemDisplays] by Reptar_ enabled!");
    24. }
    25.  
    26. @Override
    27. public void onDisable() {
    28. log.info("[ItemDisplays] by Reptar_ disabled!");
    29. }
    30.  
    31. @EventHandler
    32. public boolean onPlayerJoin(final PlayerJoinEvent e) {
    33. final Player p = e.getPlayer();
    34. final Location loc = p.getLocation();
    35. final Entity s = p.getWorld().spawnEntity(loc, EntityType.EXPERIENCE_ORB);
    36. final ItemStack DONOR = (ItemStack) p.getWorld().dropItem(loc, (new ItemStack(Material.GOLD_BLOCK)));
    37. p.setPassenger(s);
    38. s.setPassenger((Entity) DONOR);
    39.  
    40. returnfalse;
    41.  
    42. }
    43.  
    44. }
    45.  


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

    xxMOxMOxx

    If you made the block a falling block (turning it into an entity) and set it as the passenger of a player, would the fact that its "riding" the player keep it suspended, or would it still just fall?
     
  12. Offline

    Reptar_

    It would still set appear inside the player's head to others, but appear floating for the player.

    chasechocolate Or this:

    Code:java
    1.  
    2. package me.ItemDisplays.Reptar_;
    3.  
    4. import java.util.logging.Logger;
    5.  
    6. import org.bukkit.Location;
    7. import org.bukkit.Material;
    8. import org.bukkit.entity.Entity;
    9. import org.bukkit.entity.EntityType;
    10. import org.bukkit.entity.Item;
    11. import org.bukkit.entity.Player;
    12. import org.bukkit.event.EventHandler;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.event.player.PlayerJoinEvent;
    15. import org.bukkit.inventory.ItemStack;
    16. import org.bukkit.plugin.java.JavaPlugin;
    17.  
    18. public class ItemDisplays extends JavaPlugin implements Listener {
    19. public final Logger log = Logger.getLogger("Minecraft");
    20.  
    21. @Override
    22. public void onEnable() {
    23. getServer().getPluginManager().registerEvents(this, this);
    24. log.info("[ItemDisplays] by Reptar_ enabled!");
    25. }
    26.  
    27. @Override
    28. public void onDisable() {
    29. log.info("[ItemDisplays] by Reptar_ disabled!");
    30. }
    31.  
    32. @EventHandler
    33. public boolean onPlayerJoin(final PlayerJoinEvent e) {
    34. final Player p = e.getPlayer();
    35. final Location loc = p.getLocation();
    36. final Entity s = p.getWorld().spawnEntity(loc, EntityType.EXPERIENCE_ORB);
    37. Item DONOR = p.getWorld().dropItem(p.getLocation(), new ItemStack(Material.GOLD_BLOCK, 1));
    38. p.setPassenger(s);
    39. s.setPassenger(DONOR);
    40.  
    41. returnfalse;
    42.  
    43. }
    44.  
    45. }
    46.  
     
  13. Offline

    sheigutn

    You can do it with a normal block, but you would have to set the block after every reload again :)
    Code:java
    1. FallingBlock block = p.getWorld().spawnFallingBlock(p.getLocation().clone().add(0, 1 /* or 2, what you find better :)*/, 0), Material.GOLD_BLOCK.getId(), (byte) 0);
    2. block.setDropItem(false);
    3. block.setVelocity(new Vector(0,0,0));
    4. p.setPassenger(block);

    That displays a big block not an item ;)[​IMG]
    Oh, I see you don't want to do it like that,^^
     
    Meatiex likes this.
  14. Offline

    Reptar_

    I want a little block :3 And for others, it appears as a hat instead of floating.
     
  15. Offline

    Quantix

    The method I posted was just an example and doesn't repeat itself. Below is more example code that you could use. Although I don't expect players to pick up the wool blocks since they are removed a few ticks after they are spawned, you can set the items pickup delay just in case a player does somehow reach the flag block.
    Code:java
    1. final Player flagHolder;
    2.  
    3. Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(yourPlugin, new Runnable() {
    4. public void run() {
    5. final Item flag = flagHolder.getWorld().dropItemNaturally(flagHolder.getEyeLocation(), new ItemStack(Material.WOOL, 1, (byte) 14));
    6. flag.setVelocity(flag.getVelocity().setY(0.35));
    7. flag.setPickupDelay(Integer.MAX_VALUE);
    8. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(yourPlugin, new Runnable() {
    9. public void run() {
    10. flag.remove();
    11. }
    12. }, 19L);
    13. }
    14. }, 0, 20L);
     
  16. Offline

    Reptar_

    I still haven't gotten this to work. So I have it to where the gold block is set as the passenger, but to others it's inside your head. Do I set the passenger as an invisible mob and set the mob's passenger as the gold block? This would appear as it floating to all players, correct?

    Ok, so I got that to work, but when you walk through a player, the passenger seems to switch to the player you walked through. How do I cancel that? This is what I have so far:

    http://pastebin.com/0W6czjuM

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

    Reptar_

  18. Offline

    CeramicTitan

    RingOfStorms and I, have managed to fix the head glitch, however the entity appears much higher client side for the user, but appears fine server side. Due to the way this has been achieved, the hitboxes are now messed up. In order to trick the server you need to do your own collision checking.
    https://gist.github.com/RingOfStorms/3d8484134059bcb6c840
     
Thread Status:
Not open for further replies.

Share This Page