How to make an entity undeadable?

Discussion in 'Plugin Development' started by Woulfiee, Nov 14, 2015.

Thread Status:
Not open for further replies.
  1. Hi there,
    I want to protect my custom entity but everyone can kill it. I tried to loop setting health to max, I tried to protect it with events but it could still die.
    How to protect it? Or is there any method which makes the entity undeadable?
     
    Last edited: Nov 14, 2015
  2. Offline

    teej107

  3. @Michał Kolo you can show your code here or not..? would help by seeing it was you extaclty doing..
     
  4. @PeterXonwiiXx Sure, this is the Main:
    Code:
    package me.doge.tutorial.core;
    
    import static org.bukkit.ChatColor.BOLD;
    import static org.bukkit.ChatColor.GREEN;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.entity.EntityDamageEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import net.minecraft.server.v1_8_R3.EntityVillager;
    
    public class Main extends JavaPlugin implements Listener {
    
        public static ItemStack NPC;
    
        @Override
        public void onEnable() {
            NMSUtil nmsu = new NMSUtil();
            Bukkit.getPluginManager().registerEvents(this, this);
            nmsu.registerEntity("TUTORIAL", 120, EntityVillager.class, CustomEntityNPC.class);
            NPC = new ItemStack(Material.MONSTER_EGG, 1, (short) 120);
            ItemMeta npcMeta = NPC.getItemMeta();
            npcMeta.setDisplayName(GREEN + "" + BOLD + "TUTORIAL");
            NPC.setItemMeta(npcMeta);
        }
    
        @EventHandler
        public void onPlayerNPCSpawn(PlayerInteractEvent e) {
            if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if (e.getPlayer().getItemInHand() == NPC
                        && e.getPlayer().getItemInHand().getItemMeta().equals(NPC.getItemMeta())) {
                    CustomEntityNPC.spawn(e.getPlayer().getLocation());
                }
            }
        }
    
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent e) {
            if (e.getPlayer().getDisplayName().equals("Doge3")) {
                e.getPlayer().getInventory().addItem(NPC);
            }
        }
    }
    
    CustomEntityNPC:
    Code:
    package me.doge.tutorial.core;
    
    import java.lang.reflect.Field;
    import java.util.List;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
    import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
    import org.bukkit.entity.Villager;
    import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
    
    import net.minecraft.server.v1_8_R3.EntityHuman;
    import net.minecraft.server.v1_8_R3.EntityVillager;
    import net.minecraft.server.v1_8_R3.GenericAttributes;
    import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget;
    import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer;
    import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround;
    import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll;
    import net.minecraft.server.v1_8_R3.PathfinderGoalSelector;
    import net.minecraft.server.v1_8_R3.World;
    
    public class CustomEntityNPC extends EntityVillager {
       
    
    
    
        @SuppressWarnings("rawtypes")
        public CustomEntityNPC(World world) {
            super(world);
           
           
            List goalB = (List)getPrivateField("b", PathfinderGoalSelector.class, goalSelector); goalB.clear();
            List goalC = (List)getPrivateField("c", PathfinderGoalSelector.class, goalSelector); goalC.clear();
            List targetB = (List)getPrivateField("b", PathfinderGoalSelector.class, targetSelector); targetB.clear();
            List targetC = (List)getPrivateField("c", PathfinderGoalSelector.class, targetSelector); targetC.clear();
           
            this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 0.0F));
            this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 1000.0F));
            this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
            this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
           
           
        }
       
        @Override
        public void g(double d0, double d1, double d2) {
            return;
        }
       
        @SuppressWarnings("rawtypes")
        public static Object getPrivateField(String fieldName, Class clazz, Object object)
        {
            Field field;
            Object o = null;
    
            try
            {
                field = clazz.getDeclaredField(fieldName);
    
                field.setAccessible(true);
    
                o = field.get(object);
            }
            catch(NoSuchFieldException e)
            {
                e.printStackTrace();
            }
            catch(IllegalAccessException e)
            {
                e.printStackTrace();
            }
    
            return o;
        }
    
        protected void initAttributes() {
            super.initAttributes();
            this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D);
            this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.0F);
            this.setCustomName(ChatColor.GREEN + "TUTORIAL");
            this.setCustomNameVisible(true);
        }
       
    
        public static Villager spawn(Location loc) {
            World mcWorld = ((CraftWorld) loc.getWorld()).getHandle();
            final CustomEntityNPC customEntity = new CustomEntityNPC(mcWorld);
            customEntity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
            ((CraftLivingEntity) customEntity.getBukkitEntity()).setRemoveWhenFarAway(false);
            mcWorld.addEntity(customEntity, SpawnReason.CUSTOM);
            return (Villager) customEntity.getBukkitEntity();
        }
    }
    
    NMSUtil:
    Code:
    package me.doge.tutorial.core;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    import net.minecraft.server.v1_8_R3.EntityInsentient;
    import net.minecraft.server.v1_8_R3.EntityTypes;
    
    public class NMSUtil {
    
        public void registerEntity(String name, int id, Class<? extends EntityInsentient> nmsClass,
                Class<? extends EntityInsentient> customClass) {
            try {
                List<Map<?, ?>> dataMap = new ArrayList<Map<?, ?>>();
    
                for (Field f : EntityTypes.class.getDeclaredFields()) {
    
                    if (f.getType().getSimpleName().equals(Map.class.getSimpleName())) {
                        f.setAccessible(true);
                        dataMap.add((Map<?, ?>) f.get(null));
                    }
    
                }
    
                if (dataMap.get(2).containsKey(id)) {
                    dataMap.get(0).remove(name);
                    dataMap.get(2).remove(id);
                }
                Method method = EntityTypes.class.getDeclaredMethod("a", Class.class, String.class, int.class);
                method.setAccessible(true);
                method.invoke(null, customClass, name, id);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
     
  5. Offline

    Scimiguy

    I don't see anywhere there that you're tracking EntityDamageEvent
     
  6. Offline

    teej107

    I do think it's possible to do it with NMS as well. But seeing as I rarely touch NMS and I haven't done any custom mobs at all, I can't help.
     
  7. Offline

    Scimiguy

    @teej107
    It's doable
    I have a custom mobs plugin that I've been working on (think DiabloMobs for forge, but with CustomAI aswell), and it handles just fine with EventHandling
     
  8. Offline

    teej107

    That wasn't my point. I was saying that there may be a way to do it with a custom mob without listening for events.
     
  9. Offline

    Scimiguy

  10. Offline

    dlange

    The way i normally do it, is just test for the NPC. You can do this by looking for it's custom name and entity type, which should narrow it down to 1/2 entities (depending if you give multiple ones the same name)

    Try listening to EntityDamageEvent, and then testing if e.getEntity() instanceof CustomEntityNPC and then checking to see if it has a custom display name visible, if so is the name "Stuart"? if so, cancel the event.
     
    Woulfiee likes this.
Thread Status:
Not open for further replies.

Share This Page