Freeze Mobs

Discussion in 'Plugin Development' started by spoothie, Sep 9, 2011.

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

    spoothie

    Hello everyone,
    I wonder if it is possible to freeze mobs, so that they just stay at their location and do nothing (especially don't move). I already looked for an EntityMove Event, but it seems that there isn't any.

    Greetings
    spoothie
     
  2. If I remember, you have to edit the mob class manually -_-
     
  3. Offline

    Daniel Heppner

    You can't cancel the entity move event? How about teleporting entities? You could teleport them back to where they were every time that they move.
     
  4. Offline

    bergerkiller

    Yeah, but there's no entity move event (for performance reasons, else the event fires hundrets of times every tick for all entities, including dropped items) so you can't. Using a scheduled task is buggy (as hell).

    I replaced the minecart class with my own (extending the entity) to change physics behaviours, I see no other way atm.

    It's pretty easy though: simply kill (dead = true) the old entity, send death packets to all players on the world and add your custom entity by:
    - Initialize a new entity (new MyCustoMClass(world, x, y, z))
    - Set all properties of your new entity to those of the old entity
    - world.addEntity(new entity)
    - tele passenger over (if needed)

    Code:
        public static void replaceMinecarts(EntityMinecart toreplace, EntityMinecart with) {
            with.yaw = toreplace.yaw;
            with.pitch = toreplace.pitch;
            with.locX = toreplace.locX;
            with.locY = toreplace.locY;
            with.locZ = toreplace.locZ;
            with.motX = toreplace.motX;
            with.motY = toreplace.motY;
            with.motZ = toreplace.motZ;
            with.e = toreplace.e;
            with.f = toreplace.f;
            with.g = toreplace.g;
            with.uniqueId = toreplace.uniqueId;
            toreplace.uniqueId = new UUID(0, 0);
            ItemStack[] items = toreplace.getContents();
            for (int i = 0;i < items.length;i++) {
                if (items[i] != null) {
                    with.setItem(i, new ItemStack(items[i].id, items[i].count, items[i].damage));
                }
            }
            for (int i = 0;i < items.length;i++) toreplace.setItem(i, null);
    
            //This is the only 'real' remove method that seems to work...
            toreplace.dead = true;
            Packet29DestroyEntity packet = new Packet29DestroyEntity(toreplace.id);
            for (Player p : toreplace.world.getWorld().getPlayers()) {
                getNative(p).netServerHandler.sendPacket(packet);
            }
    
            with.world.addEntity(with);
            if (toreplace.passenger != null) toreplace.passenger.setPassengerOf(with);
        }    
    Code:
        public static MinecartMember get(Minecart m, MinecartGroup group) {
            //to prevent unneeded cart conversions
            EntityMinecart em = EntityUtil.getNative(m);
            if (em instanceof MinecartMember) {
                MinecartMember mm = (MinecartMember) em;
                mm.group = group;
                return mm;
            }
    
            //declare a new MinecartMember with the same characteristics as the previous EntityMinecart
            MinecartMember f = new MinecartMember(em.world, em.lastX, em.lastY, em.lastZ, em.type);
            f.group = group;
            EntityUtil.replaceMinecarts(em, f);
    
            replacedCarts.add(f);
            return f;
        }
    Important: don't forget to undo the entity replacement in onDisable or your entities could get lost forever. (is not stored on disk)
     
  5. Offline

    spoothie

    Wow. Thanks @bergerkiller, I'll try that tomorrow. :)
     
Thread Status:
Not open for further replies.

Share This Page