I meant, even with a semiclip.
Code:
BOOL IsSpawnPointValid( CBaseEntity *pPlayer, CBaseEntity *pSpot )
{
CBaseEntity *ent = NULL;
if ( !pSpot->IsTriggered( pPlayer ) )
{
return FALSE;
}
while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 128 )) != NULL )
{
// if ent is a client, don't spawn on 'em
if ( ent->IsPlayer() && ent != pPlayer )
return FALSE;
}
return TRUE;
}
void CBasePlayer::Spawn( void )
{
// [...]
g_pGameRules->PlayerSpawn( this );
}
edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer )
{
edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer );
pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1);
pPlayer->pev->v_angle = g_vecZero;
pPlayer->pev->velocity = g_vecZero;
pPlayer->pev->angles = VARS(pentSpawnSpot)->angles;
pPlayer->pev->punchangle = g_vecZero;
pPlayer->pev->fixangle = TRUE;
return pentSpawnSpot;
}
edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer )
{
CBaseEntity *pSpot;
edict_t *player;
player = pPlayer->edict();
// choose a info_player_deathmatch point
if (g_pGameRules->IsCoOp())
{
pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_coop");
if ( !FNullEnt(pSpot) )
goto ReturnSpot;
pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_start");
if ( !FNullEnt(pSpot) )
goto ReturnSpot;
}
else if ( g_pGameRules->IsDeathmatch() )
{
pSpot = g_pLastSpawn;
// Randomize the start spot
for ( int i = RANDOM_LONG(1,5); i > 0; i-- )
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
if ( FNullEnt( pSpot ) ) // skip over the null point
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
CBaseEntity *pFirstSpot = pSpot;
do
{
if ( pSpot )
{
// check if pSpot is valid
if ( IsSpawnPointValid( pPlayer, pSpot ) )
{
if ( pSpot->pev->origin == Vector( 0, 0, 0 ) )
{
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
continue;
}
// if so, go to pSpot
goto ReturnSpot;
}
}
// increment pSpot
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
} while ( pSpot != pFirstSpot ); // loop if we're not back to the start
// we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there
if ( !FNullEnt( pSpot ) )
{
CBaseEntity *ent = NULL;
while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 128 )) != NULL )
{
// if ent is a client, kill em (unless they are ourselves)
if ( ent->IsPlayer() && !(ent->edict() == player) )
ent->TakeDamage( VARS(INDEXENT(0)), VARS(INDEXENT(0)), 300, DMG_GENERIC );
}
goto ReturnSpot;
}
}
// If startspot is set, (re)spawn there.
if ( FStringNull( gpGlobals->startspot ) || !strlen(STRING(gpGlobals->startspot)))
{
pSpot = UTIL_FindEntityByClassname(NULL, "info_player_start");
if ( !FNullEnt(pSpot) )
goto ReturnSpot;
}
else
{
pSpot = UTIL_FindEntityByTargetname( NULL, STRING(gpGlobals->startspot) );
if ( !FNullEnt(pSpot) )
goto ReturnSpot;
}
ReturnSpot:
if ( FNullEnt( pSpot ) )
{
ALERT(at_error, "PutClientInServer: no info_player_start on level");
return INDEXENT(0);
}
g_pLastSpawn = pSpot;
return pSpot->edict();
}
__________________