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

    Infamous Jeezy

    Looks great! Seems fairly easy to understand.
    One question though, is it possible to rotate between spawning normal mobs and scripted mobs?
    Another way I'd like to put that question is let's say you make multiple zombie classes, all of them doing something different, can you rotate between spawning the different types?
    I ask this because in the onEnable method, you invoke the specific scripted zombie class so I am curious whether it is only limited to one custom class.

    Sorry if my question is a bit confusing, you don't need to post an example nor completely explain it, but I'd appreciate it if you could just tell me if it's possible and briefly explaining how.
    Regardless if you get a chance to answer my question, thanks for the excellent tutorial.
     
  2. Offline

    Jacek

    If you don't replace the classes in EntityType (the thing in onEnable()) you can still spawn the custom mob

    Code:
    CustomZombie zombie = new CustomZombie(/* things */);
     
    world.addEntity(zombie);
    Where world is a net.minecraft.server.World

    You can't do it with Bukkit's spawn method though so make sure not to try
    Code:
    world.spawn(CustomZombie.class);
    that will result is massive failure !
     
  3. Offline

    Ricter

    Is there any way to make your customized mobs spawn without ruining the normal spawn?

    The short of what I'm trying to do is any mobs spawned with my plug-in path to a specific static location in the game world (instead of chasing after players) while leaving the other mobs alone, as I don't want to force every mob to go to that location.

    Does that make sense? Is it possible?
     
  4. Offline

    Jacek

    The post above yours is a reply to that exact question ...
     
  5. Offline

    Ricter

    Sorry, that was poorly phrased and I misunderstood. I wasn't trying to waste your time.

    Edit: Nevermind, I keep misunderstanding things.
     
  6. Offline

    sablednah

    I'm trying to stop Giants from being so - erm - stupid:/

    I've tried to add in goals and paths - but they seam to be hard coed to their own behaviour. Is it possible to override even at a NMS level?
     
  7. Offline

    Ch4t4r

    Just to get that right, how would I do a zombie runnin faster and having more live than normal? And I don't really understand what the _s is for :/ . Is it for the said on Tick in the node in first post? If so where do I get a List with this _m() and _s() etc?
     
  8. Offline

    TKramez

    I have created a custom arrow using this tutorial. When I try to replace the original arrow on launch it just hits the player and falls if I do it immediately but if I have it wait 2 ticks to do replace it works. Having this delay kind of defeats the reason I want to be able to track the arrow's movement. Does anyone know how I could have I launch my custom arrow from the get go?
     
  9. Offline

    RingOfStorms

    I'v been looking through the obfuscated code and my gosh trying to find things int here is a nightmare. I was wondering if there was something that would let me make skeletons shoot faster?
     
  10. Offline

    Jacek

  11. Offline

    Bradley Hilton

    With the 1.4.2 update, anyone know if the _h() got changed to something else? I tried looking through the entity and entityzombie but couldn't seem to find it sadly...

    --Edit--

    Was looking in the wrong place, EntityMonster seems to have moved h_() to j_().. Somebody correct me if I'm wrong..
     
  12. Offline

    Kazzababe

    How would I go about this with say, an arrow?
     
  13. Offline

    RingOfStorms

    same way, but with EntityArrow

    :p

    What do you plan to change about it?
     
  14. Offline

    Kazzababe

    Add a particle effect to the onTick() and possibly change the way the arrow will move.
     
  15. Offline

    Jacek

    Arrows have client side prediction as far as I know so you will have to resort to some really ugly methods to get it to move differently. The way I did it for falling sand entities was to send the position and motion packes onTick() to update the position, it's not a nice method :(
     
  16. Offline

    Kazzababe

    Alright, thanks for the info.
    I got the particle effect using onTick() which is what I was mainly looking for.
     
  17. Offline

    Icyene

    Small thing for anyone who cares:

    Movement function map:

    1.2.X, F_
    1.3.X, h_
    1.4.X, j_

    Someone might find it useful.
     
    Jacek likes this.
  18. Offline

    Jacek

    It does seem to always be the one with the _ in the name, no idea why that is but it helps narrow it down a lot.
     
    Icyene likes this.
  19. Offline

    Icyene

    In EntityFireball its also the first method :)
     
  20. The custom mob method is unfortunatly broken with 1.4.2 :(
    Getting major errors in console. Seems to be something wrong with the invoke.
    errors:

    Code:
    (CraftEventFactory.java:226)
            at net.minecraft.server.World.addEntity(World.java:872)
            at mollekake.project.test.EntityListener.onCreatureSpawn(EntityListen
    er.java:35)
            at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
    it erros on the mcWorld.addentity line.
     
  21. Offline

    Jacek

    It's not broken you need to update the method names for the new version. See the above posts :p
     
  22. Yeah i know. But the custom class is empty. Tried with and without my stuff.
     
  23. Offline

    Jacek

    What is the full error ? You might be calling something with reflection that does not exist.
     
  24. couldn't post the entire error code because it was several thousand lines long, just repeating itself.
    BUT i figured it out. Apparently, i can not have an @EventHandler on the creaturespawn event, without the eventhandler, it all works smooth.
    REALLY weird :/
     
  25. Offline

    Jacek

    Oh you must be replacing the entities that are already replaced ... So then you call world.addEntity() it calls the spawn event again so you get an infinite loop of spawning :p You need to make sure that the mod that spawned is not your customised one before doing the replace.
     
  26. Offline

    aviator14

    Could it also be possible to reskin similar mobs?
    Code:java
    1. public Cannibal(World world) {
    2. super(world);
    3. this.bw = 0.5F;
    4. this.texture = "/mob/char.png";
    5. }
     
  27. Offline

    Jacek

    I'm pretty sure the texture field is just a remnant from when the server was originally made from the client so probably not, I have never tried it though.

    EDIT: There is no reason you could not get this effect by creating a zombie entity but giving it the spider behaviour code or similar :p
     
  28. Offline

    aviator14

    I'm actually trying to make a giant with default skin that attacks players and cows, plus anything that hits them. The AI is a bit confusing, as I've gotten them to attack players (or attempt to, since their melee range is smaller than their arm length, they'll stop 3 blocks away and only kill you if you walk into them), but they don't chase anything else (used zombie vs villager AI as a guide). Spider AI would be a big help though to make up for their pathetic jump height :)

    This is what I've got currently, granted I admittedly don't fully understand the how the default pathfinders work.
    Show Spoiler
    Code:java
    1. public HostileGiant(World world) {
    2. super(world);
    3. this.bw = 0.25F;
    4. this.texture = "/mob/char.png";
    5.  
    6. try {
    7. Field gsa = net.minecraft.server.PathfinderGoalSelector.class.getDeclaredField("a");
    8. gsa.setAccessible(true);
    9.  
    10. gsa.set(this.goalSelector, new UnsafeList());
    11. gsa.set(this.targetSelector, new UnsafeList());
    12. } catch (SecurityException e) {
    13. e.printStackTrace();
    14. } catch (NoSuchFieldException e) {
    15. e.printStackTrace();
    16. e.printStackTrace();
    17. e.printStackTrace();
    18. }
    19.  
    20. this.getNavigation().b(true);
    21. this.goalSelector.a(0, new PathfinderGoalFloat(this));
    22. this.goalSelector.a(1, new PathfinderGoalRandomStroll(this, (float) this.bw));
    23. this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, (float) (this.bw * 1.9f), false));
    24. this.goalSelector.a(7, new PathfinderGoalMeleeAttack(this, EntityCow.class, (float) (this.bw * 1.9f), false));
    25. this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntitySpider.class, (float) (this.bw * 1.9f), false));
    26. this.goalSelector.a(5, new PathfinderGoalMeleeAttack(this, EntitySkeleton.class, (float) (this.bw * 1.9f), false));
    27. this.goalSelector.a(6, new PathfinderGoalMeleeAttack(this, EntityZombie.class, (float) (this.bw * 1.9f), false));
    28. this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityCreeper.class, (float) (this.bw * 1.9f), false));
    29. // this.goalSelector.a(2, new PathfinderGoalMoveTowardsRestriction(this, (float) this.bw));
    30. this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 24.0F));
    31. this.goalSelector.a(9, new PathfinderGoalRandomLookaround(this));
    32. this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
    33. this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, true));
    34. this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityCow.class, 16.0F, 0, true));
    35. this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget(this, EntitySpider.class, 16.0F, 0, true));
    36. this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget(this, EntitySkeleton.class, 16.0F, 0, true));
    37. this.targetSelector.a(6, new PathfinderGoalNearestAttackableTarget(this, EntityZombie.class, 16.0F, 0, true));
    38. this.targetSelector.a(7, new PathfinderGoalNearestAttackableTarget(this, EntityCreeper.class, 16.0F, 0, true));
    39. }
    Edit: dunno how the goalselectors got out of order o.o they were in order yesterday
     
  29. Offline

    Jacek

    Ah I doubt you will be able to do that then :( The zombie has the same AI as the zombie from 1.7.3 I think, and the same hit box which is why you have to hit them in the feet :p
     
  30. Offline

    aviator14

    Ok, just wanted to clarify on something, I'm not sure if I misunderstood you, you misunderstood me, or both.
    Did you mean that as a way to spawn mobs that appear to be other mobs? That would fix the AI being restricted to a shape, but the mob using that AI would still be its original shape. I was hoping for, for example, having dragons that use the grey skin, or villagers that use the green skin, or pigmen using the non-zombie version of their skin. I guess if the client is responsible for assigning files to the mobs, that would never work anyway though.
     
Thread Status:
Not open for further replies.

Share This Page