Add free-fall prediction

This commit is contained in:
Redstone1024 2024-09-01 21:39:30 +08:00
parent 8dd456a9da
commit 1ea052c356

View File

@ -11,7 +11,6 @@ import meteordevelopment.meteorclient.utils.Utils;
import meteordevelopment.meteorclient.utils.entity.EntityUtils;
import meteordevelopment.meteorclient.utils.entity.SortPriority;
import meteordevelopment.meteorclient.utils.entity.TargetUtils;
import meteordevelopment.meteorclient.utils.misc.MissHitResult;
import meteordevelopment.meteorclient.utils.misc.Pool;
import meteordevelopment.meteorclient.utils.player.InvUtils;
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
@ -49,8 +48,8 @@ public class Prediction extends Module {
.name("prediction-level")
.description("The intelligence level for entity position prediction.")
.defaultValue(0)
.range(0, 2)
.sliderMax(2)
.range(0, 3)
.sliderMax(3)
.build()
);
@ -90,6 +89,26 @@ public class Prediction extends Module {
.build()
);
public final Setting<Integer> speedSample = sgGeneral.add(new IntSetting.Builder()
.name("speed-sample")
.description("How many ticks are used to sample the speed.")
.defaultValue(4)
.sliderMin(0)
.sliderMax(20)
.visible(() -> predictionLevel.get() >= 2)
.build()
);
public final Setting<Integer> directionSample = sgGeneral.add(new IntSetting.Builder()
.name("direction-sample")
.description("How many ticks are used to sample the direction.")
.defaultValue(1)
.sliderMin(0)
.sliderMax(20)
.visible(() -> predictionLevel.get() >= 2)
.build()
);
public final Setting<Integer> chargeOffset = sgGeneral.add(new IntSetting.Builder()
.name("charge-offset")
.description("What is the offset of the charge tick.")
@ -99,8 +118,8 @@ public class Prediction extends Module {
.build()
);
public final Setting<Integer> tickOffset = sgGeneral.add(new IntSetting.Builder()
.name("tick-offset")
public final Setting<Integer> tickXZOffset = sgGeneral.add(new IntSetting.Builder()
.name("tick-x-z-offset")
.description("What is the offset of the target tick.")
.defaultValue(4)
.sliderMin(0)
@ -109,6 +128,16 @@ public class Prediction extends Module {
.build()
);
public final Setting<Integer> tickYOffset = sgGeneral.add(new IntSetting.Builder()
.name("tick-y-offset")
.description("What is the offset of the target tick.")
.defaultValue(2)
.sliderMin(0)
.sliderMax(20)
.visible(() -> predictionLevel.get() >= 3)
.build()
);
public final Setting<Boolean> dynamicMultiplier = sgGeneral.add(new BoolSetting.Builder()
.name("dynamic-multiplier")
.description("Whether to dynamically correct the target Tick multiplier.")
@ -140,6 +169,14 @@ public class Prediction extends Module {
.build()
);
private final Setting<Boolean> aimOnlyPitch = sgGeneral.add(new BoolSetting.Builder()
.name("aim-only-pitch")
.description("Whether to target only through pitch.")
.defaultValue(false)
.visible(aimAssist::get)
.build()
);
private final Setting<Double> range = sgTarget.add(new DoubleSetting.Builder()
.name("range")
.description("The maximum range the entity can be to aim at it.")
@ -411,24 +448,33 @@ public class Prediction extends Module {
private class TargetContext {
final Entity entity;
int entityTick;
Vector3d lastPosition;
int lastChargeTick;
int lastPredictedTick;
Vector3d lastPredictedPosition;
double multiplier;
final List<Vector3d> positionList;
// For dynamic multiplier
final List<Integer> predictedTick = new ArrayList<Integer>();
final List<Vector3d> originalPosition = new ArrayList<Vector3d>();
final List<Vector3d> predictedPosition = new ArrayList<Vector3d>();
final List<Integer> predictedTick = new ArrayList<>();
final List<Vector3d> originalPosition = new ArrayList<>();
final List<Vector3d> predictedPosition = new ArrayList<>();
TargetContext(Entity entity) {
this.entity = entity;
entityTick = 0;
lastPosition = new Vector3d(entity.getX(), entity.getY(), entity.getZ());
lastChargeTick = -1;
lastPredictedPosition = new Vector3d(lastPosition);
lastPredictedPosition = new Vector3d(
entity.getBoundingBox().getCenter().x,
entity.getBoundingBox().getCenter().y,
entity.getBoundingBox().getCenter().z
);
multiplier = 1.0;
positionList = new ArrayList<>();
positionList.add(new Vector3d(lastPredictedPosition));
}
}
@ -447,21 +493,44 @@ public class Prediction extends Module {
++context.entityTick;
context.positionList.add(
new Vector3d(
context.entity.getBoundingBox().getCenter().x,
context.entity.getBoundingBox().getCenter().y,
context.entity.getBoundingBox().getCenter().z
)
);
if (context.positionList.size() > 40) context.positionList.removeFirst();
if (predictionLevel.get() >= 2) {
Box lastTargetBox = mc.player.getBoundingBox();
if (chargeTick >= 3) {
int predictedTick = -1;
double speed = 0.0;
int numSample = 0;
for (; numSample < speedSample.get(); numSample++) {
if (context.positionList.size() - numSample - 2 < 0) break;
speed += new Vector3d(
context.positionList.get(context.positionList.size() - numSample - 1).x - context.positionList.get(context.positionList.size() - numSample - 2).x,
context.positionList.get(context.positionList.size() - numSample - 1).y - context.positionList.get(context.positionList.size() - numSample - 2).y,
context.positionList.get(context.positionList.size() - numSample - 1).z - context.positionList.get(context.positionList.size() - numSample - 2).z
).length();
}
speed /= numSample;
Vector3d velocity = new Vector3d(context.positionList.getLast())
.sub(context.positionList.get(Math.max(context.positionList.size() - directionSample.get() - 1, 0)));
if (velocity.length() > 1e-6) velocity.normalize().mul(speed);
for (int i = 0; simulationTargetSteps.get() > 0 ? i < simulationTargetSteps.get() :
result.predicted.getCenter().distanceTo(lastTargetBox.getCenter()) > targetEpsilon.get(); i++) {
Vec3d velocity = new Vec3d(
context.entity.getBoundingBox().getCenter().x - context.lastPosition.x,
0,
context.entity.getBoundingBox().getCenter().z - context.lastPosition.z
);
AngleResult angleResult = calculateAngle(result.predicted, chargeTick);
if (!angleResult.successed) {
@ -471,8 +540,60 @@ public class Prediction extends Module {
PathResult pathResult = calculatePath(result.predicted, angleResult.yaw, angleResult.pitch, chargeTick, false, null);
predictedTick = pathResult.hitTick + tickOffset.get();
result.predicted = context.entity.getBoundingBox().offset(velocity.multiply(predictedTick * context.multiplier));
predictedTick = pathResult.hitTick;
if (predictionLevel.get() == 2) {
result.predicted = context.entity.getBoundingBox().offset(
new Vec3d(velocity.x, velocity.y, velocity.z).multiply(1.0, 0.0, 1.0).multiply((predictedTick + tickXZOffset.get()) * context.multiplier)
);
}
else {
Vector3d predictedOffset = new Vector3d(velocity).mul(1.0, 0.0, 1.0)
.mul((predictedTick + tickXZOffset.get()) * context.multiplier);
for (int j = 0; j <= (predictedTick + tickYOffset.get()) * context.multiplier; ++j) {
predictedOffset.add(0.0, velocity.y, 0.0);
velocity.y *= 0.98;
velocity.y -= 0.08;
}
predictedOffset.mul(context.multiplier);
double[] raycastX = new double[] {
context.entity.getBoundingBox().minX,
context.entity.getBoundingBox().minX,
context.entity.getBoundingBox().maxX,
context.entity.getBoundingBox().maxX,
};
double[] raycastZ = new double[] {
context.entity.getBoundingBox().minZ,
context.entity.getBoundingBox().maxZ,
context.entity.getBoundingBox().minZ,
context.entity.getBoundingBox().maxZ,
};
for (int k = 0; k < 4; k++) {
HitResult hitResult = mc.world.raycast(new RaycastContext(
new Vec3d(
raycastX[k] + predictedOffset.x,
context.entity.getBoundingBox().minY,
raycastZ[k] + predictedOffset.z
),
new Vec3d(
raycastX[k] + predictedOffset.x,
context.entity.getBoundingBox().minY + predictedOffset.y,
raycastZ[k] + predictedOffset.z
),
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
);
if (hitResult.getType() != HitResult.Type.MISS)
predictedOffset.y = Math.max(predictedOffset.y, hitResult.getPos().y - context.entity.getBoundingBox().minY);
}
result.predicted = context.entity.getBoundingBox().offset(predictedOffset.x, predictedOffset.y, predictedOffset.z);
}
}
context.lastPredictedTick = predictedTick;
@ -482,7 +603,7 @@ public class Prediction extends Module {
if (dynamicMultiplier.get()) {
if (context.lastChargeTick >= 3 && context.lastChargeTick > chargeTick && chargeTick != -1 && context.lastPredictedTick != -1) {
context.predictedTick.add(context.entityTick + context.lastPredictedTick);
context.originalPosition.add(new Vector3d(context.lastPosition));
context.originalPosition.add(new Vector3d(context.positionList.get(context.positionList.size() - 2)));
context.predictedPosition.add(new Vector3d(context.lastPredictedPosition));
}
@ -502,7 +623,6 @@ public class Prediction extends Module {
}
}
context.lastPosition.set(context.entity.getBoundingBox().getCenter().x, context.entity.getBoundingBox().getCenter().y, context.entity.getBoundingBox().getCenter().z);
context.lastChargeTick = chargeTick;
context.lastPredictedPosition.set(result.predicted.getCenter().x, result.predicted.getCenter().y, result.predicted.getCenter().z);
}
@ -967,15 +1087,6 @@ public class Prediction extends Module {
if (!mc.options.useKey.isPressed()) return;
if (!InvUtils.testInHands(Items.BOW)) return;
if (instant.get()) {
mc.player.setYaw((float) aimData.yaw);
} else {
double deltaAngle = MathHelper.wrapDegrees(aimData.yaw - mc.player.getYaw());
double toRotate = speed.get() * (deltaAngle >= 0 ? 1 : -1) * tickDelta;
if ((toRotate >= 0 && toRotate > deltaAngle) || (toRotate < 0 && toRotate < deltaAngle)) toRotate = deltaAngle;
mc.player.setYaw(mc.player.getYaw() + (float) toRotate);
}
if (instant.get()) {
mc.player.setPitch((float) aimData.pitch);
} else {
@ -984,5 +1095,16 @@ public class Prediction extends Module {
if ((toRotate >= 0 && toRotate > deltaAngle) || (toRotate < 0 && toRotate < deltaAngle)) toRotate = deltaAngle;
mc.player.setPitch(mc.player.getPitch() + (float) toRotate);
}
if (aimOnlyPitch.get()) return;
if (instant.get()) {
mc.player.setYaw((float) aimData.yaw);
} else {
double deltaAngle = MathHelper.wrapDegrees(aimData.yaw - mc.player.getYaw());
double toRotate = speed.get() * (deltaAngle >= 0 ? 1 : -1) * tickDelta;
if ((toRotate >= 0 && toRotate > deltaAngle) || (toRotate < 0 && toRotate < deltaAngle)) toRotate = deltaAngle;
mc.player.setYaw(mc.player.getYaw() + (float) toRotate);
}
}
}