diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df89cd351..54490caeeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - `Scene` Lua functions `AddNavigatableArea(areaName)` and `ClearNavigatableAreas()` have been renamed/corrected to `AddNavigableArea(areaName)` and `ClearNavigableAreas()`, respectively. +- `MOSRotating` Lua function `AddWound` now additionally accepts the format `MOSRotating:AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit, bool isEntryWound, bool isExitWound)`, allowing modders to specify added wounds as entry- or exit wounds, for the purpose of not playing multiple burst sounds on the same frame. These new arguments are optional. +
Fixed diff --git a/Source/Entities/AEmitter.cpp b/Source/Entities/AEmitter.cpp index 8395f9b166..a698f22bec 100644 --- a/Source/Entities/AEmitter.cpp +++ b/Source/Entities/AEmitter.cpp @@ -397,9 +397,9 @@ void AEmitter::Update() { float throttleFactor = GetThrottleFactor(); m_FlashScale = throttleFactor; // Check burst triggering against whether the spacing is fulfilled - if (m_PlayBurstSound && m_BurstTriggered && CanTriggerBurst()) { + if (m_BurstTriggered && CanTriggerBurst()) { // Play burst sound - if (m_BurstSound) { + if (m_BurstSound && m_PlayBurstSound) { m_BurstSound->Play(m_Pos); } // Start timing until next burst diff --git a/Source/Entities/MOSRotating.cpp b/Source/Entities/MOSRotating.cpp index c1fb9ebded..3e6deffc9e 100644 --- a/Source/Entities/MOSRotating.cpp +++ b/Source/Entities/MOSRotating.cpp @@ -56,7 +56,8 @@ void MOSRotating::Clear() { m_RecoilForce.Reset(); m_RecoilOffset.Reset(); m_Wounds.clear(); - m_WoundBurstSoundPlayedThisFrame = false; + m_EntryWoundBurstSoundPlayedThisFrame = false; + m_ExitWoundBurstSoundPlayedThisFrame = false; m_Attachables.clear(); m_ReferenceHardcodedAttachableUniqueIDs.clear(); m_HardcodedAttachableUniqueIDsAndSetters.clear(); @@ -443,7 +444,7 @@ void MOSRotating::DetachAttachablesFromImpulse(Vector& impulseVector) { impulseVector.SetMagnitude(impulseRemainder); } -void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit) { +void MOSRotating::AddWoundExt(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit, bool isEntryWound, bool isExitWound) { if (woundToAdd && !m_ToDelete) { if (checkGibWoundLimit && m_GibWoundLimit > 0 && m_Wounds.size() + 1 >= m_GibWoundLimit) { // Find and detach an attachable near the new wound before gibbing the object itself. TODO: Perhaps move this to Actor, since it's more relevant there? @@ -462,10 +463,21 @@ void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet woundToAdd->SetParent(this); woundToAdd->SetIsWound(true); if (woundToAdd->GetBurstSound()) { - if (m_WoundBurstSoundPlayedThisFrame) { - woundToAdd->SetPlayBurstSound(false); + if (isEntryWound) { + if (m_EntryWoundBurstSoundPlayedThisFrame) { + woundToAdd->SetPlayBurstSound(false); + } else { + m_EntryWoundBurstSoundPlayedThisFrame = true; + } + } + + if (isExitWound) { + if (m_ExitWoundBurstSoundPlayedThisFrame) { + woundToAdd->SetPlayBurstSound(false); + } else { + m_ExitWoundBurstSoundPlayedThisFrame = true; + } } - m_WoundBurstSoundPlayedThisFrame = true; } if (woundToAdd->HasNoSetDamageMultiplier()) { woundToAdd->SetDamageMultiplier(1.0F); @@ -475,6 +487,10 @@ void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet } } +void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit) { + AddWoundExt(woundToAdd, parentOffsetToSet, checkGibWoundLimit, false, false); +} + float MOSRotating::RemoveWounds(int numberOfWoundsToRemove, bool includePositiveDamageAttachables, bool includeNegativeDamageAttachables, bool includeNoDamageAttachables) { float damage = 0; int woundCount = GetWoundCount(includePositiveDamageAttachables, includeNegativeDamageAttachables, includeNoDamageAttachables); @@ -812,7 +828,7 @@ bool MOSRotating::ParticlePenetration(HitData& hd) { pEntryWound->SetDamageMultiplier(damageMultiplier * hd.Body[HITOR]->WoundDamageMultiplier()); // Adjust position so that it looks like the hole is actually *on* the Hitee. entryPos[dom] += increment[dom] * (pEntryWound->GetSpriteWidth() / 2); - AddWound(pEntryWound, entryPos + m_SpriteOffset); + AddWoundExt(pEntryWound, entryPos + m_SpriteOffset, true, true, false); pEntryWound = 0; } @@ -828,7 +844,7 @@ bool MOSRotating::ParticlePenetration(HitData& hd) { pExitWound->SetInheritedRotAngleOffset(dir.GetAbsRadAngle()); float damageMultiplier = pExitWound->HasNoSetDamageMultiplier() ? 1.0F : pExitWound->GetDamageMultiplier(); pExitWound->SetDamageMultiplier(damageMultiplier * hd.Body[HITOR]->WoundDamageMultiplier()); - AddWound(pExitWound, exitPos + m_SpriteOffset); + AddWoundExt(pExitWound, exitPos + m_SpriteOffset, true, false, true); pExitWound = 0; } @@ -1366,7 +1382,8 @@ void MOSRotating::Update() { m_Rotation += radsToGo * m_OrientToVel * velInfluence; } - m_WoundBurstSoundPlayedThisFrame = false; + m_EntryWoundBurstSoundPlayedThisFrame = false; + m_ExitWoundBurstSoundPlayedThisFrame = false; for (auto woundItr = m_Wounds.begin(); woundItr != m_Wounds.end();) { AEmitter* wound = *woundItr; diff --git a/Source/Entities/MOSRotating.h b/Source/Entities/MOSRotating.h index 93d012432d..f0ad187085 100644 --- a/Source/Entities/MOSRotating.h +++ b/Source/Entities/MOSRotating.h @@ -416,6 +416,12 @@ namespace RTE { /// @param checkGibWoundLimit Whether to gib this MOSRotating if adding this wound raises its wound count past its gib wound limit. Defaults to true. virtual void AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit = true); + /// Adds the passed in wound AEmitter to the list of wounds and changes its parent offset to the passed in Vector. + /// @param woundToAdd The wound AEmitter to add. + /// @param parentOffsetToSet The vector to set as the wound AEmitter's parent offset. + /// @param checkGibWoundLimit Whether to gib this MOSRotating if adding this wound raises its wound count past its gib wound limit. Defaults to true. + virtual void AddWoundExt(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit = true, bool isEntryWound = false, bool isExitWound = false); + /// Removes the specified number of wounds from this MOSRotating, and returns damage caused by these removed wounds. /// Includes any Attachables (and their Attachables, etc.) that have a positive damage multiplier. /// @param numberOfWoundsToRemove The number of wounds that should be removed. @@ -540,8 +546,10 @@ namespace RTE { Vector m_RecoilOffset; // The list of wound AEmitters currently attached to this MOSRotating, and owned here as well. std::vector m_Wounds; - // Whether we added a wound with a BurstSound this frame or not, so we can disable further ones to avoid audio spam. - bool m_WoundBurstSoundPlayedThisFrame; + // Whether we added an entry wound with a BurstSound this frame or not, so we can disable further ones to avoid audio spam. + bool m_EntryWoundBurstSoundPlayedThisFrame; + // Whether we added an exit wound with a BurstSound this frame or not. + bool m_ExitWoundBurstSoundPlayedThisFrame; // The list of Attachables currently attached and Owned by this. std::list m_Attachables; std::unordered_set m_ReferenceHardcodedAttachableUniqueIDs; //!< An unordered set is filled with the Unique IDs of all of the reference object's hardcoded Attachables when using the copy Create. diff --git a/Source/Lua/LuaBindingsEntities.cpp b/Source/Lua/LuaBindingsEntities.cpp index c709dba604..16834600b7 100644 --- a/Source/Lua/LuaBindingsEntities.cpp +++ b/Source/Lua/LuaBindingsEntities.cpp @@ -886,6 +886,7 @@ LuaBindingRegisterFunctionDefinitionForType(EntityLuaBindings, MOSRotating) { .def("GetWounds", &LuaAdaptersMOSRotating::GetWounds1, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator) .def("GetWounds", &LuaAdaptersMOSRotating::GetWounds2, luabind::adopt(luabind::return_value) + luabind::return_stl_iterator) .def("AddWound", &MOSRotating::AddWound, luabind::adopt(_2)) + .def("AddWound", &MOSRotating::AddWoundExt, luabind::adopt(_2)) .def("RemoveWounds", (float(MOSRotating::*)(int numberOfWoundsToRemove)) & MOSRotating::RemoveWounds) .def("RemoveWounds", (float(MOSRotating::*)(int numberOfWoundsToRemove, bool positiveDamage, bool negativeDamage, bool noDamage)) & MOSRotating::RemoveWounds) .def("IsOnScenePoint", &MOSRotating::IsOnScenePoint)