bugfix(audio): Fix particle cannon being inaudible after saveload#2302
bugfix(audio): Fix particle cannon being inaudible after saveload#2302stephanmeesters wants to merge 2 commits intoTheSuperHackers:mainfrom
Conversation
Greptile Overview
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | Added sound restoration logic in loadPostProcess() to fix missing particle cannon sounds after saveload, correctly implementing state-based sound activation |
Last reviewed commit: 169ce11
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
|
|
||
| // TheSuperHackers @info stephanmeesters 13/02/2026 | ||
| // Fix issue where sound from the particle cannon is not audible after saveload | ||
| if( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || m_status == STATUS_PACKING ) |
There was a problem hiding this comment.
Why POSTFIRE and PACKING ?
Can you explain how the statuses relate to the lifetime of the 2 sounds?
There was a problem hiding this comment.
Added a table of all possible states and all associated sounds, tried to keep this as simple as possible. More code was added for some other sounds I missed and handling of PACKING which appears twice in the sequence
…viously inaudible sounds
| } | ||
|
|
||
| if ( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || | ||
| (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) |
There was a problem hiding this comment.
This is really difficult to maintain correctness, because it needs to manually mirror the logic correctly and when the audio logic changes then this code would need to be adapted again, which then carries the risk of creating new bugs.
Instead, I suggest adding an Xfer function to AudioEventRTS and handle the state save/load in there for all possibilities. This will not work for legacy save files, but going forward it should be much simpler to maintain and be robust for any logic changes.
This also means that Xfer can be used for other module sounds as well. I expect Particle Cannon is not the only object that has this audio issue. But it is very obvious for it.
There was a problem hiding this comment.
That sounds like a much better solution.
Perhaps keep this code but put it behind RETAIL_COMPATIBLE_CRC or similar, so we know to drop it after breaking compatibility?
There was a problem hiding this comment.
With old Xfer version, if we think it is worth it? I would personally not bother with the legacy saves, but since you already did all this work...RETAIL_COMPATIBLE_XFER_SAVE
Fixes issue where sound from the particle cannon is not audible after saveload.
A savegame can be made during any of combinations of
STATUS_andLASERSTATUS_below. Sounds are triggered only during state change, so when loading a savegame any of the sounds in the Active column need to be added.Tested with a savegame for each
STATUS_.Repeating sequence of the particle cannon
STATUS_LASERSTATUS_PACKING(1)NONECHARGINGNONEpowerupSoundunpackToReadySoundfiringToIdleSoundannihilationSoundpowerupSoundPREPARINGNONEunpackToReadySoundfiringToIdleSoundannihilationSoundpowerupSoundunpackToReadySoundALMOST_READYNONEpowerupSoundunpackToReadySoundREADY_TO_FIRENONEpowerupSoundfiringToIdleSoundannihilationSoundunpackToReadySoundPREFIRENONEunpackToReadySoundFIRINGNONEBORNfiringToIdleSoundannihilationSound¹powerupSoundunpackToReadySoundfiringToIdleSoundannihilationSoundPOSTFIREBORNfiringToIdleSoundannihilationSoundPACKING(2)DECAYINGDEADannihilationSound²firingToIdleSoundannihilationSoundIDLENONEpowerupSoundunpackToReadySoundfiringToIdleSoundannihilationSound¹ Sound added at
LASERSTATUS_BORN² Sound cleared at
LASERSTATUS_DEADPACKINGappears twice for some reason.Status meanings
PACKING(1): Particle cannon is inactive and fully reset. Idle state.CHARGING: Early pre-ready phase; charging loop plays.PREPARING: Antenna/deploy preparation phase.ALMOST_READY: Near-ready phase before final ready state.READY_TO_FIRE: Weapon is available and waiting for fire command.PREFIRE: Transitional pre-shot state (defined and checked, typically brief/rare in this flow).FIRING: Main active attack phase while beam is operating.POSTFIRE: Attack is decaying after firing window ends.PACKING(2): Pack-up phase after attack/ready path.IDLE: Another form of idle, used to reset audio, lasts very short.Laser status meanings
NONE: No orbital beam lifecycle started yet for current cycle.BORN: Orbit-to-target beam was created and is in active phase.DECAYING: Beam is in decay/shutdown window.DEAD: Beam lifecycle is finished (end state before reset toNONEon next cycle setup).Sound meanings
powerupSound: Charge, at particle cannon.unpackToReadySound: Prep, at particle cannon.firingToIdleSound: Firing/packing, at particle cannon.annihilationSound: Beam-impact, at origin beam.Todo