As an enhancement to the mob already implemented in #63, the behaviour defined in MoveAwayFromPlayerGoal.java should be changed to make a mob run away from a player instead of just running around (as inherited from the class PanicGoal). An attempt was made to do just that --- see code below --- but thus far resulted in non-satisfactory results. The most prominent problem with the solution below is that a mob's body will sometimes make a full 180° turn, while the mob's direction remains unchanged.
Todo:
[ ] Choose a random angle when moving away from a player (in the range of [-α, directly away, α])
package org.crumbleworks.forge.aTFC.content.entities.goals;
import java.util.EnumSet;
import net.minecraft.entity.MobEntity;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.vector.Vector3d;
/**
* Goal which makes a mob move away from a player if they get too close.
*/
public class MoveAwayFromPlayerGoal extends Goal {
private MobEntity mob;
private double minDistance;
private double speed;
protected final float probability;
/**
* @param mob
* A mob entity
* @param minDistance
* Minimum distance to player. If the actual distance is lower
* than this value, the mob will start to move away from the
* player.
* @param speed
* Speed with which {@code mob} moves away from the player
*/
public MoveAwayFromPlayerGoal(MobEntity mob, double minDistance,
double speed) {
this.mob = mob;
this.minDistance = minDistance;
this.speed = speed;
probability = 0.8f;
setMutexFlags(EnumSet.of(Goal.Flag.MOVE));
}
@Override
public boolean shouldExecute() {
return mob.world.getClosestPlayer(mob, minDistance) != null;
}
@Override
public void tick() {
PlayerEntity closestPlayer = mob.world.getClosestPlayer(mob,
minDistance);
Vector3d mobPosition = mob.getPositionVec();
Vector3d playerPosition = closestPlayer.getPositionVec();
Vector3d targetPosition = playerPosition.subtract(mobPosition)
.normalize().inverse().mul(minDistance, 1.0, minDistance);
if(mob.getRNG().nextFloat() >= probability) {
float randomYawAngle = (float) (Math.random()
* (10.0 - (-10.0) + 1)
+ -10.0);
targetPosition = targetPosition
.rotateYaw((float)Math.PI / randomYawAngle);
}
targetPosition = targetPosition.add(mobPosition);
mob.getNavigator().tryMoveToXYZ(targetPosition.getX(),
mobPosition.getY(), targetPosition.getZ(), speed);
}
}
Definitions of goals used:
@Override
protected void registerGoals() {
goalSelector.addGoal(0, new MoveAwayFromPlayerGoal(this, 10d, 1.25d));
goalSelector.addGoal(1, new SwimGoal(this));
goalSelector.addGoal(3, new PanicGoal(this, 1.4D));
goalSelector.addGoal(4, new BreedGoal(this, 1.0D));
goalSelector.addGoal(5, new TemptGoal(this, 1.0D, false, TEMPTATION_ITEMS));
goalSelector.addGoal(6, new FollowParentGoal(this, 1.1D));
goalSelector.addGoal(7, new WaterSeekingRandomWalkingGoal(this, 1.0D));
goalSelector.addGoal(8, new LookAtGoal(this, PlayerEntity.class, 6.0F));
goalSelector.addGoal(9, new LookRandomlyGoal(this));
}
As an enhancement to the mob already implemented in #63, the behaviour defined in
MoveAwayFromPlayerGoal.java
should be changed to make a mob run away from a player instead of just running around (as inherited from the classPanicGoal
). An attempt was made to do just that --- see code below --- but thus far resulted in non-satisfactory results. The most prominent problem with the solution below is that a mob's body will sometimes make a full 180° turn, while the mob's direction remains unchanged.Todo:
Definitions of goals used: