Preventing an Entity from moving or pushing

Discussion in 'Spigot Plugin Development' started by bman7842, May 10, 2015.

  1. I am currently working on an Entity Command Script, my issue is preventing the Entity from moving. My first idea was to save all the Entity's I spawned in a HashMap storing the Entity and the Location, then there would be a loop and everytime the entity's location was not equal to the one in the HashMap it would teleport them back. My problem is I don't think this is the most effective or efficient way. If this is the only way, an example would be appreciated. Otherwise, if you know a better way please do tell me! I want to make sure this is running as efficient as possible, a loop that continues to refresh every second just seems inefficient or very laggy so I don't think it is the best way.

    Here is the code, I don't have the loop system implemented yet (I'm currently coding it and testing it now, I only posted this thread for advice), this is the method that spawns the mob.
    Code (Text):
    public static void spawnNPC(Player p, String type)
        {
            World world = p.getWorld();
            Location l = p.getLocation();
            if (type.equalsIgnoreCase("villager"))
            {
                world.spawnCreature(l, EntityType.VILLAGER);
            } else if (type.equalsIgnoreCase("slime")) {
                world.spawnCreature(l, EntityType.VILLAGER);
            } else {
                Utils.sendErrorMessage(p.getUniqueId(), "Invalid mob type, this plugin does not support this mob or this mob does not exist!");
            }
        }
     
  2. There are many options:

    1. Save the villager and its position to a hashmap. Use a scheduler to make sure he hasn't moved.
    2. Use NMS, fairly efficient, and easy to learn.
     
  3. What exactly is NMS? Sorry, I'm not familiar to the name.
     
  4. Serializator

    Supporter

    There is a NoAI tag in Minecraft, try to add it to the entity.
     
    • Agree Agree x 1
  5. Use this
    Code (Text):
      public void freezeEntity(Entity en){
          net.minecraft.server.v1_8_R2.Entity nmsEn = ((CraftEntity) en).getHandle();
          NBTTagCompound compound = new NBTTagCompound();
          nmsEn.c(compound);
          compound.setByte("NoAI", (byte) 1);
          nmsEn.f(compound);
      }
    Put this on the onEnable()
    Code (Text):
          for(World w: Bukkit.getWorlds()){
              for(Entity en : w.getEntities()){
                  if(en instanceof Creature && !(en instanceof Player)){
                      freezeEntity(en);
                  }
              }
          }
     
  6. This works (nvm my last reply if you saw it), my only issue is the user is still able to damage the frozen entity. Should I use the EntityDamageEvent and set it to canceled?
     
  7. Yes, just check and make sure the entity is one of your frozen entities and cancel the event.
     
  8. Sounds good, thanks for the help!
     
  9. No problem, be sure to post again if you need help.
     
    • Optimistic Optimistic x 1
  10. Do you have this code with NMS Reflections? Would be really important for me :)

    Thanks!
     
  11. Sorry to bump, but setting NoAI to 1 prevents any events related to that particular entity from being called, at least for me. Note this is in 1.11.2. Any tips?
     
  12. Because it doesn't do anything when it doesn't have an AI? That's literally the point.