qzdoom/src/g_hexen/a_demons.cpp

667 lines
21 KiB
C++
Raw Normal View History

#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_atk ("DemonAttack1");
static FRandom pr_demonchunks ("DemonChunks");
//============================================================================
// Demon AI
//============================================================================
void A_DemonAttack1 (AActor *);
void A_DemonAttack2_1 (AActor *);
void A_DemonAttack2_2 (AActor *);
void A_DemonDeath (AActor *);
void A_Demon2Death (AActor *);
static void TossChunks (AActor *, const PClass *const chunks[]);
// Demon, type 1 (green, like D'Sparil's) -----------------------------------
class ADemon1 : public AActor
{
DECLARE_ACTOR (ADemon1, AActor)
};
FState ADemon1::States[] =
{
#define S_DEMN_LOOK1 0
S_NORMAL (DEMN, 'A', 10, A_Look , &States[S_DEMN_LOOK1+1]),
S_NORMAL (DEMN, 'A', 10, A_Look , &States[S_DEMN_LOOK1]),
#define S_DEMN_CHASE1 (S_DEMN_LOOK1+2)
S_NORMAL (DEMN, 'A', 4, A_Chase , &States[S_DEMN_CHASE1+1]),
S_NORMAL (DEMN, 'B', 4, A_Chase , &States[S_DEMN_CHASE1+2]),
S_NORMAL (DEMN, 'C', 4, A_Chase , &States[S_DEMN_CHASE1+3]),
S_NORMAL (DEMN, 'D', 4, A_Chase , &States[S_DEMN_CHASE1]),
#define S_DEMN_PAIN1 (S_DEMN_CHASE1+4)
S_NORMAL (DEMN, 'E', 4, NULL , &States[S_DEMN_PAIN1+1]),
S_NORMAL (DEMN, 'E', 4, A_Pain , &States[S_DEMN_CHASE1]),
#define S_DEMN_ATK1_1 (S_DEMN_PAIN1+2)
S_NORMAL (DEMN, 'E', 6, A_FaceTarget , &States[S_DEMN_ATK1_1+1]),
S_NORMAL (DEMN, 'F', 8, A_FaceTarget , &States[S_DEMN_ATK1_1+2]),
S_NORMAL (DEMN, 'G', 6, A_DemonAttack1 , &States[S_DEMN_CHASE1]),
#define S_DEMN_ATK2_1 (S_DEMN_ATK1_1+3)
S_NORMAL (DEMN, 'E', 5, A_FaceTarget , &States[S_DEMN_ATK2_1+1]),
S_NORMAL (DEMN, 'F', 6, A_FaceTarget , &States[S_DEMN_ATK2_1+2]),
S_NORMAL (DEMN, 'G', 5, A_DemonAttack2_1 , &States[S_DEMN_CHASE1]),
#define S_DEMN_DEATH1 (S_DEMN_ATK2_1+3)
S_NORMAL (DEMN, 'H', 6, NULL , &States[S_DEMN_DEATH1+1]),
S_NORMAL (DEMN, 'I', 6, NULL , &States[S_DEMN_DEATH1+2]),
S_NORMAL (DEMN, 'J', 6, A_Scream , &States[S_DEMN_DEATH1+3]),
S_NORMAL (DEMN, 'K', 6, A_NoBlocking , &States[S_DEMN_DEATH1+4]),
S_NORMAL (DEMN, 'L', 6, A_QueueCorpse , &States[S_DEMN_DEATH1+5]),
S_NORMAL (DEMN, 'M', 6, NULL , &States[S_DEMN_DEATH1+6]),
S_NORMAL (DEMN, 'N', 6, NULL , &States[S_DEMN_DEATH1+7]),
S_NORMAL (DEMN, 'O', 6, NULL , &States[S_DEMN_DEATH1+8]),
S_NORMAL (DEMN, 'P', -1, NULL , NULL),
#define S_DEMN_XDEATH1 (S_DEMN_DEATH1+9)
S_NORMAL (DEMN, 'H', 6, NULL , &States[S_DEMN_XDEATH1+1]),
S_NORMAL (DEMN, 'I', 6, A_DemonDeath , &States[S_DEMN_XDEATH1+2]),
S_NORMAL (DEMN, 'J', 6, A_Scream , &States[S_DEMN_XDEATH1+3]),
S_NORMAL (DEMN, 'K', 6, A_NoBlocking , &States[S_DEMN_XDEATH1+4]),
S_NORMAL (DEMN, 'L', 6, A_QueueCorpse , &States[S_DEMN_XDEATH1+5]),
S_NORMAL (DEMN, 'M', 6, NULL , &States[S_DEMN_XDEATH1+6]),
S_NORMAL (DEMN, 'N', 6, NULL , &States[S_DEMN_XDEATH1+7]),
S_NORMAL (DEMN, 'O', 6, NULL , &States[S_DEMN_XDEATH1+8]),
S_NORMAL (DEMN, 'P', -1, NULL , NULL),
#define S_DEMON_ICE1 (S_DEMN_XDEATH1+9)
S_NORMAL (DEMN, 'Q', 5, A_FreezeDeath , &States[S_DEMON_ICE1+1]),
S_NORMAL (DEMN, 'Q', 1, A_FreezeDeathChunks , &States[S_DEMON_ICE1+1]),
};
IMPLEMENT_ACTOR (ADemon1, Hexen, 31, 3)
PROP_SpawnHealth (250)
PROP_PainChance (50)
PROP_SpeedFixed (13)
PROP_RadiusFixed (32)
PROP_HeightFixed (64)
PROP_Mass (220)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL)
PROP_Flags2 (MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_TELESTOMP|MF2_MCROSS)
PROP_SpawnState (S_DEMN_LOOK1)
PROP_SeeState (S_DEMN_CHASE1)
PROP_PainState (S_DEMN_PAIN1)
PROP_MeleeState (S_DEMN_ATK1_1)
PROP_MissileState (S_DEMN_ATK2_1)
PROP_DeathState (S_DEMN_DEATH1)
PROP_XDeathState (S_DEMN_XDEATH1)
PROP_IDeathState (S_DEMON_ICE1)
PROP_SeeSound ("DemonSight")
PROP_AttackSound ("DemonAttack")
PROP_PainSound ("DemonPain")
PROP_DeathSound ("DemonDeath")
PROP_ActiveSound ("DemonActive")
END_DEFAULTS
// Demon, type 1, mashed ----------------------------------------------------
class ADemon1Mash : public ADemon1
{
DECLARE_STATELESS_ACTOR (ADemon1Mash, ADemon1)
};
IMPLEMENT_STATELESS_ACTOR (ADemon1Mash, Hexen, -1, 100)
PROP_FlagsSet (MF_NOBLOOD)
PROP_Flags2Set (MF2_BLASTED)
PROP_Flags2Clear (MF2_TELESTOMP)
2006-04-11 16:27:41 +00:00
PROP_Flags4Set(MF4_NOICEDEATH)
PROP_RenderStyle (STYLE_Translucent)
PROP_Alpha (HX_ALTSHADOW)
PROP_DeathState (~0)
PROP_XDeathState (~0)
PROP_IDeathState (~0)
END_DEFAULTS
// Demon chunk, base class --------------------------------------------------
class ADemonChunk : public AActor
{
DECLARE_STATELESS_ACTOR (ADemonChunk, AActor);
};
IMPLEMENT_STATELESS_ACTOR (ADemonChunk, Hexen, -1, 0)
PROP_RadiusFixed (5)
PROP_HeightFixed (5)
PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF|MF_MISSILE|MF_CORPSE)
PROP_Flags2 (MF2_FLOORCLIP|MF2_NOTELEPORT)
END_DEFAULTS
// Demon, type 1, chunk 1 ---------------------------------------------------
class ADemon1Chunk1 : public ADemonChunk
{
DECLARE_ACTOR (ADemon1Chunk1, ADemonChunk)
};
FState ADemon1Chunk1::States[] =
{
#define S_DEMONCHUNK1_1 0
S_NORMAL (DEMA, 'A', 4, NULL , &States[S_DEMONCHUNK1_1+1]),
S_NORMAL (DEMA, 'A', 10, A_QueueCorpse , &States[S_DEMONCHUNK1_1+2]),
S_NORMAL (DEMA, 'A', 20, NULL , &States[S_DEMONCHUNK1_1+2]),
#define S_DEMONCHUNK1_4 (S_DEMONCHUNK1_1+3)
S_NORMAL (DEMA, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1Chunk1, Hexen, -1, 0)
PROP_SpawnState (S_DEMONCHUNK1_1)
PROP_DeathState (S_DEMONCHUNK1_4)
END_DEFAULTS
// Demon, type 1, chunk 2 ---------------------------------------------------
class ADemon1Chunk2 : public ADemonChunk
{
DECLARE_ACTOR (ADemon1Chunk2, ADemonChunk)
};
FState ADemon1Chunk2::States[] =
{
#define S_DEMONCHUNK2_1 0
S_NORMAL (DEMB, 'A', 4, NULL , &States[S_DEMONCHUNK2_1+1]),
S_NORMAL (DEMB, 'A', 10, A_QueueCorpse , &States[S_DEMONCHUNK2_1+2]),
S_NORMAL (DEMB, 'A', 20, NULL , &States[S_DEMONCHUNK2_1+2]),
#define S_DEMONCHUNK2_4 (S_DEMONCHUNK2_1+3)
S_NORMAL (DEMB, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1Chunk2, Hexen, -1, 0)
PROP_SpawnState (S_DEMONCHUNK2_1)
PROP_DeathState (S_DEMONCHUNK2_4)
END_DEFAULTS
// Demon, type 1, chunk 3 ---------------------------------------------------
class ADemon1Chunk3 : public ADemonChunk
{
DECLARE_ACTOR (ADemon1Chunk3, ADemonChunk)
};
FState ADemon1Chunk3::States[] =
{
#define S_DEMONCHUNK3_1 0
S_NORMAL (DEMC, 'A', 4, NULL , &States[S_DEMONCHUNK3_1+1]),
S_NORMAL (DEMC, 'A', 10, A_QueueCorpse , &States[S_DEMONCHUNK3_1+2]),
S_NORMAL (DEMC, 'A', 20, NULL , &States[S_DEMONCHUNK3_1+2]),
#define S_DEMONCHUNK3_4 (S_DEMONCHUNK3_1+3)
S_NORMAL (DEMC, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1Chunk3, Hexen, -1, 0)
PROP_SpawnState (S_DEMONCHUNK3_1)
PROP_DeathState (S_DEMONCHUNK3_4)
END_DEFAULTS
// Demon, type 1, chunk 4 ---------------------------------------------------
class ADemon1Chunk4 : public ADemonChunk
{
DECLARE_ACTOR (ADemon1Chunk4, ADemonChunk)
};
FState ADemon1Chunk4::States[] =
{
#define S_DEMONCHUNK4_1 0
S_NORMAL (DEMD, 'A', 4, NULL , &States[S_DEMONCHUNK4_1+1]),
S_NORMAL (DEMD, 'A', 10, A_QueueCorpse , &States[S_DEMONCHUNK4_1+2]),
S_NORMAL (DEMD, 'A', 20, NULL , &States[S_DEMONCHUNK4_1+2]),
#define S_DEMONCHUNK4_4 (S_DEMONCHUNK4_1+3)
S_NORMAL (DEMD, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1Chunk4, Hexen, -1, 0)
PROP_SpawnState (S_DEMONCHUNK4_1)
PROP_DeathState (S_DEMONCHUNK4_4)
END_DEFAULTS
// Demon, type 1, chunk 5 ---------------------------------------------------
class ADemon1Chunk5 : public ADemonChunk
{
DECLARE_ACTOR (ADemon1Chunk5, ADemonChunk)
};
FState ADemon1Chunk5::States[] =
{
#define S_DEMONCHUNK5_1 0
S_NORMAL (DEME, 'A', 4, NULL , &States[S_DEMONCHUNK5_1+1]),
S_NORMAL (DEME, 'A', 10, A_QueueCorpse , &States[S_DEMONCHUNK5_1+2]),
S_NORMAL (DEME, 'A', 20, NULL , &States[S_DEMONCHUNK5_1+2]),
#define S_DEMONCHUNK5_4 (S_DEMONCHUNK5_1+3)
S_NORMAL (DEME, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1Chunk5, Hexen, -1, 0)
PROP_SpawnState (S_DEMONCHUNK5_1)
PROP_DeathState (S_DEMONCHUNK5_4)
END_DEFAULTS
// Demon, type 1, projectile ------------------------------------------------
class ADemon1FX1 : public AActor
{
DECLARE_ACTOR (ADemon1FX1, AActor)
};
FState ADemon1FX1::States[] =
{
#define S_DEMONFX_MOVE1 0
S_BRIGHT (DMFX, 'A', 4, NULL , &States[S_DEMONFX_MOVE1+1]),
S_BRIGHT (DMFX, 'B', 4, NULL , &States[S_DEMONFX_MOVE1+2]),
S_BRIGHT (DMFX, 'C', 4, NULL , &States[S_DEMONFX_MOVE1]),
#define S_DEMONFX_BOOM1 (S_DEMONFX_MOVE1+3)
S_BRIGHT (DMFX, 'D', 4, NULL , &States[S_DEMONFX_BOOM1+1]),
S_BRIGHT (DMFX, 'E', 4, NULL , &States[S_DEMONFX_BOOM1+2]),
S_BRIGHT (DMFX, 'F', 3, NULL , &States[S_DEMONFX_BOOM1+3]),
S_BRIGHT (DMFX, 'G', 3, NULL , &States[S_DEMONFX_BOOM1+4]),
S_BRIGHT (DMFX, 'H', 3, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon1FX1, Hexen, -1, 0)
PROP_SpeedFixed (15)
PROP_RadiusFixed (10)
PROP_HeightFixed (6)
PROP_Damage (5)
PROP_DamageType (NAME_Fire)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_DEMONFX_MOVE1)
PROP_DeathState (S_DEMONFX_BOOM1)
PROP_DeathSound ("DemonMissileExplode")
END_DEFAULTS
// Demon, type 2 (brown) ----------------------------------------------------
class ADemon2 : public ADemon1
{
DECLARE_ACTOR (ADemon2, ADemon1)
};
FState ADemon2::States[] =
{
#define S_DEMN2_LOOK1 0
S_NORMAL (DEM2, 'A', 10, A_Look , &States[S_DEMN2_LOOK1+1]),
S_NORMAL (DEM2, 'A', 10, A_Look , &States[S_DEMN2_LOOK1]),
#define S_DEMN2_CHASE1 (S_DEMN2_LOOK1+2)
S_NORMAL (DEM2, 'A', 4, A_Chase , &States[S_DEMN2_CHASE1+1]),
S_NORMAL (DEM2, 'B', 4, A_Chase , &States[S_DEMN2_CHASE1+2]),
S_NORMAL (DEM2, 'C', 4, A_Chase , &States[S_DEMN2_CHASE1+3]),
S_NORMAL (DEM2, 'D', 4, A_Chase , &States[S_DEMN2_CHASE1]),
#define S_DEMN2_PAIN1 (S_DEMN2_CHASE1+4)
S_NORMAL (DEM2, 'E', 4, NULL , &States[S_DEMN2_PAIN1+1]),
S_NORMAL (DEM2, 'E', 4, A_Pain , &States[S_DEMN2_CHASE1]),
#define S_DEMN2_ATK1_1 (S_DEMN2_PAIN1+2)
S_NORMAL (DEM2, 'E', 6, A_FaceTarget , &States[S_DEMN2_ATK1_1+1]),
S_NORMAL (DEM2, 'F', 8, A_FaceTarget , &States[S_DEMN2_ATK1_1+2]),
S_NORMAL (DEM2, 'G', 6, A_DemonAttack1 , &States[S_DEMN2_CHASE1]),
#define S_DEMN2_ATK2_1 (S_DEMN2_ATK1_1+3)
S_NORMAL (DEM2, 'E', 5, A_FaceTarget , &States[S_DEMN2_ATK2_1+1]),
S_NORMAL (DEM2, 'F', 6, A_FaceTarget , &States[S_DEMN2_ATK2_1+2]),
S_NORMAL (DEM2, 'G', 5, A_DemonAttack2_2 , &States[S_DEMN2_CHASE1]),
#define S_DEMN2_DEATH1 (S_DEMN2_ATK2_1+3)
S_NORMAL (DEM2, 'H', 6, NULL , &States[S_DEMN2_DEATH1+1]),
S_NORMAL (DEM2, 'I', 6, NULL , &States[S_DEMN2_DEATH1+2]),
S_NORMAL (DEM2, 'J', 6, A_Scream , &States[S_DEMN2_DEATH1+3]),
S_NORMAL (DEM2, 'K', 6, A_NoBlocking , &States[S_DEMN2_DEATH1+4]),
S_NORMAL (DEM2, 'L', 6, A_QueueCorpse , &States[S_DEMN2_DEATH1+5]),
S_NORMAL (DEM2, 'M', 6, NULL , &States[S_DEMN2_DEATH1+6]),
S_NORMAL (DEM2, 'N', 6, NULL , &States[S_DEMN2_DEATH1+7]),
S_NORMAL (DEM2, 'O', 6, NULL , &States[S_DEMN2_DEATH1+8]),
S_NORMAL (DEM2, 'P', -1, NULL , NULL),
#define S_DEMN2_XDEATH1 (S_DEMN2_DEATH1+9)
S_NORMAL (DEM2, 'H', 6, NULL , &States[S_DEMN2_XDEATH1+1]),
S_NORMAL (DEM2, 'I', 6, A_Demon2Death , &States[S_DEMN2_XDEATH1+2]),
S_NORMAL (DEM2, 'J', 6, A_Scream , &States[S_DEMN2_XDEATH1+3]),
S_NORMAL (DEM2, 'K', 6, A_NoBlocking , &States[S_DEMN2_XDEATH1+4]),
S_NORMAL (DEM2, 'L', 6, A_QueueCorpse , &States[S_DEMN2_XDEATH1+5]),
S_NORMAL (DEM2, 'M', 6, NULL , &States[S_DEMN2_XDEATH1+6]),
S_NORMAL (DEM2, 'N', 6, NULL , &States[S_DEMN2_XDEATH1+7]),
S_NORMAL (DEM2, 'O', 6, NULL , &States[S_DEMN2_XDEATH1+8]),
S_NORMAL (DEM2, 'P', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2, Hexen, 8080, 0)
PROP_SpawnState (S_DEMN2_LOOK1)
PROP_SeeState (S_DEMN2_CHASE1)
PROP_PainState (S_DEMN2_PAIN1)
PROP_MeleeState (S_DEMN2_ATK1_1)
PROP_MissileState (S_DEMN2_ATK2_1)
PROP_DeathState (S_DEMN2_DEATH1)
PROP_XDeathState (S_DEMN2_XDEATH1)
END_DEFAULTS
// Demon, type 2, mashed ----------------------------------------------------
class ADemon2Mash : public ADemon2
{
DECLARE_STATELESS_ACTOR (ADemon2Mash, ADemon2)
};
IMPLEMENT_STATELESS_ACTOR (ADemon2Mash, Hexen, -1, 101)
PROP_FlagsSet (MF_NOBLOOD)
PROP_Flags2Set (MF2_BLASTED)
PROP_Flags2Clear (MF2_TELESTOMP)
2006-04-11 16:27:41 +00:00
PROP_Flags4Set(MF4_NOICEDEATH)
PROP_RenderStyle (STYLE_Translucent)
PROP_Alpha (HX_ALTSHADOW)
PROP_DeathState (~0)
PROP_XDeathState (~0)
PROP_IDeathState (~0)
END_DEFAULTS
// Demon, type 2, chunk 1 ---------------------------------------------------
class ADemon2Chunk1 : public ADemonChunk
{
DECLARE_ACTOR (ADemon2Chunk1, ADemonChunk)
};
FState ADemon2Chunk1::States[] =
{
#define S_DEMON2CHUNK1_1 0
S_NORMAL (DMBA, 'A', 4, NULL , &States[S_DEMON2CHUNK1_1+1]),
S_NORMAL (DMBA, 'A', 10, A_QueueCorpse , &States[S_DEMON2CHUNK1_1+2]),
S_NORMAL (DMBA, 'A', 20, NULL , &States[S_DEMON2CHUNK1_1+2]),
#define S_DEMON2CHUNK1_4 (S_DEMON2CHUNK1_1+3)
S_NORMAL (DMBA, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2Chunk1, Hexen, -1, 0)
PROP_SpawnState (S_DEMON2CHUNK1_1)
PROP_DeathState (S_DEMON2CHUNK1_4)
END_DEFAULTS
// Demon, type 2, chunk 2 ---------------------------------------------------
class ADemon2Chunk2 : public ADemonChunk
{
DECLARE_ACTOR (ADemon2Chunk2, ADemonChunk)
};
FState ADemon2Chunk2::States[] =
{
#define S_DEMON2CHUNK2_1 0
S_NORMAL (DMBB, 'A', 4, NULL , &States[S_DEMON2CHUNK2_1+1]),
S_NORMAL (DMBB, 'A', 10, A_QueueCorpse , &States[S_DEMON2CHUNK2_1+2]),
S_NORMAL (DMBB, 'A', 20, NULL , &States[S_DEMON2CHUNK2_1+2]),
#define S_DEMON2CHUNK2_4 (S_DEMON2CHUNK2_1+3)
S_NORMAL (DMBB, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2Chunk2, Hexen, -1, 0)
PROP_SpawnState (S_DEMON2CHUNK2_1)
PROP_DeathState (S_DEMON2CHUNK2_4)
END_DEFAULTS
// Demon, type 2, chunk 3 ---------------------------------------------------
class ADemon2Chunk3 : public ADemonChunk
{
DECLARE_ACTOR (ADemon2Chunk3, ADemonChunk)
};
FState ADemon2Chunk3::States[] =
{
#define S_DEMON2CHUNK3_1 0
S_NORMAL (DMBC, 'A', 4, NULL , &States[S_DEMON2CHUNK3_1+1]),
S_NORMAL (DMBC, 'A', 10, A_QueueCorpse , &States[S_DEMON2CHUNK3_1+2]),
S_NORMAL (DMBC, 'A', 20, NULL , &States[S_DEMON2CHUNK3_1+2]),
#define S_DEMON2CHUNK3_4 (S_DEMON2CHUNK3_1+3)
S_NORMAL (DMBC, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2Chunk3, Hexen, -1, 0)
PROP_SpawnState (S_DEMON2CHUNK3_1)
PROP_DeathState (S_DEMON2CHUNK3_4)
END_DEFAULTS
// Demon, type 2, chunk 4 ---------------------------------------------------
class ADemon2Chunk4 : public ADemonChunk
{
DECLARE_ACTOR (ADemon2Chunk4, ADemonChunk)
};
FState ADemon2Chunk4::States[] =
{
#define S_DEMON2CHUNK4_1 0
S_NORMAL (DMBD, 'A', 4, NULL , &States[S_DEMON2CHUNK4_1+1]),
S_NORMAL (DMBD, 'A', 10, A_QueueCorpse , &States[S_DEMON2CHUNK4_1+2]),
S_NORMAL (DMBD, 'A', 20, NULL , &States[S_DEMON2CHUNK4_1+2]),
#define S_DEMON2CHUNK4_4 (S_DEMON2CHUNK4_1+3)
S_NORMAL (DMBD, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2Chunk4, Hexen, -1, 0)
PROP_SpawnState (S_DEMON2CHUNK4_1)
PROP_DeathState (S_DEMON2CHUNK4_4)
END_DEFAULTS
// Demon, type 2, chunk 5 ---------------------------------------------------
class ADemon2Chunk5 : public ADemonChunk
{
DECLARE_ACTOR (ADemon2Chunk5, ADemonChunk)
};
FState ADemon2Chunk5::States[] =
{
#define S_DEMON2CHUNK5_1 0
S_NORMAL (DMBE, 'A', 4, NULL , &States[S_DEMON2CHUNK5_1+1]),
S_NORMAL (DMBE, 'A', 10, NULL , &States[S_DEMON2CHUNK5_1+2]),
S_NORMAL (DMBE, 'A', 20, NULL , &States[S_DEMON2CHUNK5_1+2]),
#define S_DEMON2CHUNK5_4 (S_DEMON2CHUNK5_1+3)
S_NORMAL (DMBE, 'A', -1, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2Chunk5, Hexen, -1, 0)
PROP_SpawnState (S_DEMON2CHUNK5_1)
PROP_DeathState (S_DEMON2CHUNK5_4)
END_DEFAULTS
// Demon, type 2, projectile ------------------------------------------------
class ADemon2FX1 : public AActor
{
DECLARE_ACTOR (ADemon2FX1, AActor)
};
FState ADemon2FX1::States[] =
{
#define S_DEMON2FX_MOVE1 0
S_BRIGHT (D2FX, 'A', 4, NULL , &States[S_DEMON2FX_MOVE1+1]),
S_BRIGHT (D2FX, 'B', 4, NULL , &States[S_DEMON2FX_MOVE1+2]),
S_BRIGHT (D2FX, 'C', 4, NULL , &States[S_DEMON2FX_MOVE1+3]),
S_BRIGHT (D2FX, 'D', 4, NULL , &States[S_DEMON2FX_MOVE1+4]),
S_BRIGHT (D2FX, 'E', 4, NULL , &States[S_DEMON2FX_MOVE1+5]),
S_BRIGHT (D2FX, 'F', 4, NULL , &States[S_DEMON2FX_MOVE1]),
#define S_DEMON2FX_BOOM1 (S_DEMON2FX_MOVE1+6)
S_BRIGHT (D2FX, 'G', 4, NULL , &States[S_DEMON2FX_BOOM1+1]),
S_BRIGHT (D2FX, 'H', 4, NULL , &States[S_DEMON2FX_BOOM1+2]),
S_BRIGHT (D2FX, 'I', 4, NULL , &States[S_DEMON2FX_BOOM1+3]),
S_BRIGHT (D2FX, 'J', 4, NULL , &States[S_DEMON2FX_BOOM1+4]),
S_BRIGHT (D2FX, 'K', 3, NULL , &States[S_DEMON2FX_BOOM1+5]),
S_BRIGHT (D2FX, 'L', 3, NULL , NULL),
};
IMPLEMENT_ACTOR (ADemon2FX1, Hexen, -1, 0)
PROP_SpeedFixed (15)
PROP_RadiusFixed (10)
PROP_HeightFixed (6)
PROP_Damage (5)
PROP_DamageType (NAME_Fire)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE)
PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_DEMON2FX_MOVE1)
PROP_DeathState (S_DEMON2FX_BOOM1)
PROP_DeathSound ("DemonMissileExplode")
END_DEFAULTS
//============================================================================
//
// A_DemonAttack1 (melee)
//
//============================================================================
void A_DemonAttack1 (AActor *actor)
{
if (actor->target != NULL && actor->CheckMeleeRange ())
{
int damage = pr_atk.HitDice (2);
P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
P_TraceBleed (damage, actor->target, actor);
}
}
//============================================================================
//
// A_DemonAttack2_1 (missile)
//
//============================================================================
void A_DemonAttack2_1 (AActor *actor)
{
if (actor->target != NULL)
{
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon1FX1));
actor->z -= 30*FRACUNIT;
if (mo)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
}
}
}
//============================================================================
//
// A_DemonAttack2_2 (missile)
//
//============================================================================
void A_DemonAttack2_2 (AActor *actor)
{
if (actor->target != NULL)
{
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon2FX1));
actor->z -= 30*FRACUNIT;
if (mo)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
}
}
}
//============================================================================
//
// A_DemonDeath
//
//============================================================================
void A_DemonDeath (AActor *actor)
{
const PClass *const ChunkTypes[] =
{
RUNTIME_CLASS(ADemon1Chunk5),
RUNTIME_CLASS(ADemon1Chunk4),
RUNTIME_CLASS(ADemon1Chunk3),
RUNTIME_CLASS(ADemon1Chunk2),
RUNTIME_CLASS(ADemon1Chunk1)
};
TossChunks (actor, ChunkTypes);
}
//===========================================================================
//
// A_Demon2Death
//
//===========================================================================
void A_Demon2Death (AActor *actor)
{
const PClass *const ChunkTypes[] =
{
RUNTIME_CLASS(ADemon2Chunk5),
RUNTIME_CLASS(ADemon2Chunk4),
RUNTIME_CLASS(ADemon2Chunk3),
RUNTIME_CLASS(ADemon2Chunk2),
RUNTIME_CLASS(ADemon2Chunk1)
};
TossChunks (actor, ChunkTypes);
}
static void TossChunks (AActor *actor, const PClass *const chunks[])
{
AActor *mo;
angle_t angle;
int i;
for (i = 4; i >= 0; --i)
{
2006-07-16 09:10:45 +00:00
mo = Spawn (chunks[i], actor->x, actor->y, actor->z+45*FRACUNIT, ALLOW_REPLACE);
if (mo)
{
angle = actor->angle + (i<4 ? ANGLE_270 : ANGLE_90);
mo->momz = 8*FRACUNIT;
mo->momx = FixedMul((pr_demonchunks()<<10)+FRACUNIT,
finecosine[angle>>ANGLETOFINESHIFT]);
mo->momy = FixedMul((pr_demonchunks()<<10)+FRACUNIT,
finesine[angle>>ANGLETOFINESHIFT]);
mo->target = actor;
}
}
}