From 41c758f6a47e5d6e0e8d69d3e764753c4260f85f Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Fri, 26 Jun 2026 23:02:16 -0500 Subject: [PATCH] Avoid GPS node multiplier trampoline --- red4ext/EdgeWeightGPS/src/Main.cpp | 73 ++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index e0c2e91..139f231 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -214,6 +214,9 @@ constexpr uintptr_t kMinimumReadableAddress = 0x10000; constexpr float kGpsSolverHighwayMultiplier = 0.35f; constexpr float kGpsSolverGpsOnlyMultiplier = 1.10f; constexpr float kGpsSolverPavementMultiplier = 1.25f; +constexpr std::array kGpsSolverNonRoadMultipliers = { + 10.0f, 6.0f, 2.0f, 0.0f, 4.0f, 2.5f, 1.5f, 0.0f, +}; constexpr bool kGpsSpatialPatchRequiresRouteProducer = true; constexpr float kGpsSpatialHighwayMultiplier = 0.62f; constexpr float kGpsSpatialRoadMultiplier = 1.0f; @@ -4199,6 +4202,16 @@ float GpsSolverNodeWeightMultiplier(uint16_t aFlags) return 1.0f; } +float ReadGpsSolverNonRoadMultiplier(uint32_t aRetry) +{ + if (aRetry < kGpsSolverNonRoadMultipliers.size()) + { + return kGpsSolverNonRoadMultipliers[aRetry]; + } + + return 1.0f; +} + float TrafficEdgeScoreMultiplier(uint16_t aFlags, bool aDriving) { if (!aDriving) @@ -4873,26 +4886,56 @@ float DetourGpsAuxMultiplier(void* aJob, void* aNode) float DetourGpsNodeMultiplier(void* aJob, void* aNode) { float result = 1.0f; - if (gOriginalGpsNodeMultiplier) - { - result = gOriginalGpsNodeMultiplier(aJob, aNode); - } - uint32_t mode = 0; const auto jobAddress = reinterpret_cast(aJob); - const auto hasMode = aJob && TryReadMemory(reinterpret_cast(jobAddress + 0xC4), mode); - if (hasMode && mode == 2 && std::isfinite(result)) + if (!aJob || !TryReadMemory(reinterpret_cast(jobAddress + 0xC4), mode)) { - uint16_t nodeFlags = 0; - const auto nodeAddress = reinterpret_cast(aNode); - if (aNode && TryReadMemory(reinterpret_cast(nodeAddress + 0x88), nodeFlags)) + return result; + } + + uint16_t nodeFlags = 0; + const auto nodeAddress = reinterpret_cast(aNode); + + if (mode == 1) + { + if (!aNode || !TryReadMemory(reinterpret_cast(nodeAddress + 0x88), nodeFlags)) { - const auto patchMultiplier = GpsSolverNodeWeightMultiplier(nodeFlags); - if (patchMultiplier != 1.0f) - { - result *= patchMultiplier; - } + return result; } + + return (nodeFlags & kTrafficLaneFlagPavement) != 0 ? 1.0f : 1.5f; + } + + if (mode != 0 && mode != 2 && mode != 4) + { + return result; + } + + if (!aNode || !TryReadMemory(reinterpret_cast(nodeAddress + 0x88), nodeFlags)) + { + return result; + } + + if ((nodeFlags & kTrafficLaneFlagRoad) != 0) + { + result = (nodeFlags & 0x0001) != 0 ? 1.0f : 1.2f; + + uint8_t node93 = 0; + if (TryReadMemory(reinterpret_cast(nodeAddress + 0x93), node93) && node93 == 1) + { + result *= 1.1f; + } + } + else + { + uint32_t retry = 0; + TryReadMemory(reinterpret_cast(jobAddress + 0x54), retry); + result = ReadGpsSolverNonRoadMultiplier(retry); + } + + if (mode == 2 && std::isfinite(result)) + { + result *= GpsSolverNodeWeightMultiplier(nodeFlags); } if (kEnableGpsMultiplierSignatureTrace)