Add free-fall prediction
This commit is contained in:
parent
8dd456a9da
commit
1ea052c356
@ -11,7 +11,6 @@ import meteordevelopment.meteorclient.utils.Utils;
|
|||||||
import meteordevelopment.meteorclient.utils.entity.EntityUtils;
|
import meteordevelopment.meteorclient.utils.entity.EntityUtils;
|
||||||
import meteordevelopment.meteorclient.utils.entity.SortPriority;
|
import meteordevelopment.meteorclient.utils.entity.SortPriority;
|
||||||
import meteordevelopment.meteorclient.utils.entity.TargetUtils;
|
import meteordevelopment.meteorclient.utils.entity.TargetUtils;
|
||||||
import meteordevelopment.meteorclient.utils.misc.MissHitResult;
|
|
||||||
import meteordevelopment.meteorclient.utils.misc.Pool;
|
import meteordevelopment.meteorclient.utils.misc.Pool;
|
||||||
import meteordevelopment.meteorclient.utils.player.InvUtils;
|
import meteordevelopment.meteorclient.utils.player.InvUtils;
|
||||||
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
|
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
|
||||||
@ -49,8 +48,8 @@ public class Prediction extends Module {
|
|||||||
.name("prediction-level")
|
.name("prediction-level")
|
||||||
.description("The intelligence level for entity position prediction.")
|
.description("The intelligence level for entity position prediction.")
|
||||||
.defaultValue(0)
|
.defaultValue(0)
|
||||||
.range(0, 2)
|
.range(0, 3)
|
||||||
.sliderMax(2)
|
.sliderMax(3)
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -90,6 +89,26 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.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()
|
public final Setting<Integer> chargeOffset = sgGeneral.add(new IntSetting.Builder()
|
||||||
.name("charge-offset")
|
.name("charge-offset")
|
||||||
.description("What is the offset of the charge tick.")
|
.description("What is the offset of the charge tick.")
|
||||||
@ -99,8 +118,8 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
public final Setting<Integer> tickOffset = sgGeneral.add(new IntSetting.Builder()
|
public final Setting<Integer> tickXZOffset = sgGeneral.add(new IntSetting.Builder()
|
||||||
.name("tick-offset")
|
.name("tick-x-z-offset")
|
||||||
.description("What is the offset of the target tick.")
|
.description("What is the offset of the target tick.")
|
||||||
.defaultValue(4)
|
.defaultValue(4)
|
||||||
.sliderMin(0)
|
.sliderMin(0)
|
||||||
@ -109,6 +128,16 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.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()
|
public final Setting<Boolean> dynamicMultiplier = sgGeneral.add(new BoolSetting.Builder()
|
||||||
.name("dynamic-multiplier")
|
.name("dynamic-multiplier")
|
||||||
.description("Whether to dynamically correct the target Tick multiplier.")
|
.description("Whether to dynamically correct the target Tick multiplier.")
|
||||||
@ -140,6 +169,14 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.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()
|
private final Setting<Double> range = sgTarget.add(new DoubleSetting.Builder()
|
||||||
.name("range")
|
.name("range")
|
||||||
.description("The maximum range the entity can be to aim at it.")
|
.description("The maximum range the entity can be to aim at it.")
|
||||||
@ -411,24 +448,33 @@ public class Prediction extends Module {
|
|||||||
private class TargetContext {
|
private class TargetContext {
|
||||||
final Entity entity;
|
final Entity entity;
|
||||||
int entityTick;
|
int entityTick;
|
||||||
Vector3d lastPosition;
|
|
||||||
int lastChargeTick;
|
int lastChargeTick;
|
||||||
int lastPredictedTick;
|
int lastPredictedTick;
|
||||||
Vector3d lastPredictedPosition;
|
Vector3d lastPredictedPosition;
|
||||||
double multiplier;
|
double multiplier;
|
||||||
|
|
||||||
|
final List<Vector3d> positionList;
|
||||||
|
|
||||||
// For dynamic multiplier
|
// For dynamic multiplier
|
||||||
final List<Integer> predictedTick = new ArrayList<Integer>();
|
final List<Integer> predictedTick = new ArrayList<>();
|
||||||
final List<Vector3d> originalPosition = new ArrayList<Vector3d>();
|
final List<Vector3d> originalPosition = new ArrayList<>();
|
||||||
final List<Vector3d> predictedPosition = new ArrayList<Vector3d>();
|
final List<Vector3d> predictedPosition = new ArrayList<>();
|
||||||
|
|
||||||
TargetContext(Entity entity) {
|
TargetContext(Entity entity) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
entityTick = 0;
|
entityTick = 0;
|
||||||
lastPosition = new Vector3d(entity.getX(), entity.getY(), entity.getZ());
|
|
||||||
lastChargeTick = -1;
|
lastChargeTick = -1;
|
||||||
lastPredictedPosition = new Vector3d(lastPosition);
|
|
||||||
|
lastPredictedPosition = new Vector3d(
|
||||||
|
entity.getBoundingBox().getCenter().x,
|
||||||
|
entity.getBoundingBox().getCenter().y,
|
||||||
|
entity.getBoundingBox().getCenter().z
|
||||||
|
);
|
||||||
|
|
||||||
multiplier = 1.0;
|
multiplier = 1.0;
|
||||||
|
|
||||||
|
positionList = new ArrayList<>();
|
||||||
|
positionList.add(new Vector3d(lastPredictedPosition));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,21 +493,44 @@ public class Prediction extends Module {
|
|||||||
|
|
||||||
++context.entityTick;
|
++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) {
|
if (predictionLevel.get() >= 2) {
|
||||||
Box lastTargetBox = mc.player.getBoundingBox();
|
Box lastTargetBox = mc.player.getBoundingBox();
|
||||||
|
|
||||||
if (chargeTick >= 3) {
|
if (chargeTick >= 3) {
|
||||||
int predictedTick = -1;
|
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() :
|
for (int i = 0; simulationTargetSteps.get() > 0 ? i < simulationTargetSteps.get() :
|
||||||
result.predicted.getCenter().distanceTo(lastTargetBox.getCenter()) > targetEpsilon.get(); i++) {
|
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);
|
AngleResult angleResult = calculateAngle(result.predicted, chargeTick);
|
||||||
|
|
||||||
if (!angleResult.successed) {
|
if (!angleResult.successed) {
|
||||||
@ -471,8 +540,60 @@ public class Prediction extends Module {
|
|||||||
|
|
||||||
PathResult pathResult = calculatePath(result.predicted, angleResult.yaw, angleResult.pitch, chargeTick, false, null);
|
PathResult pathResult = calculatePath(result.predicted, angleResult.yaw, angleResult.pitch, chargeTick, false, null);
|
||||||
|
|
||||||
predictedTick = pathResult.hitTick + tickOffset.get();
|
predictedTick = pathResult.hitTick;
|
||||||
result.predicted = context.entity.getBoundingBox().offset(velocity.multiply(predictedTick * context.multiplier));
|
|
||||||
|
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;
|
context.lastPredictedTick = predictedTick;
|
||||||
@ -482,7 +603,7 @@ public class Prediction extends Module {
|
|||||||
if (dynamicMultiplier.get()) {
|
if (dynamicMultiplier.get()) {
|
||||||
if (context.lastChargeTick >= 3 && context.lastChargeTick > chargeTick && chargeTick != -1 && context.lastPredictedTick != -1) {
|
if (context.lastChargeTick >= 3 && context.lastChargeTick > chargeTick && chargeTick != -1 && context.lastPredictedTick != -1) {
|
||||||
context.predictedTick.add(context.entityTick + context.lastPredictedTick);
|
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));
|
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.lastChargeTick = chargeTick;
|
||||||
context.lastPredictedPosition.set(result.predicted.getCenter().x, result.predicted.getCenter().y, result.predicted.getCenter().z);
|
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 (!mc.options.useKey.isPressed()) return;
|
||||||
if (!InvUtils.testInHands(Items.BOW)) 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()) {
|
if (instant.get()) {
|
||||||
mc.player.setPitch((float) aimData.pitch);
|
mc.player.setPitch((float) aimData.pitch);
|
||||||
} else {
|
} else {
|
||||||
@ -984,5 +1095,16 @@ public class Prediction extends Module {
|
|||||||
if ((toRotate >= 0 && toRotate > deltaAngle) || (toRotate < 0 && toRotate < deltaAngle)) toRotate = deltaAngle;
|
if ((toRotate >= 0 && toRotate > deltaAngle) || (toRotate < 0 && toRotate < deltaAngle)) toRotate = deltaAngle;
|
||||||
mc.player.setPitch(mc.player.getPitch() + (float) toRotate);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user