Add probe to try to attack the entity behind the block
This commit is contained in:
parent
fd19d4bf63
commit
4d16c1f7a1
@ -23,14 +23,12 @@ import net.minecraft.entity.EntityType;
|
|||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.passive.AnimalEntity;
|
import net.minecraft.entity.passive.AnimalEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.projectile.ProjectileUtil;
|
|
||||||
import net.minecraft.fluid.FluidState;
|
import net.minecraft.fluid.FluidState;
|
||||||
import net.minecraft.fluid.Fluids;
|
import net.minecraft.fluid.Fluids;
|
||||||
import net.minecraft.item.BowItem;
|
import net.minecraft.item.BowItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.hit.EntityHitResult;
|
|
||||||
import net.minecraft.util.hit.HitResult;
|
import net.minecraft.util.hit.HitResult;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.world.RaycastContext;
|
import net.minecraft.world.RaycastContext;
|
||||||
@ -38,11 +36,14 @@ import org.joml.Vector3d;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class Prediction extends Module {
|
public class Prediction extends Module {
|
||||||
private final SettingGroup sgGeneral = settings.getDefaultGroup();
|
private final SettingGroup sgGeneral = settings.getDefaultGroup();
|
||||||
private final SettingGroup sgTarget = settings.createGroup("Target");
|
private final SettingGroup sgTarget = settings.createGroup("Target");
|
||||||
|
private final SettingGroup sgSimulation = settings.createGroup("Simulation");
|
||||||
|
private final SettingGroup sgProbe = settings.createGroup("Probe");
|
||||||
private final SettingGroup sgSpeed = settings.createGroup("Aim Speed");
|
private final SettingGroup sgSpeed = settings.createGroup("Aim Speed");
|
||||||
private final SettingGroup sgRender = settings.createGroup("Render");
|
private final SettingGroup sgRender = settings.createGroup("Render");
|
||||||
|
|
||||||
@ -55,14 +56,6 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
public final Setting<Integer> simulationSteps = sgGeneral.add(new IntSetting.Builder()
|
|
||||||
.name("simulation-steps")
|
|
||||||
.description("How many steps to simulate projectiles. Zero for no limit.")
|
|
||||||
.defaultValue(250)
|
|
||||||
.sliderMax(5000)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
public final Setting<Integer> iterationSteps = sgGeneral.add(new IntSetting.Builder()
|
public final Setting<Integer> iterationSteps = sgGeneral.add(new IntSetting.Builder()
|
||||||
.name("iteration-steps")
|
.name("iteration-steps")
|
||||||
.description("How many iterations to aim projectiles. Zero for no limit.")
|
.description("How many iterations to aim projectiles. Zero for no limit.")
|
||||||
@ -77,7 +70,7 @@ public class Prediction extends Module {
|
|||||||
.description("How much accuracy is needed to aim a projectile.")
|
.description("How much accuracy is needed to aim a projectile.")
|
||||||
.defaultValue(0.5)
|
.defaultValue(0.5)
|
||||||
.sliderMax(1)
|
.sliderMax(1)
|
||||||
.visible(() -> iterationSteps.get() == 0)
|
.visible(() -> predictionLevel.get() >= 1 && iterationSteps.get() == 0)
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -148,6 +141,78 @@ public class Prediction extends Module {
|
|||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public final Setting<Integer> simulationSteps = sgSimulation.add(new IntSetting.Builder()
|
||||||
|
.name("simulation-steps")
|
||||||
|
.description("How many steps to simulate projectiles. Zero for no limit.")
|
||||||
|
.defaultValue(250)
|
||||||
|
.sliderMax(5000)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
public final Setting<Double> eyeHeightOffset = sgSimulation.add(new DoubleSetting.Builder()
|
||||||
|
.name("eye-height-offset")
|
||||||
|
.description("What is the offset of the actual projectile launch position from eye height.")
|
||||||
|
.defaultValue(-0.1)
|
||||||
|
.sliderMin(-1.0)
|
||||||
|
.sliderMax(1.0)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
public final Setting<Double> gravity = sgSimulation.add(new DoubleSetting.Builder()
|
||||||
|
.name("gravity")
|
||||||
|
.description("What is the acceleration of gravity on the projectile.")
|
||||||
|
.defaultValue(0.05000000074505806)
|
||||||
|
.sliderMin(0.04)
|
||||||
|
.sliderMax(0.06)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
public final Setting<Double> airDrag = sgSimulation.add(new DoubleSetting.Builder()
|
||||||
|
.name("air-drag")
|
||||||
|
.description("What is the drag value of the projectile in air.")
|
||||||
|
.defaultValue(0.99)
|
||||||
|
.sliderMin(0.95)
|
||||||
|
.sliderMax(1.0)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
public final Setting<Double> waterDrag = sgSimulation.add(new DoubleSetting.Builder()
|
||||||
|
.name("water-drag")
|
||||||
|
.description("What is the drag value of the projectile in water.")
|
||||||
|
.defaultValue(0.6)
|
||||||
|
.sliderMin(0)
|
||||||
|
.sliderMax(1)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Setting<Boolean> enableProbe = sgProbe.add(new BoolSetting.Builder()
|
||||||
|
.name("enable-probe")
|
||||||
|
.description("Enable/disable block probes.")
|
||||||
|
.defaultValue(false)
|
||||||
|
.visible(() -> predictionLevel.get() >= 1)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Setting<Double> probeRange = sgProbe.add(new DoubleSetting.Builder()
|
||||||
|
.name("probe-range")
|
||||||
|
.description("The maximum range of probe placement.")
|
||||||
|
.defaultValue(1)
|
||||||
|
.range(0, 4)
|
||||||
|
.sliderMax(4)
|
||||||
|
.visible(enableProbe::get)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Setting<Double> probeInterval = sgProbe.add(new DoubleSetting.Builder()
|
||||||
|
.name("probe-interval")
|
||||||
|
.description("The minimum interval of probe placement.")
|
||||||
|
.defaultValue(0.5)
|
||||||
|
.range(0, 1)
|
||||||
|
.sliderMax(1)
|
||||||
|
.visible(enableProbe::get)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
private final Setting<Boolean> instant = sgSpeed.add(new BoolSetting.Builder()
|
private final Setting<Boolean> instant = sgSpeed.add(new BoolSetting.Builder()
|
||||||
.name("instant-look")
|
.name("instant-look")
|
||||||
.description("Instantly looks at the entity.")
|
.description("Instantly looks at the entity.")
|
||||||
@ -166,7 +231,7 @@ public class Prediction extends Module {
|
|||||||
|
|
||||||
private final Setting<Boolean> enableRender = sgRender.add(new BoolSetting.Builder()
|
private final Setting<Boolean> enableRender = sgRender.add(new BoolSetting.Builder()
|
||||||
.name("enable-render")
|
.name("enable-render")
|
||||||
.description("Enable/Disable Render Indication.")
|
.description("Enable/disable render indication.")
|
||||||
.defaultValue(true)
|
.defaultValue(true)
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
@ -220,11 +285,8 @@ public class Prediction extends Module {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
private void onTick(TickEvent.Post event) {
|
private void onTick(TickEvent.Post event) {
|
||||||
if (mc.options.attackKey.isPressed() || !isSelectableTarget(targetEntity)) {
|
|
||||||
targetEntity = TargetUtils.get(this::isSelectableTarget, priority.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
clearPath();
|
clearPath();
|
||||||
|
calculateTarget();
|
||||||
if (targetEntity != null) calculateAngle();
|
if (targetEntity != null) calculateAngle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,9 +294,7 @@ public class Prediction extends Module {
|
|||||||
private void onRender(Render3DEvent event) {
|
private void onRender(Render3DEvent event) {
|
||||||
float tickDelta = mc.world.getTickManager().isFrozen() ? 1 : event.tickDelta;
|
float tickDelta = mc.world.getTickManager().isFrozen() ? 1 : event.tickDelta;
|
||||||
|
|
||||||
boolean canAim = aimAssist.get() && (isHitTarget || !aimOnlyHit.get()) && mc.options.useKey.isPressed() && InvUtils.testInHands(Items.BOW);
|
if (aimAssist.get()) aim(event.tickDelta);
|
||||||
|
|
||||||
if (canAim) aim(event.tickDelta);
|
|
||||||
if (enableRender.get()) renderPath(event);
|
if (enableRender.get()) renderPath(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,29 +328,22 @@ public class Prediction extends Module {
|
|||||||
return BowItem.getPullProgress(mc.player.getItemUseTime());
|
return BowItem.getPullProgress(mc.player.getItemUseTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final double gravity = 0.05000000074505806;
|
// These variables are set by the calculateTarget()
|
||||||
private static final double airDrag = 0.99;
|
|
||||||
private static final double waterDrag = 0.6;
|
|
||||||
|
|
||||||
// These variables are set by the onTick()
|
|
||||||
private Entity targetEntity;
|
private Entity targetEntity;
|
||||||
|
private Box targetBox;
|
||||||
|
|
||||||
// These variables are set by the calculateAngle()
|
// These variables are set by the calculateAngle()
|
||||||
|
private boolean targetCompleted;
|
||||||
private double targetYaw;
|
private double targetYaw;
|
||||||
private double targetPitch;
|
private double targetPitch;
|
||||||
private double targetCharge;
|
private double targetCharge;
|
||||||
|
|
||||||
// These variables are set by the calculatePath() for prediction level >= 1
|
|
||||||
private double targetHighPitch;
|
|
||||||
private double targetLowPitch;
|
|
||||||
|
|
||||||
// These variables are set by the calculatePath()
|
// These variables are set by the calculatePath()
|
||||||
private final Pool<Vector3d> vectorPool = new Pool<>(Vector3d::new);
|
private final Pool<Vector3d> vectorPool = new Pool<>(Vector3d::new);
|
||||||
private final List<Vector3d> points = new ArrayList<>();
|
private final List<Vector3d> points = new ArrayList<>();
|
||||||
private boolean hitQuad = false, hitQuadHorizontal = false;
|
private boolean hitQuad = false, hitQuadHorizontal = false;
|
||||||
private final Vector3d hitQuad1 = new Vector3d();
|
private final Vector3d hitQuad1 = new Vector3d();
|
||||||
private final Vector3d hitQuad2 = new Vector3d();
|
private final Vector3d hitQuad2 = new Vector3d();
|
||||||
private Entity collidingEntity = null;
|
|
||||||
private boolean isHitTarget;
|
private boolean isHitTarget;
|
||||||
|
|
||||||
private void clearPath() {
|
private void clearPath() {
|
||||||
@ -298,7 +351,6 @@ public class Prediction extends Module {
|
|||||||
points.clear();
|
points.clear();
|
||||||
|
|
||||||
hitQuad = false;
|
hitQuad = false;
|
||||||
collidingEntity = null;
|
|
||||||
isHitTarget = false;
|
isHitTarget = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +362,7 @@ public class Prediction extends Module {
|
|||||||
Vector3d lastPosition = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d lastPosition = new Vector3d(0.0, 0.0, 0.0);
|
||||||
Vector3d position = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d position = new Vector3d(0.0, 0.0, 0.0);
|
||||||
Vector3d velocity = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d velocity = new Vector3d(0.0, 0.0, 0.0);
|
||||||
position.set(mc.player.getX(), mc.player.getY(), mc.player.getZ()).add(0, mc.player.getEyeHeight(mc.player.getPose()), 0);
|
position.set(mc.player.getX(), mc.player.getY(), mc.player.getZ()).add(0, mc.player.getEyeHeight(mc.player.getPose()) + eyeHeightOffset.get(), 0);
|
||||||
|
|
||||||
double yaw = targetYaw;
|
double yaw = targetYaw;
|
||||||
double pitch = targetPitch;
|
double pitch = targetPitch;
|
||||||
@ -323,8 +375,9 @@ public class Prediction extends Module {
|
|||||||
velocity.add(mc.player.getVelocity().x, mc.player.isOnGround() ? 0.0D : mc.player.getVelocity().y, mc.player.getVelocity().z);
|
velocity.add(mc.player.getVelocity().x, mc.player.isOnGround() ? 0.0D : mc.player.getVelocity().y, mc.player.getVelocity().z);
|
||||||
|
|
||||||
HitResult hitResult = null;
|
HitResult hitResult = null;
|
||||||
|
Direction hitDirection = null;
|
||||||
|
|
||||||
for (int i = 0; i < (simulationSteps.get() > 0 ? simulationSteps.get() : Integer.MAX_VALUE) && hitResult == null; i++) {
|
for (int i = 0; i < (simulationSteps.get() > 0 ? simulationSteps.get() : Integer.MAX_VALUE) && !hitQuad && !isHitTarget; i++) {
|
||||||
points.add(vectorPool.get().set(position));
|
points.add(vectorPool.get().set(position));
|
||||||
|
|
||||||
lastPosition.set(position);
|
lastPosition.set(position);
|
||||||
@ -335,8 +388,8 @@ public class Prediction extends Module {
|
|||||||
if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER)
|
if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER)
|
||||||
isTouchingWater = position.y - (int) position.y <= fluidState.getHeight();
|
isTouchingWater = position.y - (int) position.y <= fluidState.getHeight();
|
||||||
|
|
||||||
velocity.mul(isTouchingWater ? waterDrag : airDrag);
|
velocity.mul(isTouchingWater ? waterDrag.get() : airDrag.get());
|
||||||
velocity.sub(0, gravity, 0);
|
velocity.sub(0, gravity.get(), 0);
|
||||||
|
|
||||||
if (position.y < mc.world.getBottomY()) {
|
if (position.y < mc.world.getBottomY()) {
|
||||||
hitResult = MissHitResult.INSTANCE;
|
hitResult = MissHitResult.INSTANCE;
|
||||||
@ -356,43 +409,79 @@ public class Prediction extends Module {
|
|||||||
);
|
);
|
||||||
if (hitResult.getType() != HitResult.Type.MISS) {
|
if (hitResult.getType() != HitResult.Type.MISS) {
|
||||||
position = new Vector3d(hitResult.getPos().x, hitResult.getPos().y, hitResult.getPos().z);
|
position = new Vector3d(hitResult.getPos().x, hitResult.getPos().y, hitResult.getPos().z);
|
||||||
}
|
|
||||||
|
|
||||||
Box box = new Box(
|
|
||||||
lastPosition.x - (EntityType.ARROW.getWidth() / 2f),
|
|
||||||
lastPosition.y,
|
|
||||||
lastPosition.z - (EntityType.ARROW.getWidth() / 2f),
|
|
||||||
lastPosition.x + (EntityType.ARROW.getWidth() / 2f),
|
|
||||||
lastPosition.y + EntityType.ARROW.getHeight(),
|
|
||||||
lastPosition.z + (EntityType.ARROW.getWidth() / 2f)
|
|
||||||
).stretch(velocity.x, velocity.y, velocity.z).expand(1.0D);
|
|
||||||
HitResult hitResultEntity = ProjectileUtil.getEntityCollision(mc.world, null,
|
|
||||||
new Vec3d(lastPosition.x, lastPosition.y, lastPosition.z), new Vec3d(position.x, position.y, position.z),
|
|
||||||
box, entity -> !entity.isSpectator() && entity.isAlive() && entity.canHit() && entity != mc.player
|
|
||||||
);
|
|
||||||
if (hitResultEntity != null) {
|
|
||||||
hitResult = hitResultEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
hitResult = hitResult.getType() == HitResult.Type.MISS ? null : hitResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hitResult != null) {
|
|
||||||
if (hitResult.getType() == HitResult.Type.BLOCK) {
|
|
||||||
BlockHitResult r = (BlockHitResult) hitResult;
|
|
||||||
|
|
||||||
hitQuad = true;
|
hitQuad = true;
|
||||||
hitQuad1.set(r.getPos().x, r.getPos().y, r.getPos().z);
|
hitQuad1.set(position);
|
||||||
hitQuad2.set(r.getPos().x, r.getPos().y, r.getPos().z);
|
hitQuad2.set(position);
|
||||||
|
hitDirection = ((BlockHitResult) hitResult).getSide();
|
||||||
|
}
|
||||||
|
|
||||||
if (r.getSide() == Direction.UP || r.getSide() == Direction.DOWN) {
|
if (!targetBox.stretch(velocity.x, velocity.y, velocity.z).expand(4.0).contains(position.x, position.y, position.z))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Box extendedBox = targetBox;
|
||||||
|
|
||||||
|
if (enableProbe.get()) {
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add(-(targetBox.getLengthX() + EntityType.ARROW.getWidth()) / 2.0, 0, 0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMinX = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().x : targetBox.minX - EntityType.ARROW.getWidth() / 2.0;
|
||||||
|
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add(0, -(targetBox.getLengthY() + EntityType.ARROW.getHeight()) / 2.0, 0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMinY = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().y : targetBox.minY - EntityType.ARROW.getHeight() / 2.0;
|
||||||
|
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add(0, 0, -(targetBox.getLengthZ() + EntityType.ARROW.getWidth()) / 2.0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMinZ = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().z : targetBox.minZ - EntityType.ARROW.getWidth() / 2.0;
|
||||||
|
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add((targetBox.getLengthX() + EntityType.ARROW.getWidth()) / 2.0, 0, 0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMaxX = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().x : targetBox.maxX + EntityType.ARROW.getWidth() / 2.0;
|
||||||
|
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add(0, (targetBox.getLengthY() + EntityType.ARROW.getHeight()) / 2.0, 0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMaxY = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().y : targetBox.maxY + EntityType.ARROW.getHeight() / 2.0;
|
||||||
|
|
||||||
|
hitResult = mc.world.raycast(new RaycastContext(
|
||||||
|
targetBox.getCenter(), targetBox.getCenter().add(0, 0, (targetBox.getLengthZ() + EntityType.ARROW.getWidth()) / 2.0),
|
||||||
|
RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player)
|
||||||
|
);
|
||||||
|
|
||||||
|
double extendedMaxZ = hitResult.getType() != HitResult.Type.MISS ? hitResult.getPos().z : targetBox.maxZ + EntityType.ARROW.getWidth() / 2.0;
|
||||||
|
|
||||||
|
extendedBox = new Box(extendedMinX, extendedMinY, extendedMinZ, extendedMaxX, extendedMaxY, extendedMaxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Vec3d> optional = extendedBox.raycast(new Vec3d(lastPosition.x, lastPosition.y, lastPosition.z), new Vec3d(position.x, position.y, position.z));
|
||||||
|
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
isHitTarget = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitQuad) {
|
||||||
|
if (hitDirection == Direction.UP || hitDirection == Direction.DOWN) {
|
||||||
hitQuadHorizontal = true;
|
hitQuadHorizontal = true;
|
||||||
hitQuad1.x -= 0.25;
|
hitQuad1.x -= 0.25;
|
||||||
hitQuad1.z -= 0.25;
|
hitQuad1.z -= 0.25;
|
||||||
hitQuad2.x += 0.25;
|
hitQuad2.x += 0.25;
|
||||||
hitQuad2.z += 0.25;
|
hitQuad2.z += 0.25;
|
||||||
}
|
}
|
||||||
else if (r.getSide() == Direction.NORTH || r.getSide() == Direction.SOUTH) {
|
else if (hitDirection == Direction.NORTH || hitDirection == Direction.SOUTH) {
|
||||||
hitQuadHorizontal = false;
|
hitQuadHorizontal = false;
|
||||||
hitQuad1.x -= 0.25;
|
hitQuad1.x -= 0.25;
|
||||||
hitQuad1.y -= 0.25;
|
hitQuad1.y -= 0.25;
|
||||||
@ -409,12 +498,6 @@ public class Prediction extends Module {
|
|||||||
|
|
||||||
points.add(Utils.set(vectorPool.get(), hitResult.getPos()));
|
points.add(Utils.set(vectorPool.get(), hitResult.getPos()));
|
||||||
}
|
}
|
||||||
else if (hitResult.getType() == HitResult.Type.ENTITY) {
|
|
||||||
collidingEntity = ((EntityHitResult) hitResult).getEntity();
|
|
||||||
points.add(Utils.set(vectorPool.get(), hitResult.getPos()).add(0, collidingEntity.getHeight() / 2, 0));
|
|
||||||
isHitTarget = collidingEntity == targetEntity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderPath(Render3DEvent event) {
|
private void renderPath(Render3DEvent event) {
|
||||||
@ -448,37 +531,31 @@ public class Prediction extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collidingEntity != null) {
|
if (targetEntity != null) {
|
||||||
double x = (collidingEntity.getX() - collidingEntity.prevX) * event.tickDelta;
|
Box box = targetEntity.getBoundingBox();
|
||||||
double y = (collidingEntity.getY() - collidingEntity.prevY) * event.tickDelta;
|
|
||||||
double z = (collidingEntity.getZ() - collidingEntity.prevZ) * event.tickDelta;
|
|
||||||
|
|
||||||
Box box = collidingEntity.getBoundingBox();
|
|
||||||
event.renderer.box(
|
event.renderer.box(
|
||||||
x + box.minX, y + box.minY, z + box.minZ, x + box.maxX, y + box.maxY, z + box.maxZ,
|
targetBox,
|
||||||
isHitTarget ? hitSideColor.get() : missSideColor.get(),
|
isHitTarget ? hitSideColor.get() : missSideColor.get(),
|
||||||
isHitTarget ? hitLineColor.get() : missLineColor.get(),
|
isHitTarget ? hitLineColor.get() : missLineColor.get(),
|
||||||
shapeMode.get(), 0
|
shapeMode.get(), 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isHitTarget && targetEntity != null) {
|
|
||||||
double x = (targetEntity.getX() - targetEntity.prevX) * event.tickDelta;
|
|
||||||
double y = (targetEntity.getY() - targetEntity.prevY) * event.tickDelta;
|
|
||||||
double z = (targetEntity.getZ() - targetEntity.prevZ) * event.tickDelta;
|
|
||||||
|
|
||||||
Box box = targetEntity.getBoundingBox();
|
|
||||||
event.renderer.box(
|
|
||||||
x + box.minX, y + box.minY, z + box.minZ, x + box.maxX, y + box.maxY, z + box.maxZ,
|
|
||||||
missSideColor.get(), missLineColor.get(), shapeMode.get(), 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateHeightOffset(Vector3d targetPosition, double pitch) {
|
private void calculateTarget() {
|
||||||
|
if (mc.options.attackKey.isPressed() || !isSelectableTarget(targetEntity)) {
|
||||||
|
targetEntity = TargetUtils.get(this::isSelectableTarget, priority.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetEntity == null) return;
|
||||||
|
|
||||||
|
targetBox = targetEntity.getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateHeightOffset(double pitch) {
|
||||||
double targetDistance = Math.sqrt(
|
double targetDistance = Math.sqrt(
|
||||||
(targetPosition.x - mc.player.getX()) * (targetPosition.x - mc.player.getX()) +
|
(targetBox.getCenter().x - mc.player.getX()) * (targetBox.getCenter().x - mc.player.getX()) +
|
||||||
(targetPosition.z - mc.player.getZ()) * (targetPosition.z - mc.player.getZ())
|
(targetBox.getCenter().z - mc.player.getZ()) * (targetBox.getCenter().z - mc.player.getZ())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (getCurrentCharge() <= 0) return Double.NaN;
|
if (getCurrentCharge() <= 0) return Double.NaN;
|
||||||
@ -487,9 +564,9 @@ public class Prediction extends Module {
|
|||||||
Vector3d lastPosition = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d lastPosition = new Vector3d(0.0, 0.0, 0.0);
|
||||||
Vector3d position = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d position = new Vector3d(0.0, 0.0, 0.0);
|
||||||
Vector3d velocity = new Vector3d(0.0, 0.0, 0.0);
|
Vector3d velocity = new Vector3d(0.0, 0.0, 0.0);
|
||||||
position.set(mc.player.getX(), mc.player.getY(), mc.player.getZ()).add(0, mc.player.getEyeHeight(mc.player.getPose()), 0);
|
position.set(mc.player.getX(), mc.player.getY(), mc.player.getZ()).add(0, mc.player.getEyeHeight(mc.player.getPose()) + eyeHeightOffset.get(), 0);
|
||||||
|
|
||||||
double yaw = Rotations.getYaw(new Vec3d(targetPosition.x, targetPosition.y, targetPosition.z));
|
double yaw = Rotations.getYaw(new Vec3d(targetBox.getCenter().x, targetBox.getCenter().y, targetBox.getCenter().z));
|
||||||
|
|
||||||
double x = -Math.sin(yaw * 0.017453292) * Math.cos(pitch * 0.017453292);
|
double x = -Math.sin(yaw * 0.017453292) * Math.cos(pitch * 0.017453292);
|
||||||
double y = -Math.sin(pitch * 0.017453292);
|
double y = -Math.sin(pitch * 0.017453292);
|
||||||
@ -507,8 +584,8 @@ public class Prediction extends Module {
|
|||||||
if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER)
|
if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER)
|
||||||
isTouchingWater = position.y - (int) position.y <= fluidState.getHeight();
|
isTouchingWater = position.y - (int) position.y <= fluidState.getHeight();
|
||||||
|
|
||||||
velocity.mul(isTouchingWater ? waterDrag : airDrag);
|
velocity.mul(isTouchingWater ? waterDrag.get() : airDrag.get());
|
||||||
velocity.sub(0, gravity, 0);
|
velocity.sub(0, gravity.get(), 0);
|
||||||
|
|
||||||
if (position.y < mc.world.getBottomY()) return Double.NEGATIVE_INFINITY;
|
if (position.y < mc.world.getBottomY()) return Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
@ -523,7 +600,7 @@ public class Prediction extends Module {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (distance > targetDistance) {
|
if (distance > targetDistance) {
|
||||||
return MathHelper.lerp((targetDistance - laseDistance) / (distance - laseDistance), lastPosition.y, position.y) - targetPosition.y;
|
return MathHelper.lerp((targetDistance - laseDistance) / (distance - laseDistance), lastPosition.y, position.y) - targetBox.getCenter().y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,6 +610,8 @@ public class Prediction extends Module {
|
|||||||
private void calculateAngle() {
|
private void calculateAngle() {
|
||||||
if (targetEntity == null) return;
|
if (targetEntity == null) return;
|
||||||
|
|
||||||
|
targetCompleted = false;
|
||||||
|
|
||||||
// parabolic prediction
|
// parabolic prediction
|
||||||
if (predictionLevel.get() == 0) {
|
if (predictionLevel.get() == 0) {
|
||||||
double posX = targetEntity.getPos().getX();
|
double posX = targetEntity.getPos().getX();
|
||||||
@ -559,42 +638,43 @@ public class Prediction extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
targetCharge = 1.0;
|
targetCharge = 1.0;
|
||||||
|
targetCompleted = true;
|
||||||
|
|
||||||
calculatePath();
|
calculatePath();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d targetPosition = new Vector3d(targetEntity.getX(), targetEntity.getY() + targetEntity.getHeight() / 2.0, targetEntity.getZ());
|
double highestPitch = 0.0;
|
||||||
|
boolean findPitch = false;
|
||||||
|
|
||||||
// Basic physics prediction
|
// Basic physics prediction
|
||||||
if (predictionLevel.get() == 1) {
|
if (predictionLevel.get() >= 1) {
|
||||||
// Solve for the highest pitch
|
// Solve for the highest pitch
|
||||||
double highestPitch;
|
|
||||||
{
|
{
|
||||||
double minPitch = -90.0;
|
double minPitch = -90.0;
|
||||||
double maxPitch = 90.0;
|
double maxPitch = 90.0;
|
||||||
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
||||||
double mid1 = minPitch + (maxPitch - minPitch) / 3.0;
|
double mid1 = minPitch + (maxPitch - minPitch) / 3.0;
|
||||||
double mid2 = maxPitch - (maxPitch - minPitch) / 3.0;
|
double mid2 = maxPitch - (maxPitch - minPitch) / 3.0;
|
||||||
double mid1Height = calculateHeightOffset(targetPosition, mid1);
|
double mid1Height = calculateHeightOffset(mid1);
|
||||||
double mid2Height = calculateHeightOffset(targetPosition, mid2);
|
double mid2Height = calculateHeightOffset(mid2);
|
||||||
if (Double.isNaN(mid1Height) || Double.isNaN(mid2Height)) return;
|
if (Double.isNaN(mid1Height) || Double.isNaN(mid2Height)) return;
|
||||||
if (mid1Height < mid2Height)
|
if (mid1Height < mid2Height)
|
||||||
minPitch = mid1;
|
minPitch = mid1;
|
||||||
else maxPitch = mid2;
|
else maxPitch = mid2;
|
||||||
}
|
}
|
||||||
highestPitch = (minPitch + maxPitch) / 2.0;
|
highestPitch = (minPitch + maxPitch) / 2.0;
|
||||||
if (calculateHeightOffset(targetPosition, highestPitch) < 0.0) return;
|
if (calculateHeightOffset(highestPitch) < 0.0) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solve for the low pitch
|
// Solve for the low pitch
|
||||||
|
double targetLowPitch = highestPitch;
|
||||||
{
|
{
|
||||||
targetLowPitch = highestPitch;
|
|
||||||
double minPitch = highestPitch;
|
double minPitch = highestPitch;
|
||||||
double maxPitch = 90.0;
|
double maxPitch = 90.0;
|
||||||
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
||||||
double mid = (minPitch + maxPitch) / 2.0;
|
double mid = (minPitch + maxPitch) / 2.0;
|
||||||
double midHeight = calculateHeightOffset(targetPosition, mid);
|
double midHeight = calculateHeightOffset(mid);
|
||||||
if (Double.isNaN(midHeight)) {
|
if (Double.isNaN(midHeight)) {
|
||||||
targetLowPitch = Double.NaN;
|
targetLowPitch = Double.NaN;
|
||||||
break;
|
break;
|
||||||
@ -606,23 +686,88 @@ public class Prediction extends Module {
|
|||||||
if (!Double.isNaN(targetLowPitch)) targetLowPitch = (minPitch + maxPitch) / 2.0;
|
if (!Double.isNaN(targetLowPitch)) targetLowPitch = (minPitch + maxPitch) / 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Double.isNaN(targetLowPitch))
|
if (!Double.isNaN(targetLowPitch)) {
|
||||||
{
|
findPitch = true;
|
||||||
|
|
||||||
targetPitch = targetLowPitch;
|
targetPitch = targetLowPitch;
|
||||||
targetYaw = Rotations.getYaw(targetEntity);
|
targetYaw = Rotations.getYaw(targetEntity);
|
||||||
targetCharge = getCurrentCharge();
|
targetCharge = getCurrentCharge();
|
||||||
|
targetCompleted = true;
|
||||||
|
|
||||||
|
calculatePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you can't hit because a block is blocking, try to use a probe.
|
||||||
|
if (targetCompleted && !isHitTarget && findPitch && enableProbe.get()) {
|
||||||
|
int numProbe = (int) (probeRange.get() / probeInterval.get());
|
||||||
|
boolean[][] arrayProbe = new boolean[numProbe * 2 + 1][numProbe * 2 + 1];
|
||||||
|
|
||||||
|
double targetDistance = Math.sqrt(
|
||||||
|
(targetBox.getCenter().x - mc.player.getX()) * (targetBox.getCenter().x - mc.player.getX()) +
|
||||||
|
(targetBox.getCenter().z - mc.player.getZ()) * (targetBox.getCenter().z - mc.player.getZ())
|
||||||
|
);
|
||||||
|
|
||||||
|
double delta = Math.atan2(targetDistance, probeInterval.get());
|
||||||
|
|
||||||
|
double centerYaw = targetYaw;
|
||||||
|
double centerPitch = targetPitch;
|
||||||
|
|
||||||
|
for (int i = 0; i < numProbe * 2 + 1; ++i) {
|
||||||
|
for (int j = 0; j < numProbe * 2 + 1; ++j) {
|
||||||
|
targetYaw = centerYaw - (i - numProbe) * delta;
|
||||||
|
targetPitch = centerPitch - (j - numProbe) * delta;
|
||||||
|
calculatePath();
|
||||||
|
arrayProbe[i][j] = isHitTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[][][] validProbe = new int[numProbe * 2 + 1][numProbe * 2 + 1][4];
|
||||||
|
|
||||||
|
for (int i = 0; i < numProbe * 2 + 1; ++i) {
|
||||||
|
for (int j = 0; j < numProbe * 2 + 1; ++j) {
|
||||||
|
if (i == 0) validProbe[i][j][0] = arrayProbe[i][j] ? 1 : 0;
|
||||||
|
else validProbe[i][j][0] = (arrayProbe[i][j] ? 1 : 0) + validProbe[i - 1][j][0];
|
||||||
|
if (j == 0) validProbe[i][j][1] = arrayProbe[i][j] ? 1 : 0;
|
||||||
|
else validProbe[i][j][1] = (arrayProbe[i][j] ? 1 : 0) + validProbe[i][j - 1][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = numProbe * 2; i >= 0; --i) {
|
||||||
|
for (int j = numProbe * 2; j >= 0; --j) {
|
||||||
|
if (i == numProbe * 2) validProbe[i][j][2] = arrayProbe[i][j] ? 1 : 0;
|
||||||
|
else validProbe[i][j][2] = (arrayProbe[i][j] ? 1 : 0) + validProbe[i + 1][j][2];
|
||||||
|
if (j == numProbe * 2) validProbe[i][j][3] = arrayProbe[i][j] ? 1 : 0;
|
||||||
|
else validProbe[i][j][3] = (arrayProbe[i][j] ? 1 : 0) + validProbe[i][j + 1][3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxProbe = 0;
|
||||||
|
targetYaw = centerYaw;
|
||||||
|
targetPitch = centerPitch;
|
||||||
|
|
||||||
|
for (int i = numProbe * 2; i >= 0; --i) {
|
||||||
|
for (int j = numProbe * 2; j >= 0; --j) {
|
||||||
|
int x = Math.max(Math.min(validProbe[i][j][0], validProbe[i][j][1]), Math.min(validProbe[i][j][2], validProbe[i][j][3]));
|
||||||
|
if (x > maxProbe) {
|
||||||
|
maxProbe = x;
|
||||||
|
targetYaw = centerYaw - (i - numProbe) * delta;
|
||||||
|
targetPitch = centerPitch - (j - numProbe) * delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
calculatePath();
|
calculatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solve for the high pitch
|
// Solve for the high pitch if allowed
|
||||||
if (!isHitTarget && allowHighThrows.get()) {
|
if (!isHitTarget && allowHighThrows.get()) {
|
||||||
targetHighPitch = highestPitch;
|
double targetHighPitch = highestPitch;
|
||||||
double minPitch = -90.0;
|
double minPitch = -90.0;
|
||||||
double maxPitch = highestPitch;
|
double maxPitch = highestPitch;
|
||||||
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
for (int i = 0; iterationSteps.get() > 0 ? i < iterationSteps.get() : maxPitch - minPitch > iterationEpsilon.get(); i++) {
|
||||||
double mid = (minPitch + maxPitch) / 2.0;
|
double mid = (minPitch + maxPitch) / 2.0;
|
||||||
double midHeight = calculateHeightOffset(targetPosition, mid);
|
double midHeight = calculateHeightOffset(mid);
|
||||||
if (Double.isNaN(midHeight)) {
|
if (Double.isNaN(midHeight)) {
|
||||||
targetHighPitch = Double.NaN;
|
targetHighPitch = Double.NaN;
|
||||||
break;
|
break;
|
||||||
@ -631,23 +776,26 @@ public class Prediction extends Module {
|
|||||||
minPitch = mid;
|
minPitch = mid;
|
||||||
else maxPitch = mid;
|
else maxPitch = mid;
|
||||||
}
|
}
|
||||||
if (!Double.isNaN(targetHighPitch)) targetHighPitch = (minPitch + maxPitch) / 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isHitTarget && !Double.isNaN(targetHighPitch) && allowHighThrows.get()) {
|
if (!Double.isNaN(targetHighPitch)) {
|
||||||
|
targetHighPitch = (minPitch + maxPitch) / 2.0;
|
||||||
|
|
||||||
targetPitch = targetHighPitch;
|
targetPitch = targetHighPitch;
|
||||||
targetYaw = Rotations.getYaw(targetEntity);
|
targetYaw = Rotations.getYaw(targetEntity);
|
||||||
targetCharge = getCurrentCharge();
|
targetCharge = getCurrentCharge();
|
||||||
|
targetCompleted = true;
|
||||||
|
|
||||||
calculatePath();
|
calculatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void aim(double tickDelta) {
|
private void aim(double tickDelta) {
|
||||||
if (targetEntity == null) return;
|
if (targetEntity == null) return;
|
||||||
|
if (!targetCompleted) return;
|
||||||
|
if (!isHitTarget && aimOnlyHit.get()) return;
|
||||||
|
if (!mc.options.useKey.isPressed()) return;
|
||||||
|
if (!InvUtils.testInHands(Items.BOW)) return;
|
||||||
|
|
||||||
if (instant.get()) {
|
if (instant.get()) {
|
||||||
mc.player.setYaw((float) targetYaw);
|
mc.player.setYaw((float) targetYaw);
|
||||||
|
Reference in New Issue
Block a user