1
0
forked from 0ad/0ad

Prevent the game from playing sounds too often (8 times for a cavalry slaughter animation) and allow for subprops with a different event time to still play the sound at the same as their parent.

Comments by: @Freagarach
Differential Revision: https://code.wildfiregames.com/D3118
This was SVN commit r24629.
This commit is contained in:
Stan 2021-01-15 14:34:45 +00:00
parent 01d24173d2
commit de2b16a904

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2018 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -30,6 +30,9 @@
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpSoundManager.h"
#include <cstdlib>
#include <cmath>
// Randomly modify the speed, so that units won't stay perfectly
// synchronised if they're playing animations of the same length
static float DesyncSpeed(float speed, float desync)
@ -161,18 +164,21 @@ void CUnitAnimation::Update(float time)
if (m_AnimStatesAreStatic)
return;
bool shouldPlaySound = false;
// Advance all of the prop models independently
for (std::vector<SModelAnimState>::iterator it = m_AnimStates.begin(); it != m_AnimStates.end(); ++it)
{
CSkeletonAnimDef* animDef = it->anim->m_AnimDef;
if (animDef == NULL)
if (!animDef)
continue; // ignore static animations
float duration = animDef->GetDuration();
float actionPos = it->anim->m_ActionPos;
float loadPos = it->anim->m_ActionPos2;
float soundPos = it->anim->m_SoundPos;
// SoundPos is either the m_SoundPos when available, or m_ActionPos. Else no sound is played.
// TODO: Should they be totally independent?
float soundPos = it->anim->m_SoundPos != -1.f ? it->anim->m_SoundPos : actionPos;
bool hasActionPos = (actionPos != -1.f);
bool hasLoadPos = (loadPos != -1.f);
bool hasSoundPos = (soundPos != -1.f);
@ -186,42 +192,32 @@ void CUnitAnimation::Update(float time)
// Convert from real time to scaled animation time
float advance = time * speed;
float nextPos = it->time + advance;
// If we're going to advance past the load point in this update, then load the ammo
if (hasLoadPos && !it->pastLoadPos && it->time + advance >= loadPos)
if (hasLoadPos && !it->pastLoadPos && nextPos >= loadPos)
{
it->model->ShowAmmoProp();
it->pastLoadPos = true;
}
// If we're going to advance past the action point in this update, then perform the action
if (hasActionPos && !it->pastActionPos && it->time + advance >= actionPos)
// If we're going to advance past the action point in this update, then perform the action.
if (hasActionPos && !it->pastActionPos && nextPos >= actionPos)
{
if (hasLoadPos)
it->model->HideAmmoProp();
if ( !hasSoundPos && !m_ActionSound.empty() )
{
CmpPtr<ICmpSoundManager> cmpSoundManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
if (cmpSoundManager)
cmpSoundManager->PlaySoundGroup(m_ActionSound, m_Entity);
}
it->pastActionPos = true;
}
if (hasSoundPos && !it->pastSoundPos && it->time + advance >= soundPos)
{
if (!m_ActionSound.empty() )
{
CmpPtr<ICmpSoundManager> cmpSoundManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
if (cmpSoundManager)
cmpSoundManager->PlaySoundGroup(m_ActionSound, m_Entity);
}
// If we're going to advance past the sound point in this update, then play the sound.
if (hasSoundPos && !it->pastSoundPos && nextPos >= soundPos && !m_ActionSound.empty())
{
shouldPlaySound = true;
it->pastSoundPos = true;
}
if (it->time + advance < duration)
if (nextPos < duration)
{
// If we're still within the current animation, then simply update it
it->time += advance;
@ -232,7 +228,7 @@ void CUnitAnimation::Update(float time)
// If we've finished the current animation and want to loop...
// Wrap the timer around
it->time = fmod(it->time + advance, duration);
it->time = std::fmod(nextPos, duration);
// Pick a new random animation
CSkeletonAnim* anim;
@ -270,13 +266,20 @@ void CUnitAnimation::Update(float time)
// Update to very nearly the end of the last frame (but not quite the end else we'll wrap around when skinning)
float nearlyEnd = duration - 1.f;
if (fabs(it->time - nearlyEnd) > 1.f)
if (std::abs(it->time - nearlyEnd) > 1.f)
{
it->time = nearlyEnd;
it->model->UpdateTo(it->time);
}
}
}
if (!shouldPlaySound)
return;
CmpPtr<ICmpSoundManager> cmpSoundManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
if (cmpSoundManager)
cmpSoundManager->PlaySoundGroup(m_ActionSound, m_Entity);
}
void CUnitAnimation::UpdateAnimationID()