[Tutorial] Creating custom entities with PathfinderGoals

Discussion in 'Spigot Plugin Development' started by XlordalX, May 11, 2014.

  1. Nice tutorial.
     
    • Like Like x 1
  2. @DarkSeraphim My getOwnerUUID returns null because it's never called by the pathfinder or other, so i didn't thought that would be essential.

    • My two fields are created
    • the getOwnerUUID() returns now the owner UUID
    Code (Text):

    // Interface de l'EntityOwnable
        @Override
        public String getOwnerUUID() {
            if (this.owner == null)
                return null;
            @SuppressWarnings("deprecation")
            Player player = Bukkit.getPlayer(this.owner.getName());
            this.uuid = player.getUniqueId();
            Bukkit.broadcastMessage("" + uuid);
            return this.uuid.toString();
        }
     
    • In the pathFinder the owner was already get by the getOwner() method and the nms already has a null verifier
    • when the player logs out the chicken simply disapear
    • the last point is quite mysterious but it will be useless in my case
    Now i can't define why the getOwner() method return a null value, wheras i assign a player to this value a bit earlier.
     
    • Funny Funny x 1
  3. Nice tutorial! Helped me a lot!
     
    • Like Like x 1
  4. Thanks :).
     
  5. @Madricas well if the chicken despawns when the player disconnects, that makes things a tad easier.
    • No need for an UUID field
    • Set the owner field just after you spawned it (so just after you did new FollowerChicken(world), you set the Player)
    • Simply return
      Code (Java):
      this.owner.getUniqueId().toString();
      in getOwnerUUID(), or if the owner is an EntityPlayer, you return
      Code (Java):
      EntityHuman.a(this.owner.getProfile()).toString();
      The EntityHuman.a(GameProfile) should never return a null UUID.
     
  6. Hey guys, im stumbling at the first few lines.. Where does the EntityZombie class come from? Eclipse tells me there aint one
    my pom.xml looks like this:
    Code (Text):
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>io.github.Azuna1</groupId>
      <artifactId>HardcoreSurvival</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <configuration>
                      <source>1.7</source>
                      <target>1.7</target>
                  </configuration>
              </plugin>
          </plugins>
       </build>
       <repositories>
           <repository>
               <id>spigot-repo</id>
               <url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
           </repository>
       </repositories>  
       <dependencies>
           <dependency>
              <groupId>org.spigotmc</groupId>
              <artifactId>spigot-api</artifactId>
              <version>1.8-R0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
    And as javadoc location i set https://hub.spigotmc.org/javadocs/spigot/ for my project
     
  7. @Azunai you need to depend on the server implementation (spigot) to access the net.minecraft.server package.
     
    • Useful Useful x 1
  8. So i created a CustomZombie and i can spawn it / it acceppts changes in the PathfinderGoals
    But creating the PathfinderGoalWalkToLoc i get
    Type mismatch: cannot convert from NavigationAbstract to Navigation
    inside the constructor on line
    Code (Text):
    this.navigation = this.entity.getNavigation();
    Also if anyone @XlordalX could maybe post a simple custom monster setup here it would be awesome as it seems that quite some parts changed since the tutorial was created

    PS: my aim is to have a controlable mob that has custom movement in a range of 100 to the nearest player
     
    #49 Azunai, Dec 8, 2014
    Last edited: Dec 8, 2014
  9. There's four things I need to know:
    - How to change entity target distance. I'll need to make it longer and shorter than the default at times.
    - How to manually set an entity's target.
    - How to erase an entity's target.
    - How to modify an entity's speed when targeting an entity.
     
  10. @The_Doctor_123
    Code (Text):
    this.getAttributeInstance(GenericAttributes.b).setValue(80); // aggro range

    this.setTarget(player)

    this.setTarget()

    this.getAttributeInstance(GenericAttributes.d).setValue(0.4D); // speed
     

    @XlordalX @DarkSeraphim
    I now want my zombies to destroy blocks between it and the target like the PathfinderGoalBreakDoor

    any hints?
     
    #51 Azunai, Dec 9, 2014
    Last edited: Dec 9, 2014
    • Useful Useful x 1
  11. If that's all everything is, then I must say, that's unexpectedly simple. Do you happen to know if those field names persist between 1.7.10 and 1.8?
     
  12. just open up GenericAttributes.java to check yourself
     
  13. Fair enough. Thanks for the info.
     
  14. @Azunai my current guess is that the logic you are looking for is located in the PathfinderNormal class (at least, that's where it checks for doors and water, which would correspond to the float and door break pathfinder goals). The field is located in Navigator (protected PathfinderNormal a). Do note, this does not apply on guardians and spiders, they seem to have their own NavigatorAbstract extensions (just check the specific classes for their implementation)
     
  15. Sorry @XlordalX ? How can we do for an entity moves from point A to B?
    I would like to spawn when it moves point A to point B

    My NMS code:
    PHP:

    package fr.makibear.entity;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Color;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.craftbukkit.v1_7_R3.CraftWorld;
    import org.bukkit.craftbukkit.v1_7_R3.inventory.CraftItemStack;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.LeatherArmorMeta;
    import org.bukkit.scheduler.BukkitScheduler;

    import fr.makibear.main.Main;
    import net.minecraft.server.v1_7_R3.DamageSource;
    import net.minecraft.server.v1_7_R3.EntityZombie;
    import net.minecraft.server.v1_7_R3.GenericAttributes;
    import net.minecraft.server.v1_7_R3.Item;
    import net.minecraft.server.v1_7_R3.Items;
    import net.minecraft.server.v1_7_R3.MathHelper;
    import net.minecraft.server.v1_7_R3.PathEntity;
    import net.minecraft.server.v1_7_R3.World;

    public class SBires extends EntityZombie{

        public Main plugin;
        private Location loc;
     
        public SBires(World world) {
            super(world);
        }
     
        public SBires(World world, Main plugin) {
            super(world);
            this.plugin = plugin;
        }
     
        public SBires(World world, Main plugin, Location loc)
        {
            super(world);
            this.plugin = plugin;
            this.loc = loc;
        }
     
        @Override
        public boolean aD()
        {
            super.aD();
            this.getAttributeInstance(GenericAttributes.d).setValue(0.25D);  // Vitesse de d├ęplacement
            this.getAttributeInstance(GenericAttributes.a).setValue(200.0D); // Vie
            this.getAttributeInstance(GenericAttributes.e).setValue(5.0D);   // D├ęgat
     
            return true;
        }
     
        @Override
        public void die(DamageSource damagesource)
        {
            final SBires respawn = new SBires(this.world, plugin, this.loc);
            final Location locR = this.loc;
         
            BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
            scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
                public void run() {
                    respawn.spawn(locR);
                }
            }, 400L);
        }
     
        public void spawn(Location loc)
        {
            World nmsWorld = ((CraftWorld) loc.getWorld()).getHandle();
            SBires sbires = new SBires(nmsWorld, plugin, loc);

            sbires.setCustomName(ChatColor.WHITE + "SBires");
            sbires.setCustomNameVisible(true);

            sbires.setPosition(loc.getX(), loc.getY(), loc.getZ());
            nmsWorld.addEntity(sbires);
        }
     
        @Override
        public String getName()
        {
            return ChatColor.WHITE + "SBires";
        }
     
        protected Item getLoot() {
            return null;
        }
     
        protected void getRareDrop(int i) {
            switch (this.random.nextInt(2)) {
            case 0:
                this.a(Items.GOLD_INGOT, 1);
                break;

            case 1:
                this.a(Items.GOLD_NUGGET, 1);
            }
        }
    }
     
    Tanks you.

    Sorry for my english, i'm french.
     
    #56 MakiBearDY, Dec 11, 2014
    Last edited: Dec 12, 2014
    • Agree Agree x 1
  16. I am using Spigot 1.8 and the entity does spawn but it spawns invisible...
    Does anyone know what might be the cause of this?

    Thanks for the tutorial!
     
  17. What entity type are you trying to spawn?
     
  18. Zombie. I also tried a Villager but same result.

    Edit: OK... never mind i have no idea what i did but its working now....
     
    #60 MrTheNewGuy, Dec 27, 2014
    Last edited: Dec 27, 2014