Advertisement
Jetp250

CustomZombie - NMS Mob Example

Apr 23rd, 2017
504
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Requires NMSUtils to be available! https://pastebin.com/V6G1B4cg
  2. // Make sure you implement IRangedEntity if you want to make the mob shoot arrows!
  3. public class CustomZombie extends EntityZombie implements IRangedEntity {
  4.  
  5.     public CustomZombie(World world) {
  6.         super(world);
  7.     }
  8.  
  9.     @Override
  10.     protected void initAttributes() {
  11.         // Calling the super method for the rest of the attributes.
  12.         super.initAttributes();
  13.         // Next, overriding armor and max health!
  14.         // Setting the max health to 40:
  15.         this.getAttributeInstance(Attributes.MAX_HEALTH.getValue()).setValue(40.0);
  16.         // Setting the 'defense' (armor) to 5:
  17.         this.getAttributeInstance(Attributes.ARMOR.getValue()).setValue(5.0);
  18.     }
  19.  
  20.     @Override
  21.     protected void r() {
  22.         // Adding our custom pathfinder selectors.
  23.         // Grants our zombie the ability to swim.
  24.         this.goalSelector.a(0, new PathfinderGoalFloat(this));
  25.         // This causes our zombie to shoot arrows.
  26.         // The parameters are: The ranged entity, movement speed, cooldown,
  27.         // maxDistance
  28.         // Or, with the second constructor: The ranged entity, movement speed,
  29.         // mincooldown, maxcooldown, maxDistance
  30.         this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0, 12, 20));
  31.         // Gets our zombie to attack creepers and skeletons!
  32.         this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityCreeper.class, true));
  33.         this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntitySkeleton.class, true));
  34.         // Causes our zombie to walk towards it restriction.
  35.         this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0));
  36.         // Causes the zombie to walk around randomly.
  37.         this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0));
  38.         // Causes the zombie to look at players. Optional in our case. Last
  39.         // argument is range.
  40.         this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0f));
  41.         // Causes the zombie to randomly look around.
  42.         this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
  43.     }
  44.  
  45.     @Override
  46.     public void a(final EntityLiving target, final float f) {
  47.         // Preparing the projectile
  48.         final EntityArrow entityarrow = this.prepareProjectile(f);
  49.         // Calculating the motion for the arrow to hit
  50.         final double motX = target.locX - this.locX;
  51.         final double motY = target.getBoundingBox().b + target.length / 3.0f - entityarrow.locY;
  52.         final double motZ = target.locZ - this.locZ;
  53.         final double horizontalMot = MathHelper.sqrt(motX * motX + motZ * motZ);
  54.         // 'Shooting' the projectile (aka preparing it for being added to the
  55.         // world.)
  56.         entityarrow.shoot(motX, motY + horizontalMot * 0.2, motZ, 1.6f, 14 - world.getDifficulty().a() * 4);
  57.  
  58.         // OPTIONAL! Calls the event for shooting, that can be cancelled. I'd
  59.         // keep it for other plugins that could cancel it.
  60.         final EntityShootBowEvent event = CraftEventFactory.callEntityShootBowEvent(this, this.getItemInMainHand(),
  61.                 entityarrow, 0.8f);
  62.         if (event.isCancelled()) {
  63.             event.getProjectile().remove();
  64.             return;
  65.         }
  66.         // Checking if the projectile has been changed thru the event..
  67.         if (event.getProjectile() == entityarrow.getBukkitEntity()) {
  68.             this.world.addEntity(entityarrow);
  69.         }
  70.         // And last, playing the shooting sound.
  71.         this.a(SoundEffects.fV, 1.0f, 1.0f / (this.getRandom().nextFloat() * 0.4f + 0.8f));
  72.     }
  73.  
  74.     protected EntityArrow prepareProjectile(final float unknown) {
  75.         // Creating the arrow instance. Now, you see, it's a Tipped Arrow. No
  76.         // idea why, but EntityArrow is abstract and we can't instantiate it
  77.         // without creating a custom class.
  78.         // This is why the arrows nowadays have the odd particle effect!
  79.         final EntityArrow arrow = new EntityTippedArrow(this.world, this);
  80.         // No idea what this does, copied from the sourcecode
  81.         arrow.a(this, unknown);
  82.         return arrow;
  83.     }
  84.  
  85.     @Override
  86.     public GroupDataEntity prepare(DifficultyDamageScaler dds, GroupDataEntity gde) {
  87.         // Calling the super method FIRST, so in case it changes the equipment,
  88.         // our equipment overrides it.
  89.         gde = super.prepare(dds, gde);
  90.         // We'll set the main hand to a bow and head to a pumpkin now!
  91.         this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.BOW));
  92.         this.setSlot(EnumItemSlot.HEAD, new ItemStack(Blocks.PUMPKIN));
  93.         // Last, returning the GroupDataEntity called gde.
  94.         return gde;
  95.     }
  96. }
Advertisement
RAW Paste Data Copied
Advertisement