package autodig.client.service; import autodig.client.config.DigConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.Monster; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; /** * 杀戮光环服务。 * *

在开关开启时,自动攻击以玩家为中心、指定半径内最近的敌对生物 * ({@link Monster})。攻击前会转向目标方向;"安全模式"开启时, * 玩家生命过低则停止攻击、保命优先。

*/ public final class KillAura { /** 攻击节流:每 N tick 才允许挥一刀,避免疯狂连点 */ private int attackCooldownTicks; /** * 每帧调用。执行杀戮光环逻辑(开关关闭时直接返回)。 * * @param config 挖矿配置 */ public void tick(DigConfig config) { MinecraftClient client = MinecraftClient.getInstance(); if (client.player == null || client.world == null || client.interactionManager == null) { return; } if (!config.killAura) { return; } net.minecraft.entity.player.PlayerEntity player = client.player; if (player.isDead()) { return; } // 安全模式:血线过低不出击 if (config.killAuraSafe) { double health = player.getHealth() / Math.max(player.getMaxHealth(), 1.0) * 100.0; if (health < config.healthFleeThreshold) { return; } } // 挥刀节流 if (this.attackCooldownTicks > 0) { this.attackCooldownTicks--; return; } // 攻击冷却未转好则等待 if (player.getAttackCooldownProgress(0.5f) < 1.0f) { return; } Entity target = this.findNearestHostile(client, player, config.killRange); if (target == null) { return; } // 转向目标 this.faceEntity(player, target); client.interactionManager.attackEntity(player, target); this.attackCooldownTicks = 4; // 约 4 tick 一刀 } /** 在玩家周围范围内找最近的敌对生物。 */ private Entity findNearestHostile(MinecraftClient client, LivingEntity player, double range) { range = Math.max(2.0, range); Box box = player.getBoundingBox().expand(range); Entity best = null; double bestDist = Double.MAX_VALUE; for (Entity e : client.world.getEntitiesByClass(Entity.class, box, e -> e instanceof Monster && e.isAlive())) { double d = e.squaredDistanceTo(player); if (d < bestDist) { bestDist = d; best = e; } } return best; } /** 让玩家面朝向实体。 */ private void faceEntity(LivingEntity player, Entity target) { Vec3d p = player.getEyePos(); Vec3d t = target.getEyePos(); double dx = t.x - p.x; double dy = t.y - p.y; double dz = t.z - p.z; double d = Math.sqrt(dx * dx + dz * dz); float yaw = (float) (Math.toDegrees(Math.atan2(dz, dx)) - 90.0); float pitch = (float) (-Math.toDegrees(Math.atan2(dy, Math.max(d, 0.0001)))); player.setYaw(yaw); player.setPitch(pitch); } }