From a92b1b33483ac4eecef2a3a97ae7e76778ab46ce Mon Sep 17 00:00:00 2001 From: comradeshook Date: Thu, 28 Nov 2024 20:16:23 +0100 Subject: [PATCH 1/2] Fixed wound sounds blocking each other too much --- Source/Entities/AEmitter.cpp | 4 ++-- Source/Entities/MOSRotating.cpp | 14 +++++++++----- Source/Entities/MOSRotating.h | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) 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..01c66b62ea 100644 --- a/Source/Entities/MOSRotating.cpp +++ b/Source/Entities/MOSRotating.cpp @@ -56,7 +56,7 @@ void MOSRotating::Clear() { m_RecoilForce.Reset(); m_RecoilOffset.Reset(); m_Wounds.clear(); - m_WoundBurstSoundPlayedThisFrame = false; + m_WoundBurstSoundsPlayedThisFrame = {}; m_Attachables.clear(); m_ReferenceHardcodedAttachableUniqueIDs.clear(); m_HardcodedAttachableUniqueIDsAndSetters.clear(); @@ -462,10 +462,14 @@ void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet woundToAdd->SetParent(this); woundToAdd->SetIsWound(true); if (woundToAdd->GetBurstSound()) { - if (m_WoundBurstSoundPlayedThisFrame) { - woundToAdd->SetPlayBurstSound(false); + std::string burstSound = woundToAdd->GetBurstSound()->GetPresetName(); + for (int i = 0; i < m_WoundBurstSoundsPlayedThisFrame.size(); i++) { + if (burstSound == m_WoundBurstSoundsPlayedThisFrame[i]) { + woundToAdd->SetPlayBurstSound(false); + break; + } } - m_WoundBurstSoundPlayedThisFrame = true; + m_WoundBurstSoundsPlayedThisFrame.push_back(burstSound); } if (woundToAdd->HasNoSetDamageMultiplier()) { woundToAdd->SetDamageMultiplier(1.0F); @@ -1366,7 +1370,7 @@ void MOSRotating::Update() { m_Rotation += radsToGo * m_OrientToVel * velInfluence; } - m_WoundBurstSoundPlayedThisFrame = false; + m_WoundBurstSoundsPlayedThisFrame = {}; 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..1c73ffc87a 100644 --- a/Source/Entities/MOSRotating.h +++ b/Source/Entities/MOSRotating.h @@ -541,7 +541,7 @@ namespace RTE { // 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; + std::vector m_WoundBurstSoundsPlayedThisFrame; // 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. From f3e57dfc279201330d8a5940e5e5025bee0994b2 Mon Sep 17 00:00:00 2001 From: comradeshook Date: Sat, 7 Dec 2024 12:32:56 +0100 Subject: [PATCH 2/2] Fixed exit wound bursts not firing, ensured entry- and exit wound burst sounds only play once per frame per MOSR, added optional isEntryWound and isExitWound bools to AddWound(Ext) --- CHANGELOG.md | 2 ++ Source/Entities/MOSRotating.cpp | 33 +++++++++++++++++++++--------- Source/Entities/MOSRotating.h | 12 +++++++++-- Source/Lua/LuaBindingsEntities.cpp | 1 + 4 files changed, 36 insertions(+), 12 deletions(-) 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/MOSRotating.cpp b/Source/Entities/MOSRotating.cpp index 01c66b62ea..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_WoundBurstSoundsPlayedThisFrame = {}; + 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,14 +463,21 @@ void MOSRotating::AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet woundToAdd->SetParent(this); woundToAdd->SetIsWound(true); if (woundToAdd->GetBurstSound()) { - std::string burstSound = woundToAdd->GetBurstSound()->GetPresetName(); - for (int i = 0; i < m_WoundBurstSoundsPlayedThisFrame.size(); i++) { - if (burstSound == m_WoundBurstSoundsPlayedThisFrame[i]) { + if (isEntryWound) { + if (m_EntryWoundBurstSoundPlayedThisFrame) { woundToAdd->SetPlayBurstSound(false); - break; + } else { + m_EntryWoundBurstSoundPlayedThisFrame = true; + } + } + + if (isExitWound) { + if (m_ExitWoundBurstSoundPlayedThisFrame) { + woundToAdd->SetPlayBurstSound(false); + } else { + m_ExitWoundBurstSoundPlayedThisFrame = true; } } - m_WoundBurstSoundsPlayedThisFrame.push_back(burstSound); } if (woundToAdd->HasNoSetDamageMultiplier()) { woundToAdd->SetDamageMultiplier(1.0F); @@ -479,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); @@ -816,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; } @@ -832,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; } @@ -1370,7 +1382,8 @@ void MOSRotating::Update() { m_Rotation += radsToGo * m_OrientToVel * velInfluence; } - m_WoundBurstSoundsPlayedThisFrame = {}; + 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 1c73ffc87a..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. - std::vector m_WoundBurstSoundsPlayedThisFrame; + // 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)