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

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

Thread Status:
Not open for further replies.
  1. Offline

    TheSourceCode95

    Great tutorial, with some changes it still works great. However, I've got one question. Is it possible to just spawn an entity, or will I have to spawn an custom entity of the same kind and then replace it with my custom entity?
     
  2. Offline

    Jacek

    You can spawn a custom entity using the world.addEntity() method as above, the only reason you need to do the replace thing is so that after a chunk is unloaded and loaded again the entity is still the custom one.
     
  3. Offline

    TheSourceCode95

    Ah, does that include server restarts? And, does the EntitySpawnEvent get triggered when an entity is reloaded instead of spawned? Didn't know that, nice!
     
  4. I'm new to coding, and I'm a fast Learner. But I'm COMPLETELY lost here, could anyone please help?
     
  5. Offline

    blablubbabc

    It would be nice to customize the behavior of mobs without craftbukkit and nms internal code.. :(
     
    pasow likes this.
  6. Offline

    Cybermaxke

    I am currently working on a extended entity api, but there is still some work to do. ;)
     
  7. Offline

    TomShar

    So with this would I be able to make them:
    move faster
    deal more damage
    break and place blocks
    ???
     
  8. Offline

    Kazzababe

    I've done this a couple of times and the latest time I've used this, certain mobs tend to spawn there edited counterpart when I'd rather that not happen.

    I have a command that spawns a custom spider, but for some reason the game tends to replace regular spiders with the edited spiders. Any ideas?
     
  9. Offline

    Cybermaxke

    Register a diffirent entity id as the default. (The invoking part.)
     
  10. Offline

    Kazzababe

    That just causes the client to crash.
     
  11. Offline

    Rockon999

    I am trying to make custom Zombies for my plugin OtherZombies. I've been able to completely change all the Zombies. But I want to make a new entity, not Modify the current zombie. Is this possible?
     
  12. Offline

    Shiny Quagsire

    Rockon999
    Kazzababe
    If you're spawning them manually via your plugin, you could have a boolean that will switch between the regular and modified behavior.
     
  13. Offline

    Jacek

    Kazzababe The game replaces all the mobs because you tell it to by replacing the entity class, if you don't do that you can still spawn the mob by creating a new instance and using World.addEntity(). The only problem is that it will revert to a vanilla mob if the chunk is unloaded and loaded again.
     
  14. Offline

    Cybermaxke

    Did you change the String?
     
  15. Offline

    SolarEpsilon

    You might just want to use the plugin Monster Apocalypse. It has all the things listed in the config, as well as the time it would take to destory the blocks, and exactly how fast, etc.
     
  16. Offline

    Techy4198

    anyone know a way I can make a mob freeze when I ride it, without making a custom entity for each mob? just because I want to support every mob, and im sure 30+ custom entities is way too much work for freezing mobs.
     
  17. Offline

    Regenwurm97

    Hey all :)

    Where do you get these cool method-calling-names from?
    I'm not so far at developing bukkit plugins but for what I understand, the

    @Override
    public void s_() {
    XXX
    }

    calls the s_() method from anywhere (I want to know the location of this awesome class :D) and the @Override cancels what the method would normally call so only the edited content of s_() {} is being run, not the default one right?

    So where can you get the Methods from? Guess that s_() is the method for spawning an entity, not?
     
  18. Offline

    Ivan

    https://github.com/Bukkit/
     
  19. Offline

    Regenwurm97

    What should I do with this?
     
  20. Offline

    CorrieKay

    You'll have to look into the source code for the craftbukkit and minecraft server code. It changes whenever theres a new update, so its pretty hard to keep up with plugins that rely on these obfuscated (hidden) methods, cuz their names change so frequently.
     
  21. Offline

    xGamingDudex

    Hi, I'm making a custom zombie that will target a custom bat I made. I also wanted them to be able to look further, to 112 blocks. Every thing works fine except that it can only see the bat from 41 blocks away in a sphere. I also noticed this is also just how long a player can see the bat entity. I tried to change it so that the zombie would target a skeleton which you can see from further away, but this also resulted in that the zombie only could see it from 41 blocks away. Here is the code and any ideas would be appreciated:
    Code:
    public CustomZombie(World world){
            super(world);
            this.getNavigation().b(true);
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
            this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CustomBat.class, this.bI, false));
            this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, CustomBat.class, this.bI, true));
            this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bI));
            this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bI, false));
            this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bI));
            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, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, CustomBat.class, 112.0F, 0, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, CustomBat.class, 112.0F, 0, false));
        }
     
  22. Offline

    Jacek

    @xGamingDudexYou probably want to remove the existing pathfinders before adding new ones, it could just be a conflict.
     
  23. Offline

    xGamingDudex

  24. Offline

    Jacek

    You can access the field with reflection

    Code:
                Field aField = this.goalSelector.getClass().getDeclaredField("a");
                aField.setAccessible(true);
                aField.get(this.goalSelector);
                List<PathfinderGoal> a = (List<PathfinderGoal>) aField.get(this.goalSelector);
               
                a.clear();
    You end up using a lot of stuff like this when messing with entities so it might be worth creating something like my ReflectionUtils which you can then use like this.
     
  25. Offline

    xGamingDudex

    Thanks, I seam to be quite new to reflection but I tried this:
    Code:
            public CustomZombie(World world){
            super(world);
            try{
                Field aField = this.goalSelector.getClass().getDeclaredField("a");
                aField.setAccessible(true);
                aField.get(this.goalSelector);
                @SuppressWarnings("unchecked")
                List<PathfinderGoal> a = (List<PathfinderGoal>) aField.get(this.goalSelector);
             
                a.clear();
            this.goalSelector.a(0, new PathfinderGoalFloat(this));
            this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
            this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, CustomBat.class, this.bI, false));
            this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, CustomBat.class, this.bI, true));
            this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bI));
            this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bI, false));
            this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bI));
            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, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, CustomBat.class, 159.0F, 0, true));
            this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, CustomBat.class, 159.0F, 0, false));
            }catch (Exception e){
                e.printStackTrace();
                this.world.removeEntity(this);
            }
     
        }
    But it don't seem to do any thing, also imported java.lang.reflect.Field
     
  26. Offline

    Jacek

    You have to do the same for both fields (a and b) and for the targetSelector too.
     
  27. Offline

    xGamingDudex

    I'm using this:
    Code:
    Field aField = this.goalSelector.getClass().getDeclaredField("a");
                aField.setAccessible(true);
                aField.get(this.goalSelector);
                @SuppressWarnings("unchecked")
                List<PathfinderGoal> a = (List<PathfinderGoal>) aField.get(this.goalSelector);
                Bukkit.broadcastMessage("##A:\n" +a.size() + "\n" + a);
                a.clear();
                Field bField = this.goalSelector.getClass().getDeclaredField("b");
                bField.setAccessible(true);
                bField.get(this.goalSelector);
                @SuppressWarnings("unchecked")
                List<PathfinderGoal> b = (List<PathfinderGoal>) bField.get(this.goalSelector);
                Bukkit.broadcastMessage("##B:\n" +b.size() + "\n" + b);
                b.clear();
               
                Field aField2 = this.targetSelector.getClass().getDeclaredField("a");
                aField2.setAccessible(true);
                aField2.get(this.targetSelector);
                @SuppressWarnings("unchecked")
                List<PathfinderGoal> a2 = (List<PathfinderGoal>) aField2.get(this.targetSelector);
                Bukkit.broadcastMessage("##A1:\n" +a2.size() + "\n" + a2);
                a2.clear();
                Field bField2 = this.targetSelector.getClass().getDeclaredField("b");
                bField2.setAccessible(true);
                bField2.get(this.targetSelector);
                @SuppressWarnings("unchecked")
                List<PathfinderGoal> b2 = (List<PathfinderGoal>) bField2.get(this.targetSelector);
                Bukkit.broadcastMessage("##A2:\n" +b2.size() + "\n" + b2);
                b2.clear();
    But it still doesn't work, and it says that the "b's"(list b from goalSelector and b from targetSelector) is empty
     
  28. Offline

    Jacek

    Well remove the line
    Code:
    bField2.get(this.targetSelector);
    since that's not actually doing anything.

    It could be that there is another limit on the distance that mobs can target or that it's instantly forgetting the target due to the distance, maybe look at the part of the code where targets are forgotten and see if there are any numbers close to 41 :p
     
  29. Offline

    xGamingDudex

    I have looken and tested to my eyes got sore:eek:
    Don't think you might help me in the right direction?
     
  30. Offline

    Jacek

    Did you find the place where the limit is applied ? I think there is an event for when entities lose their target so finding where that is fired from might be a good way to find it.
     
Thread Status:
Not open for further replies.

Share This Page