Create and Spawn entity, and control it?

Discussion in 'Plugin Development' started by cvcs1, May 16, 2011.

Thread Status:
Not open for further replies.
  1. Hey guys, I am really new to Bukkit Dev. and I want to know how to create an entity in


    public void onPlayerInteract(PlayerInteractEvent event){


    and spawn where the player is targeting: player.getTargetBlock

    How do i do this?

    Thanks!
     
  2. Offline

    Raeon

    Here's a snippet:

    Code:
    Player p = event.getPlayer(); // Gets the Player that called the event
    Block a = p.getTargetBlock(null, 256); // Gets the Block the Player was looking at
    World w = event.getPlayer().getWorld(); // Gets the World that the Player is in
    w.spawnCreature(a.getLocation(), CreatureType.PIG); // Spawn a Entity in the World
    // Edit the CreatureType to fit your likings!
    With this snippet above you can spawn a mob at the location where the player looks.
    I'm not sure, but it will probably spawn inside the block, so you will have to fix that.
    Also, I do not know how to really 'control' the creature, so that's up to you.

    Hope this is usefull!
    - Raeon
     
  3. Ok thanks, I figured out how to make it spawn above, you set location y value to its current y value + 1.
    So:

    Location target = player.getTargetBlock(null, 0).getLocation();
    int y = target.getBlockY() + 1;
    target.setY(y);

    Does anyone know how to get the spawned creature and add it to an array?

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

    chronopolis

    Just like you would add any items to an array :cool: Just make sure your array is of the correct type (creatures, or entity - im not sure)

    EDIT: Its LivingEntity...heres how to do it :p
    Code:
            Location target = player.getTargetBlock(null, 0).getLocation();
            target.setY(target.getBlockY()+1);
            LivingEntity[] pigs = new LivingEntity[4];
            pigs[0] = player.getWorld().spawnCreature(target, CreatureType.PIG);
    
    The above code will make an array that can hold 5 LivingEntitys
     
  5. Offline

    Raeon

    No problem! :)

    Also, out of curiosity, how are you going to 'control' them?
    - Raeon
     
  6. Ah! Thank you. Ok now I can actually start working on this...

    How:
    I am not sure.. I'll figure it out.
    What:
    I want to save them to a data base with a user (owner) and then it will keep them in an area (defined by owner + sign) and "breed" where if two of the same type are in one area for more then 5 (in game) days then a new one appears. They either will not despawn (if possible) or they will be spawned every time they despawn.

    hmmm... it spawns the pig, but then gives me this error:
    org.bukkit.command.CommandException: Unhandled exception executing command 'qfarm' in plugin QFarm v1
    org.bukkit.command.CommandException: Unhandled exception executing command 'qfarm' in plugin QFarm v1
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:37)
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:85)
    at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:255)
    at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.java:677)
    at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:640)
    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:634)
    at net.minecraft.server.Packet3Chat.a(Packet3Chat.java:32)
    at net.minecraft.server.NetworkManager.a(NetworkManager.java:195)
    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:74)
    at net.minecraft.server.NetworkListenThread.a(SourceFile:100)
    at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:370)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:285)
    at net.minecraft.server.ThreadServerApplication.run(SourceFile:394)
    Caused by: java.lang.NullPointerException
    at com.cvcs1.QFarm.QFarm.onCommand(QFarm.java:56)
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:35)
    ... 12 more
    and then the plugin crashes.

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

    nisovin

    That's obviously just example code, you shouldn't just blindly copy and paste it. Something is null somewhere, what line is line 56?
     
  8. I know what to do with example code, line 56 is:

    pigs[pigCount] = player.getWorld().spawnCreature(target, CreatureType.PIG);

    where pigs[] is a LivingEntity[] and pigCount is a static int
    and the whole function is:

    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
    Player player = ((Player) sender);
    if (commandLabel.equalsIgnoreCase("qfarm")){
    if (args[0].equalsIgnoreCase("spawn")){
    Location target = player.getTargetBlock(null, 0).getLocation();
    int y = target.getBlockY() + 1;
    target.setY(y);
    pigCount ++;

    player.sendMessage(pigCount + " <");
    pigs[pigCount] = player.getWorld().spawnCreature(target, CreatureType.PIG);
    return true;
    }
    }

    return false;

    }
     
  9. Offline

    nisovin

    I would have to assume that the pigs[] array is null. Also, I suspect your target isn't what you are expecting, given that your maximum range is zero.
     
  10. Hmm... I'll try a different way of declaring the array, and also I always set the number for

    getTargetBlock(null, 0)
    to 0 and it always works?

    Ok so instead of just: LivingEntity[] pigs;
    it is now: LivingEntity[] pigs = new LivingEntity[5];
    This fixed that problem. Now in a different place I have this:

    Code:
    if (QFarm.pigs != null){
    		for (int x = 0; x < QFarm.pigCount; x ++){
    			if (QFarm.pigs[x].isDead()){
    				QFarm.pigs[x] = QFarm.spawnCreature(QFarm.pigs[x].getLocation());
    			}
    		}
    		}
    But on :
    Code:
    if (QFarm.pigs[x].isDead()){
    
    it gets an error.
    It is in a different class so QFarm is the main class where I declare and spawn the pigs.
    Any ideas?

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

    Raeon

    Code:
    Player p = event.getPlayer(); // Gets the Player that called the event
    Block a = p.getTargetBlock(null, 256); // Gets the Block the Player was looking at
    World w = event.getPlayer().getWorld(); // Gets the World that the Player is in
    w.spawnCreature(a.getLocation(), CreatureType.PIG); // Spawn a Entity in the World
    // Edit the CreatureType to fit your likings!
    I haven't put (null, 256) there for a reason.. The integer defines how FAR the target block may be. Using zero will probably result into.. nothing. I used 256 because it is the furthest amount of blocks a player can see on Far (not 100% sure, but its high enough).

    EDIT: Use 200, its more than enough!
     
  12. Offline

    Shamebot

    Actually 0 means no limit
    You might look at this: http://forums.bukkit.org/threads/i-...er-gettargetblock-null-500.17272/#post-303479
     
  13. Ok thank you! I was wondering about that... But 0 has worked for me, I'll change all my code though, makes more sense!

    I GOT IT!!!!
    Code:
    
    if(player.getTargetBlock(null, 256).getState() instanceof Sign){
    			Sign s = (Sign)player.getTargetBlock(null, 256).getState();
    			String f = s.getLine(0);
    			if (f.equalsIgnoreCase("[QFarm]")){
    				String animal = s.getLine(1);
    				Location location = player.getTargetBlock(null,256).getLocation();
    				location.setX(location.getX() + 1);
    
    			QFarm.pigs[QFarm.pigCount] = plugin.spawnCreature(player, animal, location);
    			QFarm.pigCount ++;
    			}
    			player.sendMessage("First = " + f);
    		}
    
    This spawns and saves an animal based off of a sign.

    Code:
    
    for (int x = 0; x < QFarm.pigCount; x ++){
    			if (QFarm.pigs[x].isDead()){
    				QFarm.pigs[x] = QFarm.spawnCreature(QFarm.pigs[x].getLocation());
    			}
    		}
    
    This respawns if Dead!!!!! so beautiful.
    Thanks for all of your help guys!

    EDIT: Does anyone know how to get the cause-of-death on an EntityDeath event? By cause I mean if it is a player or a despawn or a creature?

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

    Raeon

    I'm glad it works! This source actually helped me out, too! :)

    EDIT: What event did you use for the Sign code? Thanks!

    - Raeon
     
  15. I used onPlayerInteract
     
  16. Offline

    Shamebot

    You would need to register a EntityDamageEvent and check the cause with getCause()
    Edit: Saving the target block would be better than invoking the method twice.
     
  17. By this I meant how do i check when a saved creature despawns?
     
  18. Offline

    Shamebot

    I don't understand, do you mean on server start/stop?
     
  19. I didn't say that I don't think. What I am trying to do is when a user creates a fenced in area and pays for it (idk how the payment will work yet) he will have a farm with a specified animal, the animals won't despawn and they will 'breed' where if two of the same type are there for more then a specified amount of time, another will spawn and save.
     
  20. Offline

    Shamebot

    I still don't get what your problem is. Entities despawning randomly without getting damaged?
     
  21. Entities despawn. Pigs and such. When you leave the chunk. I need them to not.
     
  22. Offline

    Shamebot

    save the entities per chunk, check whether they got lost, on chunk load and respawn if they did.
     
  23. How do I check? As in, is the isDead variable for LivingEntity set to true when it despawns or no?
     
  24. Offline

    Shamebot

    Only way I can think of is getting the chucks your region is within, count the entities of the Chunk.getEntities() method per creature type and spawn some if there are too less.
     
  25. Ok so heres my method: I check on chunkUnload if any entites in the chunk were saved ones, then it saves the chunk in a Chunk[]. Then on chunkLoad if the chunk loading = one of the saved chunks, it spawns the saved entities where they were.
    EDIT: This doesn't work nevermind. Any ideas?
     
  26. Offline

    Shamebot

    What doesn't work?
     
  27. Well, theres no way to save what (saved) entities were in that chunk. As in, I have the chunk they were in, but I have no way to save the corresponding entities
     
  28. Offline

    Shamebot

    Try to build upon this:
    Code:
    public class Region
    {
        Location min,max;
        public Region(Location l1, Location l2)
        {
            World world = l1.getWorld();
            this.min = new Location(world, Math.min(l1.getX(),l2.getX()),0,Math.min(l1.getZ(),l2.getZ()));
            this.max = new Location(world, Math.max(l1.getX(),l2.getX()),0,Math.max(l1.getZ(),l2.getZ()));
        }
    
        HashMap<CreatureType,Integer> getEntities()
        {
            World world = min.getWorld();
            HashMap<CreatureType,Integer> entities = new HashMap<CreatureType,Integer>();
            int chunkMinX = min.getBlockX >> 4;  //Edit: fixed mistake here
            int chunkMaxX = max.getBlockX >> 4;
            int chunkMinZ = min.getBlockZ >> 4;
            int chunkMaxZ = max.getBlockZ >> 4;
    
            for(int x = chunkMinX; x <= chunkMaxX; x++)
            {
                for(int z = chunkMinZ; z <= chunkMaxZ; z++)
                {
                    for(Entity entity : world.getChunkAt(x,z).getEntities())
                    {
                        if(min.getBlockX()-1 < entity.getLocation().getX() && entity.getLocation().getX() < max.getBlockX()+1 &&
                            min.getBlockZ()-1 < entity.getLocation().getZ() && entity.getLocation().getZ() < max.getBlockZ()+1)
                        {
                            String entityName = entity.getClass().getInterfaces()[0].getSimpleName();
                            CreatureType type = CreatureType.fromName(entityName);
                            if(type != null)
                            {
                                entities.put(type,(entities.containsKey(type))?entities.get(type)+1:1);   //Edit: fixed mistake here
                            }
                        }
                    }
                }
            }
            return entities;
        }
    }
    You need to add a HashMap<CreatureType,Integer> to store the entities which should be in the region.
    On chunk load you'll maybe need to load all chunks of the region, how you can get them is shown above, maybe add a method returning a list of chunks and a method checking whether a chunk is part of the region.
    I didn't really test this but it should work, at least for the most part.
     
  29. I'm sorry but what is a hashmap i never got them.
    EDIT: Is it basically an array where each object can have multiple types?
     
  30. Offline

    Jayjay110

    sort of, it is basically an array inside an array with only 1 variable availabe i think...

    Should be like this:
    Hashmap
    poo = fa
    da = ga
    op = pop

    Array
    poo = fa,ga,pop

    do u get it?
     
Thread Status:
Not open for further replies.

Share This Page