Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Core/GameEngine/Include/GameLogic/LogicRandomValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@

// do NOT use these functions directly, rather use the macros below
extern Int GetGameLogicRandomValue( int lo, int hi, const char *file, int line );
extern Int GetGameLogicRandomValueUnchanged(int lo, int hi, const char* file, int line);
extern Real GetGameLogicRandomValueReal( Real lo, Real hi, const char *file, int line );
extern Real GetGameLogicRandomValueRealUnchanged(Real lo, Real hi, const char* file, int line);

// use these macros to access the random value functions
#define GameLogicRandomValue( lo, hi ) GetGameLogicRandomValue( lo, hi, __FILE__, __LINE__ )
#define GameLogicRandomValueUnchanged( lo, hi ) GetGameLogicRandomValueUnchanged( lo, hi, __FILE__, __LINE__ )
#define GameLogicRandomValueReal( lo, hi ) GetGameLogicRandomValueReal( lo, hi, __FILE__, __LINE__ )
#define GameLogicRandomValueRealUnchanged( lo, hi ) GetGameLogicRandomValueRealUnchanged( lo, hi, __FILE__, __LINE__ )

//--------------------------------------------------------------------------------------------------------------
class CColorAlphaDialog;
Expand Down
6 changes: 3 additions & 3 deletions Core/GameEngine/Source/Common/Audio/AudioEventRTS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ void AudioEventRTS::generateFilename( void )
{
if (m_isLogicalAudio)
{
which = GameLogicRandomValue(0, m_eventInfo->m_sounds.size() - 1);
which = GameLogicRandomValueUnchanged(0, m_eventInfo->m_sounds.size() - 1);
}
else
{
Expand Down Expand Up @@ -388,7 +388,7 @@ void AudioEventRTS::generatePlayInfo( void )
// needs to be logic because it needs to be the same on all systems.
Int attackToPlay;
if (m_isLogicalAudio) {
attackToPlay = GameLogicRandomValue(0, attackSize - 1);
attackToPlay = GameLogicRandomValueUnchanged(0, attackSize - 1);
} else {
attackToPlay = GameAudioRandomValue(0, attackSize - 1);
}
Expand All @@ -406,7 +406,7 @@ void AudioEventRTS::generatePlayInfo( void )
// needs to be logic because it needs to be the same on all systems.
Int decayToPlay;
if (m_isLogicalAudio) {
decayToPlay = GameLogicRandomValue(0, decaySize - 1);
decayToPlay = GameLogicRandomValueUnchanged(0, decaySize - 1);
} else {
decayToPlay = GameAudioRandomValue(0, decaySize - 1);
}
Expand Down
9 changes: 8 additions & 1 deletion Core/GameEngine/Source/Common/Audio/GameAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,13 @@ AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd)
}

// TheSuperHackers @info Scripted audio events are logical, i.e. synchronized across clients.
// This early return cannot be taken for such audio events as it skips code that changes the logical game seed values.
// In retail mode this early return cannot be taken for such audio events as it skips code that changes the logical game seed values.
// In non-retail mode logical audio events are decoupled from the CRC computation, so this early return is allowed.
#if RETAIL_COMPATIBLE_CRC
const Bool logicalAudio = eventToAdd->getIsLogicalAudio();
#else
const Bool logicalAudio = FALSE;
#endif
const Bool notForLocal = !eventToAdd->getUninterruptable() && !shouldPlayLocally(eventToAdd);

if (!logicalAudio && notForLocal)
Expand All @@ -467,11 +472,13 @@ AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd)
}
}

#if RETAIL_COMPATIBLE_CRC
if (notForLocal)
{
releaseAudioEventRTS(audioEvent);
return AHSV_NotForLocal;
}
#endif

// cull muted audio
if (audioEvent->getVolume() < m_audioSettings->m_minVolume) {
Expand Down
62 changes: 62 additions & 0 deletions Core/GameEngine/Source/Common/RandomValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,37 @@ DEBUG_LOG(( "%d: GetGameLogicRandomValue = %d (%d - %d), %s line %d",
return rval;
}

//
// TheSuperHackers @info This function does not change the seed values with retail compatibility disabled.
// Consecutive calls always return the same value for the same combination of min / max values, assuming the seed values haven't changed in between.
// The intended use case for this function are randomized values that are desirable to be synchronized across clients,
// but should not result in a mismatch if they aren't synchronized; e.g. for scripted audio events.
//
Int GetGameLogicRandomValueUnchanged( int lo, int hi, const char *file, int line )
{
#if RETAIL_COMPATIBLE_CRC
return GetGameLogicRandomValue(lo, hi, file, line);
#endif

const UnsignedInt delta = hi - lo + 1;
if (delta == 0)
return hi;

UnsignedInt seed[ARRAY_SIZE(theGameLogicSeed)];
memcpy(&seed[0], &theGameLogicSeed[0], sizeof(seed));

const Int rval = ((Int)(randomValue(seed) % delta)) + lo;

DEBUG_ASSERTCRASH(rval >= lo && rval <= hi, ("Bad random val"));

#ifdef DEBUG_RANDOM_LOGIC
DEBUG_LOG(( "%d: GetGameLogicRandomValueUnchanged = %d (%d - %d), %s line %d",
TheGameLogic->getFrame(), rval, lo, hi, file, line ));
#endif

return rval;
}

//
// Integer random value
//
Expand Down Expand Up @@ -298,6 +329,37 @@ DEBUG_LOG(( "%d: GetGameLogicRandomValueReal = %f, %s line %d",
return rval;
}

//
// TheSuperHackers @info This function does not change the seed values with retail compatibility disabled.
// Consecutive calls always return the same value for the same combination of min / max values, assuming the seed values haven't changed in between.
// The intended use case for this function are randomized values that are desirable to be synchronized across clients,
// but should not result in a mismatch if they aren't synchronized; e.g. for scripted audio events.
//
Real GetGameLogicRandomValueRealUnchanged( Real lo, Real hi, const char *file, int line )
{
#if RETAIL_COMPATIBLE_CRC
return GetGameLogicRandomValueReal(lo, hi, file, line);
#endif

const Real delta = hi - lo;
if (delta <= 0.0f)
return hi;

UnsignedInt seed[ARRAY_SIZE(theGameLogicSeed)];
memcpy(&seed[0], &theGameLogicSeed[0], sizeof(seed));

const Real rval = ((Real)(randomValue(seed)) * theMultFactor) * delta + lo;

DEBUG_ASSERTCRASH(rval >= lo && rval <= hi, ("Bad random val"));

#ifdef DEBUG_RANDOM_LOGIC
DEBUG_LOG(( "%d: GetGameLogicRandomValueRealUnchanged = %f, %s line %d",
TheGameLogic->getFrame(), rval, file, line ));
#endif

return rval;
}

//
// Real valued random value
//
Expand Down
Loading