- 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:
Christoph Oelckers 2007-01-12 15:24:10 +00:00
commit 3c976ac02c
19 changed files with 857 additions and 818 deletions

View file

@ -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;