Skip to content

Commit

Permalink
Initial work to make Reach raytrace check also check for entities
Browse files Browse the repository at this point in the history
  • Loading branch information
Axionize committed Nov 16, 2024
1 parent 35f7914 commit 205e169
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/main/java/ac/grim/grimac/checks/impl/combat/Reach.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ private String checkReach(PacketEntity reachEntity, Vector3d from, boolean isPre
// - You may have to adjust the epsilon if you increase the reach threshold, especially by a lot
// ...but there is literally no reason you would ever want to increase it, only decrease, so that doesn't matter.
if (hitResult != null && (minDistance * minDistance) - hitResult.getFirst() > ENTITY_HITBOX_REACH_EPSILON) { // returned double is distanceSq
System.out.println("Dist Diff: " + Math.sqrt((minDistance * minDistance) - hitResult.getFirst()));
minDistance = Double.MIN_VALUE;
foundHitData = hitResult.getSecond();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package ac.grim.grimac.utils.data;

import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.collisions.datatypes.CollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.NoCollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
Expand Down Expand Up @@ -82,6 +84,33 @@ public static SimpleCollisionBox combineCollisionBox(SimpleCollisionBox one, Sim
return new SimpleCollisionBox(minX, minY, minZ, maxX, maxY, maxZ);
}

public static CollisionBox getOverlapHitbox(CollisionBox b1, CollisionBox b2) {
if (b1 == NoCollisionBox.INSTANCE || b2 == NoCollisionBox.INSTANCE) {
return NoCollisionBox.INSTANCE;
} else if (!(b1 instanceof SimpleCollisionBox) || !(b2 instanceof SimpleCollisionBox)) {
throw new IllegalArgumentException("Both b1 and b2 must be SimpleCollisionBox instances");
}

SimpleCollisionBox box1 = (SimpleCollisionBox) b1;
SimpleCollisionBox box2 = (SimpleCollisionBox) b2;

// Calculate the potential overlap along each axis
double overlapMinX = Math.max(box1.minX, box2.minX);
double overlapMaxX = Math.min(box1.maxX, box2.maxX);
double overlapMinY = Math.max(box1.minY, box2.minY);
double overlapMaxY = Math.min(box1.maxY, box2.maxY);
double overlapMinZ = Math.max(box1.minZ, box2.minZ);
double overlapMaxZ = Math.min(box1.maxZ, box2.maxZ);

// Check if there's actual overlap along each axis
if (overlapMinX > overlapMaxX || overlapMinY > overlapMaxY || overlapMinZ > overlapMaxZ) {
return null; // No overlap, return null or an appropriate "empty" box representation
}

// Return the overlapping hitbox
return new SimpleCollisionBox(overlapMinX, overlapMinY, overlapMinZ, overlapMaxX, overlapMaxY, overlapMaxZ);
}

// To avoid huge branching when bruteforcing interpolation -
// we combine the collision boxes for the steps.
//
Expand Down Expand Up @@ -117,6 +146,43 @@ public SimpleCollisionBox getPossibleLocationCombined() {
return minimumInterpLocation;
}

public CollisionBox getOverlapLocationCombined() {
int interpSteps = getInterpolationSteps();

double stepMinX = (targetLocation.minX - startingLocation.minX) / (double) interpSteps;
double stepMaxX = (targetLocation.maxX - startingLocation.maxX) / (double) interpSteps;
double stepMinY = (targetLocation.minY - startingLocation.minY) / (double) interpSteps;
double stepMaxY = (targetLocation.maxY - startingLocation.maxY) / (double) interpSteps;
double stepMinZ = (targetLocation.minZ - startingLocation.minZ) / (double) interpSteps;
double stepMaxZ = (targetLocation.maxZ - startingLocation.maxZ) / (double) interpSteps;

CollisionBox overlapLocation = new SimpleCollisionBox(
startingLocation.minX + (interpolationStepsLowBound * stepMinX),
startingLocation.minY + (interpolationStepsLowBound * stepMinY),
startingLocation.minZ + (interpolationStepsLowBound * stepMinZ),
startingLocation.maxX + (interpolationStepsLowBound * stepMaxX),
startingLocation.maxY + (interpolationStepsLowBound * stepMaxY),
startingLocation.maxZ + (interpolationStepsLowBound * stepMaxZ));

for (int step = interpolationStepsLowBound + 1; step <= interpolationStepsHighBound; step++) {
overlapLocation = getOverlapHitbox(overlapLocation, new SimpleCollisionBox(
startingLocation.minX + (step * stepMinX),
startingLocation.minY + (step * stepMinY),
startingLocation.minZ + (step * stepMinZ),
startingLocation.maxX + (step * stepMaxX),
startingLocation.maxY + (step * stepMaxY),
startingLocation.maxZ + (step * stepMaxZ)));

if (overlapLocation == null) {
// No overlap found, you might want to handle this case specifically
// For example, return null or a default box
return NoCollisionBox.INSTANCE;
}
}

return overlapLocation;
}

public void updatePossibleStartingLocation(SimpleCollisionBox possibleLocationCombined) {
//GrimAC.staticGetLogger().info(ChatColor.BLUE + "Updated new starting location as second trans hasn't arrived " + startingLocation);
this.startingLocation = combineCollisionBox(startingLocation, possibleLocationCombined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package ac.grim.grimac.utils.data.packetentity;

import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.collisions.datatypes.CollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import ac.grim.grimac.utils.data.ReachInterpolationData;
import ac.grim.grimac.utils.data.TrackedPosition;
Expand Down Expand Up @@ -189,6 +190,14 @@ public void setPositionRaw(SimpleCollisionBox box) {
this.newPacketLocation = new ReachInterpolationData(box);
}

public CollisionBox getMinimumPossibleCollisionBoxes() {
if (oldPacketLocation == null) {
return newPacketLocation.getOverlapLocationCombined();
}

return ReachInterpolationData.getOverlapHitbox(oldPacketLocation.getOverlapLocationCombined(), newPacketLocation.getOverlapLocationCombined());
}

public SimpleCollisionBox getPossibleCollisionBoxes() {
if (oldPacketLocation == null) {
return newPacketLocation.getPossibleLocationCombined();
Expand Down
22 changes: 18 additions & 4 deletions src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,26 +293,40 @@ public static HitData getNearestHitResult(GrimPlayer player, PacketEntity target

// Check entities
for (PacketEntity entity : player.compensatedEntities.entityMap.values()) {
SimpleCollisionBox box = entity.getPossibleCollisionBoxes();
SimpleCollisionBox box = null;
// 1.7 and 1.8 players get a bit of extra hitbox (this is why you should use 1.8 on cross version servers)
// Yes, this is vanilla and not uncertainty. All reach checks have this or they are wrong.
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_9)) {
box.expand(0.1f);
}

if (entity.equals(targetEntity)) {
box = entity.getPossibleCollisionBoxes();
box.expand(player.checkManager.getPacketCheck(Reach.class).reachThreshold);
// This is better than adding to the reach, as 0.03 can cause a player to miss their target
// Adds some more than 0.03 uncertainty in some cases, but a good trade off for simplicity
//
// Just give the uncertainty on 1.9+ clients as we have no way of knowing whether they had 0.03 movement
if (!player.packetStateData.didLastLastMovementIncludePosition || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9))
box.expand(player.getMovementThreshold());
if (ReachUtils.isVecInside(box, eyePos)) {
return new EntityHitData(entity, eyePos);
}
} else {
CollisionBox b = entity.getMinimumPossibleCollisionBoxes();
if (b instanceof NoCollisionBox) {
continue;
} else {
box = (SimpleCollisionBox) b;
}
// todo, shrink by reachThreshold as well for non-target entities?
if (!player.packetStateData.didLastLastMovementIncludePosition || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9))
box.expand(-player.getMovementThreshold());
if (ReachUtils.isVecInside(box, eyePos)) {
continue;
}
}
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_9)) {
box.expand(0.1f);
}


Pair<Vector, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(Math.sqrt(closestDistanceSquared)));

Expand Down

0 comments on commit 205e169

Please sign in to comment.