qzdoom-gpl/src/g_doom/a_fatso.cpp
Christoph Oelckers 8c2f651bdb - Replaced the static string buffer in ProcessStates with an FString.
- 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)
2006-11-04 22:26:04 +00:00

155 lines
4 KiB
C++

#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 "thingdef.h"
//
// Mancubus attack,
// firing three missiles in three different directions?
// Doesn't look like it.
//
#define FATSPREAD (ANG90/8)
void A_FatRaise (AActor *self)
{
A_FaceTarget (self);
S_Sound (self, CHAN_WEAPON, "fatso/raiseguns", 1, ATTN_NORM);
}
void A_FatAttack1 (AActor *self)
{
AActor *missile;
angle_t an;
if (!self->target)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self);
// Change direction to ...
self->angle += FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle += FATSPREAD;
an = missile->angle >> ANGLETOFINESHIFT;
missile->momx = FixedMul (missile->Speed, finecosine[an]);
missile->momy = FixedMul (missile->Speed, finesine[an]);
}
}
void A_FatAttack2 (AActor *self)
{
AActor *missile;
angle_t an;
if (!self->target)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self);
// Now here choose opposite deviation.
self->angle -= FATSPREAD;
P_SpawnMissile (self, self->target, spawntype);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle -= FATSPREAD*2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->momx = FixedMul (missile->Speed, finecosine[an]);
missile->momy = FixedMul (missile->Speed, finesine[an]);
}
}
void A_FatAttack3 (AActor *self)
{
AActor *missile;
angle_t an;
if (!self->target)
return;
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_FaceTarget (self);
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle -= FATSPREAD/2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->momx = FixedMul (missile->Speed, finecosine[an]);
missile->momy = FixedMul (missile->Speed, finesine[an]);
}
missile = P_SpawnMissile (self, self->target, spawntype);
if (missile != NULL)
{
missile->angle += FATSPREAD/2;
an = missile->angle >> ANGLETOFINESHIFT;
missile->momx = FixedMul (missile->Speed, finecosine[an]);
missile->momy = FixedMul (missile->Speed, finesine[an]);
}
}
//
// killough 9/98: a mushroom explosion effect, sorta :)
// Original idea: Linguica
//
void A_Mushroom (AActor *actor)
{
int i, j, n = actor->GetMissileDamage (0, 1);
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0)
{
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
n = EvalExpressionI (StateParameters[index+1], actor);
if (n == 0)
n = actor->GetMissileDamage (0, 1);
}
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
A_Explode (actor); // First make normal explosion
// Now launch mushroom cloud
for (i = -n; i <= n; i += 8)
{
for (j = -n; j <= n; j += 8)
{
AActor target = *actor, *mo;
target.x += i << FRACBITS; // Aim in many directions from source
target.y += j << FRACBITS;
target.z += P_AproxDistance(i,j) << (FRACBITS+2); // Aim up fairly high
mo = P_SpawnMissile (actor, &target, spawntype); // Launch fireball
if (mo != NULL)
{
mo->momx >>= 1;
mo->momy >>= 1; // Slow it down a bit
mo->momz >>= 1;
mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity
}
}
}
}