gzdoom/src/g_shared/a_fastprojectile.cpp
Christoph Oelckers f269af052c - fixed some issues with P_FindFloorCeiling's coordinate processing.
- added a new compatmode CVAR which allows setting some generic compatibility 
  flag combinations:
  Doom: sets the options needed to make most Doom.exe compatible map play without
  errors.
  Doom (strict): Same as above but sets a few more options. Please note that this
  does not mean full Doom.exe behavior emulation.
  Boom: Sets all options that consider differences between ZDoom and Boom.
  ZDoom 2.0.63: Sets only the COMPATF_SOUNDTARGET option which is needed for
  many older ZDoom maps.
- added new COMPAT_CROSSDROPOFF option to block monsters from being pushed over
  dropoffs by damage kickback.
- fixed: AFastProjectile::Tick must call Effect only 8 times per tic, regardless
  of the amount of steps taken.
- fixed: momentum checks in AFastProjectile did not use absolute values.


SVN r1369 (trunk)
2009-01-25 21:59:38 +00:00

106 lines
2 KiB
C++

#include "a_sharedglobal.h"
#include "p_local.h"
IMPLEMENT_CLASS(AFastProjectile)
//----------------------------------------------------------------------------
//
// AFastProjectile :: Tick
//
// Thinker for the ultra-fast projectiles used by Heretic and Hexen
//
//----------------------------------------------------------------------------
void AFastProjectile::Tick ()
{
int i;
fixed_t xfrac;
fixed_t yfrac;
fixed_t zfrac;
int changexy;
PrevX = x;
PrevY = y;
PrevZ = z;
// [RH] Ripping is a little different than it was in Hexen
FCheckPosition tm(!!(flags2 & MF2_RIP));
int shift = 3;
int count = 8;
if (radius > 0)
{
while ( ((abs(momx) >> shift) > radius) || ((abs(momy) >> shift) > radius))
{
// we need to take smaller steps.
shift++;
count<<=1;
}
}
// Handle movement
if (momx || momy || (z != floorz) || momz)
{
xfrac = momx>>shift;
yfrac = momy>>shift;
zfrac = momz>>shift;
changexy = xfrac || yfrac;
int ripcount = count >> 3;
for (i = 0; i < count; i++)
{
if (changexy)
{
if (--ripcount <= 0)
{
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen
}
if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
}
z += zfrac;
if (z <= floorz)
{ // Hit the floor
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (z + height > ceilingz)
{ // Hit the ceiling
z = ceilingz - height;
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy && ripcount <= 0)
{
ripcount = count >> 3;
Effect();
}
}
}
// Advance the state
if (tics != -1)
{
tics--;
while (!tics)
{
if (!SetState (state->GetNextState ()))
{ // mobj was removed
return;
}
}
}
}
void AFastProjectile::Effect()
{
}