How to set mob provocation

Started by Trutty on

Topic category: Help with MCreator software

Joined May 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
How to set mob provocation

Currently trying to make a mob that is hostile if a player's hunger bar is below a certain threshold, but is otherwise neutral (In the same way that spiders do not inherently attack during the day). However, I cannot figure out how to create a neutral mob that is provoked by anything outside of a direct attack/How to go about making that sort of check in general.

Joined Sep 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Here are two options I can…
Sun, 05/31/2020 - 17:21

Here are two options I can think of,

Option 1: on LivingSetAttackTargetEvent you can check if the target is a player and check the player's food level you get the point. That will look something like this,

    public static void OnAttackTarget(LivingSetAttackTargetEvent event) {
        Entity entityTarget = event.getTarget();
        Entity entity = event.getEntity();
        if (entity instanceof YourMob && entityTarget instanceof PlayerEntity && !entity.world.isRemote) {
            PlayerEntity playerEntity = (PlayerEntity) entityTarget;
            if (playerEntity.getFoodStats().getFoodLevel() >= 3) {
                ((MobEntity) entity).setAttackTarget(null);
                ((MobEntity) entity).setAggroed(false);
            }
        }
    }

Option 2: You said want your mob to kinda be like a spider but with a few exceptions so this is how spider does it :D,

   static class TargetGoal<T extends LivingEntity> extends NearestAttackableTargetGoal<T> {
      public TargetGoal(SpiderEntity spider, Class<T> classTarget) {
         super(spider, classTarget, true);
      }

      /**
       * Returns whether execution should begin. You can also read and cache any state necessary for execution in this
       * method as well.
       */
      public boolean shouldExecute() {
         float f = this.goalOwner.getBrightness();
         return f >= 0.5F ? false : super.shouldExecute();
      }
   }

This is also important,

   static class AttackGoal extends MeleeAttackGoal {
      public AttackGoal(SpiderEntity spider) {
         super(spider, 1.0D, true);
      }

      /**
       * Returns whether execution should begin. You can also read and cache any state necessary for execution in this
       * method as well.
       */
      public boolean shouldExecute() {
         return super.shouldExecute() && !this.attacker.isBeingRidden();
      }

      /**
       * Returns whether an in-progress EntityAIBase should continue executing
       */
      public boolean shouldContinueExecuting() {
         float f = this.attacker.getBrightness();
         if (f >= 0.5F && this.attacker.getRNG().nextInt(100) == 0) {
            this.attacker.setAttackTarget((LivingEntity)null);
            return false;
         } else {
            return super.shouldContinueExecuting();
         }
      }

      protected double getAttackReachSqr(LivingEntity attackTarget) {
         return (double)(4.0F + attackTarget.getWidth());
      }
   }

 

 

To break this down, the SpiderEntity creates it's own target methods and attack methods. So why not create your own attack methods and target methods. This is actually the "correct" way of doing it so I would do this instead of Option 1. Even though Option 1 seems simpler.