diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 044d51643..368d65c53 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -46,6 +46,8 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in m_IntensityY = intensityY; m_IntensityZ = intensityZ; m_Countdown = duration; + m_Countup = 0; + m_ScaleDownStart = duration; m_Flags = flags; } @@ -131,6 +133,7 @@ void DEarthquake::Tick () } } } + ++m_Countup; if (--m_Countdown == 0) { if (S_IsActorPlayingSomething(m_Spot, CHAN_BODY, m_QuakeSFX)) @@ -151,7 +154,7 @@ void DEarthquake::Tick () //========================================================================== int DEarthquake::StaticGetQuakeIntensities(AActor *victim, - int &x, int &y, int &z, int &relx, int &rely, int &relz) + int &x, int &y, int &z, int &relx, int &rely, int &relz, int &scaleDown, int &scaleDownStart, int &scaleUp) { if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { @@ -185,6 +188,18 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, y = MAX(y, quake->m_IntensityY); z = MAX(z, quake->m_IntensityZ); } + scaleDownStart = scaleDown = scaleUp = 1; + if (quake->m_Flags & QF_SCALEDOWN) + { + scaleDown = quake->m_Countdown; + } + else + { + scaleDownStart = 0; + scaleDown = 0; + } + if (quake->m_Flags & QF_SCALEUP) + scaleUp = quake->m_Countup; } } } diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index e153f7070..025582323 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -133,7 +133,9 @@ protected: enum { - QF_RELATIVE = 1, + QF_RELATIVE = 1, + QF_SCALEDOWN = 1 << 1, + QF_SCALEUP = 1 << 2, }; class DEarthquake : public DThinker @@ -147,12 +149,14 @@ public: void Tick (); TObjPtr m_Spot; fixed_t m_TremorRadius, m_DamageRadius; + int m_ScaleDownStart; int m_Countdown; + int m_Countup; FSoundID m_QuakeSFX; int m_Flags; int m_IntensityX, m_IntensityY, m_IntensityZ; - static int StaticGetQuakeIntensities(AActor *viewer, int &x, int &y, int &z, int &relx, int &rely, int &relz); + static int StaticGetQuakeIntensities(AActor *viewer, int &x, int &y, int &z, int &relx, int &rely, int &relz, int &scaleDown, int &scaleDownStart, int &scaleUp); private: DEarthquake (); diff --git a/src/r_utility.cpp b/src/r_utility.cpp index a65c90d93..006ce8b3f 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -770,16 +770,23 @@ bool R_GetViewInterpolationStatus() // //========================================================================== -static fixed_t QuakePower(fixed_t factor, int intensity) +static fixed_t QuakePower(fixed_t factor, int intensity, int scaleDown, int scaleDownStart, int scaleUp) { + //if (!scaledown) scaledown = 1; + //if (!scaleup) scaleup = 1; + //double sd = (scaledown / ((!scaledownstart) ? 1 : scaledownstart)); if (intensity == 0) { return 0; } - else + else if (!scaleDownStart) { return factor * ((pr_torchflicker() % (intensity << 2)) - (intensity << 1)); } + else + { + return (factor * ((pr_torchflicker() % (intensity << 2)) - (intensity << 1)) * ((scaleDown / scaleDownStart) >> 3)); + } } //========================================================================== @@ -892,40 +899,40 @@ void R_SetupFrame (AActor *actor) if (!paused) { - int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; + int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ, scaleDown, scaleDownStart, scaleUp; if (DEarthquake::StaticGetQuakeIntensities(camera, intensityX, intensityY, intensityZ, - relIntensityX, relIntensityY, relIntensityZ) > 0) + relIntensityX, relIntensityY, relIntensityZ, scaleDown, scaleDownStart, scaleUp) > 0) { fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); if (relIntensityX != 0) { int ang = (camera->angle) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, relIntensityX); + fixed_t power = QuakePower(quakefactor, relIntensityX, scaleDown, scaleDownStart, scaleUp); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } if (relIntensityY != 0) { int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, relIntensityY); + fixed_t power = QuakePower(quakefactor, relIntensityY, scaleDown, scaleDownStart, scaleUp); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } if (intensityX != 0) { - viewx += QuakePower(quakefactor, intensityX); + viewx += QuakePower(quakefactor, intensityX, scaleDown, scaleDownStart, scaleUp); } if (intensityY != 0) { - viewy += QuakePower(quakefactor, intensityY); + viewy += QuakePower(quakefactor, intensityY, scaleDown, scaleDownStart, scaleUp); } // FIXME: Relative Z is not relative intensityZ = MAX(intensityZ, relIntensityZ); if (intensityZ != 0) { - viewz += QuakePower(quakefactor, intensityZ); + viewz += QuakePower(quakefactor, intensityZ, scaleDown, scaleDownStart, scaleUp); } } } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 3df42e0f8..19845b91d 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -461,7 +461,9 @@ enum // Flags for A_QuakeEx enum { - QF_RELATIVE = 1, + QF_RELATIVE = 1, + QF_SCALEDOWN = 1 << 1, + QF_SCALEUP = 1 << 2, }; // This is only here to provide one global variable for testing.