Closed RingtailRaider closed 2 years ago
Code responsible
In the Lws
module, the following functions are responsible:
Lws_HandleTrigger
- Handles playing and stopping sound triggers.Lws_KeyPassed
- Checks if a frame start/end has been reached for a sound trigger. (only used by Lws_HandleTrigger
)Cause of the issue
This issue is a vanilla bug, but it's only prominent after #37 was fixed, as it's become much easier to notice different sounds playing at once. What causes this issue are sound triggers that execute on frame 0
(or whatever FirstFrame
is set to) in an .lws
scene file. Potentially they could also trigger on LastFrame
if the scene has LOOPING
set to FALSE
in the .ae
activity file (but this could only realistically happen if a scene's time is set to >= LastFrame
. However for example, the highest time observed for Slipup is 174.*
, always one unit below LastFrame
).
The most easily noticeable instance of this bug is Rock Raiders slipping in Driller Night!. Below are the files responsible for. SND_Slipup
can play twice, while SND_groan
never plays twice.
Data/Mini-Figures/Pilot/Pilot.ae:
Lego* { SlipUp {
FILE VLP_Slipup
LWSFILE TRUE
LOOPING FALSE
} }
Data/Mini-Figures/Pilot/VLP_Slipup.lws:
FirstFrame 0
LastFrame 175
FrameStep 1
...
AddNullObject SFX,SND_groan,140
...
AddNullObject SFX,SND_Slipup,0
Problem in the code
Sound triggers on frame 0
execute twice because when an LWS scene is created, both it's time
and lastTime
fields are set to 0.0f
. This means the first time Key_Passed
is called, it will return true. The next time Key_Passed
is called, lastTime
will still be 0.0f
with time
being a higher value, meaning the check will still return true.
Where Lws_KeyPassed
is used
Proposed solution
The best choice is to make either the upper or lower bound of these checks exclusive, rather than inclusive. After testing with lower checks as the exclusive bound (like the Gods98 commented out code at the bottom of the function), it became obvious that this won't work. Because minTime
will be 0.0f
for the two frames that would trigger the sound, neither frame would end up triggering the sound. So going with the upper checks is the only solution. This solution has solved the problem in all noticeable areas, but its unclear if there are scene files that have their sound trigger on LastFrame
, if that is the case, then this'll be a problem.
if ((maxTime - minTime) / totalTime < 0.5f) {
- if (keyTime <= maxTime && keyTime >= minTime) return true;
+ if (keyTime <= maxTime && keyTime > minTime) return true;
} else {
- if (keyTime >= maxTime || keyTime <= minTime) return true;
+ if (keyTime > maxTime || keyTime <= minTime) return true;
}
More testing will be done before pushing this solution. I'll be scanning all lws files for scenarios of LastFrame
being used. Additionally I think it'd be best to create a separate function Lws_KeyPassedExclusive
for checking to play a sound. While keeping the inclusive Lws_KeyPassed
for checking to stop a sound.
Describe the issue Issue #37 fixed the problem with some sounds in a randomized sound list not playing, but now when Rock Raiders slip on a spider, it will sometimes play both slipping sounds at the same time. This does happen with other sound lists, though it seems to vary; it happens for the rock monster's footstep sounds during its normal walking animation, but not for its carrying boulder animation.
Expected behaviour The game should only pick one sound to play, not two or more at once.
Steps to reproduce Enter Driller Night! to hear the slipping sounds. Other sounds are harder to hear, and may require replacing them in the CFG with more distinct sounds.
Additional information