Spawning a simple NPC

Discussion in 'Spigot Plugin Development' started by PaulBGD, Dec 3, 2014.

Thread Status:
Not open for further replies.
  1. Back in 1.7, I used code that looked like this:
    Code (Text):

      private static EntityHuman getNewNPC(String name) {
      EntityHuman human = new EntityHuman(((CraftWorld) Bukkit.getWorlds().get(0)).getHandle(), new GameProfile(UUID.randomUUID(), name.contains(" ") ? name : " " + name + " ")) {
      @Override
      public boolean v() {
      return false; // return true if spectating.. so no?
      }
      };
      try {
      idField.setInt(human, id);
      } catch (IllegalAccessException e) {
      e.printStackTrace();
      }
      return human;
      }
    and then this to spawn:

    Code (Text):

      PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(npc);
      ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
      PacketPlayOutEntityHeadRotation rotation = new PacketPlayOutEntityHeadRotation(npc, (byte) ((toSpawn.getYaw() * 256.0F) / 360.0F));
      ((CraftPlayer) player).getHandle().playerConnection.sendPacket(rotation);
    Now it seems that the player is not showing up. Am I missing something?
     
  2. I could be wrong, but I believe the issue is that 1.8 does not support invalid GameProfiles. If you use a real player's UUID and name, does that work?

    Edit: see below
     
    #2 St3venAU, Dec 4, 2014
    Last edited: Dec 4, 2014
  3. Scratch that. I just did some testing and I think the issue is that the 1.8 client will not render a player that is not on the tab player list. I was able to spawn an NPC by first sending the packet to add that player to the tab list:

    Code (Text):
    MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer();
    WorldServer nmsWorld = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
    EntityPlayer npc = new EntityPlayer(nmsServer, nmsWorld, new GameProfile(UUID.randomUUID(), "NPC"), new PlayerInteractManager(nmsWorld));
    npc.setLocation(0.0, 70.0, 0.0, 0F, 0F);

    PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
    connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
    connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
     
    • Useful Useful x 4
    • Agree Agree x 2
    • Like Like x 1
  4. sothatsit

    Patron

    How does it work then for normal players when you have changed the players tab name?
     
    • Agree Agree x 1
    • Funny Funny x 1
  5. Thanks!
     
    • Agree Agree x 1
  6. This very well may be, however, do you know why it is that players will only display sporadically (ie. not when the packet is sent, but some random occurrence later) when a player is disguised using a packet? Code example to follow:

    Code (Text):
    Packet destroy = new PacketPlayOutEntityDestroy(SOME_PLAYER.getEntityId());
    Packet spawn = new PacketPlayOutSpawnEntityLiving(SOME_OTHER_ENTITY);
    PlayerConnection connection = ((CraftPlayer) SOME_OBSERVER).getHandle().playerConnection;
    connection.sendPacket(destroy);
    connection.sendPacket(spawn);
    Behaviour: SOME_PLAYER remains in the tab list, however, their model is removed from SOME_OBSERVER's view. They are not visible until (seemingly randomly) they appear as SOME_OTHER_ENTITY.

    Any insight?
     

  7. How to remove ? :(
     
  8. Despawn and remove from list?
     
    • Informative Informative x 2
    • Informative Informative x 1
  9. PHP:
    PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
    connection.sendPacket(new PacketPlayOutEntityDestroy(npc.getId()));
    connection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, npc));
    Note that you need the npc EntityPlayer object to do this, so you would have to store it at the time you created it so you can refer to it when you want to remove it.

    Edit: that code was for 1.8.3. If you are using 1.8 then its just EnumPlayerInfoAction.REMOVE_PLAYER instead of PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER
     
    • Like Like x 1
  10. @Techcable just submitted an awesome library. Check it out ;D
     
  11. Do you know Postcrafter?
     
  12. Could a mod lock this, my question has been answered.
     
    • Agree Agree x 2
Thread Status:
Not open for further replies.