Skip to content

Commit 897f3fd

Browse files
committed
Bug Fix Waypoints
1 parent eddb263 commit 897f3fd

File tree

1 file changed

+73
-16
lines changed

1 file changed

+73
-16
lines changed

src/main/java/net/wurstclient/hacks/WaypointsHack.java

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public final class WaypointsHack extends Hack
6767
private static final Pattern END_PORTAL_NAME_PATTERN =
6868
Pattern.compile("^End Portal (\\d+)$", Pattern.CASE_INSENSITIVE);
6969
private static final long PORTAL_RECORD_COOLDOWN_MS = 2000L;
70+
private static final long OCCLUSION_CACHE_MS = 250L;
7071
private static final String[] DEATH_MESSAGE_PHRASES =
7172
{"was slain", "was shot", "was blown", "was killed", "was fireballed",
7273
"was roasted", "was doomed", "was squashed", "was pummeled",
@@ -93,6 +94,7 @@ public final class WaypointsHack extends Hack
9394
private final Set<UUID> knownDead = new HashSet<>();
9495
// Guard to avoid handling our own injected chat messages
9596
private boolean sendingOwnChat = false;
97+
private final Map<UUID, OcclusionSample> occlusionCache = new HashMap<>();
9698

9799
private final SliderSetting waypointRenderDistance = new SliderSetting(
98100
"Waypoint render distance", 127, 0, DISTANCE_SLIDER_INFINITE, 1,
@@ -232,6 +234,7 @@ protected void onEnable()
232234
EVENTS.add(GUIRenderListener.class, this);
233235
otherDeathCooldown.clear();
234236
knownDead.clear();
237+
occlusionCache.clear();
235238
}
236239

237240
@Override
@@ -245,6 +248,7 @@ protected void onDisable()
245248
EVENTS.remove(GUIRenderListener.class, this);
246249
otherDeathCooldown.clear();
247250
knownDead.clear();
251+
occlusionCache.clear();
248252
}
249253

250254
// Add a temporary waypoint that should not be persisted. Returns the
@@ -775,6 +779,13 @@ public void onRender(PoseStack matrices, float partialTicks)
775779
return;
776780

777781
var list = new ArrayList<>(manager.all());
782+
long nowMs = System.currentTimeMillis();
783+
double configuredLabelRange = waypointRenderDistance.getValue();
784+
boolean configuredInfiniteLabels =
785+
configuredLabelRange >= DISTANCE_SLIDER_INFINITE;
786+
double occlusionMaxDistSq =
787+
configuredInfiniteLabels ? Double.POSITIVE_INFINITY
788+
: Math.max(0.0, configuredLabelRange * configuredLabelRange);
778789
double beaconRange = beaconRenderDistance.getValue();
779790
boolean beaconInfinite = beaconRange >= DISTANCE_SLIDER_INFINITE;
780791
boolean beaconsEnabled = beaconInfinite || beaconRange > 0.0;
@@ -792,20 +803,7 @@ public void onRender(PoseStack matrices, float partialTicks)
792803

793804
double distSq = MC.player.distanceToSqr(wp.getX() + 0.5,
794805
wp.getY() + 0.5, wp.getZ() + 0.5);
795-
boolean applyObscuredRules =
796-
dimObscuredOnScreenWaypoints.isChecked()
797-
|| iconOnlyForObscuredOnScreenWaypoints.isChecked();
798-
boolean obscured = applyObscuredRules && isWaypointObscured(wp);
799-
boolean directlyLooked =
800-
obscured && isDirectlyLookingAtWaypoint(wp, 5.0);
801-
boolean suppressDetails = obscured && !directlyLooked
802-
&& iconOnlyForObscuredOnScreenWaypoints.isChecked();
803806
int waypointColor = applyFade(w.getColor(), distSq);
804-
if(obscured && !directlyLooked
805-
&& dimObscuredOnScreenWaypoints.isChecked())
806-
{
807-
waypointColor = dimForObscured(waypointColor);
808-
}
809807
double dist = Math.sqrt(distSq);
810808
double trd = waypointRenderDistance.getValue();
811809
boolean infiniteLabels = trd >= DISTANCE_SLIDER_INFINITE;
@@ -858,6 +856,24 @@ public void onRender(PoseStack matrices, float partialTicks)
858856

859857
if(renderLabel)
860858
{
859+
boolean applyObscuredRules =
860+
dimObscuredOnScreenWaypoints.isChecked()
861+
|| iconOnlyForObscuredOnScreenWaypoints.isChecked();
862+
int labelColor = waypointColor;
863+
boolean suppressDetails = false;
864+
if(applyObscuredRules)
865+
{
866+
boolean directlyLooked =
867+
isDirectlyLookingAtWaypoint(wp, 5.0);
868+
boolean obscured =
869+
!directlyLooked && isWaypointObscuredCached(w, wp,
870+
distSq, occlusionMaxDistSq, nowMs);
871+
suppressDetails = obscured
872+
&& iconOnlyForObscuredOnScreenWaypoints.isChecked();
873+
if(obscured && dimObscuredOnScreenWaypoints.isChecked())
874+
labelColor = dimForObscured(labelColor);
875+
}
876+
861877
String title = w.getName() == null ? "" : w.getName();
862878
String icon = iconChar(w.getIcon());
863879
if(suppressDetails)
@@ -944,11 +960,11 @@ public void onRender(PoseStack matrices, float partialTicks)
944960
}
945961
// Keep a constant 10px separation using local pixel offset
946962
float sepPx = 10.0f;
947-
drawWorldLabel(matrices, title, lx, ly, lz, waypointColor,
948-
scale, -sepPx);
963+
drawWorldLabel(matrices, title, lx, ly, lz, labelColor, scale,
964+
-sepPx);
949965
if(!suppressDetails)
950966
drawWorldLabel(matrices, distanceText, lx, ly, lz,
951-
waypointColor, (float)(scale * 0.9f), 0f);
967+
labelColor, (float)(scale * 0.9f), 0f);
952968
}
953969
}
954970
}
@@ -1650,13 +1666,40 @@ private boolean isWaypointObscured(BlockPos waypointPos)
16501666
{
16511667
if(MC.player == null || MC.level == null || waypointPos == null)
16521668
return false;
1669+
1670+
// If the waypoint's chunk isn't loaded, LOS is unknown. Treat it as
1671+
// obscured to avoid far waypoints popping back to full text.
1672+
if(!MC.level.hasChunkAt(waypointPos))
1673+
return true;
16531674

16541675
Vec3 eyes = MC.player.getEyePosition(1.0F);
16551676
Vec3 target = new Vec3(waypointPos.getX() + 0.5,
16561677
waypointPos.getY() + 1.2, waypointPos.getZ() + 0.5);
16571678
return !BlockUtils.hasLineOfSight(eyes, target);
16581679
}
16591680

1681+
private boolean isWaypointObscuredCached(Waypoint waypoint,
1682+
BlockPos waypointPos, double distSq, double maxOcclusionDistSq,
1683+
long nowMs)
1684+
{
1685+
if(waypoint == null || waypointPos == null)
1686+
return false;
1687+
1688+
// Respect user's waypoint render distance setting.
1689+
if(distSq > maxOcclusionDistSq)
1690+
return false;
1691+
1692+
OcclusionSample cached = occlusionCache.get(waypoint.getUuid());
1693+
if(cached != null && cached.pos.equals(waypointPos)
1694+
&& nowMs - cached.timestampMs <= OCCLUSION_CACHE_MS)
1695+
return cached.obscured;
1696+
1697+
boolean obscured = isWaypointObscured(waypointPos);
1698+
occlusionCache.put(waypoint.getUuid(),
1699+
new OcclusionSample(waypointPos.immutable(), obscured, nowMs));
1700+
return obscured;
1701+
}
1702+
16601703
private boolean isDirectlyLookingAtWaypoint(BlockPos waypointPos,
16611704
double maxAngleDeg)
16621705
{
@@ -1702,6 +1745,20 @@ private static final class WaypointEntry
17021745
}
17031746
}
17041747

1748+
private static final class OcclusionSample
1749+
{
1750+
final BlockPos pos;
1751+
final boolean obscured;
1752+
final long timestampMs;
1753+
1754+
OcclusionSample(BlockPos pos, boolean obscured, long timestampMs)
1755+
{
1756+
this.pos = pos;
1757+
this.obscured = obscured;
1758+
this.timestampMs = timestampMs;
1759+
}
1760+
}
1761+
17051762
private enum PortalKind
17061763
{
17071764
NETHER,

0 commit comments

Comments
 (0)