Simple player state save/restore and registration

This commit is contained in:
mittorn 2018-10-13 16:37:52 +00:00
parent 16d2751737
commit 353b9cba99
5 changed files with 551 additions and 78 deletions

View File

@ -116,6 +116,15 @@ GLOBALS ASSUMED SET: g_fGameOver
*/
void ClientDisconnect( edict_t *pEntity )
{
CBasePlayer *pPlayer = (CBasePlayer*)CBaseEntity::Instance( pEntity );
if( pPlayer && pPlayer->IsPlayer() )
{
GGM_SaveState( pPlayer );
pPlayer->gravgunmod_data.m_state = STATE_UNINITIALIZED;
}
if (g_fGameOver)
return;
@ -145,12 +154,6 @@ void ClientDisconnect( edict_t *pEntity )
UTIL_SetOrigin( &pEntity->v, pEntity->v.origin );
g_pGameRules->ClientDisconnected( pEntity );
if( mp_coop.value )
{
CBasePlayer *pPlayer = (CBasePlayer*)CBaseEntity::Instance( pEntity );
if( pPlayer )
pPlayer->gravgunmod_data.m_state = STATE_UNINITIALIZED;
}
}
@ -686,6 +689,8 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
if ( !pEntity->pvPrivateData )
return;
const char *name = g_engfuncs.pfnInfoKeyValue( infobuffer, "name" );
// prevent keeping other's uid on saverestore
CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)&pEntity->v);
@ -693,14 +698,19 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
if( !uid || strstr(uid, "PENDING") )
uid = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "ip" );
if( strncmp( uid ,pPlayer->gravgunmod_data.uid, 32 ) )
GGMPlayerState *pState = GGM_GetState(uid, name);
if( pState != pPlayer->gravgunmod_data.pState )
{
pEntity->v.netname = pEntity->v.frags = 0;
strncpy( pPlayer->gravgunmod_data.uid, uid, 32 );
pPlayer->gravgunmod_data.uid[32] = 0;
GGM_SaveState( pPlayer );
pPlayer->gravgunmod_data.pState = pState;
pPlayer->gravgunmod_data.m_state = STATE_UNINITIALIZED;
}
//strncpy( pPlayer->gravgunmod_data.uid, uid, 32 );
//pPlayer->gravgunmod_data.uid[32] = 0;
// msg everyone if someone changes their name, and it isn't the first time (changing no name to current name)
if( pEntity->v.netname && ( STRING( pEntity->v.netname ) )[0] != 0 && !FStrEq( STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ) )
if( pEntity->v.netname && ( STRING( pEntity->v.netname ) )[0] != 0 && !FStrEq( STRING( pEntity->v.netname ), name ) )
{
char sName[256];
char *pName = g_engfuncs.pfnInfoKeyValue( infobuffer, "name" );

View File

@ -490,8 +490,8 @@ void COOP_NewCheckpoint( entvars_t *pevPlayer )
bool COOP_PlayerDeath( CBasePlayer *pPlayer )
{
if( pPlayer->gravgunmod_data.m_iMenuState == MENUSTATE_CHECKPOINT )
return true;
// if( pPlayer->gravgunmod_data.m_iMenuState == MENUSTATE_CHECKPOINT )
// return true;
if( g_checkpoints[0].time )
{

View File

@ -5,6 +5,7 @@
#include "player.h"
#include "coop_util.h"
#include "gamerules.h"
#include "weapons.h"
cvar_t cvar_allow_gravgun = { "mp_allow_gravgun","2", FCVAR_SERVER };
@ -41,7 +42,6 @@ cvar_t mp_enttools_checkmodels = { "mp_enttools_checkmodels", "0", FCVAR_SERVER
cvar_t mp_errormdl = { "mp_errormdl", "0", FCVAR_SERVER };
cvar_t mp_errormdlpath = { "mp_errormdlpath", "models/error.mdl", FCVAR_SERVER };
void Ent_RunGC_f( void );
static bool Q_starcmp( const char *pattern, const char *text )
@ -144,6 +144,8 @@ void GGM_RegisterCVars( void )
g_engfuncs.pfnAddServerCommand( "mp_lightstyle", GGM_LightStyle_f );
}
void Ent_RunGC( int flags, const char *userid, const char *pattern )
{
int i, count = 0, removed = 0;
@ -334,6 +336,20 @@ int Ent_CheckEntitySpawn( edict_t *pent )
return 0;
}
void GGM_ChatPrintf( CBasePlayer *pPlayer, const char *format, ... )
{
va_list argptr;
char string[256];
va_start( argptr, format );
int len = vsnprintf( string, 256, format, argptr );
va_end( argptr );
string[len] = 0;
//ClientPrint( &player->v, HUD_PRINTCONSOLE, string );
CLIENT_PRINTF( pPlayer->edict(), print_chat, string );
}
void GGM_ClientPutinServer(edict_t *pEntity, CBasePlayer *pPlayer)
{
@ -346,12 +362,11 @@ void GGM_ClientPutinServer(edict_t *pEntity, CBasePlayer *pPlayer)
if( !uid || strstr(uid, "PENDING") )
uid = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "ip" );
strncpy( pPlayer->gravgunmod_data.uid, uid, 32 );
pPlayer->gravgunmod_data.uid[32] = 0;
pPlayer->gravgunmod_data.m_flEntTime = 0;
pPlayer->gravgunmod_data.m_flEntScope = 0;
pPlayer->gravgunmod_data.menu.pPlayer = pPlayer;
pPlayer->gravgunmod_data.menu.Clear();
pPlayer->gravgunmod_data.pState = GGM_GetState( uid, STRING(pEntity->v.netname) );
}
void GGM_ClientFirstSpawn(CBasePlayer *pPlayer)
@ -375,7 +390,10 @@ edict_t *GGM_PlayerByID( const char *id )
{
CBasePlayer *player = (CBasePlayer *) plr;
if( !strcmp( player->gravgunmod_data.uid, id ) )
if( !player->gravgunmod_data.pState )
continue;
if( !strcmp( player->gravgunmod_data.pState->p.uid, id ) )
return player->edict();
}
}
@ -390,7 +408,420 @@ const char *GGM_GetPlayerID( edict_t *player )
if( !plr->IsPlayer() )
return NULL;
return plr->gravgunmod_data.uid;
if( !plr->gravgunmod_data.pState )
return NULL;
return plr->gravgunmod_data.pState->p.uid;
}
struct GGMPlayerState *registered_list;
struct GGMPlayerState *anonymous_list;
struct GGMLogin *login_list;
struct GGMPlayerState *GGM_FindState( GGMPlayerState *list, const char *uid )
{
struct GGMPlayerState *pState;
for( pState = list; pState; pState = pState->pNext )
{
if( !strncmp( uid, pState->p.uid, 32 ) )
return pState;
}
return NULL;
}
struct GGMPlayerState *GGM_GetState( const char *uid, const char *name )
{
struct GGMPlayerState *pState;
for( struct GGMLogin *login = login_list; login; login = login->pNext )
{
if( !strcmp( name, login->name ) )
{
if( !strncmp(uid, login->uid, 32 ) )
return login->pState;
else
return NULL; // ask for login or nickname change
}
}
if( ( pState = GGM_FindState( anonymous_list, uid ) ) )
return pState;
pState = (struct GGMPlayerState*)calloc( 1, sizeof( struct GGMPlayerState ) );
memset( pState, 0, sizeof( struct GGMPlayerState ) );
strncpy( pState->p.uid, uid, 32 );
pState->p.uid[32] = 0;
pState->pNext = anonymous_list;
return anonymous_list = pState;
}
void GGM_SaveState(CBasePlayer *pPlayer)
{
if( !pPlayer )
return;
GGMPlayerState *pState = pPlayer->gravgunmod_data.pState;
int i, j = 0;
if( !pState )
return;
pState->t.iFrags = pPlayer->pev->frags;
pState->t.iDeaths = pPlayer->m_iDeaths;
if( pPlayer->gravgunmod_data.m_state != STATE_SPAWNED )
return;
if( pPlayer->pev->health <= 0 )
return;
pState->t.vecOrigin = pPlayer->pev->origin;
pState->t.flHealth = pPlayer->pev->health;
pState->t.flBattery = pPlayer->pev->armorvalue;
if(pPlayer->m_pActiveItem.Get())
strncpy( pState->t.WeaponName, STRING(pPlayer->m_pActiveItem.Get()->v.classname), 31);
for( i = 0; i < MAX_ITEM_TYPES; i++ )
{
CBasePlayerWeapon *pWeapon = pPlayer->m_rgpPlayerItems[i];
while( pWeapon )
{
strncpy( pState->t.rgWeapons[j], STRING(pWeapon->pev->classname), 31);
pState->t.rgiClip[j] = pWeapon->m_iClip;
j++;
pWeapon = pWeapon->m_pNext;
}
}
pState->t.rgWeapons[j][0] = 0;
for( i = 0; i < MAX_AMMO_SLOTS; i++ )
pState->t.rgAmmo[i] = pPlayer->m_rgAmmo[i];
}
bool GGM_RestoreState(CBasePlayer *pPlayer)
{
GGMPlayerState *pState = pPlayer->gravgunmod_data.pState;
int i;
if( !pState )
return false;
pPlayer->pev->frags = pState->t.iFrags;
pPlayer->m_iDeaths = pState->t.iDeaths;
if( pState->t.flHealth < 1 )
return false;
pPlayer->pev->armorvalue = pState->t.flBattery;
pPlayer->pev->origin = pState->t.vecOrigin;
pPlayer->pev->health = pState->t.flHealth;
pPlayer->RemoveAllItems( FALSE );
for( i = 0; i < MAX_WEAPONS; i++ )
{
if( !pState->t.rgWeapons[i][0] )
break;
CBasePlayerWeapon *pWeapon = (CBasePlayerWeapon*)CBaseEntity::Create(pState->t.rgWeapons[i], pPlayer->pev->origin, pPlayer->pev->angles );
if( !pWeapon )
continue;
pWeapon->pev->spawnflags |= SF_NORESPAWN;
pWeapon->m_iDefaultAmmo = 0;
pWeapon->m_iClip = pState->t.rgiClip[i];
if (pPlayer->AddPlayerItem(pWeapon)) {
pWeapon->AttachToPlayer(pPlayer);
}
}
for( i = 0; i < MAX_AMMO_SLOTS; i++ )
pPlayer->m_rgAmmo[i] = pState->t.rgAmmo[i];
pPlayer->SelectItem(pState->t.WeaponName);
return true;
}
void ClientPutInServer( edict_t *client );
bool GGM_PlayerSpawn( CBasePlayer *pPlayer )
{
if( pPlayer->gravgunmod_data.m_state == STATE_UNINITIALIZED )
{
ClientPutInServer( pPlayer->edict() );
return true;
}
if( mp_spectator.value && pPlayer->gravgunmod_data.m_state == STATE_CONNECTED )
{
pPlayer->gravgunmod_data.m_state = STATE_SPECTATOR_BEGIN;
pPlayer->RemoveAllItems( TRUE );
UTIL_BecomeSpectator( pPlayer );
return true;
}
if( mp_coop_changelevel.value && pPlayer->gravgunmod_data.m_state == STATE_POINT_SELECT && !(pPlayer->pev->flags & FL_SPECTATOR) )
{
pPlayer->RemoveAllItems( TRUE );
UTIL_BecomeSpectator( pPlayer );
return true;
}
if( pPlayer->pev->flags & FL_SPECTATOR )
return true;
if( !mp_coop_changelevel.value )
{
pPlayer->gravgunmod_data.m_state = STATE_SPAWNED;
if( GGM_RestoreState( pPlayer ) )
{
pPlayer->pev->weapons |= (1 << WEAPON_SUIT);
return true;
}
else return false;
}
g_fPause = false;
return pPlayer->gravgunmod_data.m_state == STATE_SPAWNED;
}
bool GGM_FilterFileName( const char *name )
{
while( name && *name )
{
if( *name >= 'A' && *name <= 'z' || *name >= '0' && *name <= '9' )
{
name++;
continue;
}
return false;
}
return true;
}
void GGM_FreeState( const char *uid )
{
struct GGMPlayerState *pState, *pPrevState = NULL;
CBasePlayer *pPlayer;
// unlink from all anonymous players
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( i );
if( pPlayer && pPlayer->IsPlayer() && pPlayer->gravgunmod_data.pState )
{
if( !pPlayer->gravgunmod_data.pState->registered && !strncmp( uid, pPlayer->gravgunmod_data.pState->p.uid, 32 ) )
pPlayer->gravgunmod_data.pState = NULL;
}
}
// unlink from list and free
for( pState = anonymous_list; pState; pState = pState->pNext )
{
if( strncmp( uid, pState->p.uid, 32 ) )
{
pPrevState = pState;
continue;
}
if( pState == anonymous_list )
{
anonymous_list = anonymous_list->pNext;
free( pState );
return;
}
if( pPrevState )
pPrevState->pNext = pState->pNext;
free( pState );
return;
}
}
bool GGM_CheckUserName( CBasePlayer *pPlayer, const char *name, bool exist )
{
int len = strlen( name );
if( len < 3 )
{
GGM_ChatPrintf( pPlayer, "Name %s too short (2 characters min)!\n", name );
return false;
}
if( len > 31 )
{
GGM_ChatPrintf( pPlayer, "Name %s too long (31 characters max)!\n", name );
return false;
}
if( !GGM_FilterFileName( name ) )
{
GGM_ChatPrintf( pPlayer, "Name %s contains bad characters!\n", name );
return false;
}
if( exist && GGM_FindState( registered_list, name ) )
{
GGM_ChatPrintf( pPlayer, "Name %s busy!\n", name );
return false;
}
return true;
}
void GGM_Register( CBasePlayer *pPlayer, const char *name, const char *password )
{
struct GGMPlayerState *pState;
if( !pPlayer || !pPlayer->gravgunmod_data.pState )
return;
if( pPlayer->gravgunmod_data.pState->registered )
{
GGM_ChatPrintf( pPlayer, "Cannot register, when logged in\n" );
return;
}
if( !GGM_CheckUserName( pPlayer, name, true ) )
return;
pState = (struct GGMPlayerState*)calloc( 1, sizeof( struct GGMPlayerState ) );
memset( pState, 0, sizeof( struct GGMPlayerState ) );
strncpy( pState->p.uid, name, 32 );
pState->p.uid[32] = 0;
pState->registered = true;
strncpy( pState->p.password, password, 32 );
pState->p.password[32] = 0;
pState->t = pPlayer->gravgunmod_data.pState->t;
pState->pNext = registered_list;
registered_list = pState;
GGM_FreeState( pPlayer->gravgunmod_data.pState->p.uid );
pPlayer->gravgunmod_data.pState = pState;
GGM_ChatPrintf( pPlayer, "Successfully registered as %s!\n", name );
}
void GGM_RegName_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() != 2 )
return;
if( !GGM_CheckUserName( pPlayer, CMD_ARGV(1), true ) )
return;
strncpy( pPlayer->gravgunmod_data.registering_name, CMD_ARGV(1), 31 );
CLIENT_COMMAND( pPlayer->edict(), "messagemode reg_Password\n");
}
void GGM_Register_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() == 3 )
GGM_Register( pPlayer, CMD_ARGV(1), CMD_ARGV(2) );
else if( CMD_ARGC() == 2 )
GGM_RegName_f(pPlayer);
else
CLIENT_COMMAND( pPlayer->edict(), "messagemode reg_Name\n");
}
void GGM_RegPassword_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() != 2 )
return;
GGM_Register( pPlayer, pPlayer->gravgunmod_data.registering_name, CMD_ARGV(1) );
}
void GGM_Login( CBasePlayer *pPlayer, const char *name, const char *password )
{
struct GGMPlayerState *pState;
if( !pPlayer || !pPlayer->gravgunmod_data.pState )
return;
if( pPlayer->gravgunmod_data.pState && pPlayer->gravgunmod_data.pState->registered )
{
GGM_ChatPrintf( pPlayer, "Cannot login, already logged in\n" );
return;
}
if( !GGM_CheckUserName( pPlayer, name, false ) )
return;
pState = GGM_FindState( registered_list, name );
if( !pState || strncmp( password, pState->p.password, 32 ) )
{
GGM_ChatPrintf( pPlayer, "Login failed!\n" );
return;
}
GGM_FreeState( pPlayer->gravgunmod_data.pState->p.uid );
pPlayer->gravgunmod_data.pState = pState;
GGM_ChatPrintf( pPlayer, "Successfully logged in as %s\n", name );
GGM_RestoreState( pPlayer );
}
void GGM_LoginPassword_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() != 2 )
return;
GGM_Login( pPlayer, pPlayer->gravgunmod_data.registering_name, CMD_ARGV(1) );
}
void GGM_LoginName_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() != 2 )
return;
if( !GGM_CheckUserName( pPlayer, CMD_ARGV(1), false ) )
return;
strncpy( pPlayer->gravgunmod_data.registering_name, CMD_ARGV(1), 31 );
CLIENT_COMMAND( pPlayer->edict(), "messagemode login_Password\n");
}
void GGM_Login_f( CBasePlayer *pPlayer )
{
if( !pPlayer )
return;
if( CMD_ARGC() == 3 )
GGM_Login( pPlayer, CMD_ARGV(1), CMD_ARGV(2) );
else if( CMD_ARGC() == 2 )
GGM_LoginName_f(pPlayer);
else
CLIENT_COMMAND( pPlayer->edict(), "messagemode login_Name\n");
}
/*
@ -736,21 +1167,6 @@ bool GGM_PlayerMenu::MenuSelect( int select )
return true;
}
bool GGM_FilterFileName( const char *name )
{
while( name && *name )
{
if( *name >= 'A' && *name <= 'z' || *name >= '0' && *name <= '9' )
{
name++;
continue;
}
return false;
}
return true;
}
bool GGM_MenuCommand( CBasePlayer *player, const char *name )
{
char buf[256] = "ggm/menus/";
@ -956,29 +1372,59 @@ extern float g_flWeaponCheat;
void DumpProps(); // prop.cpp
bool GGM_ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
bool GGM_ClientCommand( CBasePlayer *pPlayer, const char *pCmd )
{
bool ret = GGM_HelpCommand( pPlayer, pcmd );
bool ret = GGM_HelpCommand( pPlayer, pCmd );
if( FStrEq( pcmd, "menuselect" ) )
if( FStrEq( pCmd, "menuselect" ) )
{
int imenu = atoi( CMD_ARGV( 1 ) );
return pPlayer->gravgunmod_data.menu.MenuSelect(imenu);
}
else if( GGM_MOTDCommand( pPlayer, pcmd ) )
else if( GGM_MOTDCommand( pPlayer, pCmd ) )
return true;
else if( GGM_MenuCommand( pPlayer, pcmd ) )
else if( GGM_MenuCommand( pPlayer, pCmd ) )
return true;
else if( GGM_TouchCommand( pPlayer, pcmd ) )
else if( GGM_TouchCommand( pPlayer, pCmd ) )
return true;
else if( FStrEq(pcmd, "dumpprops") )
else if( FStrEq(pCmd, "dumpprops") )
{
if ( g_flWeaponCheat != 0.0 )
DumpProps();
return true;
}
else if( FStrEq(pcmd, "client") )
else if( FStrEq(pCmd, "reg") )
{
GGM_Register_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "reg_Name") )
{
GGM_RegName_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "reg_Password") )
{
GGM_RegPassword_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "login") )
{
GGM_Login_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "login_Name") )
{
GGM_LoginName_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "login_Password") )
{
GGM_LoginPassword_f(pPlayer);
return true;
}
else if( FStrEq(pCmd, "client") )
{
char args[256] = {0};
strncpy(args, CMD_ARGS(),254);

View File

@ -57,7 +57,7 @@ void GGM_ClientFirstSpawn(CBasePlayer *pPlayer );
const char *GGM_GetPlayerID( edict_t *player );
edict_t *GGM_PlayerByID( const char *id );
void GGM_Say( edict_t *pEntity );
bool GGM_ClientCommand( CBasePlayer *player, const char *pcmd );
bool GGM_ClientCommand( CBasePlayer *player, const char *pCmd );
void GGM_InitialMenus( CBasePlayer *pPlayer );
void GGM_CvarValue2( const edict_t *pEnt, int requestID, const char *cvarName, const char *value );
@ -104,20 +104,67 @@ public:
};
struct GGMLogin
{
struct GGMLogin *pNext;
char uid[33];
char name[32];
struct GGMPlayerState *pState;
};
// registration and game stats
// saved on every change to separate file
// but only for registered users
struct GGMPersist
{
// uid or nickname
char uid[33];
/// todo:salt/hash
char password[33];
};
// complete player state
// saved on save request, but kept in runtime
struct GGMTempState
{
char mapname[32];
Vector vecOrigin;
float flHealth;
float flBattery;
int iFrags;
int iDeaths;
char rgWeapons[MAX_WEAPONS][32];// weapon names
char rgiClip[MAX_WEAPONS];// ammo names
int rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
char WeaponName[32];
};
struct GGMPlayerState
{
struct GGMPlayerState *pNext;
struct GGMPersist p;
struct GGMTempState t;
bool registered;
};
struct GGMData
{
float m_flSpawnTime;
PlayerState m_state;
bool m_fTouchMenu;
int m_iMenuState;
int m_iLocalConfirm;
int m_iConfirmKey;
float m_flEntScope;
float m_flEntTime;
char uid[33];
GGM_PlayerMenu menu;
bool touch_loading;
struct GGMPlayerState *pState;
char registering_name[32];
};
struct GGMPlayerState *GGM_GetState(const char *uid, const char *name);
bool GGM_RestoreState( CBasePlayer *pPlayer );
void GGM_SaveState( CBasePlayer *pPlayer );
bool GGM_PlayerSpawn( CBasePlayer *pPlayer );
#endif // GRAVGUNMOD_H

View File

@ -414,6 +414,7 @@ BOOL CHalfLifeMultiplay::ClientConnected( edict_t *pEntity, const char *pszName,
extern int gmsgSayText;
extern int gmsgGameMode;
void ClientPutInServer( edict_t *client );
void CHalfLifeMultiplay::UpdateGameMode( CBasePlayer *pPlayer )
@ -598,51 +599,20 @@ extern EHANDLE g_pLastSpawn;
//=========================================================
void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer )
{
BOOL addDefault;
BOOL addDefault = !mp_skipdefaults.value;
CBaseEntity *pWeaponEntity = NULL;
if( pPlayer->gravgunmod_data.m_state == STATE_UNINITIALIZED )
{
ClientPutInServer( pPlayer->edict() );
if( GGM_PlayerSpawn( pPlayer ) )
return;
}
if( mp_spectator.value && pPlayer->gravgunmod_data.m_state == STATE_CONNECTED )
{
pPlayer->gravgunmod_data.m_state = STATE_SPECTATOR_BEGIN;
pPlayer->RemoveAllItems( TRUE );
UTIL_BecomeSpectator( pPlayer );
return;
}
if( mp_coop_changelevel.value && pPlayer->gravgunmod_data.m_state == STATE_POINT_SELECT && !(pPlayer->pev->flags & FL_SPECTATOR) )
{
pPlayer->RemoveAllItems( TRUE );
UTIL_BecomeSpectator( pPlayer );
return;
}
if( pPlayer->pev->flags & FL_SPECTATOR )
return;
if( !mp_coop_changelevel.value )
pPlayer->gravgunmod_data.m_state = STATE_SPAWNED;
g_fPause = false;
pPlayer->pev->weapons |= ( 1 << WEAPON_SUIT );
addDefault = !mp_skipdefaults.value;
while( ( pWeaponEntity = UTIL_FindEntityByClassname( pWeaponEntity, "game_player_equip" ) ) )
{
pWeaponEntity->Touch( pPlayer );
addDefault = FALSE;
}
if( pPlayer->gravgunmod_data.m_state != STATE_SPAWNED )
return;
if( addDefault )
{
pPlayer->GiveNamedItem( "weapon_crowbar" );