Merge branch 'master' into floatcvt

# Conflicts:
#	src/p_acs.cpp
#	src/r_utility.cpp
#	src/thingdef/thingdef_codeptr.cpp
#	src/version.h
This commit is contained in:
Christoph Oelckers 2016-03-23 14:15:24 +01:00
commit 70d87f94f2
8 changed files with 182 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++)
@ -148,6 +160,8 @@ void DEarthquake::Tick ()
}
}
if (m_MiniCount > 0)
m_MiniCount--;
if (--m_Countdown == 0)
{
if (S_IsActorPlayingSomething(m_Spot, CHAN_BODY, m_QuakeSFX))
@ -158,12 +172,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(g_sin(waveMultiplier * time * (M_PI * 2 / TICRATE)));
}
@ -179,35 +199,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
@ -237,12 +318,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);
@ -258,6 +343,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));
@ -294,7 +380,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;
@ -308,7 +394,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;
}
}
@ -319,7 +405,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);
}
}
@ -327,6 +413,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);
}

View file

@ -158,6 +158,7 @@ struct FQuakeJiggers
int RelIntensityX, RelIntensityY, RelIntensityZ;
int OffsetX, OffsetY, OffsetZ;
int RelOffsetX, RelOffsetY, RelOffsetZ;
int Falloff, WFalloff;
};
class DEarthquake : public DThinker
@ -167,7 +168,7 @@ class DEarthquake : public DThinker
public:
DEarthquake(AActor *center, 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);
void Serialize (FArchive &arc);
void Tick ();
@ -179,9 +180,12 @@ public:
int m_Flags;
fixed_t m_IntensityX, m_IntensityY, m_IntensityZ;
float m_WaveSpeedX, m_WaveSpeedY, m_WaveSpeedZ;
fixed_t m_Falloff;
int m_Highpoint, m_MiniCount;
fixed_t GetModIntensity(int intensity) const;
fixed_t GetModWave(double waveMultiplier) const;
fixed_t GetFalloff(fixed_t dist) const;
static int StaticGetQuakeIntensities(AActor *viewer, FQuakeJiggers &jiggers);

View file

@ -5790,6 +5790,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
argCount > 9 ? ACSToDouble(args[9]) : 1.0,
argCount > 10 ? ACSToDouble(args[10]) : 1.0,
argCount > 11 ? ACSToDouble(args[11]) : 1.0 );
argCount > 12 ? args[12] : 0,
argCount > 13 ? args[13] : 0);
}
case ACSF_SetLineActivation:

View file

@ -965,7 +965,7 @@ void P_DoDeferedScripts (void);
//
// [RH] p_quake.c
//
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);
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, int falloff, int highpoint);
bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx);
#endif

View file

@ -897,10 +897,9 @@ void R_AddInterpolationPoint(const fixedvec3a &vec)
//
//==========================================================================
static fixed_t QuakePower(fixed_t factor, fixed_t intensity, fixed_t offset)
static fixed_t QuakePower(fixed_t factor, fixed_t intensity, fixed_t offset, fixed_t falloff, fixed_t wfalloff)
{
fixed_t randumb;
if (intensity == 0)
{
randumb = 0;
@ -909,7 +908,8 @@ static fixed_t QuakePower(fixed_t factor, fixed_t intensity, fixed_t offset)
{
randumb = pr_torchflicker(intensity * 2) - intensity;
}
return FixedMul(factor, randumb + offset);
fixed_t rn2 = (FixedMul(wfalloff,offset) + FixedMul(falloff, randumb));
return FixedMul(factor, rn2);
}
//==========================================================================
@ -1051,34 +1051,33 @@ void R_SetupFrame (AActor *actor)
if ((jiggers.RelIntensityX | jiggers.RelOffsetX) != 0)
{
int ang = (camera->_f_angle()) >> ANGLETOFINESHIFT;
fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityX, jiggers.RelOffsetX);
fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityX, jiggers.RelOffsetX, jiggers.Falloff, jiggers.WFalloff);
viewx += FixedMul(finecosine[ang], power);
viewy += FixedMul(finesine[ang], power);
}
if ((jiggers.RelIntensityY | jiggers.RelOffsetY) != 0)
{
int ang = (camera->_f_angle() + ANG90) >> ANGLETOFINESHIFT;
fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityY, jiggers.RelOffsetY);
fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityY, jiggers.RelOffsetY, jiggers.Falloff, jiggers.WFalloff);
viewx += FixedMul(finecosine[ang], power);
viewy += FixedMul(finesine[ang], power);
}
// FIXME: Relative Z is not relative
// [MC]On it! Will be introducing pitch after QF_WAVE.
if ((jiggers.RelIntensityZ | jiggers.RelOffsetZ) != 0)
{
viewz += QuakePower(quakefactor, jiggers.RelIntensityZ, jiggers.RelOffsetZ);
viewz += QuakePower(quakefactor, jiggers.RelIntensityZ, jiggers.RelOffsetZ, jiggers.Falloff, jiggers.WFalloff);
}
if ((jiggers.IntensityX | jiggers.OffsetX) != 0)
{
viewx += QuakePower(quakefactor, jiggers.IntensityX, jiggers.OffsetX);
viewx += QuakePower(quakefactor, jiggers.IntensityX, jiggers.OffsetX, jiggers.Falloff, jiggers.WFalloff);
}
if ((jiggers.IntensityY | jiggers.OffsetY) != 0)
{
viewy += QuakePower(quakefactor, jiggers.IntensityY, jiggers.OffsetY);
viewy += QuakePower(quakefactor, jiggers.IntensityY, jiggers.OffsetY, jiggers.Falloff, jiggers.WFalloff);
}
if ((jiggers.IntensityZ | jiggers.OffsetZ) != 0)
{
viewz += QuakePower(quakefactor, jiggers.IntensityZ, jiggers.OffsetZ);
viewz += QuakePower(quakefactor, jiggers.IntensityZ, jiggers.OffsetZ, jiggers.Falloff, jiggers.WFalloff);
}
}
}

View file

@ -4908,7 +4908,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake)
// A_QuakeEx
//
// Extended version of A_Quake. Takes individual axis into account and can
// take a flag.
// take flags.
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx)
@ -4925,7 +4925,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx)
PARAM_FLOAT_OPT(mulWaveX) { mulWaveX = 1.; }
PARAM_FLOAT_OPT(mulWaveY) { mulWaveY = 1.; }
PARAM_FLOAT_OPT(mulWaveZ) { mulWaveZ = 1.; }
P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ);
PARAM_INT_OPT(falloff) { falloff = 0; }
PARAM_INT_OPT(highpoint) { highpoint = 0; }
P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ, falloff, highpoint);
return 0;
}
@ -6629,6 +6631,8 @@ enum CBF
CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self.
CBF_DROPOFF = 1 << 5, //Check for dropoffs.
CBF_NOACTORS = 1 << 6, //Don't check actors.
CBF_ABSOLUTEPOS = 1 << 7, //Absolute position for offsets.
CBF_ABSOLUTEANGLE = 1 << 8, //Absolute angle for offsets.
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock)
@ -6636,7 +6640,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock)
PARAM_ACTION_PROLOGUE;
PARAM_STATE(block)
PARAM_INT_OPT(flags) { flags = 0; }
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
PARAM_FIXED_OPT(xofs) { xofs = 0; }
PARAM_FIXED_OPT(yofs) { yofs = 0; }
PARAM_FIXED_OPT(zofs) { zofs = 0; }
PARAM_ANGLE_OPT(angle) { angle = 0; }
AActor *mobj = COPY_AAPTR(self, ptr);
@ -6646,6 +6654,49 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock)
ACTION_RETURN_STATE(NULL);
}
#if 0 // this needs some work.
if (!(flags & CBF_ABSOLUTEANGLE))
{
angle += self->angle;
}
angle_t ang = angle >> ANGLETOFINESHIFT;
fixedvec3 oldpos = mobj->Pos();
fixedvec3 pos;
if (flags & CBF_ABSOLUTEPOS)
{
pos.x = xofs;
pos.y = yofs;
pos.z = zofs;
}
else
{
pos = mobj->Vec3Offset(
FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]),
FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]),
mobj->Z() + zofs);
}
// Next, try checking the position based on the sensitivity desired.
// If checking for dropoffs, set the z so we can have maximum flexibility.
// Otherwise, set origin and set it back after testing.
bool checker = false;
if (flags & CBF_DROPOFF)
{
mobj->SetZ(pos.z);
checker = P_CheckMove(mobj, pos.x, pos.y);
mobj->SetZ(oldpos.z);
}
else
{
mobj->SetOrigin(pos, true);
checker = P_TestMobjLocation(mobj);
mobj->SetOrigin(oldpos, true);
}
#endif
//Nothing to block it so skip the rest.
bool checker = (flags & CBF_DROPOFF) ? P_CheckMove(mobj, mobj->_f_X(), mobj->_f_Y()) : P_TestMobjLocation(mobj);
if (checker)

View file

@ -277,7 +277,7 @@ ACTOR Actor native //: Thinker
action native A_SetUserArray(name varname, int index, int value);
action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0);
action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake");
action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1);
action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1, int falloff = 0, int highpoint = 0);
action native A_SetTics(int tics);
action native A_SetDamageType(name damagetype);
action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
@ -317,7 +317,7 @@ ACTOR Actor native //: Thinker
action native A_SetRipMax(int maximum);
action native A_SetChaseThreshold(int threshold, bool def = false, int ptr = AAPTR_DEFAULT);
action native state A_CheckProximity(state jump, class<Actor> classname, float distance, int count = 1, int flags = 0, int ptr = AAPTR_DEFAULT);
action native state A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT);
action native state A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0);
action native state A_CheckSightOrRange(float distance, state label, bool two_dimension = false);
action native state A_CheckRange(float distance, state label, bool two_dimension = false);
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);

View file

@ -527,6 +527,8 @@ enum
CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self.
CBF_DROPOFF = 1 << 5, //Check for dropoffs.
CBF_NOACTORS = 1 << 6, //Don't check actors.
CBF_ABSOLUTEPOS = 1 << 7, //Absolute position for offsets.
CBF_ABSOLUTEANGLE = 1 << 8, //Absolute angle for offsets.
};
enum