# HG changeset patch # User Adam Kaminski # Date 1626998064 14400 # Thu Jul 22 19:54:24 2021 -0400 # Node ID 5a044ece3c8868a2cf51755f358ab6ad2ae07359 # Parent ed6a98d691cef74941af618d57999647b7123c5e Changed some rules on how players are respawned if sv_samespotspawn is enabled. Particularly, players won't spawn where they died if it's in a damaging sector or crusher, or if there's not enough room to respawn in the first place. diff -r ed6a98d691ce -r 5a044ece3c88 src/d_player.h --- a/src/d_player.h Mon Jul 19 20:06:54 2021 -0400 +++ b/src/d_player.h Thu Jul 22 19:54:24 2021 -0400 @@ -804,6 +804,7 @@ bool PLAYER_NameMatchesServer( const FString &Name ); bool PLAYER_NameUsed( const FString &Name, const ULONG ulIgnorePlayer = MAXPLAYERS ); FString PLAYER_GenerateUniqueName( void ); +bool PLAYER_CanRespawnWhereDied( player_t *pPlayer ); void P_CheckPlayerSprite(AActor *mo, int &spritenum, fixed_t &scalex, fixed_t &scaley); diff -r ed6a98d691ce -r 5a044ece3c88 src/p_interaction.cpp --- a/src/p_interaction.cpp Mon Jul 19 20:06:54 2021 -0400 +++ b/src/p_interaction.cpp Thu Jul 22 19:54:24 2021 -0400 @@ -81,6 +81,7 @@ #include "r_data/colormaps.h" #include "v_video.h" #include "st_hud.h" +#include "p_terrain.h" // [BC] Ugh. void SERVERCONSOLE_UpdatePlayerInfo( LONG lPlayer, ULONG ulUpdateFlags ); @@ -3325,6 +3326,67 @@ return name; } +//***************************************************************************** +// +bool PLAYER_CanRespawnWhereDied( player_t *pPlayer ) +{ + // [AK] The player shouldn't respawn in any sectors that have damaging floors. + if (( pPlayer->mo->Sector->damage > 0 ) || ( Terrains[P_GetThingFloorType( pPlayer->mo )].DamageAmount > 0 )) + return false; + + switch ( pPlayer->mo->Sector->special ) + { + case dLight_Strobe_Hurt: + case dDamage_Hellslime: + case dDamage_Nukage: + case dDamage_End: + case dDamage_SuperHellslime: + case dDamage_LavaWimpy: + case dDamage_LavaHefty: + case dScroll_EastLavaDamage: + case hDamage_Sludge: + case sLight_Strobe_Hurt: + case sDamage_Hellslime: + case sDamage_SuperHellslime: + return false; + } + + // [AK] Don't respawn the player in an instant death sector. Taken directly from P_PlayerSpawn. + if (( pPlayer->mo->Sector->Flags & SECF_NORESPAWN ) || (( pPlayer->mo->Sector->special & 255 ) == Damage_InstantDeath )) + return false; + + // [AK] Make sure they're not going to be blocked by anything upon respawning where they died. + AActor *temp = Spawn( pPlayer->cls->TypeName.GetChars( ), pPlayer->mo->x, pPlayer->mo->y, pPlayer->mo->z, NO_REPLACE ); + bool bCanSpawn = P_TestMobjLocation( temp ); + + temp->Destroy( ); + if ( bCanSpawn == false ) + return false; + + DCeiling *pCeiling; + TThinkerIterator CeilingIterator; + + // [AK] The player shouldn't respawn in a sector that has any active crushers. We'll first iterate + // through all ceilings crushers and see if one is connected to the sector the player's body is in. + while (( pCeiling = CeilingIterator.Next( )) != NULL ) + { + if (( pCeiling->GetSector( ) == pPlayer->mo->Sector ) && ( pCeiling->GetCrush( ) > -1 )) + return false; + } + + DFloor *pFloor; + TThinkerIterator FloorIterator; + + // [AK] Next, check all the floor crushers. + while (( pFloor = FloorIterator.Next( )) != NULL ) + { + if (( pFloor->GetSector( ) == pPlayer->mo->Sector ) && ( pFloor->GetCrush( ) > -1 )) + return false; + } + + return true; +} + CCMD (kill) { // Only allow it in a level. diff -r ed6a98d691ce -r 5a044ece3c88 src/p_mobj.cpp --- a/src/p_mobj.cpp Mon Jul 19 20:06:54 2021 -0400 +++ b/src/p_mobj.cpp Thu Jul 22 19:54:24 2021 -0400 @@ -5424,10 +5424,9 @@ ( deathmatch == false ) && ( teamgame == false ) && ( gameaction != ga_worlddone ) && - ( p->bSpawnOkay ) && ( p->mo != NULL ) && - ( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) && - ( (p->mo->Sector->special & 255) != Damage_InstantDeath )) + // [AK] Moved the SECF_NORESPAWN and Damage_InstantDeath checks into PLAYER_CanRespawnWhereDied. + ( PLAYER_CanRespawnWhereDied( p ))) { spawn_x = p->mo->x; spawn_y = p->mo->y;