Files
AdapativeMobs/src/main/java/net/fretux/adaptivemobs/ai/AdaptiveMobHooks.java
T
2026-06-29 15:59:48 +02:00

72 lines
3.1 KiB
Java

package net.fretux.adaptivemobs.ai;
import net.fretux.adaptivemobs.config.AMConfig;
import net.fretux.adaptivemobs.difficulty.AdaptiveDifficultyManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.monster.AbstractSkeleton;
import net.minecraft.world.entity.monster.Pillager;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
public final class AdaptiveMobHooks {
private AdaptiveMobHooks() {
}
public static void onProjectileJoin(EntityJoinLevelEvent event) {
if (!AMConfig.enabled || !AMConfig.AI_ENABLED.get() || !AMConfig.ENABLE_ADVANCED_AI.get()
|| !AMConfig.ENABLE_RANGED_AI.get() || !(event.getLevel() instanceof ServerLevel level)) {
return;
}
Entity entity = event.getEntity();
if (!(entity instanceof Projectile projectile) || !(projectile.getOwner() instanceof Mob mob)) {
return;
}
LivingEntity target = mob.getTarget();
if (target == null || !target.isAlive()) {
return;
}
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
if (tier <= 1) {
return;
}
if (tier >= 3 && AdaptiveAIGoalUtils.isBlockingShield(target) && mob.getRandom().nextFloat() < 0.45F) {
projectile.setDeltaMovement(projectile.getDeltaMovement().scale(0.94D));
AdaptiveAIGoalUtils.debug(mob, () -> tier, "shield-blocked shot softened");
return;
}
if (tier >= 4 && AdaptiveTargetingUtils.hasAllyBetween(mob, target, 0.8D)) {
projectile.setDeltaMovement(projectile.getDeltaMovement().scale(0.90D));
AdaptiveAIGoalUtils.debug(mob, () -> tier, "ally in ranged line");
return;
}
double accuracy = AMConfig.tierValue(AMConfig.AI_ACCURACY_BONUS.get(), tier);
if (accuracy <= 0.0D) {
return;
}
double lead = tier >= 5 ? AMConfig.tierValue(AMConfig.AI_INTERCEPTION_STRENGTH.get(), tier) : 0.0D;
Vec3 aim = AdaptivePositioningUtils.predictedPosition(target, lead)
.add(0.0D, target.getBbHeight() * aimHeight(mob, target, tier), 0.0D);
Vec3 wanted = aim.subtract(projectile.position()).normalize().scale(projectile.getDeltaMovement().length());
Vec3 blended = projectile.getDeltaMovement().scale(1.0D - accuracy).add(wanted.scale(accuracy));
projectile.setDeltaMovement(blended);
AdaptiveAIGoalUtils.debug(mob, () -> tier, "projectile aim adjusted");
}
private static double aimHeight(Mob mob, LivingEntity target, int tier) {
if ((mob instanceof AbstractSkeleton || mob instanceof Pillager) && tier >= 4) {
double chance = AMConfig.tierValue(AMConfig.AI_HEADSHOT_CHANCE.get(), tier);
if (mob.getRandom().nextDouble() < chance) {
return 0.82D;
}
}
return 0.55D;
}
}