首次提交 AutoDig Mod

这个提交包含在:
lyizai
2026-08-20 21:04:27 +08:00
当前提交 95c4e97db0
共修改 26 个文件,包含 1851 行新增和 0 行删除
@@ -0,0 +1,95 @@
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;
/**
* 杀戮光环服务。
*
* <p>在开关开启时,自动攻击以玩家为中心、指定半径内最近的敌对生物
* ({@link Monster})。攻击前会转向目标方向;"安全模式"开启时,
* 玩家生命过低则停止攻击、保命优先。</p>
*/
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);
}
}