Move/Copy LivingEntity to different world

Discussion in 'Plugin Development' started by Stoux, Dec 6, 2013.

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

    Stoux

    'Ello people,

    As the title already says, I'm having some troubles moving LivingEntities from World A to World B.

    Small bit of code I'm using:
    Code:java
    1. int teleportedEntities = 0;
    2. double dRadius = (double) radius;
    3. List<Entity> foundEntities = p.getNearbyEntities(dRadius, dRadius, dRadius);
    4. for (Entity e : foundEntities) {
    5. if (e instanceof LivingEntity && !(e instanceof Player)) {
    6. LivingEntity le = (LivingEntity) e;
    7. le.teleport(toLocation);
    8. teleportedEntities++;
    9. }
    10. }


    The toLocation is the location of a different player, in a different world. This way I make sure the teleport-to location is loaded (as there are players there). When I execute the code it teleports them away (no errors are thrown), but they never arrive. So, I'm fairly sure I can conclude from this that Entities cannot be moved to a different world (would be awesome if someone could confirm this).

    So, the next option is than (unless someone has a way to move them) to 'Copy' them. Has anyone else tried messing with this?

    Thanks,
    Stoux
     
  2. Offline

    Wolfey

    try this:

    Code:java
    1.  
    2. public void move(Player p, double x, double y, double z, org.bukkit.Location toLocation) {
    3. int teleported = 0;
    4. List<Entity> ents = p.getNearbyEntities(x, y, z);
    5. for(Entity e : ents) {
    6. if(!(e instanceof Player)) {
    7. e.teleport(toLocation);
    8. teleported++;
    9. }
    10. }
    11. p.sendMessage(ChatColor.GREEN + "You have teleported " + teleported + " entities to another location!");
    12. }
    13.  
     
  3. Offline

    Stoux

    Wolfey That's pretty much a simpler version of my code, only checking for Entity instead of LivingEntity. :confused:
     
  4. Offline

    MrGermanrain

    So... did his code work? A small difference in code can be a big difference in a plugin.
     
  5. Offline

    PogoStick29

    Stoux Do me a favor and before if(!(e instanceof Player)) {, add

    System.out.println(toLocation.getWorld() == e.getLocation().getWorld());
     
  6. Offline

    Wolfey

    Hm, I see what you mean. Just tested it out, teleports entities to the location, but not to different worlds.
     
  7. Offline

    Stoux

    MrGermanrain It did not since it's the same code only checking for more entities.
    PogoStick29 Is false every time as expected, since the teleport happens after that check, not before it.

    The teleporting works fine as Wolfey just said as long as you stay in the same world. When one of the players is in a different world, the LivingEntities just disappear.

    EDIT:
    Made a runnable which runs 2 seconds after the teleporting.
    Code:java
    1. System.out.println(foundEntity.isValid());
    2. if (foundEntity.isValid()) {
    3. System.out.println(foundEntity.getLocation());
    4. p.teleport(foundEntity);
    5. }

    Here's the kicker: It claims to be valid, and its location is the exact location as the 2nd player (so in a different world). So it is alive/there, but it isn't. I don't even.
     
  8. Offline

    Scyntrus

    It appears you may have uncovered a bug in the code.
    Here is craftbukkit's teleport code:
    https://github.com/Bukkit/CraftBukk...kkit/craftbukkit/entity/CraftEntity.java#L203
    Craftbukkit's teleport code neglects to call NMS's world.addEntity function. As a result, the entity is not added to the destination world's entityList.
    https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/World.java#L840
    I'm not 100% sure, but you may want to talk to one of the bukkit staff if this is true.

    Edit: What should really be used is this:
    https://github.com/Bukkit/CraftBukk...n/java/net/minecraft/server/Entity.java#L1776
     
    Stoux and PogoStick29 like this.
  9. Offline

    Stoux

    Scyntrus Apperently bug has been there since Bukkit 1.4 (and some variants of the problems since 1.2). See Bug Report.
    So now is the question, is there a way to (temporary) get around this problem. I fear that I have to write a 'copy' method for each mob (to copy all of the stats for each mob).
     
  10. Offline

    Wolfey

    Instead of teleporting, try killing the mob, then spawning it in a different world?
     
  11. Offline

    Stoux

    Wolfey Yeh, that's what I mean with copying. The problem is, that I want each mob to have the exact same stats. So that includes all mob specific stuff, examples: Horse Jumping height, Mob armor, Etc etc. The only thing I won't be able to copy is the UUID. But still, writing copy methods for each different mob is loads & loads of work.
     
  12. Offline

    Stoux

    Scyntrus Eventually ended up with quite a simple hack for it. Thanks for referring me to those links.

    Code:java
    1. public static void teleportMob(LivingEntity e, Location toLocation) {
    2. if (e.getWorld() == toLocation.getWorld()) {
    3. e.teleport(toLocation);
    4. } else {
    5. CraftEntity craftEntity = (CraftEntity) e;
    6. craftEntity.getHandle().teleportTo(toLocation, false);
    7. }
    8. }
     
Thread Status:
Not open for further replies.

Share This Page