mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- Converted the StrifePlayer to DECORATE. Even though it requires exporting
3 new code pointers without general use it was necessary to handle GiveDefaultInventory consistently for all players without the need to subclass this function. - Added a Player.RunHealth property to expose the StrifePlayer's behavior of not being able to run when its health is below 10. - Changed APlayerPawn::GiveDefaultInventory so that it always adds a HexenArmor and a BasicArmor item to the inventory. If these items are not the first ones added to the inventory anything else that might absorb damage is not guaranteed to work consistently because their function depends on the order in the inventory. - Changed handling of APowerup's DoEffect so that it is called from the owner's Tick function, not the item's. This is so that the order of execution is determined by the order in the inventory. When done in the item's Tick function order depends on the global thinker table which can cause problems with the order in which conflicting powerups apply their effect. Now it is guaranteed that the item that was added to the inventory first applies its effect last. - Fixed: Added checks for Speed==0 to A_Tracer and A_Tracer2 because this could cause a divide by zero. - Fixed: P_MoveThing must also set the moved actor's previous position to prevent interpolation of the move. - Fixed: APowerInvisibility and its subclasses need to constantly update the owner's translucency information in case of interference between different subclasses. Also changed Hexen's Cleric's invulnerability mode to disable the translucency effect if an invisibility powerup is active. SVN r448 (trunk)
This commit is contained in:
parent
1cd8370327
commit
3c976ac02c
19 changed files with 943 additions and 904 deletions
|
@ -1,3 +1,29 @@
|
|||
January 12, 2007 (Changes by Graf Zahl)
|
||||
- Converted the StrifePlayer to DECORATE. Even though it requires exporting
|
||||
3 new code pointers without general use it was necessary to handle
|
||||
GiveDefaultInventory consistently for all players without the need to
|
||||
subclass this function.
|
||||
- Added a Player.RunHealth property to expose the StrifePlayer's behavior of
|
||||
not being able to run when its health is below 10.
|
||||
- Changed APlayerPawn::GiveDefaultInventory so that it always adds a HexenArmor
|
||||
and a BasicArmor item to the inventory. If these items are not the first ones
|
||||
added to the inventory anything else that might absorb damage is not guaranteed
|
||||
to work consistently because their function depends on the order in the inventory.
|
||||
- Changed handling of APowerup's DoEffect so that it is called from the owner's
|
||||
Tick function, not the item's. This is so that the order of execution is
|
||||
determined by the order in the inventory. When done in the item's Tick function
|
||||
order depends on the global thinker table which can cause problems with the
|
||||
order in which conflicting powerups apply their effect. Now it is guaranteed
|
||||
that the item that was added to the inventory first applies its effect last.
|
||||
- Fixed: Added checks for Speed==0 to A_Tracer and A_Tracer2 because this could
|
||||
cause a divide by zero.
|
||||
- Fixed: P_MoveThing must also set the moved actor's previous position to
|
||||
prevent interpolation of the move.
|
||||
- Fixed: APowerInvisibility and its subclasses need to constantly update
|
||||
the owner's translucency information in case of interference between different
|
||||
subclasses. Also changed Hexen's Cleric's invulnerability mode to disable
|
||||
the translucency effect if an invisibility powerup is active.
|
||||
|
||||
January 9, 2007 (Changes by Graf Zahl)
|
||||
- Added Skulltag's REDMAP and GREENMAP.
|
||||
- Fixed: The PlayerSpeedTrail must copy the player's scaling information
|
||||
|
|
|
@ -96,3 +96,8 @@ ACTOR(Respawn)
|
|||
ACTOR(BarrelDestroy)
|
||||
ACTOR(PlayerSkinCheck)
|
||||
ACTOR(QueueCorpse)
|
||||
|
||||
// Special code pointers for Strife's player - not to be used elsewhere!
|
||||
ACTOR(ItBurnsItBurns)
|
||||
ACTOR(CrispyPlayer)
|
||||
ACTOR(DropFire)
|
||||
|
|
|
@ -78,7 +78,6 @@ public:
|
|||
virtual void PlayIdle ();
|
||||
virtual void PlayRunning ();
|
||||
virtual void ThrowPoisonBag ();
|
||||
virtual void GiveDefaultInventory ();
|
||||
virtual void TweakSpeeds (int &forwardmove, int &sidemove);
|
||||
virtual void MorphPlayerThink ();
|
||||
virtual void ActivateMorphWeapon ();
|
||||
|
@ -87,6 +86,7 @@ public:
|
|||
virtual void GiveDeathmatchInventory ();
|
||||
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
|
||||
|
||||
void GiveDefaultInventory ();
|
||||
void PlayAttacking ();
|
||||
void PlayAttacking2 ();
|
||||
const char *GetSoundClass ();
|
||||
|
@ -104,6 +104,7 @@ public:
|
|||
|
||||
int crouchsprite;
|
||||
int MaxHealth;
|
||||
int RunHealth;
|
||||
AInventory *InvFirst; // first inventory item displayed on inventory bar
|
||||
AInventory *InvSel; // selected inventory item
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void A_Tracer (AActor *self)
|
|||
// adjust direction
|
||||
dest = self->tracer;
|
||||
|
||||
if (!dest || dest->health <= 0)
|
||||
if (!dest || dest->health <= 0 || self->Speed == 0)
|
||||
return;
|
||||
|
||||
// change angle
|
||||
|
|
|
@ -89,45 +89,14 @@ void APowerupGiver::Serialize (FArchive &arc)
|
|||
|
||||
void APowerup::Tick ()
|
||||
{
|
||||
// Powerups cannot exist outside an inventory
|
||||
if (Owner == NULL)
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
else if (EffectTics > 0)
|
||||
if (EffectTics > 0 && --EffectTics == 0)
|
||||
{
|
||||
DoEffect ();
|
||||
|
||||
if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8))
|
||||
{
|
||||
if (BlendColor == INVERSECOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = INVERSECOLORMAP;
|
||||
}
|
||||
else if (BlendColor == GOLDCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = GOLDCOLORMAP;
|
||||
}
|
||||
else if (BlendColor == REDCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = REDCOLORMAP;
|
||||
}
|
||||
else if (BlendColor == GREENCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = GREENCOLORMAP;
|
||||
}
|
||||
}
|
||||
else if ((BlendColor == INVERSECOLOR && Owner->player->fixedcolormap == INVERSECOLORMAP) ||
|
||||
(BlendColor == GOLDCOLOR && Owner->player->fixedcolormap == GOLDCOLORMAP) ||
|
||||
(BlendColor == REDCOLOR && Owner->player->fixedcolormap == REDCOLORMAP) ||
|
||||
(BlendColor == GREENCOLOR && Owner->player->fixedcolormap == GREENCOLORMAP))
|
||||
{
|
||||
Owner->player->fixedcolormap = 0;
|
||||
}
|
||||
|
||||
if (--EffectTics == 0)
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,6 +151,41 @@ void APowerup::InitEffect ()
|
|||
|
||||
void APowerup::DoEffect ()
|
||||
{
|
||||
if (Owner == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EffectTics > 0)
|
||||
{
|
||||
int oldcolormap = Owner->player->fixedcolormap;
|
||||
if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8))
|
||||
{
|
||||
if (BlendColor == INVERSECOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = INVERSECOLORMAP;
|
||||
}
|
||||
else if (BlendColor == GOLDCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = GOLDCOLORMAP;
|
||||
}
|
||||
else if (BlendColor == REDCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = REDCOLORMAP;
|
||||
}
|
||||
else if (BlendColor == GREENCOLOR)
|
||||
{
|
||||
Owner->player->fixedcolormap = GREENCOLORMAP;
|
||||
}
|
||||
}
|
||||
else if ((BlendColor == INVERSECOLOR && Owner->player->fixedcolormap == INVERSECOLORMAP) ||
|
||||
(BlendColor == GOLDCOLOR && Owner->player->fixedcolormap == GOLDCOLORMAP) ||
|
||||
(BlendColor == REDCOLOR && Owner->player->fixedcolormap == REDCOLORMAP) ||
|
||||
(BlendColor == GREENCOLOR && Owner->player->fixedcolormap == GREENCOLORMAP))
|
||||
{
|
||||
Owner->player->fixedcolormap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -361,6 +365,8 @@ void APowerInvulnerable::InitEffect ()
|
|||
|
||||
void APowerInvulnerable::DoEffect ()
|
||||
{
|
||||
Super::DoEffect ();
|
||||
|
||||
if (Owner == NULL)
|
||||
{
|
||||
return;
|
||||
|
@ -368,30 +374,39 @@ void APowerInvulnerable::DoEffect ()
|
|||
|
||||
if (mode == NAME_Ghost)
|
||||
{
|
||||
Owner->RenderStyle = STYLE_Translucent;
|
||||
if (!(level.time & 7) && Owner->alpha > 0 && Owner->alpha < OPAQUE)
|
||||
if (!(Owner->flags & MF_SHADOW))
|
||||
{
|
||||
if (Owner->alpha == HX_SHADOW)
|
||||
// Don't mess with the translucency settings if an
|
||||
// invisibility powerup is active.
|
||||
Owner->RenderStyle = STYLE_Translucent;
|
||||
if (!(level.time & 7) && Owner->alpha > 0 && Owner->alpha < OPAQUE)
|
||||
{
|
||||
Owner->alpha = HX_ALTSHADOW;
|
||||
if (Owner->alpha == HX_SHADOW)
|
||||
{
|
||||
Owner->alpha = HX_ALTSHADOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner->alpha = 0;
|
||||
Owner->flags2 |= MF2_NONSHOOTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!(level.time & 31))
|
||||
{
|
||||
Owner->alpha = 0;
|
||||
Owner->flags2 |= MF2_NONSHOOTABLE;
|
||||
if (Owner->alpha == 0)
|
||||
{
|
||||
Owner->flags2 &= ~MF2_NONSHOOTABLE;
|
||||
Owner->alpha = HX_ALTSHADOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner->alpha = HX_SHADOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(level.time & 31))
|
||||
else
|
||||
{
|
||||
if (Owner->alpha == 0)
|
||||
{
|
||||
Owner->flags2 &= ~MF2_NONSHOOTABLE;
|
||||
Owner->alpha = HX_ALTSHADOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner->alpha = HX_SHADOW;
|
||||
}
|
||||
Owner->flags2 &= ~MF2_NONSHOOTABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,8 +429,13 @@ void APowerInvulnerable::EndEffect ()
|
|||
if (mode == NAME_Ghost)
|
||||
{
|
||||
Owner->flags2 &= ~MF2_NONSHOOTABLE;
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->alpha = OPAQUE;
|
||||
if (!(Owner->flags & MF_SHADOW))
|
||||
{
|
||||
// Don't mess with the translucency settings if an
|
||||
// invisibility powerup is active.
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->alpha = OPAQUE;
|
||||
}
|
||||
}
|
||||
else if (mode == NAME_Reflective)
|
||||
{
|
||||
|
@ -430,7 +450,7 @@ void APowerInvulnerable::EndEffect ()
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvuInvulnerable :: AlterWeaponSprite
|
||||
// APowerInvulnerable :: AlterWeaponSprite
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
@ -438,7 +458,7 @@ void APowerInvulnerable::AlterWeaponSprite (vissprite_t *vis)
|
|||
{
|
||||
if (Owner != NULL)
|
||||
{
|
||||
if (mode == NAME_Ghost)
|
||||
if (mode == NAME_Ghost && !(Owner->flags & MF_SHADOW))
|
||||
{
|
||||
fixed_t wp_alpha = MIN<fixed_t>(FRACUNIT/4 + Owner->alpha*3/4, FRACUNIT);
|
||||
if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha;
|
||||
|
@ -486,10 +506,11 @@ void APowerStrength::InitEffect ()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerStrength::DoEffect ()
|
||||
void APowerStrength::Tick ()
|
||||
{
|
||||
// Strength counts up to diminish the fade.
|
||||
EffectTics += 2;
|
||||
Super::Tick();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -531,6 +552,14 @@ void APowerInvisibility::InitEffect ()
|
|||
Owner->RenderStyle = STYLE_OptFuzzy;
|
||||
}
|
||||
|
||||
void APowerInvisibility::DoEffect ()
|
||||
{
|
||||
Super::DoEffect();
|
||||
// Due to potential interference with other PowerInvisibility items
|
||||
// the effect has to be refreshed each tic.
|
||||
InitEffect();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: EndEffect
|
||||
|
@ -556,15 +585,16 @@ void APowerInvisibility::EndEffect ()
|
|||
|
||||
void APowerInvisibility::AlterWeaponSprite (vissprite_t *vis)
|
||||
{
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
Inventory->AlterWeaponSprite (vis);
|
||||
}
|
||||
|
||||
// Blink if the powerup is wearing off
|
||||
if (EffectTics < 4*32 && !(EffectTics & 8))
|
||||
{
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
Inventory->AlterWeaponSprite (vis);
|
||||
}
|
||||
}
|
||||
|
||||
// Ghost Powerup (Heretic's version of invisibility) -------------------------
|
||||
|
@ -692,14 +722,13 @@ END_DEFAULTS
|
|||
|
||||
void APowerLightAmp::DoEffect ()
|
||||
{
|
||||
if (Owner->player != NULL)
|
||||
Super::DoEffect ();
|
||||
|
||||
if (Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS)
|
||||
{
|
||||
if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8))
|
||||
{ // almost full bright
|
||||
if (Owner->player->fixedcolormap != NUMCOLORMAPS)
|
||||
{
|
||||
Owner->player->fixedcolormap = 1;
|
||||
}
|
||||
{
|
||||
Owner->player->fixedcolormap = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -716,7 +745,7 @@ void APowerLightAmp::DoEffect ()
|
|||
|
||||
void APowerLightAmp::EndEffect ()
|
||||
{
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS)
|
||||
{
|
||||
Owner->player->fixedcolormap = 0;
|
||||
}
|
||||
|
@ -748,31 +777,41 @@ void APowerTorch::Serialize (FArchive &arc)
|
|||
|
||||
void APowerTorch::DoEffect ()
|
||||
{
|
||||
if (EffectTics <= BLINKTHRESHOLD || Owner->player->fixedcolormap == NUMCOLORMAPS)
|
||||
if (Owner == NULL || Owner->player == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EffectTics <= BLINKTHRESHOLD || Owner->player->fixedcolormap >= NUMCOLORMAPS)
|
||||
{
|
||||
Super::DoEffect ();
|
||||
}
|
||||
else if (!(level.time & 16) && Owner->player != NULL)
|
||||
else
|
||||
{
|
||||
if (NewTorch != 0)
|
||||
APowerup::DoEffect ();
|
||||
|
||||
if (!(level.time & 16) && Owner->player != NULL)
|
||||
{
|
||||
if (Owner->player->fixedcolormap + NewTorchDelta > 7
|
||||
|| Owner->player->fixedcolormap + NewTorchDelta < 1
|
||||
|| NewTorch == Owner->player->fixedcolormap)
|
||||
if (NewTorch != 0)
|
||||
{
|
||||
NewTorch = 0;
|
||||
if (Owner->player->fixedcolormap + NewTorchDelta > 7
|
||||
|| Owner->player->fixedcolormap + NewTorchDelta < 1
|
||||
|| NewTorch == Owner->player->fixedcolormap)
|
||||
{
|
||||
NewTorch = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner->player->fixedcolormap += NewTorchDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner->player->fixedcolormap += NewTorchDelta;
|
||||
NewTorch = (pr_torch() & 7) + 1;
|
||||
NewTorchDelta = (NewTorch == Owner->player->fixedcolormap) ?
|
||||
0 : ((NewTorch > Owner->player->fixedcolormap) ? 1 : -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewTorch = (pr_torch() & 7) + 1;
|
||||
NewTorchDelta = (NewTorch == Owner->player->fixedcolormap) ?
|
||||
0 : ((NewTorch > Owner->player->fixedcolormap) ? 1 : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,13 +860,16 @@ void APowerFlight::InitEffect ()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerFlight::DoEffect ()
|
||||
void APowerFlight::Tick ()
|
||||
{
|
||||
// The Wings of Wrath only expire in multiplayer and non-hub games
|
||||
if (!multiplayer && (level.clusterflags & CLUSTER_HUB))
|
||||
{
|
||||
EffectTics++;
|
||||
}
|
||||
|
||||
Super::Tick ();
|
||||
|
||||
// Owner->flags |= MF_NOGRAVITY;
|
||||
// Owner->flags2 |= MF2_FLY;
|
||||
}
|
||||
|
@ -1026,6 +1068,8 @@ void APowerSpeed::InitEffect ()
|
|||
|
||||
void APowerSpeed::DoEffect ()
|
||||
{
|
||||
Super::DoEffect ();
|
||||
|
||||
if (Owner->player->cheats & CF_PREDICTING)
|
||||
return;
|
||||
|
||||
|
@ -1117,11 +1161,9 @@ void APowerTargeter::InitEffect ()
|
|||
|
||||
void APowerTargeter::DoEffect ()
|
||||
{
|
||||
if (Owner == NULL)
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
else if (Owner->player != NULL)
|
||||
Super::DoEffect ();
|
||||
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
player_t *player = Owner->player;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
PalEntry GetBlend ();
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void DoEffect ();
|
||||
void Tick ();
|
||||
bool HandlePickup (AInventory *item);
|
||||
};
|
||||
|
||||
|
@ -88,6 +88,7 @@ class APowerInvisibility : public APowerup
|
|||
DECLARE_STATELESS_ACTOR (APowerInvisibility, APowerup)
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void DoEffect ();
|
||||
void EndEffect ();
|
||||
void AlterWeaponSprite (vissprite_t *vis);
|
||||
};
|
||||
|
@ -148,7 +149,7 @@ public:
|
|||
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void DoEffect ();
|
||||
void Tick ();
|
||||
void EndEffect ();
|
||||
|
||||
bool HitCenterFrame;
|
||||
|
|
|
@ -492,6 +492,19 @@ void AInventory::BeginPlay ()
|
|||
flags |= MF_DROPPED; // [RH] Items are dropped by default
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: DoEffect
|
||||
//
|
||||
// Handles any effect an item might apply to its owner
|
||||
// Normally only used by subclasses of APowerup
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AInventory::DoEffect ()
|
||||
{
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: Travelled
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
virtual void DoPickupSpecial (AActor *toucher);
|
||||
virtual bool SpecialDropAction (AActor *dropper);
|
||||
virtual bool DrawPowerup (int x, int y);
|
||||
virtual void DoEffect ();
|
||||
|
||||
virtual const char *PickupMessage ();
|
||||
virtual void PlayPickupSound (AActor *toucher);
|
||||
|
|
|
@ -316,7 +316,7 @@ void A_Tracer2 (AActor *self)
|
|||
|
||||
dest = self->tracer;
|
||||
|
||||
if (dest == NULL || dest->health <= 0)
|
||||
if (dest == NULL || dest->health <= 0 || self->Speed == 0)
|
||||
return;
|
||||
|
||||
// change angle
|
||||
|
|
|
@ -1,163 +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 "a_doomglobal.h"
|
||||
#include "templates.h"
|
||||
|
||||
void A_Pain (AActor *);
|
||||
void A_PlayerScream (AActor *);
|
||||
void A_XXScream (AActor *);
|
||||
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 ---------------------------------------------------------------
|
||||
|
||||
class AStrifePlayer : public APlayerPawn
|
||||
{
|
||||
DECLARE_ACTOR (AStrifePlayer, APlayerPawn)
|
||||
public:
|
||||
void GiveDefaultInventory ();
|
||||
void TweakSpeeds (int &forward, int &side);
|
||||
};
|
||||
|
||||
FState AStrifePlayer::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_NORMAL (PLAY, 'F', 6, NULL , &States[S_PLAY_ATK+0]),
|
||||
|
||||
#define S_PLAY_PAIN (S_PLAY_ATK+2)
|
||||
S_NORMAL (PLAY, 'Q', 4, NULL , &States[S_PLAY_PAIN+1]),
|
||||
S_NORMAL (PLAY, 'Q', 4, A_Pain , &States[S_PLAY]),
|
||||
|
||||
#define S_PLAY_DIE (S_PLAY_PAIN+2)
|
||||
S_NORMAL (PLAY, 'H', 3, NULL , &States[S_PLAY_DIE+1]),
|
||||
S_NORMAL (PLAY, 'I', 3, A_PlayerScream , &States[S_PLAY_DIE+2]),
|
||||
S_NORMAL (PLAY, 'J', 3, A_NoBlocking , &States[S_PLAY_DIE+3]),
|
||||
S_NORMAL (PLAY, 'K', 4, NULL , &States[S_PLAY_DIE+4]),
|
||||
S_NORMAL (PLAY, 'L', 4, NULL , &States[S_PLAY_DIE+5]),
|
||||
S_NORMAL (PLAY, 'M', 4, NULL , &States[S_PLAY_DIE+6]),
|
||||
S_NORMAL (PLAY, 'N', 4, NULL , &States[S_PLAY_DIE+7]),
|
||||
S_NORMAL (PLAY, 'O', 4, NULL , &States[S_PLAY_DIE+8]),
|
||||
S_NORMAL (PLAY, 'P', 700, NULL , &States[S_PLAY_DIE+9+7]),
|
||||
|
||||
#define S_PLAY_XDIE (S_PLAY_DIE+9)
|
||||
S_NORMAL (RGIB, 'A', 5, A_TossGib , &States[S_PLAY_XDIE+1]),
|
||||
S_NORMAL (RGIB, 'B', 5, A_XXScream , &States[S_PLAY_XDIE+2]),
|
||||
S_NORMAL (RGIB, 'C', 5, A_NoBlocking , &States[S_PLAY_XDIE+3]),
|
||||
S_NORMAL (RGIB, 'D', 5, A_TossGib , &States[S_PLAY_XDIE+4]),
|
||||
S_NORMAL (RGIB, 'E', 5, A_TossGib , &States[S_PLAY_XDIE+5]),
|
||||
S_NORMAL (RGIB, 'F', 5, A_TossGib , &States[S_PLAY_XDIE+6]),
|
||||
S_NORMAL (RGIB, 'G', 5, A_TossGib , &States[S_PLAY_XDIE+7]),
|
||||
S_NORMAL (RGIB, 'H', -1, A_TossGib , NULL),
|
||||
|
||||
// [RH] These weren't bright in Strife, but I think they should be.
|
||||
// (After all, they are now a light source.)
|
||||
#define S_PLAY_BURNDEATH (S_PLAY_XDIE+8)
|
||||
S_BRIGHT (BURN, 'A', 3, A_ItBurnsItBurns, &States[S_PLAY_BURNDEATH+1]),
|
||||
S_BRIGHT (BURN, 'B', 3, A_DropFire, &States[S_PLAY_BURNDEATH+2]),
|
||||
S_BRIGHT (BURN, 'C', 3, A_Wander, &States[S_PLAY_BURNDEATH+3]),
|
||||
S_BRIGHT (BURN, 'D', 3, A_NoBlocking, &States[S_PLAY_BURNDEATH+4]),
|
||||
S_BRIGHT (BURN, 'E', 5, A_DropFire, &States[S_PLAY_BURNDEATH+5]),
|
||||
S_BRIGHT (BURN, 'F', 5, A_Wander, &States[S_PLAY_BURNDEATH+6]),
|
||||
S_BRIGHT (BURN, 'G', 5, A_Wander, &States[S_PLAY_BURNDEATH+7]),
|
||||
S_BRIGHT (BURN, 'H', 5, A_Wander, &States[S_PLAY_BURNDEATH+8]),
|
||||
S_BRIGHT (BURN, 'I', 5, A_DropFire, &States[S_PLAY_BURNDEATH+9]),
|
||||
S_BRIGHT (BURN, 'J', 5, A_Wander, &States[S_PLAY_BURNDEATH+10]),
|
||||
S_BRIGHT (BURN, 'K', 5, A_Wander, &States[S_PLAY_BURNDEATH+11]),
|
||||
S_BRIGHT (BURN, 'L', 5, A_Wander, &States[S_PLAY_BURNDEATH+12]),
|
||||
S_BRIGHT (BURN, 'M', 3, A_DropFire, &States[S_PLAY_BURNDEATH+13]),
|
||||
S_BRIGHT (BURN, 'N', 3, A_CrispyPlayer, &States[S_PLAY_BURNDEATH+14]),
|
||||
S_BRIGHT (BURN, 'O', 5, NULL, &States[S_PLAY_BURNDEATH+15]),
|
||||
S_BRIGHT (BURN, 'P', 5, NULL, &States[S_PLAY_BURNDEATH+16]),
|
||||
S_BRIGHT (BURN, 'Q', 5, NULL, &States[S_PLAY_BURNDEATH+17]),
|
||||
S_BRIGHT (BURN, 'P', 5, NULL, &States[S_PLAY_BURNDEATH+18]),
|
||||
S_BRIGHT (BURN, 'Q', 5, NULL, &States[S_PLAY_BURNDEATH+19]),
|
||||
S_BRIGHT (BURN, 'R', 7, NULL, &States[S_PLAY_BURNDEATH+20]),
|
||||
S_BRIGHT (BURN, 'S', 7, NULL, &States[S_PLAY_BURNDEATH+21]),
|
||||
S_BRIGHT (BURN, 'T', 7, NULL, &States[S_PLAY_BURNDEATH+22]),
|
||||
S_BRIGHT (BURN, 'U', 7, NULL, &States[S_PLAY_BURNDEATH+23]),
|
||||
S_NORMAL (BURN, 'V',-1, NULL, NULL),
|
||||
|
||||
#define S_PLAY_ZAPDEATH (S_PLAY_BURNDEATH+24)
|
||||
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]),
|
||||
S_NORMAL (DISR, 'E', 5, NULL, &States[S_PLAY_ZAPDEATH+5]),
|
||||
S_NORMAL (DISR, 'F', 5, NULL, &States[S_PLAY_ZAPDEATH+6]),
|
||||
S_NORMAL (DISR, 'G', 4, NULL, &States[S_PLAY_ZAPDEATH+7]),
|
||||
S_NORMAL (DISR, 'H', 4, NULL, &States[S_PLAY_ZAPDEATH+8]),
|
||||
S_NORMAL (DISR, 'I', 4, NULL, &States[S_PLAY_ZAPDEATH+9]),
|
||||
S_NORMAL (DISR, 'J', 4, NULL, &States[S_PLAY_ZAPDEATH+10]),
|
||||
S_NORMAL (MEAT, 'D',-1, NULL, NULL)
|
||||
};
|
||||
|
||||
IMPLEMENT_ACTOR (AStrifePlayer, Strife, -1, 0)
|
||||
PROP_SpawnHealth (100)
|
||||
PROP_RadiusFixed (18)
|
||||
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_SLIDE|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_FLOORCLIP)
|
||||
PROP_Flags3 (MF3_NOBLOCKMONST)
|
||||
PROP_MaxStepHeight (16)
|
||||
|
||||
PROP_SpawnState (S_PLAY)
|
||||
PROP_SeeState (S_PLAY_RUN)
|
||||
PROP_PainState (S_PLAY_PAIN)
|
||||
PROP_MissileState (S_PLAY_ATK)
|
||||
PROP_MeleeState (S_PLAY_ATK+1)
|
||||
PROP_DeathState (S_PLAY_DIE)
|
||||
PROP_XDeathState (S_PLAY_XDIE)
|
||||
PROP_BDeathState (S_PLAY_BURNDEATH)
|
||||
PROP_EDeathState (S_PLAY_ZAPDEATH)
|
||||
|
||||
// [GRB]
|
||||
PROP_PlayerPawn_ColorRange (96, 111)
|
||||
PROP_PlayerPawn_DisplayName ("Rebel")
|
||||
END_DEFAULTS
|
||||
|
||||
void AStrifePlayer::GiveDefaultInventory ()
|
||||
{
|
||||
Super::GiveDefaultInventory ();
|
||||
|
||||
if (!Inventory)
|
||||
{
|
||||
AWeapon *weapon;
|
||||
|
||||
player->health = GetDefault()->health;
|
||||
weapon = static_cast<AWeapon *>(player->mo->GiveInventoryType (PClass::FindClass ("PunchDagger")));
|
||||
player->ReadyWeapon = player->PendingWeapon = weapon;
|
||||
}
|
||||
}
|
||||
|
||||
void AStrifePlayer::TweakSpeeds (int &forward, int &side)
|
||||
{
|
||||
if (health<=10)
|
||||
{
|
||||
forward = clamp(forward, -0x1900, 0x1900);
|
||||
side = clamp(side, -0x1800, 0x1800);
|
||||
}
|
||||
Super::TweakSpeeds (forward, side);
|
||||
}
|
|
@ -288,10 +288,16 @@ static void DoTakeInv (AActor *actor, const PClass *info, int amount)
|
|||
item->Amount -= amount;
|
||||
if (item->Amount <= 0)
|
||||
{
|
||||
// If it's not ammo, destroy it. Ammo needs to stick around, even
|
||||
// when it's zero for the benefit of the weapons that use it and
|
||||
// to maintain the maximum ammo amounts a backpack might have given.
|
||||
if (item->GetClass()->ParentClass != RUNTIME_CLASS(AAmmo))
|
||||
// If it's not ammo or an internal armor, destroy it.
|
||||
// Ammo needs to stick around, even when it's zero for the benefit
|
||||
// of the weapons that use it and to maintain the maximum ammo
|
||||
// amounts a backpack might have given.
|
||||
// Armor shouldn't be removed because they only work properly when
|
||||
// they are the last items in the inventory.
|
||||
if (item->GetClass()->ParentClass != RUNTIME_CLASS(AAmmo) &&
|
||||
item->GetClass() != RUNTIME_CLASS(ABasicArmor) &&
|
||||
item->GetClass() != RUNTIME_CLASS(AHexenArmor)
|
||||
)
|
||||
{
|
||||
item->Destroy ();
|
||||
}
|
||||
|
|
|
@ -2486,6 +2486,16 @@ void AActor::Tick ()
|
|||
PrevY = y;
|
||||
PrevZ = z;
|
||||
|
||||
AInventory * item = Inventory;
|
||||
|
||||
// Handle powerup effects here so that the order is controlled
|
||||
// by the order in the inventory, not the order in the thinker table
|
||||
while (item != NULL && item->Owner == this)
|
||||
{
|
||||
item->DoEffect();
|
||||
item = item->Inventory;
|
||||
}
|
||||
|
||||
if (flags & MF_UNMORPHED)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -142,6 +142,9 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog)
|
|||
Spawn<ATeleportFog> (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
}
|
||||
source->PrevX=x;
|
||||
source->PrevY=y;
|
||||
source->PrevZ=z;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -400,6 +400,7 @@ void APlayerPawn::Serialize (FArchive &arc)
|
|||
|
||||
arc << JumpZ
|
||||
<< MaxHealth
|
||||
<< RunHealth
|
||||
<< SpawnMask
|
||||
<< ForwardMove1
|
||||
<< ForwardMove2
|
||||
|
@ -874,6 +875,32 @@ void APlayerPawn::GiveDefaultInventory ()
|
|||
// [GRB] Give inventory specified in DECORATE
|
||||
player->health = GetDefault ()->health;
|
||||
|
||||
// HexenArmor must always be the first item in the inventory because
|
||||
// it provides player class based protection that should not affect
|
||||
// any other protection item.
|
||||
fixed_t hx[5];
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
hx[i] = GetClass()->Meta.GetMetaFixed(APMETA_Hexenarmor0+i);
|
||||
}
|
||||
GiveInventoryType (RUNTIME_CLASS(AHexenArmor));
|
||||
AHexenArmor *harmor = FindInventory<AHexenArmor>();
|
||||
harmor->Slots[4] = hx[0];
|
||||
harmor->SlotsIncrement[0] = hx[1];
|
||||
harmor->SlotsIncrement[1] = hx[2];
|
||||
harmor->SlotsIncrement[2] = hx[3];
|
||||
harmor->SlotsIncrement[3] = hx[4];
|
||||
|
||||
// BasicArmor must come right after that. It should not affect any
|
||||
// other protection item as well but needs to process the damage
|
||||
// before the HexenArmor does.
|
||||
ABasicArmor *barmor = Spawn<ABasicArmor> (0,0,0, NO_REPLACE);
|
||||
barmor->BecomeItem ();
|
||||
barmor->SavePercent = 0;
|
||||
barmor->Amount = 0;
|
||||
AddInventory (barmor);
|
||||
|
||||
// Now add the items from the DECORATE definition
|
||||
FDropItem *di = GetDropItems(RUNTIME_TYPE(this));
|
||||
|
||||
while (di)
|
||||
|
@ -913,26 +940,6 @@ void APlayerPawn::GiveDefaultInventory ()
|
|||
}
|
||||
di = di->Next;
|
||||
}
|
||||
|
||||
fixed_t hx[5];
|
||||
bool ishx=false;
|
||||
|
||||
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 ()
|
||||
|
@ -1038,6 +1045,13 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
|
||||
void APlayerPawn::TweakSpeeds (int &forward, int &side)
|
||||
{
|
||||
// Strife's player can't run when its healh is below 10
|
||||
if (health <= RunHealth)
|
||||
{
|
||||
forward = clamp(forward, -0x1900, 0x1900);
|
||||
side = clamp(side, -0x1800, 0x1800);
|
||||
}
|
||||
|
||||
// [GRB]
|
||||
if ((unsigned int)(forward + 0x31ff) < 0x63ff)
|
||||
{
|
||||
|
|
|
@ -3900,6 +3900,15 @@ static void PlayerMaxHealth (APlayerPawn *defaults, Baggage &bag)
|
|||
defaults->MaxHealth = sc_Number;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
static void PlayerRunHealth (APlayerPawn *defaults, Baggage &bag)
|
||||
{
|
||||
SC_MustGetNumber ();
|
||||
defaults->RunHealth = sc_Number;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -4134,6 +4143,7 @@ static const ActorProps props[] =
|
|||
{ "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.runhealth", (apf)PlayerRunHealth, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.scoreicon", (apf)PlayerScoreIcon, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.sidemove", (apf)PlayerSideMove, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.soundclass", (apf)PlayerSoundClass, RUNTIME_CLASS(APlayerPawn) },
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "actors/hexen/centaur.txt"
|
||||
#include "actors/hexen/demons.txt"
|
||||
|
||||
#include "actors/strife/strifeplayer.txt"
|
||||
#include "actors/strife/beggars.txt"
|
||||
#include "actors/strife/merchants.txt"
|
||||
#include "actors/strife/peasants.txt"
|
||||
|
|
72
wadsrc/decorate/strife/strifeplayer.txt
Normal file
72
wadsrc/decorate/strife/strifeplayer.txt
Normal file
|
@ -0,0 +1,72 @@
|
|||
// The player ---------------------------------------------------------------
|
||||
|
||||
ACTOR StrifePlayer : PlayerPawn
|
||||
{
|
||||
Health 100
|
||||
Radius 18
|
||||
Height 56
|
||||
Mass 100
|
||||
PainChance 255
|
||||
Speed 1
|
||||
MaxStepHeight 16
|
||||
Player.ColorRange 96, 111
|
||||
Player.DisplayName "Rebel"
|
||||
Player.StartItem "PunchDagger"
|
||||
|
||||
action native A_ItBurnsItBurns();
|
||||
action native A_DropFire();
|
||||
action native A_CrispyPlayer();
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
PLAY A -1
|
||||
stop
|
||||
See:
|
||||
PLAY ABCD 4
|
||||
loop
|
||||
Missile:
|
||||
PLAY E 12
|
||||
goto Spawn
|
||||
Melee:
|
||||
PLAY F 6
|
||||
goto Missile
|
||||
Death:
|
||||
PLAY H 3
|
||||
PLAY I 3 A_PlayerScream
|
||||
PLAY J 3 A_NoBlocking
|
||||
PLAY KLMNO 4
|
||||
PLAY P -1
|
||||
Stop
|
||||
XDeath:
|
||||
RGIB A 5 A_TossGib
|
||||
RGIB B 5 A_XScream
|
||||
RGIB C 5 A_NoBlocking
|
||||
RGIB DEFG 5 A_TossGib
|
||||
RGIB H -1 A_TossGib
|
||||
Burn:
|
||||
BURN A 3 Bright A_ItBurnsItBurns
|
||||
BURN B 3 Bright A_DropFire
|
||||
BURN C 3 Bright A_Wander
|
||||
BURN D 3 Bright A_NoBlocking
|
||||
BURN E 5 Bright A_DropFire
|
||||
BURN FGH 5 Bright A_Wander
|
||||
BURN I 5 Bright A_DropFire
|
||||
BURN JKL 5 Bright A_Wander
|
||||
BURN M 5 Bright A_DropFire
|
||||
BURN N 5 Bright A_CrispyPlayer
|
||||
BURN OPQPQ 5 Bright
|
||||
BURN RSTU 7 Bright
|
||||
BURN V -1
|
||||
Stop
|
||||
Disintegrate:
|
||||
DISR A 5 A_PlaySoundEx("misc/disruptordeath", "Voice")
|
||||
DISR BC 5
|
||||
DISR D 5 A_NoBlocking
|
||||
DISR EF 5
|
||||
DISR GHIJ 4
|
||||
MEAT D -1
|
||||
Stop
|
||||
}
|
||||
}
|
||||
|
|
@ -312,6 +312,7 @@ actors/hexen/ettin.txt decorate/hexen/ettin.txt
|
|||
actors/hexen/centaur.txt decorate/hexen/centaur.txt
|
||||
actors/hexen/demons.txt decorate/hexen/demons.txt
|
||||
|
||||
actors/strife/strifeplayer.txt decorate/strife/strifeplayer.txt
|
||||
actors/strife/beggars.txt decorate/strife/beggars.txt
|
||||
actors/strife/merchants.txt decorate/strife/merchants.txt
|
||||
actors/strife/peasants.txt decorate/strife/peasants.txt
|
||||
|
|
1246
zdoom.vcproj
1246
zdoom.vcproj
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue