qzdoom/src/g_strife/a_strifebishop.cpp
Christoph Oelckers fdeb374fdb SVN r37 (trunk)
2006-04-13 16:52:24 +00:00

212 lines
6.1 KiB
C++

#include "actor.h"
#include "p_enemy.h"
#include "a_action.h"
#include "s_sound.h"
#include "p_local.h"
void A_TossGib (AActor *);
// Bishop -------------------------------------------------------------------
void A_SBishopAttack (AActor *);
void A_SpawnSpectre2 (AActor *);
class AStrifeBishop : public AActor
{
DECLARE_ACTOR (AStrifeBishop, AActor)
public:
void GetExplodeParms (int &damage, int &dist, bool &hurtSource)
{
damage = dist = 64;
}
void NoBlockingSet ()
{
P_DropItem (this, "CrateOfMissiles", 20, 256);
}
};
FState AStrifeBishop::States[] =
{
#define S_BISHOP_STND 0
S_NORMAL (MLDR, 'A', 10, A_Look, &States[S_BISHOP_STND]),
#define S_BISHOP_RUN (S_BISHOP_STND+1)
S_NORMAL (MLDR, 'A', 3, A_Chase, &States[S_BISHOP_RUN+1]),
S_NORMAL (MLDR, 'A', 3, A_Chase, &States[S_BISHOP_RUN+2]),
S_NORMAL (MLDR, 'B', 3, A_Chase, &States[S_BISHOP_RUN+3]),
S_NORMAL (MLDR, 'B', 3, A_Chase, &States[S_BISHOP_RUN+4]),
S_NORMAL (MLDR, 'C', 3, A_Chase, &States[S_BISHOP_RUN+5]),
S_NORMAL (MLDR, 'C', 3, A_Chase, &States[S_BISHOP_RUN+6]),
S_NORMAL (MLDR, 'D', 3, A_Chase, &States[S_BISHOP_RUN+7]),
S_NORMAL (MLDR, 'D', 3, A_Chase, &States[S_BISHOP_RUN]),
#define S_BISHOP_ATK (S_BISHOP_RUN+8)
S_NORMAL (MLDR, 'E', 3, A_FaceTarget, &States[S_BISHOP_ATK+1]),
S_BRIGHT (MLDR, 'F', 2, A_SBishopAttack, &States[S_BISHOP_RUN]),
#define S_BISHOP_PAIN (S_BISHOP_ATK+2)
S_NORMAL (MLDR, 'D', 1, A_Pain, &States[S_BISHOP_RUN]),
#define S_BISHOP_DIE (S_BISHOP_PAIN+1)
S_BRIGHT (MLDR, 'G', 3, NULL, &States[S_BISHOP_DIE+1]),
S_BRIGHT (MLDR, 'H', 5, A_Scream, &States[S_BISHOP_DIE+2]),
S_BRIGHT (MLDR, 'I', 4, A_TossGib, &States[S_BISHOP_DIE+3]),
S_BRIGHT (MLDR, 'J', 4, A_ExplodeAndAlert, &States[S_BISHOP_DIE+4]),
S_BRIGHT (MLDR, 'K', 4, NULL, &States[S_BISHOP_DIE+5]),
S_BRIGHT (MLDR, 'L', 4, NULL, &States[S_BISHOP_DIE+6]),
S_BRIGHT (MLDR, 'M', 4, A_NoBlocking, &States[S_BISHOP_DIE+7]),
S_BRIGHT (MLDR, 'N', 4, NULL, &States[S_BISHOP_DIE+8]),
S_BRIGHT (MLDR, 'O', 4, A_TossGib, &States[S_BISHOP_DIE+9]),
S_BRIGHT (MLDR, 'P', 4, NULL, &States[S_BISHOP_DIE+10]),
S_BRIGHT (MLDR, 'Q', 4, A_TossGib, &States[S_BISHOP_DIE+11]),
S_BRIGHT (MLDR, 'R', 4, NULL, &States[S_BISHOP_DIE+12]),
S_BRIGHT (MLDR, 'S', 4, A_TossGib, &States[S_BISHOP_DIE+13]),
S_BRIGHT (MLDR, 'T', 4, NULL, &States[S_BISHOP_DIE+14]),
S_BRIGHT (MLDR, 'U', 4, A_TossGib, &States[S_BISHOP_DIE+15]),
S_BRIGHT (MLDR, 'V', 4, A_SpawnSpectre2, NULL),
};
IMPLEMENT_ACTOR (AStrifeBishop, Strife, 187, 0)
PROP_SpawnState (S_BISHOP_STND)
PROP_SeeState (S_BISHOP_RUN)
PROP_PainState (S_BISHOP_PAIN)
PROP_MissileState (S_BISHOP_ATK)
PROP_DeathState (S_BISHOP_DIE)
PROP_SpawnHealth (500)
PROP_PainChance (128)
PROP_SpeedFixed (8)
PROP_RadiusFixed (40)
PROP_HeightFixed (56)
PROP_Mass (500)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_COUNTKILL|MF_NOTDMATCH)
PROP_Flags2 (MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_MCROSS)
PROP_Flags4 (MF4_INCOMBAT|MF4_FIRERESIST|MF4_NOICEDEATH)
PROP_MinMissileChance (150)
PROP_MaxDropOffHeight (32)
PROP_StrifeType (64)
PROP_SeeSound ("bishop/sight")
PROP_PainSound ("bishop/pain")
PROP_DeathSound ("bishop/death")
PROP_ActiveSound ("bishop/active")
END_DEFAULTS
// The Bishop's missile -----------------------------------------------------
void A_RocketInFlight (AActor *);
void A_Tracer2 (AActor *);
class ABishopMissile : public AActor
{
DECLARE_ACTOR (ABishopMissile, AActor)
public:
void PreExplode ()
{
RenderStyle = STYLE_Add;
S_StopSound (this, CHAN_VOICE);
}
void GetExplodeParms (int &damage, int &dist, bool &hurtSource)
{
damage = dist = 64;
}
};
FState ABishopMissile::States[] =
{
S_BRIGHT (MISS, 'A', 4, A_RocketInFlight, &States[1]),
S_BRIGHT (MISS, 'B', 3, A_Tracer2, &States[0]),
S_BRIGHT (SMIS, 'A', 5, A_ExplodeAndAlert, &States[3]),
S_BRIGHT (SMIS, 'B', 5, NULL, &States[4]),
S_BRIGHT (SMIS, 'C', 4, NULL, &States[5]),
S_BRIGHT (SMIS, 'D', 2, NULL, &States[6]),
S_BRIGHT (SMIS, 'E', 2, NULL, &States[7]),
S_BRIGHT (SMIS, 'F', 2, NULL, &States[8]),
S_BRIGHT (SMIS, 'G', 2, NULL, NULL),
};
IMPLEMENT_ACTOR (ABishopMissile, Strife, -1, 0)
PROP_SpawnState (0)
PROP_DeathState (2)
PROP_SpeedFixed (20)
PROP_RadiusFixed (10)
PROP_HeightFixed (14)
PROP_Damage (10)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT|MF2_SEEKERMISSILE)
PROP_Flags4 (MF4_STRIFEDAMAGE)
PROP_MaxStepHeight (4)
PROP_SeeSound ("bishop/misl")
PROP_DeathSound ("bishop/mislx")
END_DEFAULTS
void A_SBishopAttack (AActor *self)
{
if (self->target != NULL)
{
AActor *missile = P_SpawnMissileZ (self, self->z + 64*FRACUNIT, self->target, RUNTIME_CLASS(ABishopMissile));
if (missile != NULL)
{
missile->tracer = self->target;
}
}
}
// In Strife, this number is stored in the data segment, but it doesn't seem to be
// altered anywhere.
#define TRACEANGLE (0xe000000)
void A_Tracer2 (AActor *self)
{
AActor *dest;
angle_t exact;
fixed_t dist;
fixed_t slope;
dest = self->tracer;
if (dest == NULL || 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 /= 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;
}
}