qzdoom-gpl/src/g_hexen/a_ettin.cpp
Christoph Oelckers 25f90d6221 SVN r27 (trunk)
2006-04-11 16:27:41 +00:00

185 lines
5.8 KiB
C++

#include "actor.h"
#include "info.h"
#include "p_local.h"
#include "s_sound.h"
#include "p_enemy.h"
#include "a_action.h"
#include "m_random.h"
static FRandom pr_ettinatk ("EttinAttack");
static FRandom pr_dropmace ("DropMace");
// Ettin --------------------------------------------------------------------
void A_EttinAttack (AActor *);
void A_DropMace (AActor *);
class AEttin : public AActor
{
DECLARE_ACTOR (AEttin, AActor)
public:
void Howl ();
};
FState AEttin::States[] =
{
#define S_ETTIN_LOOK 0
S_NORMAL (ETTN, 'A', 10, A_Look , &States[S_ETTIN_LOOK+1]),
S_NORMAL (ETTN, 'A', 10, A_Look , &States[S_ETTIN_LOOK+0]),
#define S_ETTIN_CHASE (S_ETTIN_LOOK+2)
S_NORMAL (ETTN, 'A', 5, A_Chase , &States[S_ETTIN_CHASE+1]),
S_NORMAL (ETTN, 'B', 5, A_Chase , &States[S_ETTIN_CHASE+2]),
S_NORMAL (ETTN, 'C', 5, A_Chase , &States[S_ETTIN_CHASE+3]),
S_NORMAL (ETTN, 'D', 5, A_Chase , &States[S_ETTIN_CHASE+0]),
#define S_ETTIN_PAIN (S_ETTIN_CHASE+4)
S_NORMAL (ETTN, 'H', 7, A_Pain , &States[S_ETTIN_CHASE+0]),
#define S_ETTIN_ATK1 (S_ETTIN_PAIN+1)
S_NORMAL (ETTN, 'E', 6, A_FaceTarget , &States[S_ETTIN_ATK1+1]),
S_NORMAL (ETTN, 'F', 6, A_FaceTarget , &States[S_ETTIN_ATK1+2]),
S_NORMAL (ETTN, 'G', 8, A_EttinAttack , &States[S_ETTIN_CHASE+0]),
#define S_ETTIN_DEATH1 (S_ETTIN_ATK1+3)
S_NORMAL (ETTN, 'I', 4, NULL , &States[S_ETTIN_DEATH1+1]),
S_NORMAL (ETTN, 'J', 4, NULL , &States[S_ETTIN_DEATH1+2]),
S_NORMAL (ETTN, 'K', 4, A_Scream , &States[S_ETTIN_DEATH1+3]),
S_NORMAL (ETTN, 'L', 4, A_NoBlocking , &States[S_ETTIN_DEATH1+4]),
S_NORMAL (ETTN, 'M', 4, A_QueueCorpse , &States[S_ETTIN_DEATH1+5]),
S_NORMAL (ETTN, 'N', 4, NULL , &States[S_ETTIN_DEATH1+6]),
S_NORMAL (ETTN, 'O', 4, NULL , &States[S_ETTIN_DEATH1+7]),
S_NORMAL (ETTN, 'P', 4, NULL , &States[S_ETTIN_DEATH1+8]),
S_NORMAL (ETTN, 'Q', -1, NULL , NULL),
#define S_ETTIN_DEATH2 (S_ETTIN_DEATH1+9)
S_NORMAL (ETTB, 'A', 4, NULL , &States[S_ETTIN_DEATH2+1]),
S_NORMAL (ETTB, 'B', 4, A_NoBlocking , &States[S_ETTIN_DEATH2+2]),
S_NORMAL (ETTB, 'C', 4, A_DropMace , &States[S_ETTIN_DEATH2+3]),
S_NORMAL (ETTB, 'D', 4, A_Scream , &States[S_ETTIN_DEATH2+4]),
S_NORMAL (ETTB, 'E', 4, A_QueueCorpse , &States[S_ETTIN_DEATH2+5]),
S_NORMAL (ETTB, 'F', 4, NULL , &States[S_ETTIN_DEATH2+6]),
S_NORMAL (ETTB, 'G', 4, NULL , &States[S_ETTIN_DEATH2+7]),
S_NORMAL (ETTB, 'H', 4, NULL , &States[S_ETTIN_DEATH2+8]),
S_NORMAL (ETTB, 'I', 4, NULL , &States[S_ETTIN_DEATH2+9]),
S_NORMAL (ETTB, 'J', 4, NULL , &States[S_ETTIN_DEATH2+10]),
S_NORMAL (ETTB, 'K', 4, NULL , &States[S_ETTIN_DEATH2+11]),
S_NORMAL (ETTB, 'L', -1, NULL , NULL),
#define S_ETTIN_ICE (S_ETTIN_DEATH2+12)
S_NORMAL (ETTN, 'R', 5, A_FreezeDeath , &States[S_ETTIN_ICE+1]),
S_NORMAL (ETTN, 'R', 1, A_FreezeDeathChunks , &States[S_ETTIN_ICE+1])
};
IMPLEMENT_ACTOR (AEttin, Hexen, 10030, 4)
PROP_SpawnHealth (175)
PROP_RadiusFixed (25)
PROP_HeightFixed (68)
PROP_Mass (175)
PROP_SpeedFixed (13)
PROP_Damage (3)
PROP_PainChance (60)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL)
PROP_Flags2 (MF2_FLOORCLIP|MF2_PUSHWALL|MF2_MCROSS|MF2_TELESTOMP)
PROP_SpawnState (S_ETTIN_LOOK)
PROP_SeeState (S_ETTIN_CHASE)
PROP_PainState (S_ETTIN_PAIN)
PROP_MeleeState (S_ETTIN_ATK1)
PROP_DeathState (S_ETTIN_DEATH1)
PROP_XDeathState (S_ETTIN_DEATH2)
PROP_IDeathState (S_ETTIN_ICE)
PROP_SeeSound ("EttinSight")
PROP_AttackSound ("EttinAttack")
PROP_PainSound ("EttinPain")
PROP_DeathSound ("EttinDeath")
PROP_ActiveSound ("EttinActive")
END_DEFAULTS
void AEttin::Howl ()
{
int howl = S_FindSound ("PuppyBeat");
if (!S_GetSoundPlayingInfo (this, howl))
{
S_SoundID (this, CHAN_BODY, howl, 1, ATTN_NORM);
}
}
// Ettin mace ---------------------------------------------------------------
class AEttinMace : public AActor
{
DECLARE_ACTOR (AEttinMace, AActor)
};
FState AEttinMace::States[] =
{
S_NORMAL (ETTB, 'M', 5, NULL , &States[1]),
S_NORMAL (ETTB, 'N', 5, NULL , &States[2]),
S_NORMAL (ETTB, 'O', 5, NULL , &States[3]),
S_NORMAL (ETTB, 'P', 5, NULL , &States[0]),
S_NORMAL (ETTB, 'Q', 5, NULL , &States[5]),
S_NORMAL (ETTB, 'R', 5, A_QueueCorpse , &States[6]),
S_NORMAL (ETTB, 'S', -1, NULL , NULL)
};
IMPLEMENT_ACTOR (AEttinMace, Hexen, -1, 0)
PROP_RadiusFixed (5)
PROP_HeightFixed (5)
PROP_Flags (MF_DROPOFF|MF_CORPSE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_FLOORCLIP)
PROP_SpawnState (0)
PROP_CrashState (4)
END_DEFAULTS
// Ettin mash ---------------------------------------------------------------
class AEttinMash : public AEttin
{
DECLARE_STATELESS_ACTOR (AEttinMash, AEttin)
};
IMPLEMENT_STATELESS_ACTOR (AEttinMash, Hexen, -1, 102)
PROP_FlagsSet (MF_NOBLOOD)
PROP_Flags2Set (MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_MCROSS|MF2_PUSHWALL|MF2_BLASTED)
PROP_Flags4Set(MF4_NOICEDEATH)
PROP_RenderStyle (STYLE_Translucent)
PROP_Alpha (HX_ALTSHADOW)
PROP_DeathState (~0)
PROP_XDeathState (~0)
PROP_IDeathState (~0)
END_DEFAULTS
//============================================================================
// Ettin AI
//============================================================================
void A_EttinAttack (AActor *actor)
{
if (actor->CheckMeleeRange())
{
int damage = pr_ettinatk.HitDice (2);
P_DamageMobj (actor->target, actor, actor, damage, MOD_HIT);
P_TraceBleed (damage, actor->target, actor);
}
}
void A_DropMace (AActor *actor)
{
AEttinMace *mo;
mo = Spawn<AEttinMace> (actor->x, actor->y,
actor->z + (actor->height>>1));
if (mo)
{
mo->momx = (pr_dropmace()-128) << 11;
mo->momy = (pr_dropmace()-128) << 11;
mo->momz = FRACUNIT*10+(pr_dropmace()<<10);
mo->target = actor;
}
}