From 8f930f1a95f2b4ff991f2404963cd4259bbfd1ce Mon Sep 17 00:00:00 2001 From: Architector #4 <23612841+Architector4@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:20:39 +0300 Subject: [PATCH] AHuman - rewrite EstimateJumpHeight I got bored and set a scene to have zero gravity and soon found that the AIs caused this function to loop forever. I looked at it, was horrified by the code, yet felt it's simple enough to fix up in its entirety. On quick testing, returns about the same results as the old code. Doesn't loop forever with no gravity though, and also accounts for burst fuel consumption a little better now lol --- Source/Entities/AHuman.cpp | 60 +++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/Source/Entities/AHuman.cpp b/Source/Entities/AHuman.cpp index f84fecb1b..56866a98e 100644 --- a/Source/Entities/AHuman.cpp +++ b/Source/Entities/AHuman.cpp @@ -967,27 +967,61 @@ float AHuman::EstimateJumpHeight() const { return 0.0F; } + // Estimate by "simulating" the character velocity frame by frame as the jetpack is used. + // In pixels per second. Positive value means moving upward. + // + // Start with zero, for now. + float currentYVelocity = 0.0F; + + // Upward acceleration per frame. + float yGravity = -(g_SceneMan.GetGlobalAcc().GetY() * g_TimerMan.GetDeltaTimeSecs()); + float totalMass = GetMass(); - float fuelTime = m_pJetpack->GetJetTimeTotal(); - float fuelUseMultiplier = m_pJetpack->GetThrottleFactor(); float impulseBurst = m_pJetpack->EstimateImpulse(true) / totalMass; float impulseThrust = m_pJetpack->EstimateImpulse(false) / totalMass; + float fuelTime = m_pJetpack->GetJetTimeTotal(); + float fuelUseMultiplierThrust = m_pJetpack->GetThrottleFactor(); + float fuelUseMultiplierBurst = fuelUseMultiplierThrust * impulseBurst / impulseThrust; + + bool hasBursted = false; + + float totalHeight = 0.0F; + + // Simulate up until we start falling. + while (true) { + // Account for the forces upon us. + if (!hasBursted && fuelTime > 0.0F) { + currentYVelocity += impulseBurst; + fuelTime -= g_TimerMan.GetDeltaTimeMS() * fuelUseMultiplierBurst; + hasBursted = true; + } - Vector globalAcc = g_SceneMan.GetGlobalAcc() * g_TimerMan.GetDeltaTimeSecs(); - Vector currentVelocity = Vector(0.0F, -impulseBurst); - float totalHeight = currentVelocity.GetY() * g_TimerMan.GetDeltaTimeSecs() * c_PPM; - do { - currentVelocity += globalAcc; - totalHeight += currentVelocity.GetY() * g_TimerMan.GetDeltaTimeSecs() * c_PPM; if (fuelTime > 0.0F) { - currentVelocity.m_Y -= impulseThrust; - fuelTime -= g_TimerMan.GetDeltaTimeMS() * fuelUseMultiplier; + currentYVelocity += impulseThrust; + fuelTime -= g_TimerMan.GetDeltaTimeMS() * fuelUseMultiplierThrust; } - } while (currentVelocity.GetY() < 0.0F); - float finalCalculatedHeight = totalHeight * -1.0F * c_MPP; + if (currentYVelocity + yGravity >= currentYVelocity) { + // Velocity is too big or gravity is too small. Either way, this will loop forever now. + // Just assume that we can reach the stars. + totalHeight = g_SceneMan.GetSceneHeight() * c_MPP; + break; + } + + currentYVelocity += yGravity; + + if (currentYVelocity > 0.0F) { + // If we're still flying up, that means more height. + totalHeight += currentYVelocity * g_TimerMan.GetDeltaTimeSecs() * c_PPM; + } else { + // If we're not, that means we're done simulating. + break; + } + } + float finalHeightMultipler = 0.6f; // Make us think we can do less because AI path following is shit - return finalCalculatedHeight * finalHeightMultipler; + + return totalHeight * c_MPP * finalHeightMultipler; } bool AHuman::EquipShield() {