diff --git a/Source/Entities/AEmitter.cpp b/Source/Entities/AEmitter.cpp index e407c1e40..5803b963a 100644 --- a/Source/Entities/AEmitter.cpp +++ b/Source/Entities/AEmitter.cpp @@ -278,29 +278,26 @@ float AEmitter::EstimateImpulse(bool burst) { if (emission->PushesEmitter()) { // TODO: we're not checking emission start/stop times here, so this will always calculate the impulse as if the emission was active. // There's not really an easy way to do this, since the emission rate is not necessarily constant over time. + float emissionsPerFrame = (emission->GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs(); + float scale = 1.0F; - // TODO: burst emissions shouldn't be affected by delta time, but they were. - // However our values were tuned for 60hz, so hack in constant 60Hz deltatime in milliseconds. - float deltaTimeSecs = burst ? 1.0f / 60.0f : g_TimerMan.GetDeltaTimeSecs(); + // Get all the particles emitted this frame + emissionsPerFrame *= emission->GetParticleCount(); - float emissions = (emission->GetRate() / 60.0f) * deltaTimeSecs; - float scale = 1.0F; + // When bursting, add on all the bursted emissions + // We also use m_BurstScale on ALL emissions, not just the extra bursted ones + // This is a bit funky but consistent with the code that applies the impulse if (burst) { - emissions *= emission->GetBurstSize(); + emissionsPerFrame += emission->GetBurstSize(); scale = m_BurstScale; } - if (emissions > 0) { - int extraEmissions = emission->GetParticleCount() - 1; - emissions += extraEmissions; - } - float velMin = emission->GetMinVelocity() * scale; - float velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * scale * 0.5f; - float spread = (std::max(static_cast(c_PI) - (emission->GetSpread() * scale), 0.0F) / c_PI); // A large spread will cause the forces to cancel eachother out + float velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * scale * 0.5f; + float spread = (std::max(static_cast(c_PI) - (emission->GetSpread() * scale), 0.0F) / c_PI); // A large spread will cause the forces to cancel eachother out // Add to accumulative recoil impulse generated, F = m * a. - impulse += (velMin + velRange) * spread * emission->m_pEmission->GetMass() * emissions; + impulse += (velMin + velRange) * spread * emission->m_pEmission->GetMass() * emissionsPerFrame; } } @@ -458,17 +455,18 @@ void AEmitter::Update() { } else { emission->m_Accumulator = 0; } + float scale = 1.0F; // Add extra emissions if bursting. if (m_BurstTriggered) { emissionCount += emission->GetBurstSize(); scale = m_BurstScale; } + + // We don't consider extra particles for our emission count, so add prior to multiply emissionCountTotal += emissionCount; - if (emissionCount > 0) { - int extraEmissions = emission->GetParticleCount() - 1; - emissionCount += extraEmissions; - } + emissionCount *= emission->GetParticleCount(); + pParticle = 0; emitVel.Reset(); parentVel = pRootParent->GetVel() * emission->InheritsVelocity(); diff --git a/Source/Entities/AHuman.cpp b/Source/Entities/AHuman.cpp index a21ef1dbe..e032cd8a0 100644 --- a/Source/Entities/AHuman.cpp +++ b/Source/Entities/AHuman.cpp @@ -1007,8 +1007,7 @@ float AHuman::EstimateJumpHeight() const { 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; + return FLT_MAX; } currentYVelocity += yGravity; @@ -1022,9 +1021,7 @@ float AHuman::EstimateJumpHeight() const { } } - float finalHeightMultipler = 0.6f; // Make us think we can do less because AI path following is shit - - return totalHeight * c_MPP * finalHeightMultipler; + return totalHeight * c_MPP; } bool AHuman::EquipShield() { diff --git a/Source/Entities/PEmitter.cpp b/Source/Entities/PEmitter.cpp index 1734c5674..13141a80b 100644 --- a/Source/Entities/PEmitter.cpp +++ b/Source/Entities/PEmitter.cpp @@ -232,26 +232,28 @@ float PEmitter::EstimateImpulse(bool burst) { for (Emission* emission: m_EmissionList) { // Only check emissions that push the emitter if (emission->PushesEmitter()) { - // Todo... we're not checking emission start/stop times here, so this will always calculate the impulse as if the emission was active. + // TODO: we're not checking emission start/stop times here, so this will always calculate the impulse as if the emission was active. // There's not really an easy way to do this, since the emission rate is not necessarily constant over time. - float emissions = (emission->GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs(); + float emissionsPerFrame = (emission->GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs(); float scale = 1.0F; + + // Get all the particles emitted this frame + emissionsPerFrame *= emission->GetParticleCount(); + + // When bursting, add on all the bursted emissions + // We also use m_BurstScale on ALL emissions, not just the extra bursted ones + // This is a bit funky but consistent with the code that applies the impulse if (burst) { - emissions *= emission->GetBurstSize(); + emissionsPerFrame += emission->GetBurstSize(); scale = m_BurstScale; } - if (emissions > 0) { - int extraEmissions = emission->GetParticleCount() - 1; - emissions += extraEmissions; - } - float velMin = emission->GetMinVelocity() * scale; float velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * scale * 0.5f; float spread = (std::max(static_cast(c_PI) - (emission->GetSpread() * scale), 0.0F) / c_PI); // A large spread will cause the forces to cancel eachother out // Add to accumulative recoil impulse generated, F = m * a. - impulse += (velMin + velRange) * spread * emission->m_pEmission->GetMass() * emissions; + impulse += (velMin + velRange) * spread * emission->m_pEmission->GetMass() * emissionsPerFrame; } } @@ -320,7 +322,7 @@ void PEmitter::Update() { else m_BurstTriggered = false; - int emissions = 0; + int emissionCountTotal = 0; float velMin, velRange, spread; double currentPPM, SPE; MovableObject* pParticle = 0; @@ -331,7 +333,7 @@ void PEmitter::Update() { if (emission->IsEmissionTime()) { // Apply the throttle factor to the emission rate currentPPM = emission->GetRate() * throttleFactor; - emissions = 0; + int emissionCount = 0; // Only do all this if the PPM is acutally above zero if (currentPPM > 0) { @@ -342,25 +344,32 @@ void PEmitter::Update() { emission->m_Accumulator += m_LastEmitTmr.GetElapsedSimTimeS(); // Now figure how many full emissions can fit in the current accumulator - emissions = std::floor(emission->m_Accumulator / SPE); + emissionCount = std::floor(emission->m_Accumulator / SPE); // Deduct the about to be emitted emissions from the accumulator - emission->m_Accumulator -= emissions * SPE; + emission->m_Accumulator -= emissionCount * SPE; RTEAssert(emission->m_Accumulator >= 0, "Emission accumulator negative!"); } + float scale = 1.0F; // Add extra emissions if bursting. - if (m_BurstTriggered) - emissions += emission->GetBurstSize() * std::floor(throttleFactor); + if (m_BurstTriggered) { + emissionCount += emission->GetBurstSize(); + scale = m_BurstScale; + } + + // We don't consider extra particles for our emission count, so add prior to multiply + emissionCountTotal += emissionCount; + emissionCount *= emission->GetParticleCount(); pParticle = 0; emitVel.Reset(); parentVel = pRootParent->GetVel() * emission->InheritsVelocity(); - for (int i = 0; i < emissions; ++i) { - velMin = emission->GetMinVelocity() * (m_BurstTriggered ? m_BurstScale : 1.0); - velRange = emission->GetMaxVelocity() - emission->GetMinVelocity() * (m_BurstTriggered ? m_BurstScale : 1.0); - spread = emission->GetSpread() * (m_BurstTriggered ? m_BurstScale : 1.0); + for (int i = 0; i < emissionCount; ++i) { + velMin = emission->GetMinVelocity() * scale; + velRange = emission->GetMaxVelocity() - emission->GetMinVelocity() * scale; + spread = emission->GetSpread() * scale; // Make a copy after the reference particle pParticle = dynamic_cast(emission->GetEmissionParticlePreset()->Clone()); // Set up its position and velocity according to the parameters of this. @@ -405,7 +414,7 @@ void PEmitter::Update() { m_LastEmitTmr.Reset(); // Count the total emissions since enabling, and stop emitting if beyong limit (and limit is also enabled) - m_EmitCount += emissions; + m_EmitCount += emissionCountTotal; if (m_EmitCountLimit > 0 && m_EmitCount > m_EmitCountLimit) EnableEmission(false);