Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(LeastDifferencePreference): always choose a spot on or in the box #5637

Merged
merged 9 commits into from
Feb 15, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ object ModuleSprint : ClientModule("Sprint", Category.MOVEMENT) {
MathHelper.sin(deltaYaw * 0.017453292f) > 1.0E-5
val preventSprint = (if (player.isOnGround) stopOnGround else stopOnAir)
&& !shouldSprintOmnidirectional
&& RotationManager.workingRotationTarget?.movementCorrection == MovementCorrection.OFF && !hasForwardMovement
&& RotationManager.workingRotationTarget?.movementCorrection == MovementCorrection.OFF
&& !hasForwardMovement

return running && preventSprint
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ object ModuleFreeCam : ClientModule("FreeCam", Category.RENDER, disableOnQuit =
return@handler
}

RotationManager.setRotationTarget(rotationsConfigurable.toAimPlan(lookAt), Priority.NOT_IMPORTANT, ModuleFreeCam)
RotationManager.setRotationTarget(rotationsConfigurable.toAimPlan(lookAt),
Priority.NOT_IMPORTANT, ModuleFreeCam)
}

fun applyCameraPosition(entity: Entity, tickDelta: Float) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,43 @@ import net.ccbluex.liquidbounce.utils.aiming.RotationManager
import net.ccbluex.liquidbounce.utils.aiming.data.Rotation
import net.ccbluex.liquidbounce.utils.client.player
import net.ccbluex.liquidbounce.utils.entity.rotation
import net.ccbluex.liquidbounce.utils.math.geometry.Line
import net.ccbluex.liquidbounce.utils.math.minus
import net.ccbluex.liquidbounce.utils.math.plus
import net.ccbluex.liquidbounce.utils.math.sq
import net.ccbluex.liquidbounce.utils.math.times
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d

class LeastDifferencePreference(
private val baseRotation: Rotation,
private val basePoint: Vec3d? = null,
private val basePoint: Vec3d? = null
) : RotationPreference {

override fun getPreferredSpot(eyesPos: Vec3d, range: Double): Vec3d {
if (this.basePoint != null) {
return this.basePoint
if (basePoint != null) {
return basePoint
}

return eyesPos + this.baseRotation.directionVector * range
return eyesPos + baseRotation.directionVector * range
}

override fun getPreferredSpotOnBox(box: Box, eyesPos: Vec3d, range: Double): Vec3d? {
if (basePoint != null) {
return basePoint
}

if (box.contains(eyesPos)) {
return eyesPos
}

val preferredSpot = getPreferredSpot(eyesPos, range)
if (box.contains(preferredSpot)) {
return preferredSpot
}

val look = Line(eyesPos, preferredSpot - eyesPos)
return look.getPointOnBoxInDirection(box)?.takeIf { it.squaredDistanceTo(eyesPos) <= range.sq() }
}

override fun compare(o1: Rotation, o2: Rotation): Int {
Expand All @@ -47,12 +69,14 @@ class LeastDifferencePreference(
}

companion object {

val LEAST_DISTANCE_TO_CURRENT_ROTATION: LeastDifferencePreference
get() = LeastDifferencePreference(RotationManager.currentRotation ?: player.rotation)

fun leastDifferenceToLastPoint(eyes: Vec3d, point: Vec3d): LeastDifferencePreference {
return LeastDifferencePreference(Rotation.lookingAt(point, from = eyes), point)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
package net.ccbluex.liquidbounce.utils.aiming.preference

import net.ccbluex.liquidbounce.utils.aiming.data.Rotation
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d

interface RotationPreference : Comparator<Rotation> {
fun getPreferredSpot(
eyesPos: Vec3d,
range: Double,
): Vec3d
}

fun getPreferredSpot(eyesPos: Vec3d, range: Double, ): Vec3d

fun getPreferredSpotOnBox(box: Box, eyesPos: Vec3d, range: Double): Vec3d? {
return getPreferredSpot(eyesPos, range)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ fun raytraceBox(
val rangeSquared = range * range
val wallsRangeSquared = wallsRange * wallsRange

val preferredSpot = rotationPreference.getPreferredSpot(eyes, range)
var preferredSpotOnBox = if (box.contains(eyes) && box.contains(preferredSpot)) {
val preferredSpot = rotationPreference.getPreferredSpotOnBox(box, eyes, range) ?: return null
val preferredSpotOnBox = if (box.contains(eyes) && box.contains(preferredSpot)) {
preferredSpot
} else {
box.raycast(eyes, preferredSpot).getOrNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,11 @@ fun Box.isHitByLine(start: Vec3d, p: Vec3d): Boolean {

val Box.size: Double
get() = this.lengthX * this.lengthY * this.lengthZ

fun Box.getCoordinate(direction: Direction): Double {
return if (direction.direction == Direction.AxisDirection.POSITIVE) {
this.getMax(direction.axis)
} else {
this.getMin(direction.axis)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,10 @@ fun Vec3d.toVec3() = Vec3(this.x, this.y, this.z)
fun Vec3d.toVec3i() = Vec3i(this.x.toInt(), this.y.toInt(), this.z.toInt())

fun Vec3d.toBlockPos() = BlockPos.ofFloored(x, y, z)!!

fun Vec3d.preferOver(other: Vec3d): Vec3d {
val x = if (this.x == 0.0) other.x else this.x
val y = if (this.y == 0.0) other.y else this.y
val z = if (this.z == 0.0) other.z else this.z
return Vec3d(x, y, z)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
*/
package net.ccbluex.liquidbounce.utils.math.geometry

import net.ccbluex.liquidbounce.utils.math.getCoordinate
import net.ccbluex.liquidbounce.utils.math.plus
import net.ccbluex.liquidbounce.utils.math.preferOver
import net.minecraft.util.math.Box
import net.minecraft.util.math.Direction
import net.minecraft.util.math.MathHelper
import net.minecraft.util.math.Vec3d
import kotlin.math.abs

@Suppress("TooManyFunctions")
open class Line(val position: Vec3d, val direction: Vec3d) {

companion object {
Expand Down Expand Up @@ -85,6 +90,41 @@ open class Line(val position: Vec3d, val direction: Vec3d) {
return doubleArrayOf(phi1, phi2)
}

/**
* Finds the closest point on the box's surface to the [position] in positive [direction].
*/
fun getPointOnBoxInDirection(box: Box): Vec3d? {
val candidates = Direction.entries.mapNotNull { dir ->
val positionCoordinate = position.getComponentAlongAxis(dir.axis)
val directionCoordinate = direction.getComponentAlongAxis(dir.axis)
computeIntersection(box.getCoordinate(dir), positionCoordinate, directionCoordinate)?.let { factor ->
val pointOnFace = dir.doubleVector.multiply(factor)
val directionalPointsOnFace = position.add(direction.normalize().multiply(factor))
pointOnFace.preferOver(directionalPointsOnFace)
}
}

var minDistanceSq = Double.POSITIVE_INFINITY
var intersection: Vec3d? = null
candidates.forEach { candidate ->
if (position.squaredDistanceTo(candidate) < minDistanceSq) {
minDistanceSq = position.squaredDistanceTo(candidate)
intersection = candidate
}
}

return intersection
}

private fun computeIntersection(plane: Double, pos: Double, dir: Double): Double? {
if (dir == 0.0) {
return null
}

val t = (plane - pos) / dir
return if (t > 0) t else null
}

@Suppress("MaxLineLength")
protected open fun calculateNearestPhiTo(other: Line): Double? {
val pos1X = other.position.x
Expand Down
Loading