diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 462deafb6..874ecbb51 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -42,12 +42,11 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in // Radii are specified in tile units (64 pixels) m_DamageRadius = damrad << (FRACBITS); m_TremorRadius = tremrad << (FRACBITS); - m_Intensity = intensityX; + m_IntensityX = intensityX; + m_IntensityY = intensityY; + m_IntensityZ = intensityZ; m_Countdown = duration; m_Flags = flags; - m_iX = intensityX; - m_iY = intensityY; - m_iZ = intensityZ; } //========================================================================== @@ -58,10 +57,20 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in void DEarthquake::Serialize (FArchive &arc) { - Super::Serialize (arc); //[MC] m_Intensity is unused now but I don't want to break compatibility... - arc << m_Spot << m_Intensity << m_Countdown + Super::Serialize (arc); + arc << m_Spot << m_IntensityX << m_Countdown << m_TremorRadius << m_DamageRadius - << m_QuakeSFX << m_Flags << m_iX << m_iY << m_iZ; + << m_QuakeSFX; + if (SaveVersion < 4519) + { + m_IntensityY = m_IntensityX; + m_IntensityZ = 0; + m_Flags = 0; + } + else + { + arc << m_IntensityY << m_IntensityZ << m_Flags; + } } //========================================================================== @@ -106,7 +115,18 @@ void DEarthquake::Tick () } // Thrust player around angle_t an = victim->angle + ANGLE_1*pr_quake(); - P_ThrustMobj (victim, an, m_Intensity << (FRACBITS-1)); + if (m_IntensityX == m_IntensityY) + { // Thrust in a circle + P_ThrustMobj (victim, an, m_IntensityX << (FRACBITS-1)); + } + else + { // Thrust in an ellipse + an >>= ANGLETOFINESHIFT; + // So this is actually completely wrong, but it ought to be good + // enough. Otherwise, I'd have to use tangents and square roots. + victim->velx += FixedMul(m_IntensityX << (FRACBITS-1), finecosine[an]); + victim->vely += FixedMul(m_IntensityY << (FRACBITS-1), finesine[an]); + } } } } @@ -130,18 +150,20 @@ void DEarthquake::Tick () // //========================================================================== -int DEarthquake::StaticGetQuakeIntensity (AActor *victim, int selector) +int DEarthquake::StaticGetQuakeIntensities(AActor *victim, + int &x, int &y, int &z, int &relx, int &rely, int &relz) { - int intensity = 0; - int quakeIntensity = 0; - TThinkerIterator iterator (STAT_EARTHQUAKE); - DEarthquake *quake; - if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { return 0; } + x = y = z = relx = rely = 0; + + TThinkerIterator iterator(STAT_EARTHQUAKE); + DEarthquake *quake; + int count = 0; + while ( (quake = iterator.Next()) != NULL) { if (quake->m_Spot != NULL) @@ -150,64 +172,25 @@ int DEarthquake::StaticGetQuakeIntensity (AActor *victim, int selector) victim->y - quake->m_Spot->y); if (dist < quake->m_TremorRadius) { - switch (selector) + ++count; + if (quake->m_Flags & QF_RELATIVE) { - default: - case 0: - quakeIntensity = quake->m_iX; - break; - case 1: - quakeIntensity = quake->m_iY; - break; - case 2: - quakeIntensity = quake->m_iZ; - break; - + relx = MAX(relx, quake->m_IntensityX); + rely = MAX(rely, quake->m_IntensityY); + relz = MAX(relz, quake->m_IntensityZ); + } + else + { + x = MAX(x, quake->m_IntensityX); + y = MAX(y, quake->m_IntensityY); + z = MAX(z, quake->m_IntensityZ); } - - if (intensity < quakeIntensity) - intensity = quakeIntensity; } } } - return intensity; + return count; } -//========================================================================== -// -// DEarthquake::StaticGetQuakeIntensity -// -// Searches for all quakes near the victim and returns their combined -// intensity. -// -//========================================================================== - -int DEarthquake::StaticGetQuakeFlags(AActor *victim) -{ - int flags = 0; - TThinkerIterator iterator(STAT_EARTHQUAKE); - DEarthquake *quake; - - if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) - { - return 0; - } - - while ((quake = iterator.Next()) != NULL) - { - if (quake->m_Spot != NULL) - { - fixed_t dist = P_AproxDistance(victim->x - quake->m_Spot->x, - victim->y - quake->m_Spot->y); - if (dist < quake->m_TremorRadius) - { - if (!(flags & QF_RELATIVE) && (quake->m_Flags & QF_RELATIVE)) - flags += QF_RELATIVE; - } - } - } - return flags; -} //========================================================================== // // P_StartQuake diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index a186fa010..e153f7070 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -147,15 +147,12 @@ public: void Tick (); TObjPtr m_Spot; fixed_t m_TremorRadius, m_DamageRadius; - int m_Intensity; int m_Countdown; FSoundID m_QuakeSFX; int m_Flags; - int m_iX, m_iY, m_iZ; + int m_IntensityX, m_IntensityY, m_IntensityZ; - static int StaticGetQuakeFlags(AActor *viewer); - static int StaticGetQuakeIntensity (AActor *viewer, int selector); - + static int StaticGetQuakeIntensities(AActor *viewer, int &x, int &y, int &z, int &relx, int &rely, int &relz); private: DEarthquake (); diff --git a/src/r_utility.cpp b/src/r_utility.cpp index f809a6800..a65c90d93 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -764,6 +764,23 @@ bool R_GetViewInterpolationStatus() return NoInterpolateView; } +//========================================================================== +// +// QuakePower +// +//========================================================================== + +static fixed_t QuakePower(fixed_t factor, int intensity) +{ + if (intensity == 0) + { + return 0; + } + else + { + return factor * ((pr_torchflicker() % (intensity << 2)) - (intensity << 1)); + } +} //========================================================================== // @@ -875,37 +892,41 @@ void R_SetupFrame (AActor *actor) if (!paused) { - int intensityX = DEarthquake::StaticGetQuakeIntensity(camera, 0); - int intensityY = DEarthquake::StaticGetQuakeIntensity(camera, 1); - int intensityZ = DEarthquake::StaticGetQuakeIntensity(camera, 2); - int quakeflags = DEarthquake::StaticGetQuakeFlags(camera); - if (intensityX || intensityY || intensityZ) + int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; + if (DEarthquake::StaticGetQuakeIntensities(camera, + intensityX, intensityY, intensityZ, + relIntensityX, relIntensityY, relIntensityZ) > 0) { fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); - if ((quakeflags & QF_RELATIVE) && (intensityX != intensityY)) + if (relIntensityX != 0) { - if (intensityX) - { - int ang = (camera->angle) >> ANGLETOFINESHIFT; - int tflicker = pr_torchflicker(); - viewx += FixedMul(finecosine[ang], (quakefactor * ((tflicker % (intensityX << 2)) - (intensityX << 1)))); - viewy += FixedMul(finesine[ang], (quakefactor * ((tflicker % (intensityX << 2)) - (intensityX << 1)))); - } - if (intensityY) - { - int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; - int tflicker = pr_torchflicker(); - viewx += FixedMul(finecosine[ang], (quakefactor * ((tflicker % (intensityY << 2)) - (intensityY << 1)))); - viewy += FixedMul(finesine[ang], (quakefactor * ((tflicker % (intensityY << 2)) - (intensityY << 1)))); - } + int ang = (camera->angle) >> ANGLETOFINESHIFT; + fixed_t power = QuakePower(quakefactor, relIntensityX); + viewx += FixedMul(finecosine[ang], power); + viewy += FixedMul(finesine[ang], power); } - else + if (relIntensityY != 0) { - if (intensityX) viewx += quakefactor * ((pr_torchflicker() % (intensityX << 2)) - (intensityX << 1)); - if (intensityY) viewy += quakefactor * ((pr_torchflicker() % (intensityY << 2)) - (intensityY << 1)); + int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; + fixed_t power = QuakePower(quakefactor, relIntensityY); + viewx += FixedMul(finecosine[ang], power); + viewy += FixedMul(finesine[ang], power); + } + if (intensityX != 0) + { + viewx += QuakePower(quakefactor, intensityX); + } + if (intensityY != 0) + { + viewy += QuakePower(quakefactor, intensityY); + } + // FIXME: Relative Z is not relative + intensityZ = MAX(intensityZ, relIntensityZ); + if (intensityZ != 0) + { + viewz += QuakePower(quakefactor, intensityZ); } - if (intensityZ) viewz += quakefactor * ((pr_torchflicker() % (intensityZ << 2)) - (intensityZ << 1)); } } diff --git a/src/version.h b/src/version.h index 09b830438..2be4787ee 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4518 +#define SAVEVER 4519 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)