- 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:
parent
f38dbc5055
commit
0d1fbcf65f
8 changed files with 131 additions and 38 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue