update mob behaviour for zombies and spooders
This commit is contained in:
@@ -30,6 +30,7 @@ import net.fretux.adaptivemobs.ai.goals.AdaptiveTargetPriorityGoal;
|
||||
import net.fretux.adaptivemobs.ai.goals.AdaptiveThreatMemoryGoal;
|
||||
import net.fretux.adaptivemobs.ai.goals.AdaptiveWardenTacticsGoal;
|
||||
import net.fretux.adaptivemobs.ai.goals.AdaptiveWitchTacticsGoal;
|
||||
import net.fretux.adaptivemobs.ai.goals.AdaptiveZombiePackTacticsGoal;
|
||||
import net.fretux.adaptivemobs.config.AMConfig;
|
||||
import net.fretux.adaptivemobs.difficulty.AdaptiveDifficultyManager;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -101,6 +102,7 @@ public final class AdaptiveGoalInjector {
|
||||
mob.goalSelector.addGoal(4, new AdaptiveFlankGoal(pathfinder, tier, 2, 8.0D, 1.0D, true));
|
||||
} else if (pathfinder != null && mob instanceof Zombie && AMConfig.AI_ZOMBIE.get()) {
|
||||
mob.goalSelector.addGoal(3, new AdaptiveFlankGoal(pathfinder, tier, 2, 2.5D, 1.05D, true));
|
||||
mob.goalSelector.addGoal(2, new AdaptiveZombiePackTacticsGoal((Zombie) mob, tier));
|
||||
} else if (pathfinder != null && mob instanceof Creeper creeper && AMConfig.AI_CREEPER.get()) {
|
||||
mob.goalSelector.addGoal(2, new AdaptiveCreeperPressureGoal(creeper, tier));
|
||||
mob.goalSelector.addGoal(4, new AdaptiveFlankGoal(pathfinder, tier, 2, 3.0D, 1.0D, false));
|
||||
@@ -141,7 +143,7 @@ public final class AdaptiveGoalInjector {
|
||||
mob.goalSelector.addGoal(8, new AdaptiveBiomeTacticsGoal(pathfinder, tier));
|
||||
}
|
||||
if (pathfinder != null && AMConfig.ENABLE_ANTI_CHEESE_AI.get()) {
|
||||
mob.goalSelector.addGoal(7, new AdaptiveAntiCheeseGoal(pathfinder, tier));
|
||||
mob.goalSelector.addGoal(mob instanceof Zombie ? 1 : 7, new AdaptiveAntiCheeseGoal(pathfinder, tier));
|
||||
}
|
||||
if (pathfinder != null && isRangedMob(mob) && rangedEnabled(mob)) {
|
||||
mob.goalSelector.addGoal(3, new AdaptiveRangedAttackGoal(pathfinder, tier, rangedOptimalRange(mob), 1.0D));
|
||||
@@ -158,8 +160,8 @@ public final class AdaptiveGoalInjector {
|
||||
}
|
||||
if (pathfinder != null && mob instanceof Spider && AMConfig.ENABLE_SPIDER_AI.get() && AMConfig.AI_SPIDER.get()) {
|
||||
mob.goalSelector.addGoal(3, new AdaptiveSpiderTacticsGoal(pathfinder, tier, mob instanceof CaveSpider));
|
||||
mob.goalSelector.addGoal(6, new AdaptiveSpiderDisengageGoal(pathfinder, tier, mob instanceof CaveSpider ? 4 : 5, 0.25D, 1.2D));
|
||||
mob.goalSelector.addGoal(7, new AdaptiveLowHealthRetreatGoal(pathfinder, tier, 4, 0.28D, 1.15D));
|
||||
mob.goalSelector.addGoal(2, new AdaptiveSpiderDisengageGoal(pathfinder, tier, mob instanceof CaveSpider ? 3 : 4, 0.14D, 1.3D));
|
||||
mob.goalSelector.addGoal(5, new AdaptiveLowHealthRetreatGoal(pathfinder, tier, 4, 0.38D, 1.15D));
|
||||
}
|
||||
if (mob instanceof Witch witch && AMConfig.ENABLE_WITCH_AI.get() && AMConfig.AI_WITCH.get()) {
|
||||
mob.goalSelector.addGoal(3, new AdaptiveWitchTacticsGoal(witch, tier));
|
||||
|
||||
@@ -38,16 +38,24 @@ public class AdaptiveAntiCheeseGoal extends Goal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
return AMConfig.ENABLE_ANTI_CHEESE_AI.get()
|
||||
&& tierSupplier.getAsInt() >= 3
|
||||
&& mob.getTarget() != null
|
||||
&& mob.getTarget().isAlive()
|
||||
&& --cooldown <= 0;
|
||||
if (!AMConfig.ENABLE_ANTI_CHEESE_AI.get() || tierSupplier.getAsInt() < 3) {
|
||||
return false;
|
||||
}
|
||||
LivingEntity target = mob.getTarget();
|
||||
if (target == null || !target.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
if (isInTrapVehicle() || isNearTrapVehicle()) {
|
||||
return true;
|
||||
}
|
||||
if (tierSupplier.getAsInt() >= 5 && mob instanceof Zombie && isVerticalObstacleCheese(target)) {
|
||||
return true;
|
||||
}
|
||||
return --cooldown <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
cooldown = 55 + mob.getRandom().nextInt(80);
|
||||
LivingEntity target = mob.getTarget();
|
||||
if (target == null) {
|
||||
return;
|
||||
@@ -55,8 +63,10 @@ public class AdaptiveAntiCheeseGoal extends Goal {
|
||||
mob.getLookControl().setLookAt(target, 30.0F, 30.0F);
|
||||
|
||||
if (avoidTrap()) {
|
||||
cooldown = 8 + mob.getRandom().nextInt(16);
|
||||
return;
|
||||
}
|
||||
cooldown = 55 + mob.getRandom().nextInt(80);
|
||||
if (mob instanceof Zombie && isVerticalObstacleCheese(target)) {
|
||||
if (tryCorpseLadderSurge(target)) {
|
||||
return;
|
||||
@@ -108,6 +118,16 @@ public class AdaptiveAntiCheeseGoal extends Goal {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInTrapVehicle() {
|
||||
Entity vehicle = mob.getVehicle();
|
||||
return vehicle instanceof Boat || vehicle instanceof AbstractMinecart;
|
||||
}
|
||||
|
||||
private boolean isNearTrapVehicle() {
|
||||
Entity trapVehicle = nearestTrapVehicle();
|
||||
return trapVehicle != null && mob.distanceToSqr(trapVehicle) < 2.9D;
|
||||
}
|
||||
|
||||
private Entity nearestTrapVehicle() {
|
||||
List<Entity> vehicles = mob.level().getEntitiesOfClass(Entity.class, mob.getBoundingBox().inflate(2.5D),
|
||||
entity -> entity instanceof Boat || entity instanceof AbstractMinecart);
|
||||
@@ -170,6 +190,7 @@ public class AdaptiveAntiCheeseGoal extends Goal {
|
||||
zombie -> zombie != mob
|
||||
&& zombie.isAlive()
|
||||
&& !zombie.isVehicle()
|
||||
&& !zombie.isPassenger()
|
||||
&& zombie.getTarget() == target
|
||||
&& Math.abs(zombie.getY() - mob.getY()) < 1.25D);
|
||||
Zombie bestCarrier = null;
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.function.IntSupplier;
|
||||
public class AdaptiveSpiderDisengageGoal extends Goal {
|
||||
|
||||
private static final int DISENGAGE_TICKS = 100;
|
||||
private static final double LOW_HEALTH_TRIGGER = 0.62D;
|
||||
|
||||
private final PathfinderMob mob;
|
||||
private final IntSupplier tierSupplier;
|
||||
@@ -23,6 +24,8 @@ public class AdaptiveSpiderDisengageGoal extends Goal {
|
||||
private final double triggerHealthLoss;
|
||||
private final double speed;
|
||||
private int cooldown;
|
||||
private int retreatTicks;
|
||||
private int pathRefreshTicks;
|
||||
private float lastHealth;
|
||||
|
||||
public AdaptiveSpiderDisengageGoal(PathfinderMob mob, IntSupplier tierSupplier,
|
||||
@@ -41,17 +44,31 @@ public class AdaptiveSpiderDisengageGoal extends Goal {
|
||||
float current = mob.getHealth();
|
||||
float lost = lastHealth - current;
|
||||
lastHealth = current;
|
||||
LivingEntity target = mob.getTarget();
|
||||
return AMConfig.AI_RETREAT_ENABLED.get()
|
||||
&& tierSupplier.getAsInt() >= minTier
|
||||
&& lost >= mob.getMaxHealth() * triggerHealthLoss
|
||||
&& mob.getTarget() != null
|
||||
&& mob.getTarget().isAlive()
|
||||
&& cooldown-- <= 0;
|
||||
&& target != null
|
||||
&& target.isAlive()
|
||||
&& !mob.hasEffect(MobEffects.REGENERATION)
|
||||
&& cooldown-- <= 0
|
||||
&& (lost >= mob.getMaxHealth() * triggerHealthLoss
|
||||
|| AdaptiveAIGoalUtils.healthFraction(mob) <= LOW_HEALTH_TRIGGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canContinueToUse() {
|
||||
LivingEntity target = mob.getTarget();
|
||||
return retreatTicks > 0
|
||||
&& target != null
|
||||
&& target.isAlive()
|
||||
&& AdaptiveAIGoalUtils.healthFraction(mob) < 0.95D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
cooldown = 110 + mob.getRandom().nextInt(90);
|
||||
cooldown = 55 + mob.getRandom().nextInt(45);
|
||||
retreatTicks = DISENGAGE_TICKS;
|
||||
pathRefreshTicks = 0;
|
||||
LivingEntity target = mob.getTarget();
|
||||
if (target == null) {
|
||||
return;
|
||||
@@ -59,8 +76,32 @@ public class AdaptiveSpiderDisengageGoal extends Goal {
|
||||
mob.addEffect(new MobEffectInstance(MobEffects.INVISIBILITY, DISENGAGE_TICKS, 0));
|
||||
mob.addEffect(new MobEffectInstance(MobEffects.REGENERATION, DISENGAGE_TICKS, 4));
|
||||
|
||||
Vec3 dest = AdaptivePositioningUtils.retreatPosition(mob, target, 5.0D);
|
||||
mob.getNavigation().moveTo(dest.x, dest.y, dest.z, speed);
|
||||
retreatFrom(target);
|
||||
AdaptiveAIGoalUtils.debug(mob, tierSupplier, "spider invisible regeneration disengage");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
LivingEntity target = mob.getTarget();
|
||||
if (target == null) {
|
||||
return;
|
||||
}
|
||||
retreatTicks--;
|
||||
mob.getLookControl().setLookAt(target, 30.0F, 30.0F);
|
||||
if (pathRefreshTicks-- <= 0) {
|
||||
pathRefreshTicks = 12;
|
||||
retreatFrom(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
retreatTicks = 0;
|
||||
pathRefreshTicks = 0;
|
||||
}
|
||||
|
||||
private void retreatFrom(LivingEntity target) {
|
||||
Vec3 dest = AdaptivePositioningUtils.retreatPosition(mob, target, 5.0D);
|
||||
mob.getNavigation().moveTo(dest.x, dest.y, dest.z, speed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user