mirror of https://github.com/FWGS/hlsdk-xash3d
Advanced coop spawnpoint generation
This commit is contained in:
parent
0b22605eb4
commit
dd54375dd6
|
@ -670,13 +670,25 @@ void PlayerPostThink( edict_t *pEntity )
|
|||
pPlayer->PostThink( );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CoopClearData( void );
|
||||
void CoopClearWeaponList( void );
|
||||
void ParmsNewLevel( void )
|
||||
{
|
||||
// retrieve the pointer to the save data
|
||||
SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData;
|
||||
|
||||
if ( pSaveData )
|
||||
pSaveData->connectionCount = BuildChangeList( pSaveData->levelList, MAX_LEVEL_CONNECTIONS );
|
||||
else
|
||||
if( mp_coop_changelevel.value )
|
||||
{
|
||||
CoopClearData();
|
||||
CoopClearWeaponList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ParmsChangeLevel( void )
|
||||
{
|
||||
// retrieve the pointer to the save data
|
||||
|
@ -684,6 +696,13 @@ void ParmsChangeLevel( void )
|
|||
|
||||
if ( pSaveData )
|
||||
pSaveData->connectionCount = BuildChangeList( pSaveData->levelList, MAX_LEVEL_CONNECTIONS );
|
||||
else
|
||||
if( mp_coop_changelevel.value )
|
||||
{
|
||||
CoopClearData();
|
||||
CoopClearWeaponList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,9 @@ BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
bool CoopGetSpawnPoint( Vector *point, Vector *angles);
|
||||
|
||||
bool CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles );
|
||||
|
||||
//=========================================================
|
||||
//=========================================================
|
||||
|
@ -72,6 +75,8 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
|||
pPlayer->pev->velocity = g_vecZero;
|
||||
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
|
||||
pPlayer->pev->punchangle = g_vecZero;
|
||||
if( mp_coop_changelevel.value && !CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles ))
|
||||
CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles );
|
||||
pPlayer->pev->fixangle = TRUE;
|
||||
|
||||
return pentSpawnSpot;
|
||||
|
|
|
@ -84,8 +84,17 @@ public:
|
|||
for(int i = 0; i < m_iWeapons;i++)
|
||||
player->GiveNamedItem(weapons[i]);
|
||||
}
|
||||
void Clear()
|
||||
{
|
||||
m_iWeapons = 0;
|
||||
}
|
||||
} g_WeaponList;
|
||||
|
||||
void CoopClearWeaponList( void )
|
||||
{
|
||||
g_WeaponList.Clear();
|
||||
}
|
||||
|
||||
//*********************************************************
|
||||
// Rules for the half-life multiplayer game.
|
||||
//*********************************************************
|
||||
|
|
|
@ -1445,6 +1445,92 @@ void CChangeLevel::UseChangeLevel( CBaseEntity *pActivator, CBaseEntity *pCaller
|
|||
ChangeLevelNow( pActivator );
|
||||
}
|
||||
|
||||
struct SavedCoords
|
||||
{
|
||||
char ip[32][32];
|
||||
Vector origin[32];
|
||||
Vector angles[32];
|
||||
char landmark[32];
|
||||
Vector triggerorigin;
|
||||
Vector triggerangles;
|
||||
Vector offset;
|
||||
int iCount;
|
||||
bool valid;
|
||||
bool validoffset;
|
||||
bool validspawnpoint;
|
||||
} g_SavedCoords;
|
||||
void CoopClearData( void )
|
||||
{
|
||||
// nullify
|
||||
SavedCoords l_SavedCoords = {};
|
||||
g_SavedCoords = l_SavedCoords;
|
||||
}
|
||||
|
||||
static void validateoffset( void )
|
||||
{
|
||||
if( !g_SavedCoords.validoffset)
|
||||
{
|
||||
edict_t *landmark = CChangeLevel::FindLandmark(g_SavedCoords.landmark);
|
||||
if(landmark)
|
||||
g_SavedCoords.offset = landmark->v.origin - g_SavedCoords.offset;
|
||||
else
|
||||
g_SavedCoords.offset = g_vecZero;
|
||||
g_SavedCoords.validoffset = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles )
|
||||
{
|
||||
if(!g_SavedCoords.valid)
|
||||
return false;
|
||||
validateoffset();
|
||||
// compute player by IQ
|
||||
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( player->edict() ), "ip" );
|
||||
for( int i = 0;i < g_SavedCoords.iCount;i++)
|
||||
{
|
||||
if(!strcmp(ip, g_SavedCoords.ip[i]))
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector point = g_SavedCoords.origin[i] + g_SavedCoords.offset;
|
||||
|
||||
UTIL_TraceHull( point, point, missile, human_hull, NULL, &tr );
|
||||
g_SavedCoords.ip[i][0] = 0;
|
||||
|
||||
if( tr.fStartSolid )
|
||||
return false;
|
||||
*origin = point;
|
||||
*angles = g_SavedCoords.angles[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoopGetSpawnPoint( Vector *point, Vector *angles)
|
||||
{
|
||||
if(!g_SavedCoords.valid)
|
||||
return false;
|
||||
validateoffset();
|
||||
*point = g_SavedCoords.triggerorigin + g_SavedCoords.offset;
|
||||
*angles = g_SavedCoords.triggerangles;
|
||||
if( !g_SavedCoords.validspawnpoint )
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector angle;
|
||||
UTIL_MakeVectorsPrivate( *angles, (float*)&angle, NULL, NULL );
|
||||
UTIL_TraceHull( *point, *point + angle * 100, missile, human_hull, NULL, &tr );
|
||||
if( !tr.fStartSolid )
|
||||
{
|
||||
g_SavedCoords.triggerorigin = tr.vecEndPos;
|
||||
g_SavedCoords.validspawnpoint = true;
|
||||
}
|
||||
else
|
||||
g_SavedCoords.valid = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
||||
{
|
||||
edict_t *pentLandmark;
|
||||
|
@ -1454,9 +1540,11 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||
|
||||
if(mp_coop_changelevel.value)
|
||||
{
|
||||
SavedCoords l_SavedCoords = {};
|
||||
// if not activated by touch, do not count players
|
||||
if( !m_bUsed )
|
||||
{
|
||||
|
||||
m_uTouchCount |= ENTINDEX( pActivator->edict() );
|
||||
unsigned int count1 = m_uTouchCount;
|
||||
unsigned int count2 = 0;
|
||||
|
@ -1475,6 +1563,17 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||
if( plr )
|
||||
{
|
||||
count2++;
|
||||
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( plr->edict() ), "ip" );
|
||||
|
||||
// player touched trigger, save it's coordinates
|
||||
if( m_uTouchCount & (i - 1) )
|
||||
{
|
||||
strcpy(l_SavedCoords.ip[l_SavedCoords.iCount], ip );
|
||||
l_SavedCoords.origin[l_SavedCoords.iCount] = plr->pev->origin;
|
||||
l_SavedCoords.angles[l_SavedCoords.iCount] = plr->pev->angles;
|
||||
l_SavedCoords.iCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1495,7 +1594,13 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||
|
||||
if( count1 == 1 && count2 == 2 )
|
||||
return;
|
||||
g_SavedCoords.triggerangles = pActivator->pev->angles;
|
||||
g_SavedCoords.triggerorigin = pActivator->pev->origin;
|
||||
g_SavedCoords.valid = true;
|
||||
}
|
||||
g_SavedCoords = l_SavedCoords;
|
||||
|
||||
|
||||
}
|
||||
// Don't work in deathmatch
|
||||
else if( g_pGameRules->IsDeathmatch() )
|
||||
|
@ -1544,7 +1649,8 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||
if( !FNullEnt( pentLandmark ) )
|
||||
{
|
||||
strcpy( st_szNextSpot, m_szLandmarkName );
|
||||
gpGlobals->vecLandmarkOffset = VARS( pentLandmark )->origin;
|
||||
strcpy( g_SavedCoords.landmark, m_szLandmarkName );
|
||||
g_SavedCoords.offset = gpGlobals->vecLandmarkOffset = VARS( pentLandmark )->origin;
|
||||
}
|
||||
//ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) );
|
||||
ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot );
|
||||
|
|
|
@ -1585,11 +1585,11 @@ void UTIL_CleanSpawnPoint( Vector origin, float dist )
|
|||
{
|
||||
if( ent->IsPlayer() )
|
||||
{
|
||||
TraceResult tr = {0};
|
||||
TraceResult tr;
|
||||
UTIL_TraceHull( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), dont_ignore_monsters, human_hull, ent->edict(), &tr);
|
||||
//UTIL_TraceModel( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), 0, ent->edict(), &tr);
|
||||
|
||||
UTIL_SetOrigin(ent->pev, tr.vecEndPos);
|
||||
if( !tr.fAllSolid )
|
||||
UTIL_SetOrigin(ent->pev, tr.vecEndPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue