gzdoom/src/g_doom/a_revenant.cpp
Christoph Oelckers 3b477d7022 - Fixed: POwered up weapons with a different ready state than their base
weapon didn't change back when the powerup expired.
- Fixed: The powered up version of Heretic's Gauntlets missed the proper
  state assignments for Ready, Lower and Raise.
- Fixed: The Strife player was missing its pain state.
- Fixed: Revenant missiles couldn't home in on targets with a height lower than
  40.
- Fixed: The code which checked for hitscan traces hitting actors from above
  and below must test whether the calculated hit position is actually inside 
  the actor being checked. If it crosses the top/bottom plane outside the
  bounding box there can't be a hit.
- Changed: State labels in code pointer calls must now be enclosed in quotation marks.
  This was done to ensure compatibility with parsers that will parse these as
  identifier-aware script code later.


SVN r554 (trunk)
2007-10-19 08:49:02 +00:00

146 lines
3.2 KiB
C++

#include "templates.h"
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
#include "a_action.h"
#include "a_doomglobal.h"
static FRandom pr_tracer ("Tracer");
static FRandom pr_skelfist ("SkelFist");
//
// A_SkelMissile
//
void A_SkelMissile (AActor *self)
{
AActor *missile;
if (!self->target)
return;
A_FaceTarget (self);
missile = P_SpawnMissileZ (self, self->z + 48*FRACUNIT,
self->target, PClass::FindClass("RevenantTracer"));
if (missile != NULL)
{
missile->x += missile->momx;
missile->y += missile->momy;
missile->tracer = self->target;
}
}
#define TRACEANGLE (0xc000000)
void A_Tracer (AActor *self)
{
angle_t exact;
fixed_t dist;
fixed_t slope;
AActor *dest;
AActor *smoke;
// killough 1/18/98: this is why some missiles do not have smoke
// and some do. Also, internal demos start at random gametics, thus
// the bug in which revenants cause internal demos to go out of sync.
//
// killough 3/6/98: fix revenant internal demo bug by subtracting
// levelstarttic from gametic:
//
// [RH] level.time is always 0-based, so nothing special to do here.
if (level.time & 3)
return;
// spawn a puff of smoke behind the rocket
P_SpawnPuff (PClass::FindClass(NAME_BulletPuff), self->x, self->y, self->z, 0, 3);
smoke = Spawn ("RevenantTracerSmoke", self->x - self->momx,
self->y - self->momy, self->z, ALLOW_REPLACE);
smoke->momz = FRACUNIT;
smoke->tics -= pr_tracer()&3;
if (smoke->tics < 1)
smoke->tics = 1;
// adjust direction
dest = self->tracer;
if (!dest || dest->health <= 0 || self->Speed == 0)
return;
// change angle
exact = R_PointToAngle2 (self->x, self->y, dest->x, dest->y);
if (exact != self->angle)
{
if (exact - self->angle > 0x80000000)
{
self->angle -= TRACEANGLE;
if (exact - self->angle < 0x80000000)
self->angle = exact;
}
else
{
self->angle += TRACEANGLE;
if (exact - self->angle > 0x80000000)
self->angle = exact;
}
}
exact = self->angle>>ANGLETOFINESHIFT;
self->momx = FixedMul (self->Speed, finecosine[exact]);
self->momy = FixedMul (self->Speed, finesine[exact]);
// change slope
dist = P_AproxDistance (dest->x - self->x,
dest->y - self->y);
dist = dist / self->Speed;
if (dist < 1)
dist = 1;
if (dest->height >= 56*FRACUNIT)
{
slope = (dest->z+40*FRACUNIT - self->z) / dist;
}
else
{
slope = (dest->z + self->height*2/3 - self->z) / dist;
}
if (slope < self->momz)
self->momz -= FRACUNIT/8;
else
self->momz += FRACUNIT/8;
}
void A_SkelWhoosh (AActor *self)
{
if (!self->target)
return;
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "skeleton/swing", 1, ATTN_NORM);
}
void A_SkelFist (AActor *self)
{
if (!self->target)
return;
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = ((pr_skelfist()%10)+1)*6;
S_Sound (self, CHAN_WEAPON, "skeleton/melee", 1, ATTN_NORM);
P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (damage, self->target, self);
}
}