mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-12-14 06:01:09 +00:00
8c2f651bdb
- After doing some tests with state label scopes I had to conclude that using '.' both for separating sub-state-labels and scope resolution identifiers does not work reliably unless all actor class names were prohibited from being used as state labels. Since that is undesirable the only solution is to change the scope resolution operator. Fortunately no WADs so far have used it so implementing such a breaking change isn't a major issue. Now it uses '::', like C++ for this purpose. - Converted Revenant, Mancubus and Pain Elemental to DECORATE. SVN r375 (trunk)
138 lines
3 KiB
C++
138 lines
3 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)
|
|
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;
|
|
slope = (dest->z+40*FRACUNIT - 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);
|
|
}
|
|
}
|