diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 1e6c11d57..a5f979076 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,7 @@ May 1, 2007 (Changes by Graf Zahl) +- Fixed: player_t::Powers was not saved in a savegame. +- Removed all unused PW_* player power flags. +- Added Skulltag's TimeFreezer powerup. - Moved most of the menu strings (except options and player setup menu) into the string table. diff --git a/src/b_func.cpp b/src/b_func.cpp index cd15645df..e77761bc5 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -429,8 +429,8 @@ AActor *DCajunMaster::Find_enemy (AActor *bot) //Too dark? if (temp > DARK_DIST && - client->mo->Sector->lightlevel < WHATS_DARK && - bot->player->Powers & PW_INFRARED) + client->mo->Sector->lightlevel < WHATS_DARK /*&& + bot->player->Powers & PW_INFRARED*/) continue; if (temp < closest_dist) diff --git a/src/d_player.h b/src/d_player.h index 04db087e5..3f57f3dc6 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -168,17 +168,9 @@ typedef enum enum { - PW_INVULNERABILITY = 1, - PW_INVISIBILITY = 2, - PW_INFRARED = 4, - -// Powerups added in Heretic - PW_WEAPONLEVEL2 = 8, - PW_FLIGHT = 16, - -// Powerups added in Hexen - PW_SPEED = 32, - PW_MINOTAUR = 64, + PW_SPEED = 1, + PW_TIMEFREEZE = 2, +// }; #define WP_NOCHANGE ((AWeapon*)~0) diff --git a/src/g_level.h b/src/g_level.h index 9ca4bbfba..992e36fdd 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -94,7 +94,7 @@ #define LEVEL_LAXACTIVATIONMAPINFO UCONST64(0x800000000) // LEVEL_LAXMONSTERACTIVATION is not a default. #define LEVEL_MISSILESACTIVATEIMPACT UCONST64(0x1000000000) // Missiles are the activators of SPAC_IMPACT events, not their shooters -// an unused bit here! +#define LEVEL_FROZEN UCONST64(0x2000000000) // Game is frozen by a TimeFreezer #define LEVEL_KEEPFULLINVENTORY UCONST64(0x4000000000) // doesn't reduce the amount of inventory items to 1 diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 46287e68d..da5baccb4 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -27,6 +27,7 @@ static FRandom pr_torch ("Torch"); #define FLIGHTTICS (60*TICRATE) #define SPEEDTICS (45*TICRATE) #define MAULATORTICS (25*TICRATE) +#define TIMEFREEZE_TICS ( 12 * TICRATE ) EXTERN_CVAR (Bool, r_drawfuzz); @@ -1359,3 +1360,95 @@ IMPLEMENT_STATELESS_ACTOR (APowerScanner, Any, -1, 0) PROP_Powerup_EffectTics (80*TICRATE) PROP_Inventory_FlagsSet (IF_HUBPOWER) END_DEFAULTS + + +// Time freezer powerup ----------------------------------------------------- + +IMPLEMENT_STATELESS_ACTOR( APowerTimeFreezer, Any, -1, 0 ) + PROP_Powerup_EffectTics( TIMEFREEZE_TICS ) +END_DEFAULTS + +//=========================================================================== +// +// APowerTimeFreezer :: InitEffect +// +//=========================================================================== + +void APowerTimeFreezer::InitEffect( ) +{ + int ulIdx; + + // When this powerup is in effect, pause the music. + S_PauseSound( false ); + + // Give the player and his teammates the power to move when time is frozen. + Owner->player->Powers |= PW_TIMEFREEZE; + for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) + { + if ( playeringame[ulIdx] && + players[ulIdx].mo != NULL && + players[ulIdx].mo->IsTeammate( Owner ) + ) + { + players[ulIdx].Powers |= PW_TIMEFREEZE; + } + } + + // Finally, freeze the game. + level.flags|= LEVEL_FROZEN; +} + +//=========================================================================== +// +// APowerTimeFreezer :: DoEffect +// +//=========================================================================== + +void APowerTimeFreezer::DoEffect( ) +{ + if ( EffectTics > 4*32 + || (( EffectTics > 3*32 && EffectTics <= 4*32 ) && EffectTics % 16 != 0 ) + || (( EffectTics > 2*32 && EffectTics <= 3*32 ) && EffectTics % 8 != 0 ) + || (( EffectTics > 32 && EffectTics <= 2*32 ) && EffectTics % 4 != 0 ) + || (( EffectTics > 0 && EffectTics <= 1*32 ) && EffectTics % 2 != 0 )) + level.flags |= LEVEL_FROZEN; + else + level.flags &= ~LEVEL_FROZEN; +} + +//=========================================================================== +// +// APowerTimeFreezer :: EndEffect +// +//=========================================================================== + +void APowerTimeFreezer::EndEffect( ) +{ + int ulIdx; + + // Allow other actors to move about freely once again. + level.flags &= ~LEVEL_FROZEN; + + // Also, turn the music back on. + S_ResumeSound( ); + + // Nothing more to do if there's no owner. + if (( Owner == NULL ) || ( Owner->player == NULL )) + { + return; + } + + // Take away the time freeze power, and his teammates. + Owner->player->Powers &= ~PW_TIMEFREEZE; + for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) + { + if ( playeringame[ulIdx] && + players[ulIdx].mo != NULL && + players[ulIdx].mo->IsTeammate( Owner ) + ) + { + players[ulIdx].Powers &= ~PW_TIMEFREEZE; + } + } +} + diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 151b228cb..25c2f6cde 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -204,6 +204,16 @@ protected: void EndEffect (); }; +class APowerTimeFreezer : public APowerup +{ + DECLARE_STATELESS_ACTOR( APowerTimeFreezer, APowerup ) +protected: + void InitEffect( ); + void DoEffect( ); + void EndEffect( ); +}; + + class player_s; diff --git a/src/infomacros.h b/src/infomacros.h index 7e3f8b77c..19c5a40cb 100644 --- a/src/infomacros.h +++ b/src/infomacros.h @@ -310,6 +310,7 @@ public: #define PROP_PowerupGiver_EffectTics(x) ADD_LONG_PROP(ADEF_PowerupGiver_EffectTics,x) #define PROP_Powerup_EffectTics(x) ADD_LONG_PROP(ADEF_Powerup_EffectTics,x) #define PROP_Powerup_Color(a,r,g,b) ADD_LONG_PROP(ADEF_Powerup_Color,((a)<<24)|((r)<<16)|((g)<<8)|(b)) +#define PROP_Powerup_Colormap(m) ADD_LONG_PROP(ADEF_Powerup_Color,m) #define PROP_Ammo_BackpackAmount(x) ADD_WORD_PROP(ADEF_Ammo_BackpackAmount,x) #define PROP_Ammo_BackpackMaxAmount(x) ADD_WORD_PROP(ADEF_Ammo_BackpackMaxAmount,x) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c3cb64e16..961cc066b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2534,6 +2534,13 @@ void AActor::Tick () return; } + // Apply freeze mode. + if (( level.flags & LEVEL_FROZEN ) && ( player == NULL || !( player->Powers & PW_TIMEFREEZE ))) + { + return; + } + + fixed_t oldz = z; // [RH] Give the pain elemental vertical friction diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 99e810b4e..8e6ecb343 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -75,13 +75,24 @@ void P_Ticker (void) if (paused || (playerswiping && !demoplayback) || P_CheckTickerPaused()) return; - S_ResumeSound (); + // [BC] Do a quick check to see if anyone has the freeze time power. If they do, + // then don't resume the sound, since one of the effects of that power is to shut + // off the music. + for (i = 0; i < MAXPLAYERS; i++ ) + { + if (playeringame[i] && players[i].Powers & PW_TIMEFREEZE) + break; + } + + if ( i == MAXPLAYERS ) + S_ResumeSound (); + P_ResetSightCounters (false); // Since things will be moving, it's okay to interpolate them in the renderer. r_NoInterpolate = false; - if (!bglobal.freeze) + if (!bglobal.freeze && !(level.flags & LEVEL_FROZEN)) { P_ThinkParticles (); // [RH] make the particles think } @@ -96,7 +107,7 @@ void P_Ticker (void) DThinker::RunThinkers (); //if added by MC: Freeze mode. - if (!bglobal.freeze) + if (!bglobal.freeze && !(level.flags & LEVEL_FROZEN)) { P_UpdateSpecials (); P_RunEffects (); // [RH] Run particle effects diff --git a/src/p_user.cpp b/src/p_user.cpp index e81fb5dfd..4acfcbc0f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2359,7 +2359,8 @@ void player_s::Serialize (FArchive &arc) << BlendB << BlendA << accuracy << stamina - << LogText; + << LogText + << Powers; for (i = 0; i < MAXPLAYERS; i++) arc << frags[i];