mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 05:51:26 +00:00
d878c2e7d6
SVN r97 (trunk)
283 lines
9.7 KiB
C++
283 lines
9.7 KiB
C++
#include "actor.h"
|
|
#include "gi.h"
|
|
#include "m_random.h"
|
|
#include "s_sound.h"
|
|
#include "d_player.h"
|
|
#include "a_action.h"
|
|
#include "p_local.h"
|
|
|
|
static FRandom pr_skullpop ("SkullPop");
|
|
|
|
void A_Pain (AActor *);
|
|
void A_PlayerScream (AActor *);
|
|
void A_CheckSkullFloor (AActor *);
|
|
void A_CheckSkullDone (AActor *);
|
|
void A_FlameSnd (AActor *);
|
|
void A_HereticSkinCheck1 (AActor *);
|
|
void A_HereticSkinCheck2 (AActor *);
|
|
void A_XScream (AActor *);
|
|
|
|
// The player ---------------------------------------------------------------
|
|
|
|
class AHereticPlayer : public APlayerPawn
|
|
{
|
|
DECLARE_ACTOR (AHereticPlayer, APlayerPawn)
|
|
public:
|
|
void GiveDefaultInventory ();
|
|
};
|
|
|
|
FState AHereticPlayer::States[] =
|
|
{
|
|
#define S_PLAY 0
|
|
S_NORMAL (PLAY, 'A', -1, NULL , NULL),
|
|
|
|
#define S_PLAY_RUN (S_PLAY+1)
|
|
S_NORMAL (PLAY, 'A', 4, NULL , &States[S_PLAY_RUN+1]),
|
|
S_NORMAL (PLAY, 'B', 4, NULL , &States[S_PLAY_RUN+2]),
|
|
S_NORMAL (PLAY, 'C', 4, NULL , &States[S_PLAY_RUN+3]),
|
|
S_NORMAL (PLAY, 'D', 4, NULL , &States[S_PLAY_RUN+0]),
|
|
|
|
#define S_PLAY_ATK (S_PLAY_RUN+4)
|
|
S_NORMAL (PLAY, 'E', 12, NULL , &States[S_PLAY]),
|
|
S_BRIGHT (PLAY, 'F', 6, NULL , &States[S_PLAY_ATK+0]),
|
|
|
|
#define S_PLAY_PAIN (S_PLAY_ATK+2)
|
|
S_NORMAL (PLAY, 'G', 4, NULL , &States[S_PLAY_PAIN+1]),
|
|
S_NORMAL (PLAY, 'G', 4, A_Pain , &States[S_PLAY]),
|
|
|
|
#define S_PLAY_DIE (S_PLAY_PAIN+2)
|
|
S_NORMAL (PLAY, 'H', 6, A_HereticSkinCheck1 , &States[S_PLAY_DIE+1]),
|
|
S_NORMAL (PLAY, 'I', 6, A_PlayerScream , &States[S_PLAY_DIE+2]),
|
|
S_NORMAL (PLAY, 'J', 6, NULL , &States[S_PLAY_DIE+3]),
|
|
S_NORMAL (PLAY, 'K', 6, NULL , &States[S_PLAY_DIE+4]),
|
|
S_NORMAL (PLAY, 'L', 6, A_NoBlocking , &States[S_PLAY_DIE+5]),
|
|
S_NORMAL (PLAY, 'M', 6, NULL , &States[S_PLAY_DIE+6]),
|
|
S_NORMAL (PLAY, 'N', 6, NULL , &States[S_PLAY_DIE+7]),
|
|
S_NORMAL (PLAY, 'O', 6, NULL , &States[S_PLAY_DIE+8]),
|
|
S_NORMAL (PLAY, 'P', -1, NULL , NULL),
|
|
|
|
#define S_PLAY_XDIE (S_PLAY_DIE+9)
|
|
S_NORMAL (PLAY, 'Q', 5, A_HereticSkinCheck2 , &States[S_PLAY_XDIE+1]),
|
|
S_NORMAL (PLAY, 'R', 0, A_NoBlocking , &States[S_PLAY_XDIE+2]),
|
|
S_NORMAL (PLAY, 'R', 5, A_SkullPop , &States[S_PLAY_XDIE+3]),
|
|
S_NORMAL (PLAY, 'S', 5, NULL , &States[S_PLAY_XDIE+4]),
|
|
S_NORMAL (PLAY, 'T', 5, NULL , &States[S_PLAY_XDIE+5]),
|
|
S_NORMAL (PLAY, 'U', 5, NULL , &States[S_PLAY_XDIE+6]),
|
|
S_NORMAL (PLAY, 'V', 5, NULL , &States[S_PLAY_XDIE+7]),
|
|
S_NORMAL (PLAY, 'W', 5, NULL , &States[S_PLAY_XDIE+8]),
|
|
S_NORMAL (PLAY, 'X', 5, NULL , &States[S_PLAY_XDIE+9]),
|
|
S_NORMAL (PLAY, 'Y', -1, NULL , NULL),
|
|
|
|
#define S_PLAY_FDTH (S_PLAY_XDIE+10)
|
|
S_BRIGHT (FDTH, 'A', 5, A_FlameSnd , &States[S_PLAY_FDTH+1]),
|
|
S_BRIGHT (FDTH, 'B', 4, NULL , &States[S_PLAY_FDTH+2]),
|
|
S_BRIGHT (FDTH, 'C', 5, NULL , &States[S_PLAY_FDTH+3]),
|
|
S_BRIGHT (FDTH, 'D', 4, A_PlayerScream , &States[S_PLAY_FDTH+4]),
|
|
S_BRIGHT (FDTH, 'E', 5, NULL , &States[S_PLAY_FDTH+5]),
|
|
S_BRIGHT (FDTH, 'F', 4, NULL , &States[S_PLAY_FDTH+6]),
|
|
S_BRIGHT (FDTH, 'G', 5, A_FlameSnd , &States[S_PLAY_FDTH+7]),
|
|
S_BRIGHT (FDTH, 'H', 4, NULL , &States[S_PLAY_FDTH+8]),
|
|
S_BRIGHT (FDTH, 'I', 5, NULL , &States[S_PLAY_FDTH+9]),
|
|
S_BRIGHT (FDTH, 'J', 4, NULL , &States[S_PLAY_FDTH+10]),
|
|
S_BRIGHT (FDTH, 'K', 5, NULL , &States[S_PLAY_FDTH+11]),
|
|
S_BRIGHT (FDTH, 'L', 4, NULL , &States[S_PLAY_FDTH+12]),
|
|
S_BRIGHT (FDTH, 'M', 5, NULL , &States[S_PLAY_FDTH+13]),
|
|
S_BRIGHT (FDTH, 'N', 4, NULL , &States[S_PLAY_FDTH+14]),
|
|
S_BRIGHT (FDTH, 'O', 5, A_NoBlocking , &States[S_PLAY_FDTH+15]),
|
|
S_BRIGHT (FDTH, 'P', 4, NULL , &States[S_PLAY_FDTH+16]),
|
|
S_BRIGHT (FDTH, 'Q', 5, NULL , &States[S_PLAY_FDTH+17]),
|
|
S_BRIGHT (FDTH, 'R', 4, NULL , &States[S_PLAY_FDTH+18]),
|
|
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_PLAY_FDTH+18]),
|
|
|
|
#define S_DOOM_DIE (S_PLAY_FDTH+19)
|
|
S_NORMAL (PLAY, 'H', 10, NULL , &States[S_DOOM_DIE+1]),
|
|
S_NORMAL (PLAY, 'I', 10, A_PlayerScream , &States[S_DOOM_DIE+2]),
|
|
S_NORMAL (PLAY, 'J', 10, A_NoBlocking , &States[S_DOOM_DIE+3]),
|
|
S_NORMAL (PLAY, 'K', 10, NULL , &States[S_DOOM_DIE+4]),
|
|
S_NORMAL (PLAY, 'L', 10, NULL , &States[S_DOOM_DIE+5]),
|
|
S_NORMAL (PLAY, 'M', 10, NULL , &States[S_DOOM_DIE+6]),
|
|
S_NORMAL (PLAY, 'N', -1, NULL , NULL),
|
|
|
|
#define S_DOOM_XDIE (S_DOOM_DIE+7)
|
|
S_NORMAL (PLAY, 'O', 5, NULL , &States[S_DOOM_XDIE+1]),
|
|
S_NORMAL (PLAY, 'P', 5, A_XScream , &States[S_DOOM_XDIE+2]),
|
|
S_NORMAL (PLAY, 'Q', 5, A_NoBlocking , &States[S_DOOM_XDIE+3]),
|
|
S_NORMAL (PLAY, 'R', 5, NULL , &States[S_DOOM_XDIE+4]),
|
|
S_NORMAL (PLAY, 'S', 5, NULL , &States[S_DOOM_XDIE+5]),
|
|
S_NORMAL (PLAY, 'T', 5, NULL , &States[S_DOOM_XDIE+6]),
|
|
S_NORMAL (PLAY, 'U', 5, NULL , &States[S_DOOM_XDIE+7]),
|
|
S_NORMAL (PLAY, 'V', 5, NULL , &States[S_DOOM_XDIE+8]),
|
|
S_NORMAL (PLAY, 'W', -1, NULL , NULL)
|
|
};
|
|
|
|
IMPLEMENT_ACTOR (AHereticPlayer, Heretic, -1, 0)
|
|
PROP_SpawnHealth (100)
|
|
PROP_RadiusFixed (16)
|
|
PROP_HeightFixed (56)
|
|
PROP_Mass (100)
|
|
PROP_PainChance (255)
|
|
PROP_SpeedFixed (1)
|
|
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY)
|
|
PROP_Flags2 (MF2_WINDTHRUST|MF2_FLOORCLIP|MF2_SLIDE|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_TELESTOMP)
|
|
PROP_Flags3 (MF3_NOBLOCKMONST)
|
|
|
|
PROP_SpawnState (S_PLAY)
|
|
PROP_SeeState (S_PLAY_RUN)
|
|
PROP_PainState (S_PLAY_PAIN)
|
|
PROP_MissileState (S_PLAY_ATK)
|
|
PROP_DeathState (S_PLAY_DIE)
|
|
PROP_XDeathState (S_PLAY_XDIE)
|
|
PROP_BDeathState (S_PLAY_FDTH)
|
|
END_DEFAULTS
|
|
|
|
void AHereticPlayer::GiveDefaultInventory ()
|
|
{
|
|
AInventory *wand, *ammo;
|
|
|
|
player->health = GetDefault()->health;
|
|
player->mo->GiveInventoryType (PClass::FindClass ("Staff"));
|
|
wand = player->mo->GiveInventoryType (PClass::FindClass ("GoldWand"));
|
|
// Adding the gold wand automatically adds its ammo
|
|
ammo = player->mo->FindInventory (PClass::FindClass ("GoldWandAmmo"));
|
|
ammo->Amount = 50;
|
|
player->ReadyWeapon = player->PendingWeapon = static_cast<AWeapon *> (wand);
|
|
}
|
|
|
|
// The player's skull -------------------------------------------------------
|
|
|
|
class ABloodySkull : public APlayerChunk
|
|
{
|
|
DECLARE_ACTOR (ABloodySkull, APlayerChunk)
|
|
};
|
|
|
|
FState ABloodySkull::States[] =
|
|
{
|
|
S_NORMAL (PLAY, 'A', 0, NULL , &States[1]),
|
|
#define S_BLOODYSKULL 1
|
|
S_NORMAL (BSKL, 'A', 5, A_CheckSkullFloor , &States[S_BLOODYSKULL+1]),
|
|
S_NORMAL (BSKL, 'B', 5, A_CheckSkullFloor , &States[S_BLOODYSKULL+2]),
|
|
S_NORMAL (BSKL, 'C', 5, A_CheckSkullFloor , &States[S_BLOODYSKULL+3]),
|
|
S_NORMAL (BSKL, 'D', 5, A_CheckSkullFloor , &States[S_BLOODYSKULL+4]),
|
|
S_NORMAL (BSKL, 'E', 5, A_CheckSkullFloor , &States[S_BLOODYSKULL+0]),
|
|
|
|
#define S_BLOODYSKULLX1 (S_BLOODYSKULL+5)
|
|
S_NORMAL (BSKL, 'F', 16, A_CheckSkullDone , &States[S_BLOODYSKULLX1]),
|
|
};
|
|
|
|
IMPLEMENT_ACTOR (ABloodySkull, Heretic, -1, 0)
|
|
PROP_RadiusFixed (4)
|
|
PROP_HeightFixed (4)
|
|
PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF)
|
|
PROP_Flags2 (MF2_LOGRAV|MF2_CANNOTPUSH)
|
|
PROP_Flags3 (MF3_SKYEXPLODE|MF3_NOBLOCKMONST)
|
|
|
|
PROP_SpawnState (0)
|
|
END_DEFAULTS
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// PROC A_SkullPop
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void A_SkullPop (AActor *actor)
|
|
{
|
|
APlayerPawn *mo;
|
|
player_t *player;
|
|
|
|
actor->flags &= ~MF_SOLID;
|
|
mo = Spawn<ABloodySkull> (actor->x, actor->y, actor->z + 48*FRACUNIT);
|
|
//mo->target = actor;
|
|
mo->momx = pr_skullpop.Random2() << 9;
|
|
mo->momy = pr_skullpop.Random2() << 9;
|
|
mo->momz = 2*FRACUNIT + (pr_skullpop() << 6);
|
|
// Attach player mobj to bloody skull
|
|
player = actor->player;
|
|
actor->player = NULL;
|
|
mo->player = player;
|
|
mo->health = actor->health;
|
|
mo->angle = actor->angle;
|
|
if (player != NULL)
|
|
{
|
|
player->mo = mo;
|
|
if (player->camera == actor)
|
|
{
|
|
player->camera = mo;
|
|
}
|
|
player->damagecount = 32;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// PROC A_CheckSkullFloor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void A_CheckSkullFloor (AActor *actor)
|
|
{
|
|
if (actor->z <= actor->floorz)
|
|
{
|
|
actor->SetState (&ABloodySkull::States[S_BLOODYSKULLX1]);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// PROC A_CheckSkullDone
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void A_CheckSkullDone (AActor *actor)
|
|
{
|
|
if (actor->player == NULL)
|
|
{
|
|
actor->Destroy ();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// PROC A_FlameSnd
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void A_FlameSnd (AActor *actor)
|
|
{
|
|
S_Sound (actor, CHAN_BODY, "misc/burn", 1, ATTN_NORM); // Burn sound
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// A_HereticSkinCheck1
|
|
//
|
|
//==========================================================================
|
|
|
|
void A_HereticSkinCheck1 (AActor *actor)
|
|
{
|
|
if (actor->player != NULL &&
|
|
skins[actor->player->userinfo.skin].game == GAME_Doom)
|
|
{
|
|
actor->SetState (&AHereticPlayer::States[S_DOOM_DIE]);
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// A_HereticSkinCheck2
|
|
//
|
|
//==========================================================================
|
|
|
|
void A_HereticSkinCheck2 (AActor *actor)
|
|
{
|
|
if (actor->player != NULL &&
|
|
skins[actor->player->userinfo.skin].game == GAME_Doom)
|
|
{
|
|
actor->SetState (&AHereticPlayer::States[S_DOOM_XDIE]);
|
|
}
|
|
else
|
|
{
|
|
A_PlayerScream (actor);
|
|
}
|
|
}
|
|
|