Custom Entity and Targetting

Discussion in 'Spigot Plugin Development' started by N1ark, Jun 13, 2018.

  1. Hello!
    I am currently trying to spawn a custom entity, that will only target a specific Player, but my custom entity is made with NMS, while the rest of the program is in Spigot, and I'm having trouble converting it...
    Here is my code:

    Code (Java):
    CustomSmartCreature[] summons = new CustomSmartCreature[] {
                        (CustomSmartCreature) EntityTypes.spawnEntity(new CustomSmartCreature(p.getWorld()), p.getLocation()),
                        (CustomSmartCreature) EntityTypes.spawnEntity(new CustomSmartCreature(p.getWorld()), p.getLocation()),
                        (CustomSmartCreature) EntityTypes.spawnEntity(new CustomSmartCreature(p.getWorld()), p.getLocation())
                };
                int x = 0;
                for(net.minecraft.server.v1_12_R1.Entity e : summons) {
                    ArrayList<Player> attack = Utile.getNearAttackablePlayers(p, 15, 15, 15); // This returns near players
                    if(!attack.isEmpty())
                        ((CustomSmartCreature) e).setTarget(attack.get(Math.min(x, attack.size())));
                    x++;
                }
                Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getInstance(), new Runnable() {
                    @Override
                    public void run() {
                        for(CustomSmartCreature e : summons)
                            if(e.isAlive())
                                e.killEntity();
                    }
                }, 200);

    Code (Java):
    public class CustomSmartCreature extends EntityZombie{

        @SuppressWarnings("rawtypes")
        public CustomSmartCreature(World world) {
            super(((CraftWorld) world).getHandle());
            List goalB = (List) Utile.getPrivateField("b", PathfinderGoalSelector.class, goalSelector);
            goalB.clear();
            List goalC = (List) Utile.getPrivateField("c", PathfinderGoalSelector.class, goalSelector);
            goalC.clear();
            List targetB = (List) Utile.getPrivateField("b", PathfinderGoalSelector.class, targetSelector);
            targetB.clear();
            List targetC = (List) Utile.getPrivateField("c", PathfinderGoalSelector.class, targetSelector);
            targetC.clear();

            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1, false));
            this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1));
            this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1, false));
            this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1));
            this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8));
            this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
            this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<EntityPlayer>(this, EntityPlayer.class, true));
        }
        public void setTarget(EntityCreature e) {
            this.goalSelector.a(2, new PathfinderGoalMeleeAttack(e, 1, false));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<EntityPlayer>(this, EntityPlayer.class, true));
        }
    }
     

    Code (Java):
    public enum EntityTypes{
        CUSTOM_ZOMBIE("Zombie", 54, CustomSmartCreature.class);

        private EntityTypes(String name, int id, Class<? extends Entity> custom)
        {
            addToMaps(custom, name, id);
        }

      public static Entity spawnEntity(Entity entity, Location loc)
       {
         entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
         ((CraftWorld)loc.getWorld()).getHandle().addEntity(entity);
         return entity;
       }

        @SuppressWarnings("unchecked")
        private static void addToMaps(Class<? extends Entity> clazz, String name, int id)
        {
            ((Map<String, Class<? extends Entity>>) Utile.getPrivateField("c", net.minecraft.server.v1_12_R1.EntityTypes.class, null)).put(name, clazz);
            ((Map<Class<? extends Entity>, String>) Utile.getPrivateField("d", net.minecraft.server.v1_12_R1.EntityTypes.class, null)).put(clazz, name);
            ((Map<Class<? extends Entity>, Integer>) Utile.getPrivateField("f", net.minecraft.server.v1_12_R1.EntityTypes.class, null)).put(clazz, Integer.valueOf(id));
        }
    }

    As you can see, I get an error in the first bit of code, because setTarget() takes an NMS Entity, while my getNearAttackablePlayers() returns Bukkit entities...
    Does somebody know how to convert it?
    And am I doing all this custom entity stuff right? I used this tutorial, but I don't know if it's outdated and I currently can't test my code.

    Thanks for the help!
     
  2. If you don't understand this, then your basics of Java aren't up to par with the requirements to use NMS properly.

    Hint: A Player is a Bukkit entity, that has a handle. This handle is has a reference to it's NMS entity.
     
    #2 BillyGalbreath, Jun 13, 2018
    Last edited: Jun 13, 2018
  3. I managed to get this:
    ((CraftPlayer) attack.get(Math.min(x, attack.size()))).getHandle()
    but I can't parse CraftPlayer to EntityCreature, so I have no clue what to do...
    I am still learning Java, and telling me I'm not good enough won't help me learn :)
     
    • Like Like x 1
  4. Sorry, used wrong word (has, not is). Edited last post.
     
  5. I'm quite troubled, as all the methods and variables are obfuscated so I have absolutely no clue what I'm supposed to search for, and there is no NMS documentation so I can't tell what are the classes implementing EntityCreature... could I get another hint? :unsure:
     
  6. I'm half asleep and not at my PC, so I can't really help much more lol

    But, I did notice you said you wanted the player's nms entity object, but now you're trying to cast to a creature. Players aren't creatures, so I'm a bit lost (probably from lack of sleep)
     
  7. Yeah I guess I expressed myself pretty bad, sorry!
    I actually need an Entity Creature, from a Bukkit Player, so I can then create a PathfinderGoalMeleeAttack to attack said player, but PathfinderGoalMeleeAttack has the constructor (EntityCreature, int, boolean)
     
  8. Players Cant have pathfinders, CraftPlayer or Player don’t extend Creature, monster or Animal, just entity
     
  9. I am not trying to create a Pathfinder for the player, but for a custom entity to attack a Player
     
  10. ~ Bump
    Could anyone help? :/
     
  11. I'm not completely sure why you'd need a custom entity for this, it sounds kind of like an XY problem to me. Just spawn regular zombies and use setTarget, and be sure to listen for EntityTargetEvent and cancel whenever the zombie changes targets.
     
  12. Oh okay, I'll try it! I didn't do that because I read that it didn't work, but I guess I should have tried :rolleyes:
     

Share This Page