diff --git a/CHANGELOG.md b/CHANGELOG.md index 571348dce..5c2af8c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -149,6 +149,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Added `MovableObject` Lua function `EnableOrDisableAllScripts` that allows you to enable or disable all scripts on a `MovableObject` based on the passed in value. +- Added `AEmitter` and `PEmitter` Lua (R/W) properties `NegativeThrottleMultiplier` and `PositiveThrottleMultiplier` that affect the emission rate relative to throttle. + - Added `Attachable` Lua function and INI property `InheritsFrame` which lets `Attachables` inherit their parent's frame. It is set to false by default. - Added `MovableObject` Lua (R/W) and INI properties `ApplyWoundDamageOnCollision` and `ApplyWoundBurstDamageOnCollision` which allow `MovableObject`s to apply the `EntryWound` damage/burst damage that would occur when they penetrate another object, without actually creating a wound. @@ -186,6 +188,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
Changed +- `AEmitter` and `PEmitter` throttle logic has changed: + The properties `MinThrottleRange` and `MaxThrottleRange` have been changed to `NegativeThrottleMultiplier` and `PositiveThrottleMultiplier` respectively. + The new logic uses the multipliers to multiply the emission rate relative to the absolute throttle value. `NegativeThrottleMultiplier` is used when throttle is negative, and vice versa. + - Doors in `Team = -1` will now open up for all actors. - `MovableMan` function `KillAllActors` (commonly found in activities) has been appropriately renamed `KillAllEnemyActors`. diff --git a/Entities/ACrab.cpp b/Entities/ACrab.cpp index ad5170111..429020a4a 100644 --- a/Entities/ACrab.cpp +++ b/Entities/ACrab.cpp @@ -2130,8 +2130,6 @@ void ACrab::Update() // Jetpack throttle depletes relative to jet time, but only if throttle range values have been defined float jetTimeRatio = std::max(m_JetTimeLeft / m_JetTimeTotal, 0.0F); m_pJetpack->SetThrottle(jetTimeRatio * 2.0F - 1.0F); - float minScale = 1.0F - m_pJetpack->GetMinThrottle(); - m_pJetpack->SetFlashScale(minScale + (1.0F + m_pJetpack->GetMaxThrottle() - minScale) * jetTimeRatio); } // Start Jetpack burn if (m_Controller.IsState(BODY_JUMPSTART) && m_JetTimeLeft > 0 && m_Status != INACTIVE) diff --git a/Entities/AEmitter.cpp b/Entities/AEmitter.cpp index 493c32664..9ba6f5e08 100644 --- a/Entities/AEmitter.cpp +++ b/Entities/AEmitter.cpp @@ -38,8 +38,8 @@ void AEmitter::Clear() m_WasEmitting = false; m_EmitCount = 0; m_EmitCountLimit = 0; - m_MinThrottleRange = 1.0F; - m_MaxThrottleRange = 1.0F; + m_NegativeThrottleMultiplier = 1.0F; + m_PositiveThrottleMultiplier = 1.0F; m_Throttle = 0; m_EmissionsIgnoreThis = false; m_BurstScale = 1.0F; @@ -85,8 +85,8 @@ int AEmitter::Create(const AEmitter &reference) { m_EmitEnabled = reference.m_EmitEnabled; m_EmitCount = reference.m_EmitCount; m_EmitCountLimit = reference.m_EmitCountLimit; - m_MinThrottleRange = reference.m_MinThrottleRange; - m_MaxThrottleRange = reference.m_MaxThrottleRange; + m_NegativeThrottleMultiplier = reference.m_NegativeThrottleMultiplier; + m_PositiveThrottleMultiplier = reference.m_PositiveThrottleMultiplier; m_Throttle = reference.m_Throttle; m_EmissionsIgnoreThis = reference.m_EmissionsIgnoreThis; m_BurstScale = reference.m_BurstScale; @@ -138,10 +138,10 @@ int AEmitter::ReadProperty(const std::string_view &propName, Reader &reader) { reader >> ppm; // Go through all emissions and set the rate so that it emulates the way it used to work, for mod backwards compatibility. for (Emission *emission : m_EmissionList) { emission->m_PPM = ppm / static_cast(m_EmissionList.size()); } - } else if (propName == "MinThrottleRange") { - reader >> m_MinThrottleRange; - } else if (propName == "MaxThrottleRange") { - reader >> m_MaxThrottleRange; + } else if (propName == "NegativeThrottleMultiplier") { + reader >> m_NegativeThrottleMultiplier; + } else if (propName == "PositiveThrottleMultiplier") { + reader >> m_PositiveThrottleMultiplier; } else if (propName == "Throttle") { reader >> m_Throttle; } else if (propName == "EmissionsIgnoreThis") { @@ -212,10 +212,10 @@ int AEmitter::Save(Writer &writer) const writer << m_EmitCountLimit; writer.NewProperty("EmissionsIgnoreThis"); writer << m_EmissionsIgnoreThis; - writer.NewProperty("MinThrottleRange"); - writer << m_MinThrottleRange; - writer.NewProperty("MaxThrottleRange"); - writer << m_MaxThrottleRange; + writer.NewProperty("NegativeThrottleMultiplier"); + writer << m_NegativeThrottleMultiplier; + writer.NewProperty("PositiveThrottleMultiplier"); + writer << m_PositiveThrottleMultiplier; writer.NewProperty("Throttle"); writer << m_Throttle; writer.NewProperty("BurstScale"); @@ -344,12 +344,13 @@ float AEmitter::EstimateImpulse(bool burst) } - // Figure out the throttle factor + // Scale the emission rate up or down according to the appropriate throttle multiplier. float throttleFactor = 1.0F; - if (m_Throttle < 0) { // Negative throttle, scale down according to the min throttle range - throttleFactor += std::abs(m_MinThrottleRange) * m_Throttle; - } else if (m_Throttle > 0) { // Positive throttle, scale up - throttleFactor += std::abs(m_MaxThrottleRange) * m_Throttle; + float absThrottle = std::abs(m_Throttle); + if (m_Throttle < 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_NegativeThrottleMultiplier * absThrottle); + } else if (m_Throttle > 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_PositiveThrottleMultiplier * absThrottle); } // Apply the throttle factor to the emission rate per update if (burst) { return m_AvgBurstImpulse * throttleFactor; } @@ -432,12 +433,15 @@ void AEmitter::Update() // TODO: Potentially get this once outside instead, like in attach/detach") MovableObject *pRootParent = GetRootParent(); + // Scale the emission rate up or down according to the appropriate throttle multiplier. float throttleFactor = 1.0F; - if (m_Throttle < 0) { // Negative throttle, scale down according to the min throttle range - throttleFactor += std::abs(m_MinThrottleRange) * m_Throttle; - } else if (m_Throttle > 0) { // Positive throttle, scale up - throttleFactor += std::abs(m_MaxThrottleRange) * m_Throttle; + float absThrottle = std::abs(m_Throttle); + if (m_Throttle < 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_NegativeThrottleMultiplier * absThrottle); + } else if (m_Throttle > 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_PositiveThrottleMultiplier * absThrottle); } + m_FlashScale = throttleFactor; // Check burst triggering against whether the spacing is fulfilled if (m_BurstTriggered && (m_BurstSpacing <= 0 || m_BurstTimer.IsPastSimMS(m_BurstSpacing))) { diff --git a/Entities/AEmitter.h b/Entities/AEmitter.h index be4d8d25f..ab316d88d 100644 --- a/Entities/AEmitter.h +++ b/Entities/AEmitter.h @@ -263,16 +263,29 @@ ClassInfoGetters; float GetThrottle() const { return m_Throttle; } /// - /// Gets the minimum throttle range of this AEmitter. + /// Gets the negative throttle multiplier of this AEmitter. /// - /// The minimum throttle range of this AEmitter. - float GetMinThrottle() const { return m_MinThrottleRange; } + /// The negative throttle multiplier of this AEmitter. + float GetNegativeThrottleMultiplier() const { return m_NegativeThrottleMultiplier; } /// - /// Gets the maximum throttle range of this AEmitter. + /// Gets the positive throttle multiplier of this AEmitter. /// - /// The maximum throttle range of this AEmitter. - float GetMaxThrottle() const { return m_MaxThrottleRange; } + /// The positive throttle multiplier of this AEmitter. + float GetPositiveThrottleMultiplier() const { return m_PositiveThrottleMultiplier; } + + /// + /// Sets the negative throttle multiplier of this AEmitter. + /// + /// The new throttle multiplier of this AEmitter. + void SetNegativeThrottleMultiplier(float newValue) { m_NegativeThrottleMultiplier = newValue; } + + /// + /// Sets the positive throttle multiplier of this AEmitter. + /// + /// The new throttle multiplier of this AEmitter. + void SetPositiveThrottleMultiplier(float newValue) { m_PositiveThrottleMultiplier = newValue; } + /* ////////////////////////////////////////////////////////////////////////////////////////// // Method: SetEmitRate @@ -632,8 +645,8 @@ ClassInfoGetters; long m_EmitCount; // The max number of emissions to emit per emit being enabled long m_EmitCountLimit; - float m_MinThrottleRange; //!< The range negative throttle has on emission rate. 1.0 means the rate can be throttled down to 0%, 0 means negative throttle has no effect - float m_MaxThrottleRange; //!< The range positive throttle has on emission rate. 1.0 means the rate can be throttled up to 200%, 0 means positive throttle has no effect + float m_NegativeThrottleMultiplier; //!< The multiplier applied to the emission rate when throttle is negative. Relative to the absolute throttle value. + float m_PositiveThrottleMultiplier; //!< The multiplier applied to the emission rate when throttle is positive. Relative to the absolute throttle value. float m_Throttle; //!< The normalized throttle which controls the MSPE between 1.0 * m_MSPERange and -1.0 * m_MSPERange. 0 means emit the regular m_PPM amount. // Whether or not this' emissions ignore hits with itself, even if they are set to hit other MOs. bool m_EmissionsIgnoreThis; diff --git a/Entities/AHuman.cpp b/Entities/AHuman.cpp index ff470ddb7..825056c6b 100644 --- a/Entities/AHuman.cpp +++ b/Entities/AHuman.cpp @@ -3130,8 +3130,6 @@ void AHuman::Update() // Jetpack throttle depletes relative to jet time, but only if throttle range values have been defined float jetTimeRatio = std::max(m_JetTimeLeft / m_JetTimeTotal, 0.0F); m_pJetpack->SetThrottle(jetTimeRatio * 2.0F - 1.0F); - float minScale = 1.0F - m_pJetpack->GetMinThrottle(); - m_pJetpack->SetFlashScale(minScale + (1.0F + m_pJetpack->GetMaxThrottle() - minScale) * jetTimeRatio); } // Start Jetpack burn if (m_Controller.IsState(BODY_JUMPSTART) && m_JetTimeLeft > 0 && m_Status != INACTIVE) diff --git a/Entities/PEmitter.cpp b/Entities/PEmitter.cpp index 385e9c283..405658163 100644 --- a/Entities/PEmitter.cpp +++ b/Entities/PEmitter.cpp @@ -37,8 +37,8 @@ namespace RTE { m_WasEmitting = false; m_EmitCount = 0; m_EmitCountLimit = 0; - m_MinThrottleRange = -1; - m_MaxThrottleRange = 1; + m_NegativeThrottleMultiplier = 1.0F; + m_PositiveThrottleMultiplier = 1.0F; m_Throttle = 0; m_EmissionsIgnoreThis = false; m_BurstScale = 1.0; @@ -90,8 +90,8 @@ namespace RTE { m_EmitEnabled = reference.m_EmitEnabled; m_EmitCount = reference.m_EmitCount; m_EmitCountLimit = reference.m_EmitCountLimit; - m_MinThrottleRange = reference.m_MinThrottleRange; - m_MaxThrottleRange = reference.m_MaxThrottleRange; + m_NegativeThrottleMultiplier = reference.m_NegativeThrottleMultiplier; + m_PositiveThrottleMultiplier = reference.m_PositiveThrottleMultiplier; m_Throttle = reference.m_Throttle; m_EmissionsIgnoreThis = reference.m_EmissionsIgnoreThis; m_BurstScale = reference.m_BurstScale; @@ -143,10 +143,10 @@ namespace RTE { for (list::iterator eItr = m_EmissionList.begin(); eItr != m_EmissionList.end(); ++eItr) (*eItr).m_PPM = ppm / m_EmissionList.size(); } - else if (propName == "MinThrottleRange") - reader >> m_MinThrottleRange; - else if (propName == "MaxThrottleRange") - reader >> m_MaxThrottleRange; + else if (propName == "NegativeThrottleMultiplier") + reader >> m_NegativeThrottleMultiplier; + else if (propName == "PositiveThrottleMultiplier") + reader >> m_PositiveThrottleMultiplier; else if (propName == "Throttle") reader >> m_Throttle; else if (propName == "EmissionsIgnoreThis") @@ -213,10 +213,10 @@ namespace RTE { writer << m_EmitCountLimit; writer.NewProperty("EmissionsIgnoreThis"); writer << m_EmissionsIgnoreThis; - writer.NewProperty("MinThrottleRange"); - writer << m_MinThrottleRange; - writer.NewProperty("MaxThrottleRange"); - writer << m_MaxThrottleRange; + writer.NewProperty("NegativeThrottleMultiplier"); + writer << m_NegativeThrottleMultiplier; + writer.NewProperty("PositiveThrottleMultiplier"); + writer << m_PositiveThrottleMultiplier; writer.NewProperty("Throttle"); writer << m_Throttle; writer.NewProperty("BurstScale"); @@ -339,13 +339,14 @@ namespace RTE { } - // Figure out the throttle factor - float throttleFactor = 1.0f; - if (m_Throttle < 0) // Negative throttle, scale down according to the min throttle range - throttleFactor += fabs(m_MinThrottleRange) * m_Throttle; - else if (m_Throttle > 0) // Positive throttle, scale up - throttleFactor += fabs(m_MaxThrottleRange) * m_Throttle; - + // Scale the emission rate up or down according to the appropriate throttle multiplier. + float throttleFactor = 1.0F; + float absThrottle = std::abs(m_Throttle); + if (m_Throttle < 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_NegativeThrottleMultiplier * absThrottle); + } else if (m_Throttle > 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_PositiveThrottleMultiplier * absThrottle); + } // Apply the throttle factor to the emission rate per update if (burst) return m_AvgBurstImpulse * throttleFactor; @@ -397,15 +398,15 @@ namespace RTE { // TODO: Potentially get this once outside instead, like in attach/detach") MovableObject *pRootParent = GetRootParent(); - // Figure out the throttle factor - // Negative throttle, scale down according to the min throttle range - float throttleFactor = 1.0f; - if (m_Throttle < 0) - throttleFactor += fabs(m_MinThrottleRange) * m_Throttle; - // Positive throttle, scale up - else if (m_Throttle > 0) - throttleFactor += fabs(m_MaxThrottleRange) * m_Throttle; - + // Scale the emission rate up or down according to the appropriate throttle multiplier. + float throttleFactor = 1.0F; + float absThrottle = std::abs(m_Throttle); + if (m_Throttle < 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_NegativeThrottleMultiplier * absThrottle); + } else if (m_Throttle > 0) { + throttleFactor = throttleFactor * (1 - absThrottle) + (m_PositiveThrottleMultiplier * absThrottle); + } + m_FlashScale = throttleFactor; // Check burst triggering against whether the spacing is fulfilled if (m_BurstTriggered && (m_BurstSpacing <= 0 || m_BurstTimer.IsPastSimMS(m_BurstSpacing))) { @@ -477,8 +478,7 @@ namespace RTE { emitVel = RotateOffset(emitVel); pParticle->SetVel(parentVel + emitVel); - if (pParticle->GetLifetime() != 0) - pParticle->SetLifetime(pParticle->GetLifetime() * (1.0F + ((*eItr).GetLifeVariation() * RandomNormalNum()))); + if (pParticle->GetLifetime() != 0) { pParticle->SetLifetime(std::max(static_cast(pParticle->GetLifetime() * (1.0F + ((*eItr).GetLifeVariation() * RandomNormalNum()))), 1)); } pParticle->SetTeam(m_Team); pParticle->SetIgnoresTeamHits(true); diff --git a/Entities/PEmitter.h b/Entities/PEmitter.h index 3c9c8d07a..8bc0acb79 100644 --- a/Entities/PEmitter.h +++ b/Entities/PEmitter.h @@ -506,10 +506,8 @@ class PEmitter : long m_EmitCount; // The max number of emissions to emit per emit being enabled long m_EmitCountLimit; - // The range negative throttle has on emission rate. 1.0 means the rate can be throttled down to 0%, 0 means negative throttle has no effect - double m_MinThrottleRange; - // The range positive throttle has on emission rate. 1.0 means the rate can be throttled up to 200%, 0 means negative throttle has no effect - double m_MaxThrottleRange; + float m_NegativeThrottleMultiplier; //!< The multiplier applied to the emission rate when throttle is negative. Relative to the absolute throttle value. + float m_PositiveThrottleMultiplier; //!< The multiplier applied to the emission rate when throttle is positive. Relative to the absolute throttle value. // The normalized throttle which controls the MSPE between 1.0 * m_MSPERange and -1.0 * m_MSPERange. 0 means emit the regular m_PPM amount. float m_Throttle; // Whether or not this' emissions ignore hits with itself, even if they are set to hit other MOs. diff --git a/Lua/LuaBindingsEntities.cpp b/Lua/LuaBindingsEntities.cpp index 9cb6c0d84..3275592f3 100644 --- a/Lua/LuaBindingsEntities.cpp +++ b/Lua/LuaBindingsEntities.cpp @@ -364,6 +364,8 @@ namespace RTE { .property("EmitAngle", &AEmitter::GetEmitAngle, &AEmitter::SetEmitAngle) .property("GetThrottle", &AEmitter::GetThrottle, &AEmitter::SetThrottle) .property("Throttle", &AEmitter::GetThrottle, &AEmitter::SetThrottle) + .property("NegativeThrottleMultiplier", &AEmitter::GetNegativeThrottleMultiplier, &AEmitter::SetNegativeThrottleMultiplier) + .property("PositiveThrottleMultiplier", &AEmitter::GetPositiveThrottleMultiplier, &AEmitter::SetPositiveThrottleMultiplier) .property("BurstSpacing", &AEmitter::GetBurstSpacing, &AEmitter::SetBurstSpacing) .property("BurstDamage", &AEmitter::GetBurstDamage, &AEmitter::SetBurstDamage) .property("EmitterDamageMultiplier", &AEmitter::GetEmitterDamageMultiplier, &AEmitter::SetEmitterDamageMultiplier)