diff --git a/src/d_player.h b/src/d_player.h index fa91f825..fc30df8d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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 diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index ede148c6..c0dc797f 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -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) //=========================================================================== // diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8df97f1d..1e9427cb 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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; } diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 4fcfebaf..33034467 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -802,6 +802,31 @@ int sector_t::GetCeilingLight () const } } +sector_t *sector_t::GetHeightSec() const +{ + if (heightsec == NULL) + { + return NULL; + } + if (heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) + { + return NULL; + } + if (e && e->XFloor.ffloors.Size()) + { + // If any of these fake floors render their planes, ignore heightsec. + for (unsigned i = e->XFloor.ffloors.Size(); i-- > 0; ) + { + if ((e->XFloor.ffloors[i]->flags & (FF_EXISTS | FF_RENDERPLANES)) == (FF_EXISTS | FF_RENDERPLANES)) + { + return NULL; + } + } + } + return heightsec; +} + + bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const { bool copy = false; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 29e6c9cf..512730dd 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -288,7 +288,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType) { - int lineActivation = line->activation; + int lineActivation = line->activation; if (line->flags & ML_FIRSTSIDEONLY && side == 1) { diff --git a/src/p_switch.cpp b/src/p_switch.cpp index c1c1ffb4..5aeff7b4 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -121,9 +121,15 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) fixed_t checkbot; sector_t *front = side->sector; FLineOpening open; + int flags = line->flags; + + if (!side->GetTexture(side_t::mid).isValid()) + { // Do not force range checks for 3DMIDTEX lines if there is no actual midtexture. + flags &= ~ML_3DMIDTEX; + } // 3DMIDTEX forces CHECKSWITCHRANGE because otherwise it might cause problems. - if (!(line->flags & (ML_3DMIDTEX|ML_CHECKSWITCHRANGE))) + if (!(flags & (ML_3DMIDTEX|ML_CHECKSWITCHRANGE))) return true; // calculate the point where the user would touch the wall. @@ -169,15 +175,15 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) if (open.range <= 0) goto onesided; - if ((TexMan.FindSwitch (side->GetTexture(side_t::top))) != NULL) + if ((TexMan.FindSwitch(side->GetTexture(side_t::top))) != NULL) { return (user->z + user->height >= open.top); } - else if ((TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != NULL) + else if ((TexMan.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) { return (user->z <= open.bottom); } - else if ((line->flags & (ML_3DMIDTEX)) || (TexMan.FindSwitch (side->GetTexture(side_t::mid))) != NULL) + else if ((flags & ML_3DMIDTEX) || (TexMan.FindSwitch(side->GetTexture(side_t::mid))) != NULL) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 5f663606..26c4c2ae 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -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; } diff --git a/src/p_user.cpp b/src/p_user.cpp index 411de703..bb2d90ea 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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; @@ -2694,6 +2695,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 @@ -2784,5 +2794,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); } diff --git a/src/r_defs.h b/src/r_defs.h index afaafef1..e17c981e 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -475,6 +475,7 @@ struct sector_t void ClosestPoint(fixed_t x, fixed_t y, fixed_t &ox, fixed_t &oy) const; int GetFloorLight () const; int GetCeilingLight () const; + sector_t *GetHeightSec() const; DInterpolation *SetInterpolation(int position, bool attach); void StopInterpolation(int position); @@ -636,14 +637,6 @@ struct sector_t planes[pos].TexZ += val; } - sector_t *GetHeightSec() const - { - return (heightsec && - !(heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && - !(this->e && this->e->XFloor.ffloors.Size()) - )? heightsec : NULL; - } - static inline short ClampLight(int level) { return (short)clamp(level, SHRT_MIN, SHRT_MAX); diff --git a/src/svnrevision.h b/src/svnrevision.h index 29bbaa5a..47446c6a 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "3598" -#define ZD_SVN_REVISION_NUMBER 3598 +#define ZD_SVN_REVISION_STRING "3601" +#define ZD_SVN_REVISION_NUMBER 3601