Added A_QuakeEx(intensity x, y, z, duration, damrad, tremrad, sound, flags)

- Unlocks the full potential of using quakes, including the Z axis. Each intensity applies to X/Y/Z planes whenever a player is experiencing it.
- Flags:
- QF_RELATIVE - Adjusts the quaking of the camera to go in the direction its aiming (X: forward/backward. Y: Left/right.)
- Plans for including pitch will be implemented in the future for the Z axis with relativity.
This commit is contained in:
MajorCooke 2015-02-14 15:58:39 -06:00
parent d8d2058ec6
commit 7050d03222
7 changed files with 143 additions and 20 deletions

View File

@ -33,8 +33,8 @@ DEarthquake::DEarthquake()
// //
//========================================================================== //==========================================================================
DEarthquake::DEarthquake (AActor *center, int intensity, int duration, DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesound) int damrad, int tremrad, FSoundID quakesound, int flags)
: DThinker(STAT_EARTHQUAKE) : DThinker(STAT_EARTHQUAKE)
{ {
m_QuakeSFX = quakesound; m_QuakeSFX = quakesound;
@ -42,8 +42,12 @@ DEarthquake::DEarthquake (AActor *center, int intensity, int duration,
// Radii are specified in tile units (64 pixels) // Radii are specified in tile units (64 pixels)
m_DamageRadius = damrad << (FRACBITS); m_DamageRadius = damrad << (FRACBITS);
m_TremorRadius = tremrad << (FRACBITS); m_TremorRadius = tremrad << (FRACBITS);
m_Intensity = intensity; m_Intensity = intensityX;
m_Countdown = duration; m_Countdown = duration;
m_Flags = flags;
m_iX = intensityX;
m_iY = intensityY;
m_iZ = intensityZ;
} }
//========================================================================== //==========================================================================
@ -54,10 +58,10 @@ DEarthquake::DEarthquake (AActor *center, int intensity, int duration,
void DEarthquake::Serialize (FArchive &arc) void DEarthquake::Serialize (FArchive &arc)
{ {
Super::Serialize (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 arc << m_Spot << m_Intensity << m_Countdown
<< m_TremorRadius << m_DamageRadius << m_TremorRadius << m_DamageRadius
<< m_QuakeSFX; << m_QuakeSFX << m_Flags << m_iX << m_iY << m_iZ;
} }
//========================================================================== //==========================================================================
@ -126,9 +130,10 @@ void DEarthquake::Tick ()
// //
//========================================================================== //==========================================================================
int DEarthquake::StaticGetQuakeIntensity (AActor *victim) int DEarthquake::StaticGetQuakeIntensity (AActor *victim, int selector)
{ {
int intensity = 0; int intensity = 0;
int quakeIntensity = 0;
TThinkerIterator<DEarthquake> iterator (STAT_EARTHQUAKE); TThinkerIterator<DEarthquake> iterator (STAT_EARTHQUAKE);
DEarthquake *quake; DEarthquake *quake;
@ -145,32 +150,84 @@ int DEarthquake::StaticGetQuakeIntensity (AActor *victim)
victim->y - quake->m_Spot->y); victim->y - quake->m_Spot->y);
if (dist < quake->m_TremorRadius) if (dist < quake->m_TremorRadius)
{ {
if (intensity < quake->m_Intensity) switch (selector)
intensity = quake->m_Intensity; {
default:
case 0:
quakeIntensity = quake->m_iX;
break;
case 1:
quakeIntensity = quake->m_iY;
break;
case 2:
quakeIntensity = quake->m_iZ;
break;
}
if (intensity < quakeIntensity)
intensity = quakeIntensity;
} }
} }
} }
return intensity; return intensity;
} }
//==========================================================================
//
// DEarthquake::StaticGetQuakeIntensity
//
// Searches for all quakes near the victim and returns their combined
// intensity.
//
//==========================================================================
int DEarthquake::StaticGetQuakeFlags(AActor *victim)
{
int flags = 0;
TThinkerIterator<DEarthquake> 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 // P_StartQuake
// //
//========================================================================== //==========================================================================
bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx) bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags)
{ {
AActor *center; AActor *center;
bool res = false; bool res = false;
intensity = clamp (intensity, 1, 9); if (intensityX) intensityX = clamp(intensityX, 1, 9);
if (intensityY) intensityY = clamp(intensityY, 1, 9);
if (intensityZ) intensityZ = clamp(intensityZ, 1, 9);
if (tid == 0) if (tid == 0)
{ {
if (activator != NULL) if (activator != NULL)
{ {
new DEarthquake(activator, intensity, duration, damrad, tremrad, quakesfx); new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags);
return true; return true;
} }
} }
@ -180,9 +237,14 @@ bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int
while ( (center = iterator.Next ()) ) while ( (center = iterator.Next ()) )
{ {
res = true; res = true;
new DEarthquake (center, intensity, duration, damrad, tremrad, quakesfx); new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags);
} }
} }
return res; return res;
} }
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);
}

View File

@ -131,23 +131,31 @@ protected:
DFlashFader (); DFlashFader ();
}; };
enum
{
QF_RELATIVE = 1,
};
class DEarthquake : public DThinker class DEarthquake : public DThinker
{ {
DECLARE_CLASS (DEarthquake, DThinker) DECLARE_CLASS (DEarthquake, DThinker)
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
DEarthquake (AActor *center, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags);
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
void Tick (); void Tick ();
TObjPtr<AActor> m_Spot; TObjPtr<AActor> m_Spot;
fixed_t m_TremorRadius, m_DamageRadius; fixed_t m_TremorRadius, m_DamageRadius;
int m_Intensity; int m_Intensity;
int m_Countdown; int m_Countdown;
FSoundID m_QuakeSFX; FSoundID m_QuakeSFX;
int m_Flags;
int m_iX, m_iY, m_iZ;
static int StaticGetQuakeFlags(AActor *viewer);
static int StaticGetQuakeIntensity (AActor *viewer, int selector);
static int StaticGetQuakeIntensity (AActor *viewer);
private: private:
DEarthquake (); DEarthquake ();

View File

@ -929,6 +929,7 @@ void P_DoDeferedScripts (void);
// //
// [RH] p_quake.c // [RH] p_quake.c
// //
bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags);
bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx);
#endif #endif

View File

@ -875,13 +875,37 @@ void R_SetupFrame (AActor *actor)
if (!paused) if (!paused)
{ {
int intensity = DEarthquake::StaticGetQuakeIntensity (camera); int intensityX = DEarthquake::StaticGetQuakeIntensity(camera, 0);
if (intensity != 0) int intensityY = DEarthquake::StaticGetQuakeIntensity(camera, 1);
int intensityZ = DEarthquake::StaticGetQuakeIntensity(camera, 2);
int quakeflags = DEarthquake::StaticGetQuakeFlags(camera);
if (intensityX || intensityY || intensityZ)
{ {
fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity);
viewx += quakefactor * ((pr_torchflicker() % (intensity<<2)) - (intensity<<1)); if ((quakeflags & QF_RELATIVE) && (intensityX != intensityY))
viewy += quakefactor * ((pr_torchflicker() % (intensity<<2)) - (intensity<<1)); {
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))));
}
}
else
{
if (intensityX) viewx += quakefactor * ((pr_torchflicker() % (intensityX << 2)) - (intensityX << 1));
if (intensityY) viewy += quakefactor * ((pr_torchflicker() % (intensityY << 2)) - (intensityY << 1));
}
if (intensityZ) viewz += quakefactor * ((pr_torchflicker() % (intensityZ << 2)) - (intensityZ << 1));
} }
} }

View File

@ -4403,6 +4403,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake)
P_StartQuake(self, 0, intensity, duration, damrad, tremrad, sound); P_StartQuake(self, 0, intensity, duration, damrad, tremrad, sound);
} }
//===========================================================================
//
// A_QuakeEx
//
// Extended version of A_Quake. Takes individual axis into account and can
// take a flag.
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx)
{
ACTION_PARAM_START(8);
ACTION_PARAM_INT(intensityX, 0);
ACTION_PARAM_INT(intensityY, 1);
ACTION_PARAM_INT(intensityZ, 2);
ACTION_PARAM_INT(duration, 3);
ACTION_PARAM_INT(damrad, 4);
ACTION_PARAM_INT(tremrad, 5);
ACTION_PARAM_SOUND(sound, 6);
ACTION_PARAM_INT(flags, 7);
P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags);
}
//=========================================================================== //===========================================================================
// //
// A_Weave // A_Weave

View File

@ -299,6 +299,7 @@ ACTOR Actor native //: Thinker
action native A_SetUserArray(name varname, int index, int value); 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_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_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);
action native A_SetTics(int tics); action native A_SetTics(int tics);
action native A_SetDamageType(name damagetype); action native A_SetDamageType(name damagetype);
action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256); action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);

View File

@ -457,6 +457,11 @@ enum
FAF_NODISTFACTOR = 8, FAF_NODISTFACTOR = 8,
}; };
// Flags for A_QuakeEx
enum
{
QF_RELATIVE = 1,
};
// This is only here to provide one global variable for testing. // This is only here to provide one global variable for testing.
native int testglobalvar; native int testglobalvar;