- Converted Heretic's and Hexen's players to DECORATE.

- Made Hexenarmor factors configurable by DECORATE.
- Added support for selecting the invulnerability mode per item as well.
- Made Invulnerability and Healing radius behavior selectable by player
  class instead of hard coding the special behavior to the Hexen classes.


SVN r379 (trunk)
This commit is contained in:
Christoph Oelckers 2006-11-07 10:20:09 +00:00
parent 80950553c6
commit e5bce37755
32 changed files with 737 additions and 1037 deletions

View file

@ -1,4 +1,9 @@
November 5, 2006 (Changes by Graf Zahl)
- Converted Heretic's and Hexen's players to DECORATE.
- Made Hexenarmor factors configurable by DECORATE.
- Added support for selecting the invulnerability mode per item as well.
- Made Invulnerability and Healing radius behavior selectable by player
class instead of hard coding the special behavior to the Hexen classes.
- Converted the DoomPlayer to DECORATE.
- Extended all A_Jump commands to take labels as parameters in addition
to offsets.

View file

@ -52,6 +52,13 @@ enum
APMETA_DisplayName, // display name (used in menus etc.)
APMETA_SoundClass, // sound class
APMETA_ColorRange, // skin color range
APMETA_InvulMode,
APMETA_HealingRadius,
APMETA_Hexenarmor0,
APMETA_Hexenarmor1,
APMETA_Hexenarmor2,
APMETA_Hexenarmor3,
APMETA_Hexenarmor4,
};
class player_s;
@ -73,7 +80,6 @@ public:
virtual void ThrowPoisonBag ();
virtual void GiveDefaultInventory ();
virtual void TweakSpeeds (int &forwardmove, int &sidemove);
virtual bool DoHealingRadius (APlayerPawn *other);
virtual void MorphPlayerThink ();
virtual void ActivateMorphWeapon ();
virtual AWeapon *PickNewWeapon (const PClass *ammotype);
@ -93,8 +99,6 @@ public:
INVUL_GetAlpha
};
virtual void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha=NULL);
void BeginPlay ();
void Die (AActor *source, AActor *inflictor);

View file

@ -1,302 +0,0 @@
#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"
#include "thingdef.h"
static FRandom pr_skullpop ("SkullPop");
void A_Pain (AActor *);
void A_PlayerScream (AActor *);
void A_CheckSkullFloor (AActor *);
void A_CheckSkullDone (AActor *);
void A_FireScream (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_FireScream , &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_FireScream , &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+1) // Heretic never uses the non-flash attack state directly.
PROP_MeleeState (S_PLAY_ATK+1)
PROP_DeathState (S_PLAY_DIE)
PROP_XDeathState (S_PLAY_XDIE)
PROP_BDeathState (S_PLAY_FDTH)
// [GRB]
PROP_PlayerPawn_ColorRange (225, 240)
PROP_PlayerPawn_DisplayName ("Corvus")
END_DEFAULTS
void AHereticPlayer::GiveDefaultInventory ()
{
Super::GiveDefaultInventory ();
if (!Inventory)
{
AInventory *wand, *ammo;
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"));
if (ammo != NULL) 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_FireScream
//
//----------------------------------------------------------------------------
void A_FireScream (AActor *self)
{
S_Sound (self, CHAN_BODY, "*burndeath", 1, ATTN_NORM);
}
//----------------------------------------------------------------------------
//
// PROC A_SkullPop
//
//----------------------------------------------------------------------------
void A_SkullPop (AActor *actor)
{
APlayerPawn *mo;
player_t *player;
// [GRB] Parameterized version
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0)
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
if (!spawntype || !spawntype->IsDescendantOf (RUNTIME_CLASS (APlayerChunk)))
spawntype = RUNTIME_CLASS (ABloodySkull);
actor->flags &= ~MF_SOLID;
mo = (APlayerPawn *)Spawn (spawntype, actor->x, actor->y, actor->z + 48*FRACUNIT, NO_REPLACE);
//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->ObtainInventory (actor);
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 ();
}
}
//==========================================================================
//
// A_HereticSkinCheck1
//
//==========================================================================
void A_HereticSkinCheck1 (AActor *actor)
{
if (actor->player != NULL &&
skins[actor->player->userinfo.skin].othergame)
{
actor->SetState (&AHereticPlayer::States[S_DOOM_DIE]);
}
}
//==========================================================================
//
// A_HereticSkinCheck2
//
//==========================================================================
void A_HereticSkinCheck2 (AActor *actor)
{
if (actor->player != NULL &&
skins[actor->player->userinfo.skin].othergame)
{
actor->SetState (&AHereticPlayer::States[S_DOOM_XDIE]);
}
else
{
A_PlayerScream (actor);
}
}

View file

@ -83,9 +83,7 @@ FState AClericBoss::States[] =
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_CLERIC_BURN+15]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_CLERIC_BURN+16]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_CLERIC_BURN+17]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_CLERIC_BURN+18]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_CLERIC_BURN+18]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
S_BRIGHT (FDTH, 'V', 4, NULL , NULL),
};

View file

@ -46,8 +46,8 @@ END_DEFAULTS
bool AClericWeaponPiece::MatchPlayerClass (AActor *toucher)
{
return !toucher->IsKindOf (RUNTIME_CLASS(AFighterPlayer)) &&
!toucher->IsKindOf (RUNTIME_CLASS(AMagePlayer));
return !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) &&
!toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer));
}
//==========================================================================

View file

@ -1,210 +0,0 @@
#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"
#include "p_enemy.h"
#include "a_action.h"
#include "a_hexenglobal.h"
#include "templates.h"
// The cleric ---------------------------------------------------------------
FState AClericPlayer::States[] =
{
#define S_CPLAY 0
S_NORMAL (CLER, 'A', -1, NULL , NULL),
#define S_CPLAY_RUN1 (S_CPLAY+1)
S_NORMAL (CLER, 'A', 4, NULL , &States[S_CPLAY_RUN1+1]),
S_NORMAL (CLER, 'B', 4, NULL , &States[S_CPLAY_RUN1+2]),
S_NORMAL (CLER, 'C', 4, NULL , &States[S_CPLAY_RUN1+3]),
S_NORMAL (CLER, 'D', 4, NULL , &States[S_CPLAY_RUN1]),
#define S_CPLAY_PAIN (S_CPLAY_RUN1+4)
S_NORMAL (CLER, 'H', 4, NULL , &States[S_CPLAY_PAIN+1]),
S_NORMAL (CLER, 'H', 4, A_Pain , &States[S_CPLAY]),
#define S_CPLAY_ATK1 (S_CPLAY_PAIN+2)
S_NORMAL (CLER, 'E', 6, NULL , &States[S_CPLAY_ATK1+1]),
S_NORMAL (CLER, 'F', 6, NULL , &States[S_CPLAY_ATK1+2]),
S_NORMAL (CLER, 'G', 6, NULL , &States[S_CPLAY]),
#define S_CPLAY_DIE1 (S_CPLAY_ATK1+3)
S_NORMAL (CLER, 'I', 6, NULL , &States[S_CPLAY_DIE1+1]),
S_NORMAL (CLER, 'K', 6, A_PlayerScream , &States[S_CPLAY_DIE1+2]),
S_NORMAL (CLER, 'L', 6, NULL , &States[S_CPLAY_DIE1+3]),
S_NORMAL (CLER, 'L', 6, NULL , &States[S_CPLAY_DIE1+4]),
S_NORMAL (CLER, 'M', 6, A_NoBlocking , &States[S_CPLAY_DIE1+5]),
S_NORMAL (CLER, 'N', 6, NULL , &States[S_CPLAY_DIE1+6]),
S_NORMAL (CLER, 'O', 6, NULL , &States[S_CPLAY_DIE1+7]),
S_NORMAL (CLER, 'P', 6, NULL , &States[S_CPLAY_DIE1+8]),
S_NORMAL (CLER, 'Q', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_CPLAY_XDIE1 (S_CPLAY_DIE1+9)
S_NORMAL (CLER, 'R', 5, A_PlayerScream , &States[S_CPLAY_XDIE1+1]),
S_NORMAL (CLER, 'S', 5, NULL , &States[S_CPLAY_XDIE1+2]),
S_NORMAL (CLER, 'T', 5, A_NoBlocking , &States[S_CPLAY_XDIE1+3]),
S_NORMAL (CLER, 'U', 5, NULL , &States[S_CPLAY_XDIE1+4]),
S_NORMAL (CLER, 'V', 5, NULL , &States[S_CPLAY_XDIE1+5]),
S_NORMAL (CLER, 'W', 5, NULL , &States[S_CPLAY_XDIE1+6]),
S_NORMAL (CLER, 'X', 5, NULL , &States[S_CPLAY_XDIE1+7]),
S_NORMAL (CLER, 'Y', 5, NULL , &States[S_CPLAY_XDIE1+8]),
S_NORMAL (CLER, 'Z', 5, NULL , &States[S_CPLAY_XDIE1+9]),
S_NORMAL (CLER, '[', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_CPLAY_ICE (S_CPLAY_XDIE1+10)
S_NORMAL (CLER, '\\', 5, A_FreezeDeath , &States[S_CPLAY_ICE+1]),
S_NORMAL (CLER, '\\', 1, A_FreezeDeathChunks , &States[S_CPLAY_ICE+1]),
#define S_PLAY_C_FDTH (S_CPLAY_ICE+2)
S_BRIGHT (FDTH, 'C', 5, A_FireScream , &States[S_PLAY_C_FDTH+1]),
S_BRIGHT (FDTH, 'D', 4, NULL , &States[S_PLAY_C_FDTH+2]),
#define S_PLAY_FDTH (S_PLAY_C_FDTH+2)
S_BRIGHT (FDTH, 'G', 5, NULL , &States[S_PLAY_FDTH+1]),
S_BRIGHT (FDTH, 'H', 4, A_PlayerScream , &States[S_PLAY_FDTH+2]),
S_BRIGHT (FDTH, 'I', 5, NULL , &States[S_PLAY_FDTH+3]),
S_BRIGHT (FDTH, 'J', 4, NULL , &States[S_PLAY_FDTH+4]),
S_BRIGHT (FDTH, 'K', 5, NULL , &States[S_PLAY_FDTH+5]),
S_BRIGHT (FDTH, 'L', 4, NULL , &States[S_PLAY_FDTH+6]),
S_BRIGHT (FDTH, 'M', 5, NULL , &States[S_PLAY_FDTH+7]),
S_BRIGHT (FDTH, 'N', 4, NULL , &States[S_PLAY_FDTH+8]),
S_BRIGHT (FDTH, 'O', 5, NULL , &States[S_PLAY_FDTH+9]),
S_BRIGHT (FDTH, 'P', 4, NULL , &States[S_PLAY_FDTH+10]),
S_BRIGHT (FDTH, 'Q', 5, NULL , &States[S_PLAY_FDTH+11]),
S_BRIGHT (FDTH, 'R', 4, NULL , &States[S_PLAY_FDTH+12]),
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_PLAY_FDTH+13]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_PLAY_FDTH+14]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_PLAY_FDTH+15]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
};
IMPLEMENT_ACTOR (AClericPlayer, Hexen, -1, 0)
PROP_SpawnHealth (100)
PROP_ReactionTime (0)
PROP_PainChance (255)
PROP_RadiusFixed (16)
PROP_HeightFixed (64)
PROP_SpeedFixed (1)
PROP_RadiusdamageFactor(FRACUNIT/4)
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_TELESTOMP|MF2_PUSHWALL)
PROP_Flags3 (MF3_NOBLOCKMONST)
PROP_Flags4 (MF4_NOSKIN)
PROP_SpawnState (S_CPLAY)
PROP_SeeState (S_CPLAY_RUN1)
PROP_PainState (S_CPLAY_PAIN)
PROP_MissileState (S_CPLAY_ATK1)
PROP_MeleeState (S_CPLAY_ATK1)
PROP_DeathState (S_CPLAY_DIE1)
PROP_XDeathState (S_CPLAY_XDIE1)
PROP_BDeathState (S_PLAY_C_FDTH)
PROP_IDeathState (S_CPLAY_ICE)
// [GRB]
PROP_PlayerPawn_JumpZ (FRACUNIT*39/4) // ~9.75
PROP_PlayerPawn_ViewHeight (48*FRACUNIT)
PROP_PlayerPawn_ColorRange (146, 163)
PROP_PlayerPawn_SpawnMask (MTF_CLERIC)
PROP_PlayerPawn_DisplayName ("Cleric")
PROP_PlayerPawn_SoundClass ("cleric")
PROP_PlayerPawn_ScoreIcon ("CLERFACE")
PROP_PainSound ("PlayerClericPain")
END_DEFAULTS
void AClericPlayer::GiveDefaultInventory ()
{
Super::GiveDefaultInventory ();
if (!Inventory)
{
player->ReadyWeapon = player->PendingWeapon = static_cast<AWeapon *>
(GiveInventoryType (PClass::FindClass ("CWeapMace")));
}
GiveInventoryType (RUNTIME_CLASS(AHexenArmor));
AHexenArmor *armor = FindInventory<AHexenArmor>();
armor->Slots[4] = 10*FRACUNIT;
armor->SlotsIncrement[0] = 10*FRACUNIT;
armor->SlotsIncrement[1] = 25*FRACUNIT;
armor->SlotsIncrement[2] = 5*FRACUNIT;
armor->SlotsIncrement[3] = 20*FRACUNIT;
}
void AClericPlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha)
{
if (state == INVUL_Active)
{
RenderStyle = STYLE_Translucent;
if (!(level.time & 7) && alpha > 0 && alpha < OPAQUE)
{
if (alpha == HX_SHADOW)
{
alpha = HX_ALTSHADOW;
}
else
{
alpha = 0;
flags2 |= MF2_NONSHOOTABLE;
}
}
if (!(level.time & 31))
{
if (alpha == 0)
{
flags2 &= ~MF2_NONSHOOTABLE;
alpha = HX_ALTSHADOW;
}
else
{
alpha = HX_SHADOW;
}
}
}
else if (state == INVUL_Stop)
{
flags2 &= ~MF2_NONSHOOTABLE;
RenderStyle = STYLE_Normal;
alpha = OPAQUE;
}
else if (state == INVUL_GetAlpha)
{
if (pAlpha != NULL) *pAlpha = MIN<fixed_t>(FRACUNIT/4 + alpha*3/4, FRACUNIT);
}
}
// Cleric Weapon Base Class -------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AClericWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
bool AClericWeapon::TryPickup (AActor *toucher)
{
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (RUNTIME_CLASS(AFighterPlayer)) ||
toucher->IsKindOf (RUNTIME_CLASS(AMagePlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
return Super::TryPickup (toucher);
}

View file

@ -78,9 +78,7 @@ FState AFighterBoss::States[] =
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_FIGHTER_BURN+15]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_FIGHTER_BURN+16]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_FIGHTER_BURN+17]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_FIGHTER_BURN+18]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_FIGHTER_BURN+18]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
S_BRIGHT (FDTH, 'V', 4, NULL , NULL),
};
IMPLEMENT_ACTOR (AFighterBoss, Hexen, 10100, 0)

View file

@ -9,138 +9,97 @@
#include "a_action.h"
#include "a_hexenglobal.h"
static FRandom pr_fpatk ("FPunchAttack");
void A_FSwordFlames (AActor *);
// Fighter Weapon Base Class ------------------------------------------------
// The fighter --------------------------------------------------------------
FState AFighterPlayer::States[] =
{
#define S_FPLAY 0
S_NORMAL (PLAY, 'A', -1, NULL , NULL),
#define S_FPLAY_RUN (S_FPLAY+1)
S_NORMAL (PLAY, 'A', 4, NULL , &States[S_FPLAY_RUN+1]),
S_NORMAL (PLAY, 'B', 4, NULL , &States[S_FPLAY_RUN+2]),
S_NORMAL (PLAY, 'C', 4, NULL , &States[S_FPLAY_RUN+3]),
S_NORMAL (PLAY, 'D', 4, NULL , &States[S_FPLAY_RUN+0]),
#define S_FPLAY_ATK (S_FPLAY_RUN+4)
S_NORMAL (PLAY, 'E', 8, NULL , &States[S_FPLAY_ATK+1]),
S_NORMAL (PLAY, 'F', 8, NULL , &States[S_FPLAY]),
#define S_FPLAY_PAIN (S_FPLAY_ATK+2)
S_NORMAL (PLAY, 'G', 4, NULL , &States[S_FPLAY_PAIN+1]),
S_NORMAL (PLAY, 'G', 4, A_Pain , &States[S_FPLAY]),
#define S_FPLAY_DIE (S_FPLAY_PAIN+2)
S_NORMAL (PLAY, 'H', 6, NULL , &States[S_FPLAY_DIE+1]),
S_NORMAL (PLAY, 'I', 6, A_PlayerScream , &States[S_FPLAY_DIE+2]),
S_NORMAL (PLAY, 'J', 6, NULL , &States[S_FPLAY_DIE+3]),
S_NORMAL (PLAY, 'K', 6, NULL , &States[S_FPLAY_DIE+4]),
S_NORMAL (PLAY, 'L', 6, A_NoBlocking , &States[S_FPLAY_DIE+5]),
S_NORMAL (PLAY, 'M', 6, NULL , &States[S_FPLAY_DIE+6]),
S_NORMAL (PLAY, 'N', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_FPLAY_XDIE (S_FPLAY_DIE+7)
S_NORMAL (PLAY, 'O', 5, A_PlayerScream , &States[S_FPLAY_XDIE+1]),
S_NORMAL (PLAY, 'P', 5, A_SkullPop , &States[S_FPLAY_XDIE+2]),
S_NORMAL (PLAY, 'R', 5, A_NoBlocking , &States[S_FPLAY_XDIE+3]),
S_NORMAL (PLAY, 'S', 5, NULL , &States[S_FPLAY_XDIE+4]),
S_NORMAL (PLAY, 'T', 5, NULL , &States[S_FPLAY_XDIE+5]),
S_NORMAL (PLAY, 'U', 5, NULL , &States[S_FPLAY_XDIE+6]),
S_NORMAL (PLAY, 'V', 5, NULL , &States[S_FPLAY_XDIE+7]),
S_NORMAL (PLAY, 'W', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_FPLAY_ICE (S_FPLAY_XDIE+8)
S_NORMAL (PLAY, 'X', 5, A_FreezeDeath , &States[S_FPLAY_ICE+1]),
S_NORMAL (PLAY, 'X', 1, A_FreezeDeathChunks , &States[S_FPLAY_ICE+1]),
#define S_PLAY_FDTH (S_FPLAY_ICE+2)
S_BRIGHT (FDTH, 'G', 5, NULL , &States[S_PLAY_FDTH+1]),
S_BRIGHT (FDTH, 'H', 4, A_PlayerScream , &States[S_PLAY_FDTH+2]),
S_BRIGHT (FDTH, 'I', 5, NULL , &States[S_PLAY_FDTH+3]),
S_BRIGHT (FDTH, 'J', 4, NULL , &States[S_PLAY_FDTH+4]),
S_BRIGHT (FDTH, 'K', 5, NULL , &States[S_PLAY_FDTH+5]),
S_BRIGHT (FDTH, 'L', 4, NULL , &States[S_PLAY_FDTH+6]),
S_BRIGHT (FDTH, 'M', 5, NULL , &States[S_PLAY_FDTH+7]),
S_BRIGHT (FDTH, 'N', 4, NULL , &States[S_PLAY_FDTH+8]),
S_BRIGHT (FDTH, 'O', 5, NULL , &States[S_PLAY_FDTH+9]),
S_BRIGHT (FDTH, 'P', 4, NULL , &States[S_PLAY_FDTH+10]),
S_BRIGHT (FDTH, 'Q', 5, NULL , &States[S_PLAY_FDTH+11]),
S_BRIGHT (FDTH, 'R', 4, NULL , &States[S_PLAY_FDTH+12]),
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_PLAY_FDTH+13]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_PLAY_FDTH+14]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_PLAY_FDTH+15]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
#define S_PLAY_F_FDTH (S_PLAY_FDTH+18)
S_BRIGHT (FDTH, 'A', 5, A_FireScream , &States[S_PLAY_F_FDTH+1]),
S_BRIGHT (FDTH, 'B', 4, NULL , &States[S_PLAY_FDTH]),
};
IMPLEMENT_ACTOR (AFighterPlayer, Hexen, -1, 0)
PROP_SpawnHealth (100)
PROP_RadiusFixed (16)
PROP_HeightFixed (64)
PROP_Mass (100)
PROP_PainChance (255)
PROP_SpeedFixed (1)
PROP_RadiusdamageFactor(FRACUNIT/4)
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_TELESTOMP|MF2_PUSHWALL)
PROP_Flags3 (MF3_NOBLOCKMONST)
PROP_Flags4 (MF4_NOSKIN)
PROP_SpawnState (S_FPLAY)
PROP_SeeState (S_FPLAY_RUN)
PROP_PainState (S_FPLAY_PAIN)
PROP_MissileState (S_FPLAY_ATK)
PROP_MeleeState (S_FPLAY_ATK)
PROP_DeathState (S_FPLAY_DIE)
PROP_XDeathState (S_FPLAY_XDIE)
PROP_BDeathState (S_PLAY_F_FDTH)
PROP_IDeathState (S_FPLAY_ICE)
// [GRB]
PROP_PlayerPawn_JumpZ (FRACUNIT*39/4) // ~9.75
PROP_PlayerPawn_ViewHeight (48*FRACUNIT)
PROP_PlayerPawn_ForwardMove1 (FRACUNIT * 0x1d / 0x19)
PROP_PlayerPawn_ForwardMove2 (FRACUNIT * 0x3c / 0x32)
PROP_PlayerPawn_SideMove1 (FRACUNIT * 0x1b / 0x18)
PROP_PlayerPawn_SideMove2 (FRACUNIT * 0x3b / 0x28) // The fighter is a very fast strafer when running!
PROP_PlayerPawn_ColorRange (246, 254)
PROP_PlayerPawn_SpawnMask (MTF_FIGHTER)
PROP_PlayerPawn_DisplayName ("Fighter")
PROP_PlayerPawn_SoundClass ("fighter")
PROP_PlayerPawn_ScoreIcon ("FITEFACE")
PROP_PainSound ("PlayerFighterPain")
IMPLEMENT_STATELESS_ACTOR (AFighterWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
void AFighterPlayer::GiveDefaultInventory ()
bool AFighterWeapon::TryPickup (AActor *toucher)
{
Super::GiveDefaultInventory ();
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) ||
toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
if (!Inventory)
{
player->ReadyWeapon = player->PendingWeapon = static_cast<AWeapon *>
(GiveInventoryType (PClass::FindClass ("FWeapFist")));
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
GiveInventoryType (RUNTIME_CLASS(AHexenArmor));
AHexenArmor *armor = FindInventory<AHexenArmor>();
armor->Slots[4] = 15*FRACUNIT;
armor->SlotsIncrement[0] = 25*FRACUNIT;
armor->SlotsIncrement[1] = 20*FRACUNIT;
armor->SlotsIncrement[2] = 15*FRACUNIT;
armor->SlotsIncrement[3] = 5*FRACUNIT;
return Super::TryPickup (toucher);
}
// --- Fighter Weapons ------------------------------------------------------
// Cleric Weapon Base Class -------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AClericWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
bool AClericWeapon::TryPickup (AActor *toucher)
{
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) ||
toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
return Super::TryPickup (toucher);
}
// Mage Weapon Base Class ---------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AMageWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
bool AMageWeapon::TryPickup (AActor *toucher)
{
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) ||
toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
return Super::TryPickup (toucher);
}
static FRandom pr_fpatk ("FPunchAttack");
//============================================================================
//
@ -345,58 +304,3 @@ punchdone:
return;
}
// Radius armor boost
bool AFighterPlayer::DoHealingRadius (APlayerPawn *other)
{
bool gotSome = false;
for (int i = 0; i < 4; ++i)
{
AHexenArmor *armor = Spawn<AHexenArmor> (0,0,0, NO_REPLACE);
armor->health = i;
armor->Amount = 1;
if (!armor->TryPickup (player->mo))
{
armor->Destroy ();
}
else
{
gotSome = true;
}
}
if (gotSome)
{
S_Sound (other, CHAN_AUTO, "MysticIncant", 1, ATTN_NORM);
return true;
}
return false;
}
// Fighter Weapon Base Class ------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AFighterWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
bool AFighterWeapon::TryPickup (AActor *toucher)
{
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (RUNTIME_CLASS(AClericPlayer)) ||
toucher->IsKindOf (RUNTIME_CLASS(AMagePlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
return Super::TryPickup (toucher);
}

View file

@ -34,8 +34,8 @@ END_DEFAULTS
bool AFighterWeaponPiece::MatchPlayerClass (AActor *toucher)
{
return !toucher->IsKindOf (RUNTIME_CLASS(AClericPlayer)) &&
!toucher->IsKindOf (RUNTIME_CLASS(AMagePlayer));
return !toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) &&
!toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer));
}
//==========================================================================

View file

@ -278,11 +278,11 @@ bool AArtiPoisonBag::HandlePickup (AInventory *item)
bool matched;
if (Owner->IsKindOf (RUNTIME_CLASS(AClericPlayer)))
if (Owner->IsKindOf (PClass::FindClass(NAME_ClericPlayer)))
{
matched = (GetClass() == RUNTIME_CLASS(AArtiPoisonBag1));
}
else if (Owner->IsKindOf (RUNTIME_CLASS(AMagePlayer)))
else if (Owner->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
{
matched = (GetClass() == RUNTIME_CLASS(AArtiPoisonBag2));
}
@ -327,11 +327,11 @@ AInventory *AArtiPoisonBag::CreateCopy (AActor *other)
AInventory *copy;
const PClass *spawntype;
if (other->IsKindOf (RUNTIME_CLASS(AClericPlayer)))
if (other->IsKindOf (PClass::FindClass(NAME_ClericPlayer)))
{
spawntype = RUNTIME_CLASS(AArtiPoisonBag1);
}
else if (other->IsKindOf (RUNTIME_CLASS(AMagePlayer)))
else if (other->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
{
spawntype = RUNTIME_CLASS(AArtiPoisonBag2);
}

View file

@ -12,6 +12,8 @@
#define HEAL_RADIUS_DIST 255*FRACUNIT
static FRandom pr_healradius ("HealRadius");
// Healing Radius Artifact --------------------------------------------------
class AArtiHealingRadius : public AInventory
@ -55,6 +57,7 @@ END_DEFAULTS
bool AArtiHealingRadius::Use (bool pickup)
{
bool effective = false;
int mode = Owner->GetClass()->Meta.GetMetaInt(APMETA_HealingRadius);
for (int i = 0; i < MAXPLAYERS; ++i)
{
@ -63,7 +66,50 @@ bool AArtiHealingRadius::Use (bool pickup)
players[i].mo->health > 0 &&
P_AproxDistance (players[i].mo->x - Owner->x, players[i].mo->y - Owner->y) <= HEAL_RADIUS_DIST)
{
effective |= static_cast<APlayerPawn*>(Owner)->DoHealingRadius (players[i].mo);
// Q: Is it worth it to make this selectable as a player property?
// A: Probably not - but it sure doesn't hurt.
bool gotsome=false;
switch (mode)
{
case NAME_Armor:
for (int j = 0; j < 4; ++j)
{
AHexenArmor *armor = Spawn<AHexenArmor> (0,0,0, NO_REPLACE);
armor->health = j;
armor->Amount = 1;
if (!armor->TryPickup (players[i].mo))
{
armor->Destroy ();
}
else
{
gotsome = true;
}
}
break;
case NAME_Mana:
{
int amount = 50 + (pr_healradius() % 50);
if (players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana1), amount) ||
players[i].mo->GiveAmmo (PClass::FindClass(NAME_Mana2), amount))
{
gotsome = true;
}
break;
}
default:
//case NAME_Health:
gotsome = P_GiveBody (players[i].mo, 50 + (pr_healradius()%50));
break;
}
if (gotsome)
{
S_Sound (players[i].mo, CHAN_AUTO, "MysticIncant", 1, ATTN_NORM);
effective=true;
}
}
}
return effective;

View file

@ -77,14 +77,6 @@ protected:
bool PrivateShouldStay ();
};
class AFighterPlayer : public APlayerPawn
{
DECLARE_ACTOR (AFighterPlayer, APlayerPawn)
public:
void GiveDefaultInventory ();
bool DoHealingRadius (APlayerPawn *other);
};
class AFighterWeapon : public AWeapon
{
DECLARE_STATELESS_ACTOR (AFighterWeapon, AWeapon);
@ -92,14 +84,6 @@ public:
bool TryPickup (AActor *toucher);
};
class AClericPlayer : public APlayerPawn
{
DECLARE_ACTOR (AClericPlayer, APlayerPawn)
public:
void GiveDefaultInventory ();
void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha);
};
class AClericWeapon : public AWeapon
{
DECLARE_STATELESS_ACTOR (AClericWeapon, AWeapon);
@ -107,15 +91,6 @@ public:
bool TryPickup (AActor *toucher);
};
class AMagePlayer : public APlayerPawn
{
DECLARE_ACTOR (AMagePlayer, APlayerPawn)
public:
void GiveDefaultInventory ();
bool DoHealingRadius (APlayerPawn *other);
void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha);
};
class AMageWeapon : public AWeapon
{
DECLARE_STATELESS_ACTOR (AMageWeapon, AWeapon);

View file

@ -78,9 +78,7 @@ FState AMageBoss::States[] =
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_MAGE_BURN+15]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_MAGE_BURN+16]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_MAGE_BURN+17]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_MAGE_BURN+18]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_MAGE_BURN+18]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
S_BRIGHT (FDTH, 'V', 4, NULL , NULL),
};

View file

@ -1,199 +0,0 @@
#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"
#include "p_enemy.h"
#include "a_action.h"
#include "a_hexenglobal.h"
static FRandom pr_manaradius ("ManaRadius");
// The mage -----------------------------------------------------------------
FState AMagePlayer::States[] =
{
#define S_MPLAY 0
S_NORMAL (MAGE, 'A', -1, NULL , NULL),
#define S_MPLAY_RUN1 (S_MPLAY+1)
S_NORMAL (MAGE, 'A', 4, NULL , &States[S_MPLAY_RUN1+1]),
S_NORMAL (MAGE, 'B', 4, NULL , &States[S_MPLAY_RUN1+2]),
S_NORMAL (MAGE, 'C', 4, NULL , &States[S_MPLAY_RUN1+3]),
S_NORMAL (MAGE, 'D', 4, NULL , &States[S_MPLAY_RUN1]),
#define S_MPLAY_PAIN (S_MPLAY_RUN1+4)
S_NORMAL (MAGE, 'G', 4, NULL , &States[S_MPLAY_PAIN+1]),
S_NORMAL (MAGE, 'G', 4, A_Pain , &States[S_MPLAY]),
#define S_MPLAY_ATK1 (S_MPLAY_PAIN+2)
S_NORMAL (MAGE, 'E', 8, NULL , &States[S_MPLAY_ATK1+1]),
S_BRIGHT (MAGE, 'F', 8, NULL , &States[S_MPLAY]),
#define S_MPLAY_DIE1 (S_MPLAY_ATK1+2)
S_NORMAL (MAGE, 'H', 6, NULL , &States[S_MPLAY_DIE1+1]),
S_NORMAL (MAGE, 'I', 6, A_PlayerScream , &States[S_MPLAY_DIE1+2]),
S_NORMAL (MAGE, 'J', 6, NULL , &States[S_MPLAY_DIE1+3]),
S_NORMAL (MAGE, 'K', 6, NULL , &States[S_MPLAY_DIE1+4]),
S_NORMAL (MAGE, 'L', 6, A_NoBlocking , &States[S_MPLAY_DIE1+5]),
S_NORMAL (MAGE, 'M', 6, NULL , &States[S_MPLAY_DIE1+6]),
S_NORMAL (MAGE, 'N', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_MPLAY_XDIE1 (S_MPLAY_DIE1+7)
S_NORMAL (MAGE, 'O', 5, A_PlayerScream , &States[S_MPLAY_XDIE1+1]),
S_NORMAL (MAGE, 'P', 5, NULL , &States[S_MPLAY_XDIE1+2]),
S_NORMAL (MAGE, 'R', 5, A_NoBlocking , &States[S_MPLAY_XDIE1+3]),
S_NORMAL (MAGE, 'S', 5, NULL , &States[S_MPLAY_XDIE1+4]),
S_NORMAL (MAGE, 'T', 5, NULL , &States[S_MPLAY_XDIE1+5]),
S_NORMAL (MAGE, 'U', 5, NULL , &States[S_MPLAY_XDIE1+6]),
S_NORMAL (MAGE, 'V', 5, NULL , &States[S_MPLAY_XDIE1+7]),
S_NORMAL (MAGE, 'W', 5, NULL , &States[S_MPLAY_XDIE1+8]),
S_NORMAL (MAGE, 'X', -1, NULL/*A_AddPlayerCorpse*/, NULL),
#define S_MPLAY_ICE (S_MPLAY_XDIE1+9)
S_NORMAL (MAGE, 'Y', 5, A_FreezeDeath , &States[S_MPLAY_ICE+1]),
S_NORMAL (MAGE, 'Y', 1, A_FreezeDeathChunks , &States[S_MPLAY_ICE+1]),
#define S_PLAY_M_FDTH (S_MPLAY_ICE+2)
S_BRIGHT (FDTH, 'E', 5, A_FireScream , &States[S_PLAY_M_FDTH+1]),
S_BRIGHT (FDTH, 'F', 4, NULL , &States[S_PLAY_M_FDTH+2]),
#define S_PLAY_FDTH (S_PLAY_M_FDTH+2)
S_BRIGHT (FDTH, 'G', 5, NULL , &States[S_PLAY_FDTH+1]),
S_BRIGHT (FDTH, 'H', 4, A_PlayerScream , &States[S_PLAY_FDTH+2]),
S_BRIGHT (FDTH, 'I', 5, NULL , &States[S_PLAY_FDTH+3]),
S_BRIGHT (FDTH, 'J', 4, NULL , &States[S_PLAY_FDTH+4]),
S_BRIGHT (FDTH, 'K', 5, NULL , &States[S_PLAY_FDTH+5]),
S_BRIGHT (FDTH, 'L', 4, NULL , &States[S_PLAY_FDTH+6]),
S_BRIGHT (FDTH, 'M', 5, NULL , &States[S_PLAY_FDTH+7]),
S_BRIGHT (FDTH, 'N', 4, NULL , &States[S_PLAY_FDTH+8]),
S_BRIGHT (FDTH, 'O', 5, NULL , &States[S_PLAY_FDTH+9]),
S_BRIGHT (FDTH, 'P', 4, NULL , &States[S_PLAY_FDTH+10]),
S_BRIGHT (FDTH, 'Q', 5, NULL , &States[S_PLAY_FDTH+11]),
S_BRIGHT (FDTH, 'R', 4, NULL , &States[S_PLAY_FDTH+12]),
S_BRIGHT (FDTH, 'S', 5, A_NoBlocking , &States[S_PLAY_FDTH+13]),
S_BRIGHT (FDTH, 'T', 4, NULL , &States[S_PLAY_FDTH+14]),
S_BRIGHT (FDTH, 'U', 5, NULL , &States[S_PLAY_FDTH+15]),
S_BRIGHT (FDTH, 'V', 4, NULL , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 35, A_CheckBurnGone , &States[S_PLAY_FDTH+16]),
S_NORMAL (ACLO, 'E', 8, NULL , NULL),
};
IMPLEMENT_ACTOR (AMagePlayer, Hexen, -1, 0)
PROP_SpawnHealth (100)
PROP_ReactionTime (0)
PROP_PainChance (255)
PROP_RadiusFixed (16)
PROP_HeightFixed (64)
PROP_SpeedFixed (1)
PROP_RadiusdamageFactor(FRACUNIT/4)
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_TELESTOMP|MF2_PUSHWALL)
PROP_Flags3 (MF3_NOBLOCKMONST)
PROP_Flags4 (MF4_NOSKIN)
PROP_SpawnState (S_MPLAY)
PROP_SeeState (S_MPLAY_RUN1)
PROP_PainState (S_MPLAY_PAIN)
PROP_MissileState (S_MPLAY_ATK1)
PROP_MeleeState (S_MPLAY_ATK1)
PROP_DeathState (S_MPLAY_DIE1)
PROP_XDeathState (S_MPLAY_XDIE1)
PROP_BDeathState (S_PLAY_M_FDTH)
PROP_IDeathState (S_MPLAY_ICE)
// [GRB]
PROP_PlayerPawn_JumpZ (FRACUNIT*39/4) // ~9.75
PROP_PlayerPawn_ViewHeight (48*FRACUNIT)
PROP_PlayerPawn_ForwardMove1 (FRACUNIT * 0x16 / 0x19)
PROP_PlayerPawn_ForwardMove2 (FRACUNIT * 0x2e / 0x32)
PROP_PlayerPawn_SideMove1 (FRACUNIT * 0x15 / 0x18)
PROP_PlayerPawn_SideMove2 (FRACUNIT * 0x25 / 0x28)
PROP_PlayerPawn_ColorRange (146, 163)
PROP_PlayerPawn_SpawnMask (MTF_MAGE)
PROP_PlayerPawn_DisplayName ("Mage")
PROP_PlayerPawn_SoundClass ("mage")
PROP_PlayerPawn_ScoreIcon ("MAGEFACE")
PROP_PainSound ("PlayerMagePain")
END_DEFAULTS
void AMagePlayer::GiveDefaultInventory ()
{
Super::GiveDefaultInventory ();
if (!Inventory)
{
player->ReadyWeapon = player->PendingWeapon = static_cast<AWeapon *>
(GiveInventoryType (PClass::FindClass ("MWeapWand")));
}
GiveInventoryType (RUNTIME_CLASS(AHexenArmor));
AHexenArmor *armor = FindInventory<AHexenArmor>();
armor->Slots[4] = 5*FRACUNIT;
armor->SlotsIncrement[0] = 5*FRACUNIT;
armor->SlotsIncrement[1] = 15*FRACUNIT;
armor->SlotsIncrement[2] = 10*FRACUNIT;
armor->SlotsIncrement[3] = 25*FRACUNIT;
}
// Radius mana boost
bool AMagePlayer::DoHealingRadius (APlayerPawn *other)
{
int amount = 50 + (pr_manaradius() % 50);
if (GiveAmmo (PClass::FindClass("Mana1"), amount) ||
GiveAmmo (PClass::FindClass("Mana2"), amount))
{
S_Sound (other, CHAN_AUTO, "MysticIncant", 1, ATTN_NORM);
return true;
}
return false;
}
void AMagePlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha)
{
if (state == INVUL_Start)
{
flags2 |= MF2_REFLECTIVE;
}
else if (state == INVUL_Stop)
{
flags2 &= ~MF2_REFLECTIVE;
}
else if (state == INVUL_GetAlpha && pAlpha != NULL)
{
*pAlpha = FIXED_MAX;
}
}
// Mage Weapon Base Class ---------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AMageWeapon, Hexen, -1, 0)
PROP_Weapon_Kickback (150)
END_DEFAULTS
bool AMageWeapon::TryPickup (AActor *toucher)
{
// The Doom and Hexen players are not excluded from pickup in case
// somebody wants to use these weapons with either of those games.
if (toucher->IsKindOf (RUNTIME_CLASS(AFighterPlayer)) ||
toucher->IsKindOf (RUNTIME_CLASS(AClericPlayer)))
{ // Wrong class, but try to pick up for mana
if (ShouldStay())
{ // Can't pick up weapons for other classes in coop netplay
return false;
}
bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1));
gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2));
if (gaveSome)
{
GoAwayAndDie ();
}
return gaveSome;
}
return Super::TryPickup (toucher);
}

View file

@ -35,8 +35,8 @@ END_DEFAULTS
bool AMageWeaponPiece::MatchPlayerClass (AActor *toucher)
{
return !toucher->IsKindOf (RUNTIME_CLASS(AFighterPlayer)) &&
!toucher->IsKindOf (RUNTIME_CLASS(AClericPlayer));
return !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) &&
!toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer));
}
//==========================================================================

View file

@ -310,13 +310,13 @@ public:
FBaseStatusBar::AttachToPlayer (player);
if (player->mo != NULL)
{
if (player->mo->IsKindOf (RUNTIME_CLASS(AMagePlayer)))
if (player->mo->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
{
FourthWeaponShift = 6;
FourthWeaponClass = 2;
LifeBarClass = 2;
}
else if (player->mo->IsKindOf (RUNTIME_CLASS(AClericPlayer)))
else if (player->mo->IsKindOf (PClass::FindClass(NAME_ClericPlayer)))
{
FourthWeaponShift = 3;
FourthWeaponClass = 1;

View file

@ -581,16 +581,3 @@ void FaceMovementDirection (AActor *actor)
}
}
//----------------------------------------------------------------------------
//
// PROC A_CheckBurnGone
//
//----------------------------------------------------------------------------
void A_CheckBurnGone (AActor *actor)
{
if (actor->player == NULL)
{
actor->Destroy ();
}
}

View file

@ -22,5 +22,4 @@ void A_SetFloorClip (AActor *);
void A_UnSetFloorClip (AActor *);
void A_NoGravity (AActor *);
void FaceMovementDirection (AActor *);
void A_CheckBurnGone (AActor *);
void A_SkullPop (AActor *);

View file

@ -52,6 +52,10 @@ bool APowerupGiver::Use (bool pickup)
{
power->BlendColor = BlendColor;
}
if (mode != NAME_None)
{
power->mode = mode;
}
power->ItemFlags |= ItemFlags & IF_ALWAYSPICKUP;
if (power->TryPickup (Owner))
@ -72,7 +76,7 @@ void APowerupGiver::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << PowerupType;
arc << EffectTics << BlendColor;
arc << EffectTics << BlendColor << mode;
}
// Powerup -------------------------------------------------------------------
@ -120,7 +124,7 @@ void APowerup::Tick ()
void APowerup::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << EffectTics << BlendColor;
arc << EffectTics << BlendColor << mode;
}
//===========================================================================
@ -322,7 +326,11 @@ void APowerInvulnerable::InitEffect ()
{
Owner->effects &= ~FX_RESPAWNINVUL;
Owner->flags2 |= MF2_INVULNERABLE;
Owner->player->mo->SpecialInvulnerabilityHandling (APlayerPawn::INVUL_Start);
if (mode == NAME_None)
{
mode = (ENamedName)RUNTIME_TYPE(Owner)->Meta.GetMetaInt(APMETA_InvulMode);
}
if (mode == NAME_Reflective) Owner->flags2 |= MF2_REFLECTIVE;
}
//===========================================================================
@ -333,7 +341,39 @@ void APowerInvulnerable::InitEffect ()
void APowerInvulnerable::DoEffect ()
{
Owner->player->mo->SpecialInvulnerabilityHandling (APlayerPawn::INVUL_Active);
if (Owner == NULL)
{
return;
}
if (mode == NAME_Ghost)
{
Owner->RenderStyle = STYLE_Translucent;
if (!(level.time & 7) && Owner->alpha > 0 && Owner->alpha < OPAQUE)
{
if (Owner->alpha == HX_SHADOW)
{
Owner->alpha = HX_ALTSHADOW;
}
else
{
Owner->alpha = 0;
Owner->flags2 |= MF2_NONSHOOTABLE;
}
}
if (!(level.time & 31))
{
if (Owner->alpha == 0)
{
Owner->flags2 &= ~MF2_NONSHOOTABLE;
Owner->alpha = HX_ALTSHADOW;
}
else
{
Owner->alpha = HX_SHADOW;
}
}
}
}
//===========================================================================
@ -351,12 +391,19 @@ void APowerInvulnerable::EndEffect ()
Owner->flags2 &= ~MF2_INVULNERABLE;
Owner->effects &= ~FX_RESPAWNINVUL;
if (mode == NAME_Ghost)
{
Owner->flags2 &= ~MF2_NONSHOOTABLE;
Owner->RenderStyle = STYLE_Normal;
Owner->alpha = OPAQUE;
}
else if (mode == NAME_Reflective)
{
Owner->flags2 &= ~MF2_REFLECTIVE;
}
if (Owner->player != NULL)
{
if (Owner->player->mo != NULL)
{
Owner->player->mo->SpecialInvulnerabilityHandling (APlayerPawn::INVUL_Stop);
}
Owner->player->fixedcolormap = 0;
}
}
@ -369,11 +416,13 @@ void APowerInvulnerable::EndEffect ()
void APowerInvulnerable::AlterWeaponSprite (vissprite_t *vis)
{
if (Owner->player->mo != NULL)
if (Owner != NULL)
{
fixed_t wp_alpha;
Owner->player->mo->SpecialInvulnerabilityHandling (APlayerPawn::INVUL_GetAlpha, &wp_alpha);
if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha;
if (mode == NAME_Ghost)
{
fixed_t wp_alpha = MIN<fixed_t>(FRACUNIT/4 + Owner->alpha*3/4, FRACUNIT);
if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha;
}
}
}

View file

@ -36,6 +36,7 @@ public:
int EffectTics;
PalEntry BlendColor;
FNameNoInit mode;
protected:
virtual void InitEffect ();
@ -54,6 +55,7 @@ public:
const PClass *PowerupType;
int EffectTics; // Non-0 to override the powerup's default tics
PalEntry BlendColor; // Non-0 to override the powerup's default blend
FNameNoInit mode; // Meaning depends on powerup - currently only of use for Invulnerability
};
class APowerInvulnerable : public APowerup

View file

@ -16,6 +16,7 @@ void A_TossGib (AActor *);
void A_ItBurnsItBurns (AActor *);
void A_DropFire (AActor *);
void A_CrispyPlayer (AActor *);
void A_Yeargh (AActor *);
void A_Wander (AActor *);
// The player ---------------------------------------------------------------
@ -97,7 +98,7 @@ FState AStrifePlayer::States[] =
S_NORMAL (BURN, 'V',-1, NULL, NULL),
#define S_PLAY_ZAPDEATH (S_PLAY_BURNDEATH+24)
S_NORMAL (DISR, 'A', 5, NULL, &States[S_PLAY_ZAPDEATH+1]),
S_NORMAL (DISR, 'A', 5, A_Yeargh, &States[S_PLAY_ZAPDEATH+1]),
S_NORMAL (DISR, 'B', 5, NULL, &States[S_PLAY_ZAPDEATH+2]),
S_NORMAL (DISR, 'C', 5, NULL, &States[S_PLAY_ZAPDEATH+3]),
S_NORMAL (DISR, 'D', 5, A_NoBlocking, &States[S_PLAY_ZAPDEATH+4]),

View file

@ -6,6 +6,14 @@ xx(Object)
xx(Untranslated)
// Invulnerability types
xx(Ghost)
xx(Reflective)
// Healingradius types
xx(Mana)
xx(Armor)
// Per-actor sound channels
xx(Auto)
xx(Weapon)

View file

@ -52,7 +52,8 @@
#include "tarray.h"
#include "thingdef.h"
static FRandom pr_healradius ("HealRadius");
static FRandom pr_skullpop ("SkullPop");
// [RH] # of ticks to complete a turn180
#define TURN180_TICKS ((TICRATE / 4) + 1)
@ -374,7 +375,7 @@ BEGIN_STATELESS_DEFAULTS (APlayerPawn, Any, -1, 0)
PROP_PainChance (255)
PROP_SpeedFixed (1)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY)
PROP_Flags2 (MF2_SLIDE|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_FLOORCLIP|MF2_WINDTHRUST)
PROP_Flags2 (MF2_SLIDE|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_FLOORCLIP|MF2_WINDTHRUST|MF2_TELESTOMP)
PROP_Flags3 (MF3_NOBLOCKMONST)
// [GRB]
PROP_PlayerPawn_JumpZ (8*FRACUNIT)
@ -912,6 +913,26 @@ void APlayerPawn::GiveDefaultInventory ()
}
di = di->Next;
}
fixed_t hx[5];
bool ishx;
for(int i=0;i<5;i++)
{
hx[i] = GetClass()->Meta.GetMetaFixed(APMETA_Hexenarmor0+i);
ishx |= !!hx[i];
}
if (ishx)
{
GiveInventoryType (RUNTIME_CLASS(AHexenArmor));
AHexenArmor *armor = FindInventory<AHexenArmor>();
armor->Slots[4] = hx[0];
armor->SlotsIncrement[0] = hx[1];
armor->SlotsIncrement[1] = hx[2];
armor->SlotsIncrement[2] = hx[3];
armor->SlotsIncrement[3] = hx[4];
}
}
void APlayerPawn::MorphPlayerThink ()
@ -1042,23 +1063,6 @@ void APlayerPawn::TweakSpeeds (int &forward, int &side)
}
}
// The standard healing radius behavior is the cleric's
bool APlayerPawn::DoHealingRadius (APlayerPawn *other)
{
if (P_GiveBody (other, 50 + (pr_healradius()%50)))
{
S_Sound (other, CHAN_AUTO, "MysticIncant", 1, ATTN_NORM);
return true;
}
return false;
}
void APlayerPawn::SpecialInvulnerabilityHandling (EInvulState setting, fixed_t * pAlpha)
{
if (setting == INVUL_GetAlpha && pAlpha!=NULL) *pAlpha=FIXED_MAX; // indicates no change
}
//===========================================================================
//
// A_PlayerScream
@ -1128,6 +1132,66 @@ void A_PlayerScream (AActor *self)
}
//----------------------------------------------------------------------------
//
// PROC A_SkullPop
//
//----------------------------------------------------------------------------
void A_SkullPop (AActor *actor)
{
APlayerPawn *mo;
player_t *player;
// [GRB] Parameterized version
const PClass *spawntype = NULL;
int index = CheckIndex (1, NULL);
if (index >= 0)
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
if (!spawntype || !spawntype->IsDescendantOf (RUNTIME_CLASS (APlayerChunk)))
{
spawntype = PClass::FindClass("BloodySkull");
if (spawntype == NULL) return;
}
actor->flags &= ~MF_SOLID;
mo = (APlayerPawn *)Spawn (spawntype, actor->x, actor->y, actor->z + 48*FRACUNIT, NO_REPLACE);
//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->ObtainInventory (actor);
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_CheckSkullDone
//
//----------------------------------------------------------------------------
void A_CheckPlayerDone (AActor *actor)
{
if (actor->player == NULL)
{
actor->Destroy ();
}
}
//===========================================================================
//
// P_CheckPlayerSprites

View file

@ -509,7 +509,7 @@ ACTOR(Light)
ACTOR(Burst)
ACTOR(SkullPop)
ACTOR(CheckFloor)
ACTOR(CheckSkullDone)
ACTOR(CheckPlayerDone)
ACTOR(RadiusThrust)
ACTOR(Stop)
ACTOR(SPosAttackUseAtkSound)
@ -640,7 +640,7 @@ AFuncDesc AFTable[]=
FUNC(A_CStaffMissileSlither, NULL)
FUNC(A_PlayerScream, NULL)
FUNC(A_SkullPop, "m")
{"A_CheckPlayerDone", A_CheckSkullDone, NULL },
FUNC(A_CheckPlayerDone, NULL)
// useful functions from Strife
FUNC(A_Wander, NULL)
@ -1958,13 +1958,13 @@ do_stop:
case 'L':
case 'l': // Jump label
if (strlen(statestring)>0)
{
SC_ScriptError("You cannot use A_Jump commands on multistate definitions\n");
}
if (SC_CheckNumber())
{
if (strlen(statestring)>0)
{
SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n");
}
v=sc_Number;
if (v<1)
{
@ -3824,6 +3824,15 @@ static void PowerupDuration (APowerupGiver *defaults, Baggage &bag)
defaults->EffectTics = sc_Number;
}
//==========================================================================
//
//==========================================================================
static void PowerupMode (APowerupGiver *defaults, Baggage &bag)
{
SC_MustGetString();
defaults->mode = (FName)sc_String;
}
//==========================================================================
//
//==========================================================================
@ -4029,6 +4038,37 @@ static void PlayerStartItem (APlayerPawn *defaults, Baggage &bag)
bag.DropItemList = di;
}
//==========================================================================
//
//==========================================================================
static void PlayerInvulMode (APlayerPawn *defaults, Baggage &bag)
{
SC_MustGetString ();
bag.Info->Class->Meta.SetMetaInt (APMETA_InvulMode, (FName)sc_String);
}
//==========================================================================
//
//==========================================================================
static void PlayerHealRadius (APlayerPawn *defaults, Baggage &bag)
{
SC_MustGetString ();
bag.Info->Class->Meta.SetMetaInt (APMETA_HealingRadius, (FName)sc_String);
}
//==========================================================================
//
//==========================================================================
static void PlayerHexenArmor (APlayerPawn *defaults, Baggage &bag)
{
for (int i=0;i<5;i++)
{
SC_MustGetFloat ();
bag.Info->Class->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, FLOAT2FIXED (sc_Float));
if (i!=4) SC_MustGetStringName(",");
}
}
//==========================================================================
//
//==========================================================================
@ -4155,6 +4195,9 @@ static const ActorProps props[] =
{ "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) },
{ "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) },
{ "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) },
{ "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) },
{ "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) },
{ "player.invulnerabilitymode", (apf)PlayerInvulMode, RUNTIME_CLASS(APlayerPawn) },
{ "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) },
{ "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) },
{ "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) },
@ -4167,6 +4210,7 @@ static const ActorProps props[] =
{ "poisondamage", ActorPoisonDamage, RUNTIME_CLASS(AActor) },
{ "powerup.color", (apf)PowerupColor, RUNTIME_CLASS(APowerupGiver) },
{ "powerup.duration", (apf)PowerupDuration, RUNTIME_CLASS(APowerupGiver) },
{ "powerup.mode", (apf)PowerupMode, RUNTIME_CLASS(APowerupGiver) },
{ "powerup.type", (apf)PowerupType, RUNTIME_CLASS(APowerupGiver) },
{ "projectile", ActorProjectile, RUNTIME_CLASS(AActor) },
{ "puzzleitem.failmessage", (apf)PuzzleitemFailMsg, RUNTIME_CLASS(APuzzleItem) },

View file

@ -33,12 +33,16 @@
#include "actors/raven/ravenartifacts.txt"
#include "actors/raven/ravenhealth.txt"
#include "actors/heretic/hereticplayer.txt"
#include "actors/heretic/hereticammo.txt"
#include "actors/heretic/hereticarmor.txt"
#include "actors/heretic/hereticartifacts.txt"
#include "actors/heretic/heretickeys.txt"
#include "actors/heretic/hereticdecorations.txt"
#include "actors/hexen/fighterplayer.txt"
#include "actors/hexen/clericplayer.txt"
#include "actors/hexen/mageplayer.txt"
#include "actors/hexen/flame.txt"
#include "actors/hexen/hexenarmor.txt"
#include "actors/hexen/hexendecorations.txt"

View file

@ -30,7 +30,7 @@ ACTOR DoomPlayer : PlayerPawn
PLAY E 12
Goto Spawn
Melee:
PLAY F 6
PLAY F 6 BRIGHT
Goto Missile
Pain:
PLAY G 4

View file

@ -0,0 +1,109 @@
ACTOR HereticPlayer : PlayerPawn
{
Health 100
Radius 16
Height 56
Mass 100
Painchance 255
Speed 1
Player.ColorRange 225, 240
Player.DisplayName "Corvus"
Player.StartItem "GoldWand"
Player.StartItem "Staff"
Player.StartItem "GoldWandAmmo", 50
States
{
Spawn:
PLAY A -1
Stop
See:
PLAY ABCD 4
Loop
Melee:
Missile:
PLAY F 6 BRIGHT
PLAY E 12
Goto Spawn
Pain:
PLAY G 4
PLAY G 4 A_Pain
Goto Spawn
Death:
PLAY H 6 A_PlayerSkinCheck(AltSkinDeath)
PLAY I 6 A_PlayerScream
PLAY JK 6
PLAY L 6 A_NoBlocking
PLAY MNO 6
PLAY P -1
Stop
XDeath:
PLAY Q 0 A_PlayerSkinCheck(AltSkinXDeath)
PLAY Q 5 A_PlayerScream
PLAY R 0 A_NoBlocking
PLAY R 5 A_SkullPop
PLAY STUVWX 5
PLAY Y -1
Stop
Burn:
FDTH A 5 BRIGHT A_PlaySound("*burndeath")
FDTH B 4 BRIGHT
FDTH C 5 BRIGHT
FDTH D 4 BRIGHT A_PlayerScream
FDTH E 5 BRIGHT
FDTH F 4 BRIGHT
FDTH G 5 BRIGHT A_PlaySound("*burndeath")
FDTH H 4 BRIGHT
FDTH I 5 BRIGHT
FDTH J 4 BRIGHT
FDTH K 5 BRIGHT
FDTH L 4 BRIGHT
FDTH M 5 BRIGHT
FDTH N 4 BRIGHT
FDTH O 5 BRIGHT A_NoBlocking
FDTH P 4 BRIGHT
FDTH Q 5 BRIGHT
FDTH R 4 BRIGHT
ACLO E 35 A_CheckPlayerDone
Wait
AltSkinDeath:
PLAY H 10
PLAY I 10 A_PlayerScream
PLAY J 10 A_NoBlocking
PLAY KLM 10
PLAY N -1
Stop
AltSkinXDeath:
PLAY O 5
PLAY P 5 A_XScream
PLAY Q 5 A_NoBlocking
PLAY RSTUV 5
PLAY W -1
Stop
}
}
// The player's skull -------------------------------------------------------
ACTOR BloodySkull : PlayerChunk
{
Radius 4
Height 4
+NOBLOCKMAP
+DROPOFF
+LOWGRAVITY
+CANNOTPUSH
+SKYEXPLODE
+NOBLOCKMONST
+NOSKIN
States
{
Spawn:
BSKL A 0
BSKL ABCDE 5 A_CheckFloor(Hit)
Goto Spawn+1
Hit:
BSKL F 16 A_CheckPlayerDone
Wait
}
}

View file

@ -0,0 +1,85 @@
// The cleric ---------------------------------------------------------------
ACTOR ClericPlayer : PlayerPawn
{
Health 100
ReactionTime 0
PainChance 255
Radius 16
Height 64
Speed 1
+NOSKIN
PainSound "PlayerClericPain"
RadiusDamageFactor 0.25
Player.JumpZ 9.75
Player.Viewheight 48
Player.ColorRange 146, 163
Player.SpawnClass "Cleric"
Player.DisplayName "Cleric"
Player.SoundClass "cleric"
Player.ScoreIcon "CLERFACE"
Player.InvulnerabilityMode "Ghost"
Player.HealRadiusType "Health"
Player.Hexenarmor 10, 10, 25, 5, 20
Player.StartItem "CWeapMace"
States
{
Spawn:
CLER A -1
Stop
See:
CLER ABCD 4
Loop
Pain:
CLER H 4
CLER H 4 A_Pain
Goto Spawn
Missile:
Melee:
CLER EFG 6
Goto Spawn
Death:
CLER I 6
CLER J 6 A_PlayerScream
CLER KL 6
CLER M 6 A_NoBlocking
CLER NOP 6
CLER Q -1
Stop
XDeath:
CLER R 5 A_PlayerScream
CLER S 5
CLER T 5 A_NoBlocking
CLER UVWXYZ 5
CLER [ -1
Stop
Ice:
CLER "\" 5 A_FreezeDeath
CLER "\" 1 A_FreezeDeathChunks
Wait
Burn:
FDTH C 5 BRIGHT A_PlaySound("*burndeath")
FDTH D 4 BRIGHT
FDTH G 5 BRIGHT
FDTH H 4 BRIGHT A_PlayerScream
FDTH I 5 BRIGHT
FDTH J 4 BRIGHT
FDTH K 5 BRIGHT
FDTH L 4 BRIGHT
FDTH M 5 BRIGHT
FDTH N 4 BRIGHT
FDTH O 5 BRIGHT
FDTH P 4 BRIGHT
FDTH Q 5 BRIGHT
FDTH R 4 BRIGHT
FDTH S 5 BRIGHT A_NoBlocking
FDTH T 4 BRIGHT
FDTH U 5 BRIGHT
FDTH V 4 BRIGHT
ACLO E 35 A_CheckPlayerDone
Wait
ACLO E 8
Stop
}
}

View file

@ -0,0 +1,85 @@
// The fighter --------------------------------------------------------------
ACTOR FighterPlayer : PlayerPawn
{
Health 100
PainChance 255
Radius 16
Height 64
Speed 1
+NOSKIN
PainSound "PlayerFighterPain"
RadiusDamageFactor 0.25
Player.JumpZ 9.75
Player.Viewheight 48
Player.ColorRange 246, 254
Player.SpawnClass "Fighter"
Player.DisplayName "Fighter"
Player.SoundClass "fighter"
Player.ScoreIcon "FITEFACE"
Player.HealRadiusType "Armor"
Player.Hexenarmor 15, 25, 20, 15, 5
Player.StartItem "FWeapFist"
Player.ForwardMove 1.08, 1.2
Player.SideMove 1.125, 1.475
States
{
Spawn:
PLAY A -1
Stop
See:
PLAY ABCD 4
Loop
Missile:
Melee:
CLER EF 8
Goto Spawn
Pain:
PLAY G 4
PLAY G 4 A_Pain
Goto Spawn
Death:
PLAY H 6
PLAY I 6 A_PlayerScream
PLAY JK 6
PLAY L 6 A_NoBlocking
PLAY M 6
PLAY N -1
Stop
XDeath:
PLAY O 5 A_PlayerScream
PLAY P 5 A_SkullPop
PLAY R 5 A_NoBlocking
PLAY STUV 5
PLAY W -1
Stop
Ice:
PLAY X 5 A_FreezeDeath
PLAY X 1 A_FreezeDeathChunks
Wait
Burn:
FDTH A 5 BRIGHT A_PlaySound("*burndeath")
FDTH B 4 BRIGHT
FDTH G 5 BRIGHT
FDTH H 4 BRIGHT A_PlayerScream
FDTH I 5 BRIGHT
FDTH J 4 BRIGHT
FDTH K 5 BRIGHT
FDTH L 4 BRIGHT
FDTH M 5 BRIGHT
FDTH N 4 BRIGHT
FDTH O 5 BRIGHT
FDTH P 4 BRIGHT
FDTH Q 5 BRIGHT
FDTH R 4 BRIGHT
FDTH S 5 BRIGHT A_NoBlocking
FDTH T 4 BRIGHT
FDTH U 5 BRIGHT
FDTH V 4 BRIGHT
ACLO E 35 A_CheckPlayerDone
Wait
ACLO E 8
Stop
}
}

View file

@ -0,0 +1,86 @@
// The mage -----------------------------------------------------------------
ACTOR MagePlayer : PlayerPawn
{
Health 100
ReactionTime 0
PainChance 255
Radius 16
Height 64
Speed 1
+NOSKIN
PainSound "PlayerMagePain"
RadiusDamageFactor 0.25
Player.JumpZ 9.75
Player.Viewheight 48
Player.ColorRange 146, 163
Player.SpawnClass "Mage"
Player.DisplayName "Mage"
Player.SoundClass "mage"
Player.ScoreIcon "MAGEFACE"
Player.InvulnerabilityMode "Reflective"
Player.HealRadiusType "Mana"
Player.Hexenarmor 5, 5, 15, 10, 25
Player.StartItem "MWeapWand"
Player.ForwardMove 0.88, 0.92
Player.SideMove 0.875, 0.925
States
{
Spawn:
MAGE A -1
Stop
See:
MAGE ABCD 4
Loop
Missile:
Melee:
MAGE EF 8
Goto Spawn
Pain:
MAGE G 4
MAGE G 4 A_Pain
Goto Spawn
Death:
MAGE H 6
MAGE I 6 A_PlayerScream
MAGE JK 6
MAGE L 6 A_NoBlocking
MAGE M 6
MAGE N -1
Stop
XDeath:
MAGE O 5 A_PlayerScream
MAGE P 5
MAGE R 5 A_NoBlocking
MAGE STUVW 5
MAGE X -1
Stop
Ice:
MAGE Y 5 A_FreezeDeath
MAGE Y 1 A_FreezeDeathChunks
Wait
Burn:
FDTH E 5 BRIGHT A_PlaySound("*burndeath")
FDTH F 4 BRIGHT
FDTH G 5 BRIGHT
FDTH H 4 BRIGHT A_PlayerScream
FDTH I 5 BRIGHT
FDTH J 4 BRIGHT
FDTH K 5 BRIGHT
FDTH L 4 BRIGHT
FDTH M 5 BRIGHT
FDTH N 4 BRIGHT
FDTH O 5 BRIGHT
FDTH P 4 BRIGHT
FDTH Q 5 BRIGHT
FDTH R 4 BRIGHT
FDTH S 5 BRIGHT A_NoBlocking
FDTH T 4 BRIGHT
FDTH U 5 BRIGHT
FDTH V 4 BRIGHT
ACLO E 35 A_CheckPlayerDone
Wait
ACLO E 8
Stop
}
}

View file

@ -276,12 +276,16 @@ actors/raven/artiegg.txt decorate/raven/artiegg.txt
actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt
actors/raven/ravenhealth.txt decorate/raven/ravenhealth.txt
actors/heretic/hereticplayer.txt decorate/heretic/hereticplayer.txt
actors/heretic/hereticammo.txt decorate/heretic/hereticammo.txt
actors/heretic/hereticarmor.txt decorate/heretic/hereticarmor.txt
actors/heretic/hereticartifacts.txt decorate/heretic/hereticartifacts.txt
actors/heretic/heretickeys.txt decorate/heretic/heretickeys.txt
actors/heretic/hereticdecorations.txt decorate/heretic/hereticdecorations.txt
actors/hexen/fighterplayer.txt decorate/hexen/fighterplayer.txt
actors/hexen/clericplayer.txt decorate/hexen/clericplayer.txt
actors/hexen/mageplayer.txt decorate/hexen/mageplayer.txt
actors/hexen/flame.txt decorate/hexen/flame.txt
actors/hexen/hexenarmor.txt decorate/hexen/hexenarmor.txt
actors/hexen/hexendecorations.txt decorate/hexen/hexendecorations.txt

View file

@ -7330,42 +7330,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\g_heretic\a_hereticplayer.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\g_heretic\a_hereticweaps.cpp"
>
@ -7946,10 +7910,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="src\g_hexen\a_clericplayer.cpp"
>
</File>
<File
RelativePath=".\src\g_hexen\a_clericstaff.cpp"
>
@ -8578,10 +8538,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="src\g_hexen\a_mageplayer.cpp"
>
</File>
<File
RelativePath=".\src\g_hexen\a_magestaff.cpp"
>