fix various issues

This commit is contained in:
2026-07-20 23:31:22 +02:00
parent afd98209f1
commit cea3fd19d0
5 changed files with 49 additions and 9 deletions
@@ -16,6 +16,10 @@ public final class AdaptiveTargetingUtils {
private AdaptiveTargetingUtils() {
}
public static boolean areCombatAllies(Mob first, Mob second) {
return first.isAlliedTo(second) || second.isAlliedTo(first) || first.getType() == second.getType();
}
public static List<Mob> nearbyHostiles(Mob mob, double radius, Predicate<Mob> predicate) {
AABB box = mob.getBoundingBox().inflate(radius);
List<Mob> found = mob.level().getEntitiesOfClass(Mob.class, box,
@@ -46,7 +50,8 @@ public final class AdaptiveTargetingUtils {
return false;
}
List<Mob> allies = nearbyHostiles(mob, Math.min(16.0D, Math.sqrt(lenSqr) + 2.0D),
other -> other.getTarget() == target || other.getTarget() == null);
other -> areCombatAllies(mob, other)
&& (other.getTarget() == target || other.getTarget() == null));
for (Mob ally : allies) {
Vec3 toAlly = ally.position().add(0.0D, ally.getBbHeight() * 0.5D, 0.0D).subtract(start);
double t = toAlly.dot(line) / lenSqr;
@@ -3,6 +3,7 @@ package net.fretux.adaptivemobs.ai.goals;
import net.fretux.adaptivemobs.ai.AdaptiveAIGoalUtils;
import net.fretux.adaptivemobs.ai.AdaptivePositioningUtils;
import net.fretux.adaptivemobs.config.AMConfig;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.monster.MagmaCube;
@@ -147,6 +148,7 @@ public class AdaptiveSlimeTacticsGoal extends Goal {
LivingEntity inheritedTarget = AdaptiveAIGoalUtils.isValidAdaptiveTarget(slime.getTarget())
? slime.getTarget() : partner.getTarget();
float healthFraction = slime.getHealth() / slime.getMaxHealth();
absorbPartnerState(partner);
partner.discard();
slime.setSize(Math.min(MAX_RECOMBINE_SIZE, slime.getSize() * 2), false);
slime.setHealth(Math.max(1.0F, Math.min(slime.getMaxHealth(), slime.getMaxHealth() * healthFraction)));
@@ -159,6 +161,29 @@ public class AdaptiveSlimeTacticsGoal extends Goal {
return true;
}
private void absorbPartnerState(Slime partner) {
if (!slime.hasCustomName() && partner.hasCustomName()) {
slime.setCustomName(partner.getCustomName());
slime.setCustomNameVisible(partner.isCustomNameVisible());
}
if (partner.isPersistenceRequired()) {
slime.setPersistenceRequired();
}
partner.getActiveEffects().forEach(effect ->
slime.addEffect(new net.minecraft.world.effect.MobEffectInstance(effect)));
for (EquipmentSlot slot : EquipmentSlot.values()) {
if (slime.getItemBySlot(slot).isEmpty() && !partner.getItemBySlot(slot).isEmpty()) {
slime.setItemSlot(slot, partner.getItemBySlot(slot).copy());
}
}
slime.getPersistentData().merge(partner.getPersistentData().copy());
slime.getPersistentData().remove(RECOMBINE_CLAIM_KEY);
slime.getPersistentData().remove(RECOMBINE_CLAIM_EXPIRES_KEY);
if (partner.isLeashed() && partner.getLeashHolder() != null) {
slime.setLeashedTo(partner.getLeashHolder(), true);
}
}
private boolean validPartner(Slime partner, boolean requireClaim) {
if (partner == null || partner == slime || !partner.isAlive() || !slime.isAlive()
|| tierSupplier.getAsInt() < 5 || slime.getSize() >= MAX_RECOMBINE_SIZE
@@ -203,8 +228,6 @@ public class AdaptiveSlimeTacticsGoal extends Goal {
private void scheduleRecombine(int delayTicks) {
if (slime.getPersistentData().getLong(RECOMBINE_READY_AT_KEY) == 0L) {
slime.getPersistentData().putLong(RECOMBINE_READY_AT_KEY, slime.level().getGameTime() + delayTicks);
} else if (slime.getSize() > 1) {
slime.getPersistentData().putLong(RECOMBINE_READY_AT_KEY, slime.level().getGameTime() + delayTicks);
}
}
}
@@ -50,7 +50,9 @@ public class AdaptiveMobsEvents {
@SubscribeEvent
public void onLivingDeath(LivingDeathEvent event) {
LivingEntity killed = event.getEntity();
if (!(event.getSource().getEntity() instanceof ServerPlayer player)) {
ServerPlayer player = event.getSource().getEntity() instanceof ServerPlayer directPlayer
? directPlayer : killed.getKillCredit() instanceof ServerPlayer creditedPlayer ? creditedPlayer : null;
if (player == null) {
return;
}
AdaptiveDifficultyManager.recordKill(player, killed);
@@ -77,7 +79,7 @@ public class AdaptiveMobsEvents {
return;
}
int tier = AdaptiveDifficultyManager.getMobTier(level, victim.getType());
if (!attacker.isAlliedTo(victim) && !victim.isAlliedTo(attacker)) {
if (!net.fretux.adaptivemobs.ai.AdaptiveTargetingUtils.areCombatAllies(attacker, victim)) {
return;
}
if (tier < 2 || !AMConfig.isMobEnabled(victim.getType())) {
@@ -165,8 +167,7 @@ public class AdaptiveMobsEvents {
}
Entity entity = event.getEntity();
if (AMConfig.enabled && entity instanceof Mob mob && mob instanceof Enemy
&& AMConfig.isMobEnabled(mob.getType())
&& mob.getPersistentData().getBoolean(PENDING_SPAWN_PROCESSING_KEY)) {
&& AMConfig.isMobEnabled(mob.getType())) {
mob.getPersistentData().remove(PENDING_SPAWN_PROCESSING_KEY);
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
MobStatScaler.applyScaling(mob, tier);
@@ -204,6 +205,18 @@ public class AdaptiveMobsEvents {
@SubscribeEvent
public void onServerTick(TickEvent.ServerTickEvent event) {
AdaptiveSpecialAbilities.onServerTick(event);
if (event.phase == TickEvent.Phase.END && AMConfig.enabled
&& event.getServer().getTickCount() % 100 == 0) {
for (ServerLevel level : event.getServer().getAllLevels()) {
for (Entity entity : level.getAllEntities()) {
if (entity instanceof Mob mob && mob instanceof Enemy && AMConfig.isMobEnabled(mob.getType())) {
int tier = AdaptiveDifficultyManager.getMobTier(level, mob.getType());
MobStatScaler.applyScaling(mob, tier);
GearScaler.applyGear(mob, tier);
}
}
}
}
}
@SubscribeEvent
@@ -37,10 +37,10 @@ public final class GearScaler {
if (mob.getPersistentData().getBoolean(GEAR_APPLIED_KEY)) {
return;
}
mob.getPersistentData().putBoolean(GEAR_APPLIED_KEY, true);
if (!AMConfig.GEAR_SCALING_ENABLED.get() || tier <= 0) {
return;
}
mob.getPersistentData().putBoolean(GEAR_APPLIED_KEY, true);
RandomSource random = mob.getRandom();
if (mob instanceof AbstractSkeleton skeleton) {
@@ -32,7 +32,6 @@ public final class MobStatScaler {
*/
public static void applyScaling(Mob mob, int tier) {
if (!AMConfig.STAT_SCALING_ENABLED.get() || tier <= 0) {
AdaptiveMobData.markScaled(mob, Math.max(tier, 0));
return;
}
if (AdaptiveMobData.isScaled(mob)) {