Spawn a mob near player on death of an entity

Discussion in 'Plugin Development' started by Meower, Jun 19, 2014.

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

    Meower

    Alright so I decided to code a plugin that spawns a zombie near a player when the player kills either an animal, a mob, or a player. The zombie has modified speed. I have two .class files - Main and ReflectionUtil. I was wondering how to make the plugin work because it doesn't -.- The console doesn't error and when I try to kill a mob it doesn't spawn anything. Code is as follows

    Main.class
    Code:java
    1. package me.MeowerTRC.Cops;
    2.  
    3. import java.util.HashMap;
    4. import java.util.UUID;
    5.  
    6. import org.bukkit.Bukkit;
    7. import org.bukkit.ChatColor;
    8. import org.bukkit.Location;
    9. import org.bukkit.entity.Entity;
    10. import org.bukkit.entity.LivingEntity;
    11. import org.bukkit.entity.Player;
    12. import org.bukkit.entity.Zombie;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.event.entity.EntityDeathEvent;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16.  
    17. public class Main extends JavaPlugin implements Listener{
    18.  
    19. HashMap<UUID, Player> owners = new HashMap<UUID, Player>();
    20. int i;
    21.  
    22. public void onKill(EntityDeathEvent e){
    23. Player player = null;
    24. @SuppressWarnings("null")
    25. Location inFront = player.getLocation().toVector().add(player.getLocation().getDirection().multiply(3)).toLocation(player.getWorld());
    26. int x = inFront.getBlockX();
    27. int y = player.getLocation().getBlockY();
    28. int z = inFront.getBlockZ();
    29. Location finalLocation = new Location(player.getWorld(), x, y, z);
    30. Zombie cop = player.getWorld().spawn(finalLocation, Zombie.class);
    31.  
    32. cop.setCustomName(ChatColor.YELLOW + "Cop");
    33. cop.setCustomNameVisible(true);
    34.  
    35. final UUID zombieID = cop.getUniqueId();
    36. owners.put(zombieID, player);
    37.  
    38. i = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
    39.  
    40. @SuppressWarnings("deprecation")
    41. @Override
    42. public void run(){
    43. if(owners.containsKey(zombieID)){
    44. for(Entity e : Bukkit.getWorlds().get(0).getEntities()){
    45. Player owner = owners.get(zombieID);
    46. if(e.getUniqueId() == zombieID){
    47. if(e instanceof LivingEntity){
    48. LivingEntity ent = (LivingEntity)e;
    49. Location playerLoc = owner.getLocation();
    50. if(getDistance(playerLoc, ent.getLocation()) > 30){
    51. navigate(ent, playerLoc, 1.6);
    52. }else{
    53. ent.setHealth(0);
    54. }
    55. }
    56. else{
    57. Bukkit.getScheduler().cancelTask(i);
    58. }
    59.  
    60. }
    61. }
    62. }
    63. }
    64.  
    65.  
    66. }, 20, 5);
    67. }
    68. private void navigate(LivingEntity le, Location location, double velocity){
    69. try{
    70. Object entityLiving = ReflectionUtil.getMethod("getHandle", le.getClass(), 0).invoke(le);
    71. Object nav = ReflectionUtil.getMethod("getNavigation", entityLiving.getClass(), 0).invoke(entityLiving);
    72. ReflectionUtil.getMethod("a", nav.getClass(), 4).invoke(nav, location.getX(), location.getY(), location.getZ(), velocity);
    73. }catch(Exception e){
    74. e.printStackTrace();
    75. }
    76. }
    77.  
    78. private double getDistance(Location l1, Location l2){
    79. double distance = l1.distance(l2);
    80. return distance;
    81. }
    82. }



    ReflectionUtil:
    Code:java
    1. package me.MeowerTRC.Cops;
    2.  
    3. import java.lang.reflect.Constructor;
    4. import java.lang.reflect.Field;
    5. import java.lang.reflect.Method;
    6.  
    7. import org.bukkit.Bukkit;
    8.  
    9. public class ReflectionUtil {
    10. public static Object getClass(String name, Object... args) throws Exception {
    11. Class<?> c = Class.forName(ReflectionUtil.getPackageName() + "." + name);
    12. int params = 0;
    13. if (args != null) {
    14. params = args.length;
    15. }
    16. for (Constructor<?> co : c.getConstructors()) {
    17. if (co.getParameterTypes().length == params) {
    18. return co.newInstance(args);
    19. }
    20. }
    21. return null;
    22. }
    23.  
    24. public static Method getMethod(String name, Class<?> c, int params) {
    25. for (Method m : c.getMethods()) {
    26. if (m.getName().equals(name) && m.getParameterTypes().length == params) {
    27. return m;
    28. }
    29. }
    30. return null;
    31. }
    32.  
    33. public static void setValue(Object instance, String fieldName, Object value) throws Exception {
    34. Field field = instance.getClass().getDeclaredField(fieldName);
    35. field.setAccessible(true);
    36. field.set(instance, value);
    37. }
    38.  
    39. public static String getPackageName() {
    40. return "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
    41. }
    42. }



    Also could there be a way to armor the zombies and maybe give them swords? Thanks.
     
  2. Offline

    Iroh

    Moved to plugin dev.
     
  3. Offline

    Meower

    Iroh Thank you.
     
  4. Offline

    fireblast709

    Meower
    • Register your Listener using Bukkit.getPluginManager().registerEvents(this, this);
    • Your EventHandler method doesn't have the @EventHandler annotation.
    • I advise to use a BukkitRunnable instead, since it can easily cancel itself inside the run() method with one single call to cancel()
    • Don't save Player variables as Map values.
     
  5. Offline

    Meower

    fireblast709
    Thanks. I don't know how to do much of this b/c I just began coding today xD Musta forgot the eventhandler. Here's what I did:

    • I put the Bukkit.getPluginManager().registerEvents(this, this); under a newly created onEnable() Method. Was that what I was supposed to do?
    • I put the annotation directly before public void onKill(EntityDeathEvent e)
    • How do I do that?? Lol
    • ^^^^^^^^^^^^^^^
    Did I do everything up to step two right? Also is there a way to put armor on them and have the equip swords?
     
  6. Offline

    fireblast709

  7. Offline

    CraftBang

    Are you guys blind who are answering or is it just me ? xD
    Code:
        public void onKill(EntityDeathEvent e){
            Player player = null;
    
    Main.class line 23.
    Player player = null?
    That's wrong in every way?
    Player player = (Player) e.getEntity(); //Can give errors please read below.

    EntityDeathEvent e.getEntity() returns an entity.

    But before casting the entity to a player use a check if it actually is a player.
    Code:
    if(!e.getEntity() instanceof Player){
    return; //This will return the code, so it won't go further because e.getentity ist not an instance of a player.
    }
    Player player = (Player) e.getEntity();
    
    If I'm wrong please tell me :p
     
  8. Offline

    Meower

    CraftBang Lol I tried adding your code in, it errored in the console.
    Updated main.class:
    Code:
    package me.MeowerTRC.Cops;
     
    import java.util.HashMap;
    import java.util.UUID;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Zombie;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDeathEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class Main extends JavaPlugin implements Listener{
     
        HashMap<UUID, Player> owners = new HashMap<UUID, Player>();
        int i;
     
        public void onEnable(){
            Bukkit.getPluginManager().registerEvents(this, this);
        }
        @EventHandler
        public void onKill(EntityDeathEvent e){
            Player player = (Player) e.getEntity();
            Location inFront = player.getLocation().toVector().add(player.getLocation().getDirection().multiply(3)).toLocation(player.getWorld());
            int x = inFront.getBlockX();
            int y = player.getLocation().getBlockY();
            int z = inFront.getBlockZ();
            Location finalLocation = new Location(player.getWorld(), x, y, z);
            Zombie cop = player.getWorld().spawn(finalLocation, Zombie.class);
         
            cop.setCustomName(ChatColor.YELLOW + "Cop");
            cop.setCustomNameVisible(true);
         
            final UUID zombieID = cop.getUniqueId();
            owners.put(zombieID, player);
         
            i = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
             
                @SuppressWarnings("deprecation")
                @Override
                public void run(){
                    if(owners.containsKey(zombieID)){
                        for(Entity e : Bukkit.getWorlds().get(0).getEntities()){
                            Player owner = owners.get(zombieID);
                            if(e.getUniqueId() == zombieID){
                                if(e instanceof LivingEntity){
                                    LivingEntity ent = (LivingEntity)e;
                                    Location playerLoc = owner.getLocation();
                                    if(getDistance(playerLoc, ent.getLocation()) > 30){
                                    navigate(ent, playerLoc, 1.6);
                                    }else{
                                        ent.setHealth(0);
                                    }
                            }
                                else{
                                    Bukkit.getScheduler().cancelTask(i);
                                }
                                 
                                }
                        }
                    }
                }
             
         
            }, 20, 5);
    }
    private void navigate(LivingEntity le, Location location, double velocity){
        try{
            Object entityLiving = ReflectionUtil.getMethod("getHandle", le.getClass(), 0).invoke(le);
            Object nav = ReflectionUtil.getMethod("getNavigation", entityLiving.getClass(), 0).invoke(entityLiving);
            ReflectionUtil.getMethod("a", nav.getClass(), 4).invoke(nav, location.getX(), location.getY(), location.getZ(), velocity);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
     
    private double getDistance(Location l1, Location l2){
        double distance = l1.distance(l2);
        return distance;
    }
    }
    I also have the console error here:
    Code:
    [14:46:12 ERROR]: Could not pass event EntityDeathEvent to Cops v1.0.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.ja
    va:294) ~[craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.jav
    a:62) ~[craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.j
    ava:501) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.j
    ava:486) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at org.bukkit.craftbukkit.v1_7_R3.event.CraftEventFactory.callEntityDeat
    hEvent(CraftEventFactory.java:353) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e
    0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityLiving.die(EntityLiving.java:799)
    [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityLiving.damageEntity(EntityLiving.j
    ava:734) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityMonster.damageEntity(EntityMonster
    .java:48) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityZombie.damageEntity(EntityZombie.j
    ava:164) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.Entity.B(Entity.java:322) [craftbukkit.j
    ar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityLiving.B(EntityLiving.java:154) [c
    raftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityInsentient.B(EntityInsentient.java
    :111) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.Entity.h(Entity.java:242) [craftbukkit.j
    ar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityLiving.h(EntityLiving.java:1271) [
    craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityInsentient.h(EntityInsentient.java
    :150) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityMonster.h(EntityMonster.java:25) [
    craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.EntityZombie.h(EntityZombie.java:231) [c
    raftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.World.entityJoinedWorld(World.java:1421)
    [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.World.playerJoinedWorld(World.java:1402)
    [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.World.tickEntities(World.java:1290) [cra
    ftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.WorldServer.tickEntities(WorldServer.jav
    a:481) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.MinecraftServer.v(MinecraftServer.java:6
    49) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.DedicatedServer.v(DedicatedServer.java:2
    60) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.MinecraftServer.u(MinecraftServer.java:5
    58) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.MinecraftServer.run(MinecraftServer.java
    :469) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            at net.minecraft.server.v1_7_R3.ThreadServerApplication.run(SourceFile:6
    28) [craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
    Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_7_R3.entity.C
    raftZombie cannot be cast to org.bukkit.entity.Player
            at me.MeowerTRC.Cops.Main.onKill(Main.java:28) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0
    _45]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0
    _45]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1
    .7.0_45]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_45]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.ja
    va:292) ~[craftbukkit.jar:git-Bukkit-1.7.9-R0.2-1-ga6e0bfd-b3095jnks]
            ... 25 more
    >
    Keep in mind that I want it to fire when the player kills ANYTHING; including animals like pigs and cows, monsters like creepers and zombies (useful for the player trying to keal da kawpz :confused:) and players.

    fireblast709 Lol the bukkit wiki can be so hard xD

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  9. Offline

    fireblast709

    Meower you cast the dying entity to Player (which obviously is not the Player). Also compare UUIDs using .equals() instead of ==
     
  10. Offline

    Meower

    How do I?
     
  11. Offline

    fireblast709

    Meower first line of your evenhandler method
     
  12. Offline

    Meower

    fireblast709 So public void onKill(EntityDeathEvent Player)?
     
  13. Offline

    fireblast709

    Meower the line after that
     
  14. Offline

    Meower

    fireblast709 Lol sorry, I am SUCH a noob. So where do I put player in "Player player = (Player) e.getEntity();"
     
  15. Offline

    fireblast709

    Meower getEntity() returns a Zombie if a Zombie dies, not a player. Then you get the Player from getKiller(), which might be null in case the mob wasn't killed by a player
     
  16. Offline

    Meower

    fireblast709 I understand what you're saying; but how do I make it to where if a player kills a mob like a zombie, a villager, or a pig, or a cow, or something like that, then a zombie spawns behind him. The player can kill that zombie and it'll act like a regular mob so it'll spawn a new one. So no mob kill mob or mob kill player and have a zombie spawn.
     
  17. Offline

    fireblast709

    Meower in my post, the Zombie is just an example. It should with every LivingEntity
     
  18. Offline

    Meower

    fireblast709 Alright so how do I make it work? xD

    Sorry if I'm being VERRY nooby here. xD

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  19. Offline

    CraftBang

    Meower this is to check if the entity who died is a player.
    Code:
    if(!e.getEntity() instanceof Player){
    return; //This will return the code, so it won't go further because e.getentity ist not an instance of a player.
    }
    Player player = (Player) e.getEntity();
    
     
  20. Offline

    Meower

    CraftBang Ok thanks alot; it works. I have three more questions though.

    1. When a player kills another player in the main world a zombie spawns behind him. Is there a way to armor that zombie?

    2. When a player kills another player in a seperate world it throws me a "IllegalArgumentException: Cannot measure distance between spawn and rec" I have two worlds named "Spawn" and "Rec".

    3. When the player kills a zombie that was spawned when the player killed another player, can the death of the zombie result in more zombies spawning?
     
  21. Offline

    CraftBang

    1 do cop.getEquipment().add. Replace add with setleggings or something
    2 post error log
    3 you made à check if it was not instantie of player.
    So in that check do if e.getentity instanceof Zombie

    If that do if(e.getentity().getCustomName().equals("the name of the cop zombie"))
    And than spawn à zombie
     
Thread Status:
Not open for further replies.

Share This Page