1.12.2 How can I make NPCs (EntityPlayer) follow players?

Discussion in 'Spigot Plugin Development' started by xUltraGaming, Feb 2, 2020.

  1. I'm trying to make a boss that is an NPC. I want to use NPCs so I can customize their skins. I've already got the NPC loaded in my world (Using the code below), but I don't think there is a way to use Pathfinder Goals for EntityPlayers. If anyone knows a solution to this, please let me know. Thanks!


    Code (Java):
    MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
                WorldServer world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
                EntityPlayer npc = new EntityPlayer(server, world, new GameProfile(UUID.fromString("ea121947-e88e-4f61-836e-3f0cb8abe358"), "Undead Knight"), new PlayerInteractManager(world));
                PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
                connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
                connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
     
  2. Two options:
    A) You write your own class (a class that extends EntityPlayer), you override the PathFinderGoals in this class and add the pathFinderGoal that corresponds to following a player
    B) You use reflection to access the lists that the PathfinderGoals are stored inside and add the said goal.
     
  3. I've never really used NMS or PathFinderGoals, how would I override it for an EntityPlayer? Also I thought EntityPlayer's couldn't have PathFinderGoals... :unsure:
     
  4. Hmm, you are right...
    Well, you might be able to mock the behaviour of Insentient Entities for custom players. Something like this:
    Code (Java):
    public class CustomHumanEntity extends EntityHuman {
       
        public PathfinderGoalSelector goalSelector;
        public PathfinderGoalSelector targetSelector;
       
        public CustomHumanEntity(World world, GameProfile gameprofile) {
            super(world, gameprofile);
            this.goalSelector = new PathfinderGoalSelector(world.methodProfiler);
            this.targetSelector = new PathfinderGoalSelector(world.methodProfiler);
            // need to implement own follow-methods since PathSelectorGoalFinder requires a tameable entity
        }

        @Override
        protected void doTick() {
            super.doTick();
            // super experimental, might just fail spectacularly
            goalSelector.a();
        }
    }
    Or you'd mock the following part, making the player move using packets.
    You could also spawn an entity that follows the player, intercept the packets sent by that entity and send your won player-packets.

    Maybe there is also a solution to this problem that does not require black magic, but I'm not sure...
     
  5. Solution: I used the CitizensAPI to spawn an npc and make it follow and attack players. Thanks for the help! :)