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.
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 player.getInventory().setHelmet(new ItemStack(Material.GOLD_BLOCK));
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.
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 final Item item = player.getWorld().dropItemNaturally(player.getEyeLocation(), new ItemStack(Material.WOOL, 1, (byte) 14));item.setVelocity(item.getVelocity().setY(0.35));getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { public void run() { item.remove(); }}, 20); EDIT by Moderator: merged posts, please use the edit button instead of double posting.
Reptar_ Code:java Item item = world.dropItem(player.getLocation(), DONOR); item.setPickupDelay(Integer.MAX_VALUE); //Can't be picked up (for about 3 years, actually :P)player.setPassenger(item);
If you watch yourself, it works: But when another player watches it looks like that: It is inside the head! (You can see it because the head is turned back) What is the problem?
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.
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.
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 package me.ItemDisplays.Reptar_; import java.util.logging.Logger; import org.bukkit.Location;import org.bukkit.Material;import org.bukkit.entity.Entity;import org.bukkit.entity.EntityType;import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import org.bukkit.event.player.PlayerJoinEvent;import org.bukkit.inventory.ItemStack;import org.bukkit.plugin.java.JavaPlugin; public class ItemDisplays extends JavaPlugin implements Listener {public final Logger log = Logger.getLogger("Minecraft"); @Overridepublic void onEnable() {getServer().getPluginManager().registerEvents(this, this);log.info("[ItemDisplays] by Reptar_ enabled!");} @Overridepublic void onDisable() {log.info("[ItemDisplays] by Reptar_ disabled!");} @EventHandlerpublic boolean onPlayerJoin(final PlayerJoinEvent e) {final Player p = e.getPlayer();final Location loc = p.getLocation();final Entity s = p.getWorld().spawnEntity(loc, EntityType.EXPERIENCE_ORB);final ItemStack DONOR = (ItemStack) p.getWorld().dropItem(loc, (new ItemStack(Material.GOLD_BLOCK)));p.setPassenger(s);s.setPassenger((Entity) DONOR); returnfalse; } } EDIT by Moderator: merged posts, please use the edit button instead of double posting.
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?
It would still set appear inside the player's head to others, but appear floating for the player. chasechocolate Or this: Code:java package me.ItemDisplays.Reptar_; import java.util.logging.Logger; import org.bukkit.Location;import org.bukkit.Material;import org.bukkit.entity.Entity;import org.bukkit.entity.EntityType;import org.bukkit.entity.Item;import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import org.bukkit.event.player.PlayerJoinEvent;import org.bukkit.inventory.ItemStack;import org.bukkit.plugin.java.JavaPlugin; public class ItemDisplays extends JavaPlugin implements Listener {public final Logger log = Logger.getLogger("Minecraft"); @Overridepublic void onEnable() {getServer().getPluginManager().registerEvents(this, this);log.info("[ItemDisplays] by Reptar_ enabled!");} @Overridepublic void onDisable() {log.info("[ItemDisplays] by Reptar_ disabled!");} @EventHandlerpublic boolean onPlayerJoin(final PlayerJoinEvent e) {final Player p = e.getPlayer();final Location loc = p.getLocation();final Entity s = p.getWorld().spawnEntity(loc, EntityType.EXPERIENCE_ORB);Item DONOR = p.getWorld().dropItem(p.getLocation(), new ItemStack(Material.GOLD_BLOCK, 1));p.setPassenger(s);s.setPassenger(DONOR); returnfalse; } }
You can do it with a normal block, but you would have to set the block after every reload again Code:java FallingBlock block = p.getWorld().spawnFallingBlock(p.getLocation().clone().add(0, 1 /* or 2, what you find better :)*/, 0), Material.GOLD_BLOCK.getId(), (byte) 0);block.setDropItem(false);block.setVelocity(new Vector(0,0,0));p.setPassenger(block); That displays a big block not an item Oh, I see you don't want to do it like that,^^
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 final Player flagHolder; Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(yourPlugin, new Runnable() { public void run() { final Item flag = flagHolder.getWorld().dropItemNaturally(flagHolder.getEyeLocation(), new ItemStack(Material.WOOL, 1, (byte) 14)); flag.setVelocity(flag.getVelocity().setY(0.35)); flag.setPickupDelay(Integer.MAX_VALUE); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(yourPlugin, new Runnable() { public void run() { flag.remove(); } }, 19L); }}, 0, 20L);
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.
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