diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 74b6e584c8..bcc61e95a5 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,5 @@ June 30, 2009 +- Added Gez's PowerInvisibility changes. - Fixed: clearflags did not clear flags6. - Added A_SetAngle, A_SetPitch, A_ScaleVelocity, and A_ChangeVelocity. - Enough with this "momentum" garbage. What Doom calls "momentum" is really diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 4d36e34fd0..82bb719d74 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -22,6 +22,9 @@ static FRandom pr_torch ("Torch"); +/* Those are no longer needed, except maybe as reference? + * They're not used anywhere in the code anymore, except + * MAULATORTICS as redefined in a_minotaur.cpp... #define INVULNTICS (30*TICRATE) #define INVISTICS (60*TICRATE) #define INFRATICS (120*TICRATE) @@ -31,6 +34,7 @@ static FRandom pr_torch ("Torch"); #define SPEEDTICS (45*TICRATE) #define MAULATORTICS (25*TICRATE) #define TIMEFREEZE_TICS ( 12 * TICRATE ) +*/ EXTERN_CVAR (Bool, r_drawfuzz); @@ -58,9 +62,13 @@ bool APowerupGiver::Use (bool pickup) { power->BlendColor = BlendColor; } - if (mode != NAME_None) + if (Mode != NAME_None) { - power->mode = mode; + power->Mode = Mode; + } + if (Strength != 0) + { + power->Strength = Strength; } power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME); @@ -82,7 +90,11 @@ void APowerupGiver::Serialize (FArchive &arc) { Super::Serialize (arc); arc << PowerupType; - arc << EffectTics << BlendColor << mode; + arc << EffectTics << BlendColor << Mode; + if (SaveVersion >= 1693) + { + arc << Strength; + } } // Powerup ------------------------------------------------------------------- @@ -115,7 +127,11 @@ void APowerup::Tick () void APowerup::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << EffectTics << BlendColor << mode; + arc << EffectTics << BlendColor << Mode; + if (SaveVersion >= 1693) + { + arc << Strength; + } } //=========================================================================== @@ -356,11 +372,14 @@ void APowerInvulnerable::InitEffect () { Owner->effects &= ~FX_RESPAWNINVUL; Owner->flags2 |= MF2_INVULNERABLE; - if (mode == NAME_None) + if (Mode == NAME_None) { - mode = (ENamedName)RUNTIME_TYPE(Owner)->Meta.GetMetaInt(APMETA_InvulMode); + Mode = (ENamedName)RUNTIME_TYPE(Owner)->Meta.GetMetaInt(APMETA_InvulMode); + } + if (Mode == NAME_Reflective) + { + Owner->flags2 |= MF2_REFLECTIVE; } - if (mode == NAME_Reflective) Owner->flags2 |= MF2_REFLECTIVE; } //=========================================================================== @@ -378,7 +397,7 @@ void APowerInvulnerable::DoEffect () return; } - if (mode == NAME_Ghost) + if (Mode == NAME_Ghost) { if (!(Owner->flags & MF_SHADOW)) { @@ -432,7 +451,7 @@ void APowerInvulnerable::EndEffect () Owner->flags2 &= ~MF2_INVULNERABLE; Owner->effects &= ~FX_RESPAWNINVUL; - if (mode == NAME_Ghost) + if (Mode == NAME_Ghost) { Owner->flags2 &= ~MF2_NONSHOOTABLE; if (!(Owner->flags & MF_SHADOW)) @@ -443,7 +462,7 @@ void APowerInvulnerable::EndEffect () Owner->alpha = OPAQUE; } } - else if (mode == NAME_Reflective) + else if (Mode == NAME_Reflective) { Owner->flags2 &= ~MF2_REFLECTIVE; } @@ -465,7 +484,7 @@ int APowerInvulnerable::AlterWeaponSprite (vissprite_t *vis) int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis); if (Owner != NULL) { - if (mode == NAME_Ghost && !(Owner->flags & MF_SHADOW)) + if (Mode == NAME_Ghost && !(Owner->flags & MF_SHADOW)) { fixed_t wp_alpha = MIN(FRACUNIT/4 + Owner->alpha*3/4, FRACUNIT); if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha; @@ -541,6 +560,7 @@ PalEntry APowerStrength::GetBlend () // Invisibility Powerup ------------------------------------------------------ IMPLEMENT_CLASS (APowerInvisibility) +IMPLEMENT_CLASS (APowerShadow) //=========================================================================== // @@ -555,9 +575,20 @@ void APowerInvisibility::CommonInit() if (Owner != NULL) { Owner->flags |= MF_SHADOW; - // transfer seeker missile blocking (but only if the owner does not already have this flag - if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK; - else flags5 &= ~MF5_CANTSEEK; + fixed_t ts = MIN(Strength * (special1 + 1), FRACUNIT); + Owner->alpha = clamp((OPAQUE - ts), 0, OPAQUE); + Owner->RenderStyle = (Mode == NAME_Fuzzy ? STYLE_OptFuzzy : STYLE_Translucent); + // CommonInit() is called every tic by DoEffect, so the flag trick must happen only once! + if (special2 == 0) + { + // transfer seeker missile blocking (but only if the owner does not already have this flag + if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK; + else flags5 &= ~MF5_CANTSEEK; + // transfer ghost flag likewise + if (!(Owner->flags3 & MF3_GHOST) && (flags3 & MF3_GHOST)) Owner->flags3 |= MF3_GHOST; + else flags3 &= ~MF3_GHOST; + special2 = 1; + } } } @@ -570,8 +601,6 @@ void APowerInvisibility::CommonInit() void APowerInvisibility::InitEffect () { CommonInit(); - Owner->alpha = FRACUNIT/5; - Owner->RenderStyle = STYLE_OptFuzzy; } //=========================================================================== @@ -598,8 +627,8 @@ void APowerInvisibility::EndEffect () if (Owner != NULL) { if (flags5 & MF5_CANTSEEK) Owner->flags5 &= ~MF5_CANTSEEK; + if (flags3 & MF3_GHOST) Owner->flags3 &= ~MF3_GHOST; Owner->flags &= ~MF_SHADOW; - Owner->flags3 &= ~MF3_GHOST; Owner->RenderStyle = STYLE_Normal; Owner->alpha = OPAQUE; @@ -627,82 +656,41 @@ void APowerInvisibility::EndEffect () int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis) { int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis); - // Blink if the powerup is wearing off if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) { vis->RenderStyle = STYLE_Normal; + vis->alpha = OPAQUE; return 1; } else if (changed == 1) { // something else set the weapon sprite back to opaque but this item is still active. - vis->alpha = FRACUNIT/5; - vis->RenderStyle = STYLE_OptFuzzy; + fixed_t ts = MIN(Strength * (special1 + 1), FRACUNIT); + vis->alpha = clamp((OPAQUE - ts), 0, OPAQUE); + vis->RenderStyle = (Mode == NAME_Fuzzy ? STYLE_OptFuzzy : STYLE_Translucent); + } + // Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible + if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) + { + vis->alpha = clamp((OPAQUE - Strength), 0, OPAQUE); + vis->colormap = InverseColormap; } return -1; // This item is valid so another one shouldn't reset the translucency } -// Ghost Powerup (Heretic's version of invisibility) ------------------------- - -IMPLEMENT_CLASS (APowerGhost) - //=========================================================================== // -// APowerGhost :: InitEffect +// APowerInvisibility :: HandlePickup +// +// If the player already has the first stage of a cumulative powerup, getting +// it again increases the player's alpha. (But shouldn't this be in Use()?) // //=========================================================================== -void APowerGhost::InitEffect () +bool APowerInvisibility::HandlePickup (AInventory *item) { - CommonInit(); - Owner->flags3 |= MF3_GHOST; - Owner->alpha = HR_SHADOW; - Owner->RenderStyle = STYLE_Translucent; -} - -//=========================================================================== -// -// APowerGhost :: AlterWeaponSprite -// -//=========================================================================== - -int APowerGhost::AlterWeaponSprite (vissprite_t *vis) -{ - int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis); - - // Blink if the powerup is wearing off - if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) - { - vis->RenderStyle = STYLE_Normal; - return 1; - } - else if (changed == 1) - { - // something else set the weapon sprite back to opaque but this item is still active. - vis->alpha = HR_SHADOW; - vis->RenderStyle = STYLE_Translucent; - } - return -1; // This item is valid so another one shouldn't reset the translucency -} - -// Shadow Powerup (Strife's version of invisibility) ------------------------- - -IMPLEMENT_CLASS (APowerShadow) - -//=========================================================================== -// -// APowerShadow :: HandlePickup -// -// If the player already has the first stage of the powerup, getting it -// again makes them completely invisible. Special1 tracks which stage we -// are in, initially 0. -// -//=========================================================================== - -bool APowerShadow::HandlePickup (AInventory *item) -{ - if (special1 == 0 && item->GetClass() == GetClass()) + if (Mode == NAME_Cumulative && ((Strength * special1) < FRACUNIT) && item->GetClass() == GetClass()) { APowerup *power = static_cast(item); if (power->EffectTics == 0) @@ -717,56 +705,13 @@ bool APowerShadow::HandlePickup (AInventory *item) EffectTics = power->EffectTics; BlendColor = power->BlendColor; } - special1 = 1; // Go to stage 2. + special1++; // increases power power->ItemFlags |= IF_PICKUPGOOD; return true; } return Super::HandlePickup (item); } -//=========================================================================== -// -// APowerShadow :: InitEffect -// -//=========================================================================== - -void APowerShadow::InitEffect () -{ - CommonInit(); - Owner->alpha = special1 == 0 ? TRANSLUC25 : 0; - Owner->RenderStyle = STYLE_Translucent; -} - -//=========================================================================== -// -// APowerShadow :: AlterWeaponSprite -// -//=========================================================================== - -int APowerShadow::AlterWeaponSprite (vissprite_t *vis) -{ - int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis); - - // Blink if the powerup is wearing off - if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) - { - vis->RenderStyle = STYLE_Normal; - return 1; - } - else if (changed == 1) - { - // something else set the weapon sprite back to opaque but this item is still active. - vis->alpha = TRANSLUC25; - vis->RenderStyle = STYLE_Translucent; - } - if (special1 == 1) - { - vis->alpha = TRANSLUC25; - vis->colormap = InverseColormap; - } - return -1; // This item is valid so another one shouldn't reset the translucency -} - // Ironfeet Powerup ---------------------------------------------------------- IMPLEMENT_CLASS (APowerIronFeet) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 28af16e44f..c6a4098ab2 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -30,7 +30,8 @@ public: int EffectTics; PalEntry BlendColor; - FNameNoInit mode; + FNameNoInit Mode; + fixed_t Strength; protected: virtual void InitEffect (); @@ -49,7 +50,8 @@ 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 + FNameNoInit Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility + fixed_t Strength; // Meaning depends on powerup - currently used only by Invisibility }; class APowerInvulnerable : public APowerup @@ -77,6 +79,7 @@ class APowerInvisibility : public APowerup { DECLARE_CLASS (APowerInvisibility, APowerup) protected: + bool HandlePickup (AInventory *item); void CommonInit (); void InitEffect (); void DoEffect (); @@ -84,21 +87,10 @@ protected: int AlterWeaponSprite (vissprite_t *vis); }; -class APowerGhost : public APowerInvisibility -{ - DECLARE_CLASS (APowerGhost, APowerInvisibility) -protected: - void InitEffect (); - int AlterWeaponSprite (vissprite_t *vis); -}; - +// Needed only for m_cheat.cpp now class APowerShadow : public APowerInvisibility { DECLARE_CLASS (APowerShadow, APowerInvisibility) -protected: - bool HandlePickup (AInventory *item); - void InitEffect (); - int AlterWeaponSprite (vissprite_t *vis); }; class APowerIronFeet : public APowerup diff --git a/src/namedef.h b/src/namedef.h index b16e2212f6..e37c28728d 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -24,6 +24,10 @@ xx(Spray) xx(Ghost) xx(Reflective) +// Invisibility types +xx(Cumulative) +xx(Fuzzy) + // Healingradius types xx(Mana) xx(Armor) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 3531b517a9..be2c5e50e3 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1613,10 +1613,49 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory) //========================================================================== // //========================================================================== -DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, PowerupGiver) +DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) +{ + fixed_t *pStrength; + + if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup))) + { + pStrength = &((APowerup*)defaults)->Strength; + } + else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver))) + { + pStrength = &((APowerupGiver*)defaults)->Strength; + } + else + { + I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n"); + return; + } + // Puts a percent value in the 0.0..1.0 range + PROP_FIXED_PARM(f, 0); + *pStrength = f / 100; +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, Inventory) { PROP_STRING_PARM(str, 0); - defaults->mode = (FName)str; + FName *pMode; + if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup))) + { + pMode = &((APowerup*)defaults)->Mode; + } + else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver))) + { + pMode = &((APowerupGiver*)defaults)->Mode; + } + else + { + I_Error("\"powerup.mode\" requires an actor of type \"Powerup\"\n"); + return; + } + *pMode = (FName)str; } //========================================================================== diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 07630a0cd3..68b98ff32e 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -161,14 +161,24 @@ ACTOR PowerStrength : Powerup native ACTOR PowerInvisibility : Powerup native { Powerup.Duration -60 + Powerup.Strength 80 + Powerup.Mode "Fuzzy" } -ACTOR PowerGhost : PowerInvisibility native {} +ACTOR PowerGhost : PowerInvisibility +{ + +GHOST + Powerup.Duration -60 + Powerup.Strength 60 + Powerup.Mode "None" +} ACTOR PowerShadow : PowerInvisibility native { - Powerup.Duration -55 +INVENTORY.HUBPOWER + Powerup.Duration -55 + Powerup.Strength 75 + Powerup.Mode "Cumulative" } ACTOR PowerIronFeet : Powerup native