- flattened the following commits by Major Cooke:

* Added falloff parameter to A_QuakeEx.
- Treated just like A_Explode's 'fullradiusdamage' parameter, where the quake will fall off from this distance on out to the edge. Default is 0, which means no falloff.
- Credits to MaxED and Michaelis for helping.

* - Added HighPoint parameter to QuakeEx.
- Allows fine tuning of where the quake's maximum or minimum occurs, in tics. This must be a range between [1, duration).
- For up or down scaling quakes, this sets the quake to reach maximum sooner or start minimizing later.
- For both, this indicates when the strongest will occur. Default is 0, or in the middle.

The original commits were nearly impossible to find in the convoluted commit tree, so I think it's preferable to have one clean commit instead.
This commit is contained in:
Christoph Oelckers 2016-03-23 14:03:10 +01:00
commit 0d1fbcf65f
8 changed files with 131 additions and 38 deletions

View file

@ -37,7 +37,7 @@ DEarthquake::DEarthquake()
DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesound, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ)
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint)
: DThinker(STAT_EARTHQUAKE)
{
m_QuakeSFX = quakesound;
@ -54,6 +54,9 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in
m_WaveSpeedX = (float)waveSpeedX;
m_WaveSpeedY = (float)waveSpeedY;
m_WaveSpeedZ = (float)waveSpeedZ;
m_Falloff = falloff << FRACBITS;
m_Highpoint = highpoint;
m_MiniCount = highpoint;
}
//==========================================================================
@ -97,6 +100,14 @@ void DEarthquake::Serialize (FArchive &arc)
{
arc << m_WaveSpeedX << m_WaveSpeedY << m_WaveSpeedZ;
}
if (SaveVersion < 4534)
{
m_Falloff = m_Highpoint = m_MiniCount = 0;
}
else
{
arc << m_Falloff << m_Highpoint << m_MiniCount;
}
}
//==========================================================================
@ -122,6 +133,7 @@ void DEarthquake::Tick ()
{
S_Sound (m_Spot, CHAN_BODY | CHAN_LOOP, m_QuakeSFX, 1, ATTN_NORM);
}
if (m_DamageRadius > 0)
{
for (i = 0; i < MAXPLAYERS; i++)
@ -158,6 +170,8 @@ void DEarthquake::Tick ()
}
}
if (m_MiniCount > 0)
m_MiniCount--;
if (--m_Countdown == 0)
{
if (S_IsActorPlayingSomething(m_Spot, CHAN_BODY, m_QuakeSFX))
@ -168,12 +182,18 @@ void DEarthquake::Tick ()
}
}
//==========================================================================
//
// DEarthquake :: GetModWave
//
// QF_WAVE converts intensity into amplitude and unlocks a new property, the
// wave length. This is, in short, waves per second. Named waveMultiplier
// because that's as the name implies: adds more waves per second.
//
//==========================================================================
fixed_t DEarthquake::GetModWave(double waveMultiplier) const
{
//QF_WAVE converts intensity into amplitude and unlocks a new property, the wave length.
//This is, in short, waves per second (full cycles, mind you, from 0 to 360.)
//Named waveMultiplier because that's as the name implies: adds more waves per second.
double time = m_Countdown - FIXED2DBL(r_TicFrac);
return FLOAT2FIXED(sin(waveMultiplier * time * (M_PI * 2 / TICRATE)));
}
@ -189,35 +209,96 @@ fixed_t DEarthquake::GetModWave(double waveMultiplier) const
fixed_t DEarthquake::GetModIntensity(fixed_t intensity) const
{
assert(m_CountdownStart >= m_Countdown);
intensity += intensity; // always doubled
if (m_Flags & (QF_SCALEDOWN | QF_SCALEUP))
{
// Adjustable maximums must use a range between 1 and m_CountdownStart to constrain between no quake and full quake.
bool check = !!(m_Highpoint > 0 && m_Highpoint < m_CountdownStart);
int divider = (check) ? m_Highpoint : m_CountdownStart;
int scalar;
if ((m_Flags & (QF_SCALEDOWN | QF_SCALEUP)) == (QF_SCALEDOWN | QF_SCALEUP))
{
scalar = (m_Flags & QF_MAX) ? MAX(m_Countdown, m_CountdownStart - m_Countdown)
: MIN(m_Countdown, m_CountdownStart - m_Countdown);
if (check)
{
if (m_MiniCount > 0)
scalar = (m_Flags & QF_MAX) ? m_MiniCount : (m_Highpoint - m_MiniCount);
else
{
divider = m_CountdownStart - m_Highpoint;
scalar = (m_Flags & QF_MAX) ? (divider - m_Countdown) : m_Countdown;
}
}
else
{
// Defaults to middle of the road.
divider = m_CountdownStart;
scalar = (m_Flags & QF_MAX) ? MAX(m_Countdown, m_CountdownStart - m_Countdown)
: MIN(m_Countdown, m_CountdownStart - m_Countdown);
}
scalar = (scalar > divider) ? divider : scalar;
if (m_Flags & QF_FULLINTENSITY)
{
scalar *= 2;
}
}
else if (m_Flags & QF_SCALEDOWN)
else
{
scalar = m_Countdown;
}
else // QF_SCALEUP
{
scalar = m_CountdownStart - m_Countdown;
}
assert(m_CountdownStart > 0);
intensity = Scale(intensity, scalar, m_CountdownStart);
if (m_Flags & QF_SCALEDOWN)
{
scalar = m_Countdown;
}
else // QF_SCALEUP
{
scalar = m_CountdownStart - m_Countdown;
if (m_Highpoint > 0)
{
if ((m_Highpoint - m_MiniCount) < divider)
scalar = m_Highpoint - m_MiniCount;
else
scalar = divider;
}
}
scalar = (scalar > divider) ? divider : scalar;
}
assert(divider > 0);
intensity = Scale(intensity, scalar, divider);
}
return intensity;
}
//==========================================================================
//
// DEarthquake :: GetFalloff
//
// Given the distance of the player from the quake, find the multiplier.
// Process everything as doubles, and output again as fixed_t (mainly
// because fixed_t was misbehaving here...)
//
//==========================================================================
fixed_t DEarthquake::GetFalloff(fixed_t dist) const
{
if ((dist < m_Falloff) || (m_Falloff >= m_TremorRadius) || (m_Falloff <= 0) || (m_TremorRadius - m_Falloff <= 0))
{ //Player inside the minimum falloff range, or safety check kicked in.
return FRACUNIT;
}
else if ((dist > m_Falloff) && (dist < m_TremorRadius))
{ //Player inside the radius, and outside the min distance for falloff.
fixed_t tremorsize = m_TremorRadius - m_Falloff;
fixed_t tremordist = dist - m_Falloff;
assert(tremorsize > 0);
return (FRACUNIT - FixedMul(FRACUNIT,tremordist) / tremorsize);
}
else
{ //Shouldn't happen.
return FRACUNIT;
}
}
//==========================================================================
//
// DEarthquake::StaticGetQuakeIntensity
@ -247,12 +328,16 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
fixed_t dist = quake->m_Spot->AproxDistance (victim, true);
if (dist < quake->m_TremorRadius)
{
fixed_t falloff = quake->GetFalloff(dist);
++count;
fixed_t x = quake->GetModIntensity(quake->m_IntensityX);
fixed_t y = quake->GetModIntensity(quake->m_IntensityY);
fixed_t z = quake->GetModIntensity(quake->m_IntensityZ);
if (!(quake->m_Flags & QF_WAVE))
{
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
if (quake->m_Flags & QF_RELATIVE)
{
jiggers.RelIntensityX = MAX(x, jiggers.RelIntensityX);
@ -268,6 +353,7 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
}
else
{
jiggers.WFalloff = MAX(falloff, jiggers.WFalloff);
fixed_t mx = FixedMul(x, quake->GetModWave(quake->m_WaveSpeedX));
fixed_t my = FixedMul(y, quake->GetModWave(quake->m_WaveSpeedY));
fixed_t mz = FixedMul(z, quake->GetModWave(quake->m_WaveSpeedZ));
@ -304,7 +390,7 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ)
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint)
{
AActor *center;
bool res = false;
@ -318,7 +404,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
if (activator != NULL)
{
new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ);
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint);
return true;
}
}
@ -329,7 +415,7 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
{
res = true;
new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ);
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint);
}
}
@ -337,6 +423,6 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY,
}
bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx)
{ //Maintains original behavior by passing 0 to intensityZ, and flags.
return P_StartQuakeXYZ(activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0, 0, 0, 0);
{ //Maintains original behavior by passing 0 to intensityZ, flags, and everything else after QSFX.
return P_StartQuakeXYZ(activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0, 0, 0, 0, 0, 0);
}