mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- 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:
parent
f8e64a13af
commit
fc6d55c508
5 changed files with 51 additions and 36 deletions
|
@ -192,7 +192,6 @@ typedef enum
|
|||
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
|
||||
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_TIMEFREEZE = 1 << 15, // Player has an active time freezer
|
||||
CF_DRAIN = 1 << 16, // Player owns a drain powerup
|
||||
CF_REGENERATION = 1 << 17, // Player owns a regeneration artifact
|
||||
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
|
||||
|
@ -307,6 +306,7 @@ public:
|
|||
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
|
||||
|
||||
int cheats; // bit flags
|
||||
int timefreezer; // Player has an active time freezer
|
||||
short refire; // refired shots are less accurate
|
||||
short inconsistant;
|
||||
int killcount, itemcount, secretcount; // for intermission
|
||||
|
|
|
@ -1356,28 +1356,29 @@ IMPLEMENT_CLASS( APowerTimeFreezer)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerTimeFreezer::InitEffect( )
|
||||
void APowerTimeFreezer::InitEffect()
|
||||
{
|
||||
int ulIdx;
|
||||
int freezemask;
|
||||
|
||||
Super::InitEffect();
|
||||
|
||||
if (Owner== NULL || Owner->player == NULL)
|
||||
if (Owner == NULL || Owner->player == NULL)
|
||||
return;
|
||||
|
||||
// When this powerup is in effect, pause the music.
|
||||
S_PauseSound( false, false );
|
||||
S_PauseSound(false, false);
|
||||
|
||||
// Give the player and his teammates the power to move when time is frozen.
|
||||
Owner->player->cheats |= CF_TIMEFREEZE;
|
||||
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
|
||||
freezemask = 1 << (Owner->player - players);
|
||||
Owner->player->timefreezer |= freezemask;
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if ( playeringame[ulIdx] &&
|
||||
players[ulIdx].mo != NULL &&
|
||||
players[ulIdx].mo->IsTeammate( Owner )
|
||||
if (playeringame[i] &&
|
||||
players[i].mo != NULL &&
|
||||
players[i].mo->IsTeammate(Owner)
|
||||
)
|
||||
{
|
||||
players[ulIdx].cheats |= CF_TIMEFREEZE;
|
||||
players[i].timefreezer |= freezemask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1405,7 +1406,7 @@ void APowerTimeFreezer::InitEffect( )
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerTimeFreezer::DoEffect( )
|
||||
void APowerTimeFreezer::DoEffect()
|
||||
{
|
||||
Super::DoEffect();
|
||||
// [RH] Do not change LEVEL_FROZEN on odd tics, or the Revenant's tracer
|
||||
|
@ -1433,41 +1434,45 @@ void APowerTimeFreezer::DoEffect( )
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerTimeFreezer::EndEffect( )
|
||||
void APowerTimeFreezer::EndEffect()
|
||||
{
|
||||
int ulIdx;
|
||||
int i;
|
||||
|
||||
Super::EndEffect();
|
||||
|
||||
// Allow other actors to move about freely once again.
|
||||
level.flags2 &= ~LEVEL2_FROZEN;
|
||||
|
||||
// Also, turn the music back on.
|
||||
S_ResumeSound( false );
|
||||
|
||||
// Nothing more to do if there's no owner.
|
||||
if (( Owner == NULL ) || ( Owner->player == NULL ))
|
||||
// If there is an owner, remove the timefreeze flag corresponding to
|
||||
// her from all players.
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
return;
|
||||
int freezemask = ~(1 << (Owner->player - players));
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
players[i].timefreezer &= freezemask;
|
||||
}
|
||||
}
|
||||
|
||||
// Take away the time freeze power, and his teammates.
|
||||
Owner->player->cheats &= ~CF_TIMEFREEZE;
|
||||
for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
|
||||
// Are there any players who still have timefreezer bits set?
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if ( playeringame[ulIdx] &&
|
||||
players[ulIdx].mo != NULL &&
|
||||
players[ulIdx].mo->IsTeammate( Owner )
|
||||
)
|
||||
if (playeringame[i] && players[i].timefreezer != 0)
|
||||
{
|
||||
players[ulIdx].cheats &= ~CF_TIMEFREEZE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == MAXPLAYERS)
|
||||
{
|
||||
// No, so allow other actors to move about freely once again.
|
||||
level.flags2 &= ~LEVEL2_FROZEN;
|
||||
|
||||
// Also, turn the music back on.
|
||||
S_ResumeSound(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Damage powerup ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS( APowerDamage)
|
||||
IMPLEMENT_CLASS(APowerDamage)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -2905,7 +2905,7 @@ void AActor::Tick ()
|
|||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ void P_Ticker (void)
|
|||
// off the music.
|
||||
for (i = 0; i < MAXPLAYERS; i++ )
|
||||
{
|
||||
if (playeringame[i] && players[i].cheats & CF_TIMEFREEZE)
|
||||
if (playeringame[i] && players[i].timefreezer != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -247,6 +247,7 @@ player_t::player_t()
|
|||
ReadyWeapon(0),
|
||||
PendingWeapon(0),
|
||||
cheats(0),
|
||||
timefreezer(0),
|
||||
refire(0),
|
||||
inconsistant(0),
|
||||
killcount(0),
|
||||
|
@ -674,7 +675,7 @@ bool APlayerPawn::UseInventory (AInventory *item)
|
|||
{ // You can't use items if you're totally frozen
|
||||
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
|
||||
return false;
|
||||
|
@ -2685,6 +2686,15 @@ void player_t::Serialize (FArchive &arc)
|
|||
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)
|
||||
{
|
||||
arc << angle
|
||||
|
@ -2775,5 +2785,5 @@ bool P_IsPlayerTotallyFrozen(const player_t *player)
|
|||
return
|
||||
gamestate == GS_TITLELEVEL ||
|
||||
player->cheats & CF_TOTALLYFROZEN ||
|
||||
((level.flags2 & LEVEL2_FROZEN) && !(player->cheats & CF_TIMEFREEZE));
|
||||
((level.flags2 & LEVEL2_FROZEN) && player->timefreezer == 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue