mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 14:01:32 +00:00
01441cd4f0
- Added string replacement option to obituary strings. - Changed lock and pickup message handling so that it is either a real string or a LANGUAGE identifier. The only reason I did the mixed format in the first place were Hexen's lock messages but they have been replaced by unique strings in the mean time so the feature isn't needed any more. - Added a flags parameter to TranslucentLine. - Extended the second arg of Line_SetIdentification to set not only ML_ZONEBOUNDARY but all 8 bits of the third byte in the flag word. This allows a relatively simple means of setting all the new flags directly. - Moved ML_ZONEBOUNDARY to doomdata.h so that it is in the same place as the other line flags. - Fixed: Strife's teleport swirl didn't loop its animation. - Fixed: Strife's rat is not supposed to be shootable. SVN r110 (trunk)
284 lines
8.8 KiB
C++
284 lines
8.8 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"
|
|
|
|
void A_FatRaise (AActor *);
|
|
void A_FatAttack1 (AActor *);
|
|
void A_FatAttack2 (AActor *);
|
|
void A_FatAttack3 (AActor *);
|
|
|
|
class AFatso : public AActor
|
|
{
|
|
DECLARE_ACTOR (AFatso, AActor)
|
|
public:
|
|
const char *GetObituary () { return GStrings("OB_FATSO"); }
|
|
};
|
|
|
|
FState AFatso::States[] =
|
|
{
|
|
#define S_FATT_STND 0
|
|
S_NORMAL (FATT, 'A', 15, A_Look , &States[S_FATT_STND+1]),
|
|
S_NORMAL (FATT, 'B', 15, A_Look , &States[S_FATT_STND]),
|
|
|
|
#define S_FATT_RUN (S_FATT_STND+2)
|
|
S_NORMAL (FATT, 'A', 4, A_Chase , &States[S_FATT_RUN+1]),
|
|
S_NORMAL (FATT, 'A', 4, A_Chase , &States[S_FATT_RUN+2]),
|
|
S_NORMAL (FATT, 'B', 4, A_Chase , &States[S_FATT_RUN+3]),
|
|
S_NORMAL (FATT, 'B', 4, A_Chase , &States[S_FATT_RUN+4]),
|
|
S_NORMAL (FATT, 'C', 4, A_Chase , &States[S_FATT_RUN+5]),
|
|
S_NORMAL (FATT, 'C', 4, A_Chase , &States[S_FATT_RUN+6]),
|
|
S_NORMAL (FATT, 'D', 4, A_Chase , &States[S_FATT_RUN+7]),
|
|
S_NORMAL (FATT, 'D', 4, A_Chase , &States[S_FATT_RUN+8]),
|
|
S_NORMAL (FATT, 'E', 4, A_Chase , &States[S_FATT_RUN+9]),
|
|
S_NORMAL (FATT, 'E', 4, A_Chase , &States[S_FATT_RUN+10]),
|
|
S_NORMAL (FATT, 'F', 4, A_Chase , &States[S_FATT_RUN+11]),
|
|
S_NORMAL (FATT, 'F', 4, A_Chase , &States[S_FATT_RUN+0]),
|
|
|
|
#define S_FATT_ATK (S_FATT_RUN+12)
|
|
S_NORMAL (FATT, 'G', 20, A_FatRaise , &States[S_FATT_ATK+1]),
|
|
S_BRIGHT (FATT, 'H', 10, A_FatAttack1 , &States[S_FATT_ATK+2]),
|
|
S_NORMAL (FATT, 'I', 5, A_FaceTarget , &States[S_FATT_ATK+3]),
|
|
S_NORMAL (FATT, 'G', 5, A_FaceTarget , &States[S_FATT_ATK+4]),
|
|
S_BRIGHT (FATT, 'H', 10, A_FatAttack2 , &States[S_FATT_ATK+5]),
|
|
S_NORMAL (FATT, 'I', 5, A_FaceTarget , &States[S_FATT_ATK+6]),
|
|
S_NORMAL (FATT, 'G', 5, A_FaceTarget , &States[S_FATT_ATK+7]),
|
|
S_BRIGHT (FATT, 'H', 10, A_FatAttack3 , &States[S_FATT_ATK+8]),
|
|
S_NORMAL (FATT, 'I', 5, A_FaceTarget , &States[S_FATT_ATK+9]),
|
|
S_NORMAL (FATT, 'G', 5, A_FaceTarget , &States[S_FATT_RUN+0]),
|
|
|
|
#define S_FATT_PAIN (S_FATT_ATK+10)
|
|
S_NORMAL (FATT, 'J', 3, NULL , &States[S_FATT_PAIN+1]),
|
|
S_NORMAL (FATT, 'J', 3, A_Pain , &States[S_FATT_RUN+0]),
|
|
|
|
#define S_FATT_DIE (S_FATT_PAIN+2)
|
|
S_NORMAL (FATT, 'K', 6, NULL , &States[S_FATT_DIE+1]),
|
|
S_NORMAL (FATT, 'L', 6, A_Scream , &States[S_FATT_DIE+2]),
|
|
S_NORMAL (FATT, 'M', 6, A_NoBlocking , &States[S_FATT_DIE+3]),
|
|
S_NORMAL (FATT, 'N', 6, NULL , &States[S_FATT_DIE+4]),
|
|
S_NORMAL (FATT, 'O', 6, NULL , &States[S_FATT_DIE+5]),
|
|
S_NORMAL (FATT, 'P', 6, NULL , &States[S_FATT_DIE+6]),
|
|
S_NORMAL (FATT, 'Q', 6, NULL , &States[S_FATT_DIE+7]),
|
|
S_NORMAL (FATT, 'R', 6, NULL , &States[S_FATT_DIE+8]),
|
|
S_NORMAL (FATT, 'S', 6, NULL , &States[S_FATT_DIE+9]),
|
|
S_NORMAL (FATT, 'T', -1, A_BossDeath , NULL),
|
|
|
|
#define S_FATT_RAISE (S_FATT_DIE+10)
|
|
S_NORMAL (FATT, 'R', 5, NULL , &States[S_FATT_RAISE+1]),
|
|
S_NORMAL (FATT, 'Q', 5, NULL , &States[S_FATT_RAISE+2]),
|
|
S_NORMAL (FATT, 'P', 5, NULL , &States[S_FATT_RAISE+3]),
|
|
S_NORMAL (FATT, 'O', 5, NULL , &States[S_FATT_RAISE+4]),
|
|
S_NORMAL (FATT, 'N', 5, NULL , &States[S_FATT_RAISE+5]),
|
|
S_NORMAL (FATT, 'M', 5, NULL , &States[S_FATT_RAISE+6]),
|
|
S_NORMAL (FATT, 'L', 5, NULL , &States[S_FATT_RAISE+7]),
|
|
S_NORMAL (FATT, 'K', 5, NULL , &States[S_FATT_RUN+0])
|
|
};
|
|
|
|
IMPLEMENT_ACTOR (AFatso, Doom, 67, 112)
|
|
PROP_SpawnHealth (600)
|
|
PROP_RadiusFixed (48)
|
|
PROP_HeightFixed (64)
|
|
PROP_Mass (1000)
|
|
PROP_SpeedFixed (8)
|
|
PROP_PainChance (80)
|
|
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL)
|
|
PROP_Flags2 (MF2_MCROSS|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_FLOORCLIP)
|
|
PROP_Flags4 (MF4_BOSSDEATH)
|
|
|
|
PROP_SpawnState (S_FATT_STND)
|
|
PROP_SeeState (S_FATT_RUN)
|
|
PROP_PainState (S_FATT_PAIN)
|
|
PROP_MissileState (S_FATT_ATK)
|
|
PROP_DeathState (S_FATT_DIE)
|
|
PROP_RaiseState (S_FATT_RAISE)
|
|
|
|
PROP_SeeSound ("fatso/sight")
|
|
PROP_PainSound ("fatso/pain")
|
|
PROP_DeathSound ("fatso/death")
|
|
PROP_ActiveSound ("fatso/active")
|
|
END_DEFAULTS
|
|
|
|
class AFatShot : public AActor
|
|
{
|
|
DECLARE_ACTOR (AFatShot, AActor)
|
|
};
|
|
|
|
FState AFatShot::States[] =
|
|
{
|
|
#define S_FATSHOT 0
|
|
S_BRIGHT (MANF, 'A', 4, NULL , &States[S_FATSHOT+1]),
|
|
S_BRIGHT (MANF, 'B', 4, NULL , &States[S_FATSHOT+0]),
|
|
|
|
#define S_FATSHOTX (S_FATSHOT+2)
|
|
S_BRIGHT (MISL, 'B', 8, NULL , &States[S_FATSHOTX+1]),
|
|
S_BRIGHT (MISL, 'C', 6, NULL , &States[S_FATSHOTX+2]),
|
|
S_BRIGHT (MISL, 'D', 4, NULL , NULL)
|
|
};
|
|
|
|
IMPLEMENT_ACTOR (AFatShot, Doom, -1, 153)
|
|
PROP_RadiusFixed (6)
|
|
PROP_HeightFixed (8)
|
|
PROP_SpeedFixed (20)
|
|
PROP_Damage (8)
|
|
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
|
|
PROP_Flags2 (MF2_PCROSS|MF2_IMPACT|MF2_NOTELEPORT)
|
|
PROP_Flags4 (MF4_RANDOMIZE)
|
|
PROP_RenderStyle (STYLE_Add)
|
|
|
|
PROP_SpawnState (S_FATSHOT)
|
|
PROP_DeathState (S_FATSHOTX)
|
|
|
|
PROP_SeeSound ("fatso/attack")
|
|
PROP_DeathSound ("fatso/shotx")
|
|
END_DEFAULTS
|
|
|
|
//
|
|
// 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 = RUNTIME_CLASS(AFatShot);
|
|
|
|
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 = RUNTIME_CLASS(AFatShot);
|
|
|
|
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 = RUNTIME_CLASS(AFatShot);
|
|
|
|
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->damage;
|
|
|
|
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->damage;
|
|
}
|
|
if (spawntype == NULL) spawntype = RUNTIME_CLASS(AFatShot);
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|