- Fixed: PowerTimeFreezer needs to use different bits to mark timefreezing initiated by different

players, or overlapping uses of PowerTimeFreezer will malfunction.

SVN r3599 (trunk)
This commit is contained in:
Randy Heit 2012-04-27 01:40:50 +00:00
parent f8e64a13af
commit fc6d55c508
5 changed files with 51 additions and 36 deletions

View file

@ -192,7 +192,6 @@ typedef enum
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted
CF_WEAPONREADY = 1 << 14, // [RH] Weapon is in the ready state and can fire its primary attack CF_WEAPONREADY = 1 << 14, // [RH] Weapon is in the ready state and can fire its primary attack
CF_TIMEFREEZE = 1 << 15, // Player has an active time freezer
CF_DRAIN = 1 << 16, // Player owns a drain powerup CF_DRAIN = 1 << 16, // Player owns a drain powerup
CF_REGENERATION = 1 << 17, // Player owns a regeneration artifact CF_REGENERATION = 1 << 17, // Player owns a regeneration artifact
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;) CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
@ -307,6 +306,7 @@ public:
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
int cheats; // bit flags int cheats; // bit flags
int timefreezer; // Player has an active time freezer
short refire; // refired shots are less accurate short refire; // refired shots are less accurate
short inconsistant; short inconsistant;
int killcount, itemcount, secretcount; // for intermission int killcount, itemcount, secretcount; // for intermission

View file

@ -1358,7 +1358,7 @@ IMPLEMENT_CLASS( APowerTimeFreezer)
void APowerTimeFreezer::InitEffect() void APowerTimeFreezer::InitEffect()
{ {
int ulIdx; int freezemask;
Super::InitEffect(); Super::InitEffect();
@ -1369,15 +1369,16 @@ void APowerTimeFreezer::InitEffect( )
S_PauseSound(false, false); S_PauseSound(false, false);
// Give the player and his teammates the power to move when time is frozen. // Give the player and his teammates the power to move when time is frozen.
Owner->player->cheats |= CF_TIMEFREEZE; freezemask = 1 << (Owner->player - players);
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) Owner->player->timefreezer |= freezemask;
for (int i = 0; i < MAXPLAYERS; i++)
{ {
if ( playeringame[ulIdx] && if (playeringame[i] &&
players[ulIdx].mo != NULL && players[i].mo != NULL &&
players[ulIdx].mo->IsTeammate( Owner ) players[i].mo->IsTeammate(Owner)
) )
{ {
players[ulIdx].cheats |= CF_TIMEFREEZE; players[i].timefreezer |= freezemask;
} }
} }
@ -1435,33 +1436,37 @@ void APowerTimeFreezer::DoEffect( )
void APowerTimeFreezer::EndEffect() void APowerTimeFreezer::EndEffect()
{ {
int ulIdx; int i;
Super::EndEffect(); Super::EndEffect();
// Allow other actors to move about freely once again. // If there is an owner, remove the timefreeze flag corresponding to
// her from all players.
if (Owner != NULL && Owner->player != NULL)
{
int freezemask = ~(1 << (Owner->player - players));
for (i = 0; i < MAXPLAYERS; ++i)
{
players[i].timefreezer &= freezemask;
}
}
// Are there any players who still have timefreezer bits set?
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].timefreezer != 0)
{
break;
}
}
if (i == MAXPLAYERS)
{
// No, so allow other actors to move about freely once again.
level.flags2 &= ~LEVEL2_FROZEN; level.flags2 &= ~LEVEL2_FROZEN;
// Also, turn the music back on. // Also, turn the music back on.
S_ResumeSound(false); S_ResumeSound(false);
// 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->cheats &= ~CF_TIMEFREEZE;
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
{
if ( playeringame[ulIdx] &&
players[ulIdx].mo != NULL &&
players[ulIdx].mo->IsTeammate( Owner )
)
{
players[ulIdx].cheats &= ~CF_TIMEFREEZE;
}
} }
} }

View file

@ -2905,7 +2905,7 @@ void AActor::Tick ()
} }
// Apply freeze mode. // Apply freeze mode.
if (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE ))) if ((level.flags2 & LEVEL2_FROZEN) && (player == NULL || player->timefreezer == 0))
{ {
return; return;
} }

View file

@ -101,7 +101,7 @@ void P_Ticker (void)
// off the music. // off the music.
for (i = 0; i < MAXPLAYERS; i++ ) for (i = 0; i < MAXPLAYERS; i++ )
{ {
if (playeringame[i] && players[i].cheats & CF_TIMEFREEZE) if (playeringame[i] && players[i].timefreezer != 0)
break; break;
} }

View file

@ -247,6 +247,7 @@ player_t::player_t()
ReadyWeapon(0), ReadyWeapon(0),
PendingWeapon(0), PendingWeapon(0),
cheats(0), cheats(0),
timefreezer(0),
refire(0), refire(0),
inconsistant(0), inconsistant(0),
killcount(0), killcount(0),
@ -674,7 +675,7 @@ bool APlayerPawn::UseInventory (AInventory *item)
{ // You can't use items if you're totally frozen { // You can't use items if you're totally frozen
return false; return false;
} }
if (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE ))) if ((level.flags2 & LEVEL2_FROZEN) && (player == NULL || player->timefreezer == 0))
{ {
// Time frozen // Time frozen
return false; return false;
@ -2685,6 +2686,15 @@ void player_t::Serialize (FArchive &arc)
poisonpaintype = poisoner->PainType != NAME_None ? poisoner->PainType : poisoner->DamageType; poisonpaintype = poisoner->PainType != NAME_None ? poisoner->PainType : poisoner->DamageType;
} }
if (SaveVersion >= 3599)
{
arc << timefreezer;
}
else
{
cheats &= ~(1 << 15); // make sure old CF_TIMEFREEZE bit is cleared
}
if (isbot) if (isbot)
{ {
arc << angle arc << angle
@ -2775,5 +2785,5 @@ bool P_IsPlayerTotallyFrozen(const player_t *player)
return return
gamestate == GS_TITLELEVEL || gamestate == GS_TITLELEVEL ||
player->cheats & CF_TOTALLYFROZEN || player->cheats & CF_TOTALLYFROZEN ||
((level.flags2 & LEVEL2_FROZEN) && !(player->cheats & CF_TIMEFREEZE)); ((level.flags2 & LEVEL2_FROZEN) && player->timefreezer == 0);
} }