Skeletons without bows

Discussion in 'Plugin Development' started by Limeth, Nov 19, 2012.

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

    Limeth

    Hello, I've got a problem with spawning skeletons, they spawn without bows.
    When I try giving them a bow, they don't shoot with it.

    This is the code I use to give them a bow:
    Code:java
    1.  
    2. public void setEntityItem(int slot, CraftItemStack i, LivingEntity le) {
    3.  
    4. ((CraftLivingEntity)le).getHandle().setEquipment(slot, i.getHandle());
    5.  
    6. }
    7.  


    I think we have a fix now:
     
  2. Offline

    fireblast709

    what slot are you using? And are they holding the bow?
     
  3. Offline

    HouseMD

    Maybe they require an arrow inventory that doesn't get used up per shot however?
     
  4. Offline

    fireblast709

    HouseMD Only players have inventories :3, skeletons should just fire them anyway
     
  5. Offline

    Limeth

    fireblast709
    I am using slot #0.

    HouseMD
    Skeletons, zombies etc. do have their inventories (for an item in hand and armour contents).
    That means:
    0 = Hand
    1 - 4 = Armour
     
  6. Offline

    Limeth

    - Bump -

    Anyone, please? D:

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  7. i think the problem lies within the spawning of the mob. how do you spawn it in?
    If you use the custom mob tutorial method - MAKE SURE that the custom skeleton class don't extend entitytype.zombie, that will cause a skeleton to spawn, but act like a zombie. (move slow, hands out, drop flesh)
     
  8. Offline

    leiger

    Limeth I've heard that skeletons in the popular MobArena plugin also do this since the update to 1.4 - so you aren't the only one with problem.

    Wish I had a solution for you, but I don't.
     
  9. i'm running into the same problem now. not just the skeleton but also the wither skeleton. although they are the same entitytype. not tested with pigzombie though
     
  10. Offline

    gkovalecyn

    I am using Rprrr's class, but i changed it a little and it now works for me:

    Code:
    public static void setWeapon(LivingEntity mob, ItemStack item) {
            EntityLiving ent = ((CraftLivingEntity) mob).getHandle();
            net.minecraft.server.ItemStack itemStack = new CraftItemStack(item).getHandle();
            ent.setEquipment(0, itemStack);
        }
     
  11. Offline

    Limeth

    mollekake
    leiger
    This is how I spawn the mobs:
    Code:java
    1.  
    2. for(int j = 0; j < i + 5; j++) {
    3.  
    4. List<EntityType> mobTypes = new ArrayList<EntityType>();
    5. mobTypes.add(EntityType.ZOMBIE);
    6. mobTypes.add(EntityType.SPIDER);
    7. mobTypes.add(EntityType.CAVE_SPIDER);
    8. mobTypes.add(EntityType.CREEPER);
    9. mobTypes.add(EntityType.SKELETON);
    10.  
    11. int mobId = new Random().nextInt(mobTypes.size());
    12. int spawner = new Random().nextInt(3);
    13.  
    14. World world = monstersLoc[0].getWorld();
    15. Entity entity = world.spawnEntity(monstersLoc[spawner], mobTypes.get(mobId));
    16.  
    17. if(mobId == 4) {
    18.  
    19. CraftItemStack bow = new CraftItemStack(Material.BOW);
    20. setEntityItem(0, (LivingEntity) entity, bow);
    21.  
    22. }
    23.  
    24. monstersAlive.add(entity.getUniqueId());
    25.  
    26. }
    27.  


    I tried gkovalecyn 's function, didn't help.
     
  12. Offline

    fireblast709

    there seems to be a bug with arrow shooting and skeletons. Try adding an enchantment infinity:
    assume CraftItemStack cis
    Code:java
    1. cis.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
     
  13. Offline

    Limeth

    I don't think that's the problem, because when you see a skeleton spawned naturally, their bows don't glow.
     
  14. Offline

    fireblast709

    scrap my post :3. I really have no clue atm, might go try resetting the AI, because it is not shooting me while I am hitting him in survival
     
  15. the skeleton apparently don't got a bow, he does mele attack instead. Anyone figured this out?
     
  16. Offline

    Limeth

    I sadly did not. Even melee attack doesn't work for me.
     
  17. Offline

    FTWinston

    I ran into this one, and have a fix! Once you've given it a weapon, there's a funny little method you need to call so that it'll use it. It's not exactly intuitive, and it took some poking around in CraftBukkit to work this out:

    For a normal skeleton:

    Code:
    CraftSkeleton skeleton = (CraftSkeleton)stagingWorld.spawnEntity(spawnLocation, EntityType.SKELETON);
    skeleton.getHandle().setSkeletonType(0);
    skeleton.getHandle().setEquipment(0, new net.minecraft.server.ItemStack(net.minecraft.server.Item.BOW));
    skeleton.getHandle().a(new NBTTagCompound()); // this triggers attack behaviour

    And for a wither skeleton:
    Code:
    CraftSkeleton skeleton = (CraftSkeleton)stagingWorld.spawnEntity(spawnLocation, EntityType.SKELETON);
    skeleton.getHandle().setSkeletonType(1);
    skeleton.getHandle().setEquipment(0, new net.minecraft.server.ItemStack(net.minecraft.server.Item.STONE_SWORD));
    skeleton.getHandle().a(new NBTTagCompound()); // this triggers attack behaviour
    You can probably mix & match the skeleton types / weapon types, but I haven't tried.

    Edit: AFAIK You'll need to be using CraftBukkit jar for this to work.
     
  18. Offline

    Limeth

    Well now we're getting somewhere! :D
     
  19. Offline

    stirante

    I don't want to take this offtop, but It's my class. When you look at the code you can see my nick in package.

    After normal spawning skeleton with bukkit api do this:
    Code:
    ((CraftSkeleton)skeleton).getHandle().bG();
    
    Note that if skeleton will be in Nether he will change into wither skeleton.

    EDIT:This code should force them to change type, ai and weapon.
    Code:
        public void changeIntoNormal(Skeleton skeleton, boolean giveRandomEnchantments){
            EntitySkeleton ent = ((CraftSkeleton)skeleton).getHandle();
            try {
                ent.setSkeletonType(0);
                Method be = EntitySkeleton.class.getDeclaredMethod("bE");
                be.setAccessible(true);
                be.invoke(ent);
                if (giveRandomEnchantments){
                    Method bf = EntityLiving.class.getDeclaredMethod("bF");
                    bf.setAccessible(true);
                    bf.invoke(ent);
                }
                Field selector = EntitySkeleton.class.getDeclaredField("goalSelector");
                selector.setAccessible(true);
                Field d = EntitySkeleton.class.getDeclaredField("d");
                d.setAccessible(true);
                PathfinderGoalSelector goals = (PathfinderGoalSelector) selector.get(ent);
                goals.a(4, (PathfinderGoal) d.get(ent));
            }
            catch (Throwable e) {
                e.printStackTrace();
            }
        }
        public void changeIntoWither(Skeleton skeleton){
            EntitySkeleton ent = ((CraftSkeleton)skeleton).getHandle();
            try {
                ent.setSkeletonType(1);
                Field selector = EntitySkeleton.class.getDeclaredField("goalSelector");
                selector.setAccessible(true);
                Field e = EntitySkeleton.class.getDeclaredField("e");
                e.setAccessible(true);
                PathfinderGoalSelector goals = (PathfinderGoalSelector) selector.get(ent);
                goals.a(4, (PathfinderGoal) e.get(ent));
                ent.setEquipment(0, new net.minecraft.server.ItemStack(Item.STONE_SWORD));
            }
            catch (Throwable e) {
                e.printStackTrace();
            }
        }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
    Limeth likes this.
  20. Offline

    Limeth

    Impressive. Great job done on the code, thanks for sharing.
     
  21. Offline

    Dysthymic

    Very nice. I will definitely save this page down. Have a spawning method for skeletons I've been trying to crack this problem with. Finally have the solution. Thanks so much!
     
  22. Offline

    stirante

    What you think about adding it to my PrettyScaryLib ?
     
    Limeth likes this.
  23. Offline

    bakersoft

    Has this code been tested at all? I ask because I tried using it myself with the latest Bukkit beta API and get the exception:

    java.lang.NoSuchFieldException: goalSelector

    at this line:

    Field selector = EntitySkeleton.class.getDeclaredField("goalSelector");
     
  24. Offline

    stirante

    Maybe field name was changed. I wrote this on earlier version.

    Edit: Name is the same. Try changing EntitySkeleton to EntityLiving
     
  25. Offline

    Ne0nx3r0

    Is this still the best way to fix this issue?

    Just curious if the Bukkit API caught up to it or not.
     
  26. Offline

    stirante

    I just looked at code and i don't see any code that could update their weapon and AI. Maybe someone should add pull request.
     
  27. Offline

    Ne0nx3r0

    Hrm. I would, but I'm not even slightly confident in my ability to create a pull request that would be accepted.
     
  28. Offline

    K3V1N32

    I'm really sorry to resurrect a dead thread, but it took me hours to find a fix to this, and this is the first thread to come up in google searches for this, so this is where i thought it could help the most people! I hope i can help a few people save some time finding this solution!

    There is a way better fix for this now, you have to give the skeleton a bow in its hand, and set its type to normal.
    So far, in my tests, the skeletons will target players and shoot the bow just like any other vanilla skeleton.

    Like This:
    Code:java
    1. //cast to Skeleton
    2. Skeleton skeleton = (spawn mob code here i used world.spawnEntity() and cast to the Skeleton class cause i knew i was spawning a skeleton)
    3. //now that it's spawned, you have to give it a bow like so:
    4. skeleton.getEquipment().setItemInHand(new ItemStack(Material.BOW));
    5. //next you need to set it's type to normal like this:
    6. skeleton.setSkeletonType(SkeletonType.NORMAL);
    7. //and that's it! it was WAY too hard to find this simple bit of code.
    8.  
    9. //Heres a simple method to do this for you, if you want a copy/paste solution
    10. public void equipSkeleton(Skeleton skeleton) {
    11. skeleton.getEquipment().setItemInHand(new ItemStack(Material.BOW));
    12. skeleton.setSkeletonType(SkeletonType.NORMAL);
    13. }
     
    Limeth likes this.
  29. You could also do it like this, inside the CreatureSpawnEvent:
    Code:java
    1. if(entityType == EntityType.SKELETON && ((Skeleton) entity).getSkeletonType().getId() == 1){
    2. ((Skeleton) entity).getEquipment().setItemInHand(new ItemStack(Material.STONE_SWORD));
    3. }else if(entityType == EntityType.SKELETON && ((Skeleton) entity).getSkeletonType().getId() == 0){
    4. ((Skeleton) entity).getEquipment().setItemInHand(new ItemStack(Material.BOW));
    5. }
     
    Limeth likes this.
Thread Status:
Not open for further replies.

Share This Page