Tutorial - How to Customize the Behaviour of a Mob or Entity

Discussion in 'Resources' started by Jacek, Jan 14, 2012.

  1. Offline

    CorrieKay

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Bumping... does this still work? im getting undefined for super.s_(); :x
  2. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    The method still works but some of the names have changed. I don't actually know what they are now since I haven't updated BloodMoon for 1.2.4 yet. Probably somethign with an _ in it.
  3. Offline

    vildaberper

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Looks like it's F_() now.
  4. Offline

    CorrieKay

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Is this only to detect movement? or can i actually issue a movement command with this stuff?
  5. Offline

    blackwolf12333

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    I have one little question, how do you guys know what these functions do: a(), or F_(), because i have looked at mcp, but that uses different functions so i have no idea what these functions do, is there something like a list or so on which they are listed with their functionality?

    greetz blackwolf12333
  6. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Mostly by trial and error and looking at the code. It's not easy.
  7. Offline

    blackwolf12333

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Hmm ok, maybe some people should make a list of these functions and what they do.
    Just an idea, i hope someone oould do that:p I know it is a lot...
    greetz blackwolf12333
  8. Offline

    ScriptProdigy

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    With the new versions of Craftbukkit, mainly Bukkit, you can't use extends net.minecraft.server.EntityZombie anymore. Any help on using bukkit for doing this sort of thing would be very much appreciated! I've been doing research for a while, decompiling the latest 1.3.1 bukkit build to find what I can.

    This post has been edited 1 time. It was last edited by ScriptProdigy Aug 13, 2012.
  9. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    You can, but some of the method names have changed. Have a look at how I do it for BloodMoon https://github.com/betterphp/BloodMoon/blob/master/uk/co/jacekk/bukkit/bloodmoon/BloodMoon.java#L42 and then https://github.com/betterphp/BloodM...dmoon/entities/BloodMoonEntityZombie.java#L34
  10. Offline

    ScriptProdigy

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
  11. Offline

    Icyene

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    @Jacek Its now h_() as of 1.3.1.
  12. Offline

    ScriptProdigy

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    @Jacek, Any chance you could also explain creating custom PathfinderGoal's. I'd like my entitie's to follow a specific path, I've been working on some stuff and the mob's don't move.

    Code:
    World mcWorld = ((org.bukkit.craftbukkit.CraftWorld) player.getWorld()).getHandle();
     
    TestZombie v = new TestZombie(mcWorld);
    v.spawnIn(mcWorld);
    v.setPosition(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ());
    mcWorld.addEntity(v);
     
    PathPoint[] pp = new PathPoint[2];
    pp[0] = new PathPoint(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
    pp[1] = new PathPoint(player.getEyeLocation().getBlockX(), player.getEyeLocation().getBlockY(), player.getEyeLocation().getBlockZ());
    PathEntity pe = new PathEntity(pp);
     
    v.setPathEntity(pe);
    v.setSprinting(true);
    
    I just made it a command to test some stuff.

    This post has been edited 1 time. It was last edited by ScriptProdigy Aug 14, 2012.
  13. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
  14. Offline

    javaguy78

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    So, I'm trying to build this with 1.3.1 server libraries, but the libraries

    net.minecraft.server.*

    don't exist. There is

    net.minecraft.src.EntityZombie (found by decompiling minecraft_server.jar with MCP)

    but there is no class at

    net.minecraft.server.EntityTypes

    needed to remap "zombie" to my class. Something has changed recently, but I don't know where to go from here.

    This post has been edited 1 time. It was last edited by javaguy78 Aug 16, 2012.
  15. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    @javaguy78 You need to include the craftbukkit.jar in your classpath not just the bukkit.jar

    This post has been edited 1 time. It was last edited by Jacek Aug 16, 2012.
  16. Offline

    javaguy78

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Awesome! Thanks.
  17. Offline

    AndrewAnderVille

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Okay this is a very helpful tutorial but you don't actually tell us how to change things like the mobs speed, there viewing distance, damage, etc .
  18. Offline

    javaguy78

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    To change the speed, set bw in the custom mob's constructor to the new speed. a-like so:

    Code:
    public class FasterZombie extends net.minecraft.server.EntityZombie {
     
        public FasterZombie(World world) {
            super(world);
            this.bw = 0.46F; // double speed
     
            // I found you need to add this to get it to work properly
                    try {
                //enable PathfinderGoalSelector's "a" field to be editable
                Field gsa = net.minecraft.server.PathfinderGoalSelector.class.getDeclaredField("a");
                gsa.setAccessible(true);
     
                // ok now take this instances goals and targets and blank them
                gsa.set(this.goalSelector, new ArrayList());
                gsa.set(this.targetSelector, new ArrayList());
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
     
            // and then reinitialize all AI with the new speed
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
            this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, this.bw, false));
            this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityVillager.class, this.bw, true));
            this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bw));
            this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bw, false));
            this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bw));
            this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
            this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
            this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 16.0F, 0, false));
        }
     
    }
    My question is how do you get the entityID of the new custom entity when spawning with

    ((CraftWorld) world).getHandle().addEntity(FasterZombie, CreatureSpawnEvent.SpawnReason.CUSTOM);

    as it only returns a boolean? Do I need to wait a few ticks and then manually look for the closest entity to location?
  19. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    If you just want to add a multiplier to the mobs speed then you can give it a custom Navigation like this one and apply it like this.
  20. Offline

    Gravious

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    I know this is quite an old thread but I have a question regarding this.

    I've downloaded the EntityAPI of Jacek and implemented it into my Plugin, but how do I now use this to spawn a NEW Cow and teleport it to the player? (No edited Cow, just the old regular one, I get how to modify them.)
  21. Offline

    CorrieKay

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    You could just spawn a new cow at the player you want to have it located at. Otherwise, just use cow.teleport(player);
  22. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    That is nowhere near finished yet :p
  23. Offline

    Gravious

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Oh, haha, it's a great idea though.

    Am I using the right approach for spawning a cow with edited Health?
    Or is there an easier way to edit health of a new spawned cow at a certain location/spawn a new cow with more health than usual?
  24. Offline

    Shiny Quagsire

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Hey, this also can work with other entities besides living ones, aka falling sand. I used this and spawned my new FallingBlock manually. Works like a charm, and much easier than modifying the server code in the end. :)
  25. Offline

    gamerguy14

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME

    Maybe invoking the EntityTypes.a(Class, String, int) method would work then invoking it back. Like this:

    Code:
    public void spawnCow(World world, double x, double y, double z) {
    try {
    Class[] args = new Class[3];
    args[0] = Class.class;
    args[1] = String.class;
    args[2] = int.class;
     
    Method a = EntityTypes.class.getDeclaredMethod("a", args);
    a.setAccessible(true);
     
    a.invoke(a, EntityCow.class, "cow", 92);
     
    EntityCow cow = new EntityCow(world);//World is just a net.minecraft.server.World
    cow.setPosition(world, x, y, z);//x, y, z are to be replaced with the coordinates
    CraftCow craftCow = new CraftCow((CraftServer) Bukkit.getServer(), cow);
    world.addEntity(cow, SpawnReason.Custom);
     
    a.invoke(a, CustomEntityCow.class, "cow", 92);
    } catch (IOException ex) {
    ex.printStackTrace();
    }
    }
    [code]
     
    This may cause some problems if a custom mob spawns while spawning the normal one.

    This post has been edited 3 times. It was last edited by gamerguy14 Aug 28, 2012.
  26. Offline

    Jacek

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    You can spawn a custom entity in the world without editing the EntityTypes list, you only need that for one the server starts up and tries to load the custom entities if you don't modify it they revert back the the vanilla ones.

    Yeah a lot of people are using this method and causing conflicts so I figured an API for it would be a good idea . I'm hoping to add all the stuff that you can do with this method.

    To create a cow with more health you could just listen on EntityDamageEvent and reduce the damage given

    Code:
    if (event.getEntityType() == EntityType.COW){
        event.setDamage(event.getDamage() / 2);
    }
    would effectively double it's health.
  27. Offline

    CookCreeperz

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    can someone please help me with the zombies??? the 1.3.2 update changed so much stuff!!!!! please help!!!
  28. Offline

    Bradley Hilton

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Anyone know if it changed with 1.3.2 and the dev builds of craftbukkit?
  29. Offline

    CorrieKay

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    as mojang obfuscates the code, it changes with every new build of MC.
  30. Offline

    CookCreeperz

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Sooo? use mcp to obfuscate it?

Share This Page