Update checkpoint system

This commit is contained in:
mittorn 2018-10-21 08:21:58 +07:00
parent e46a562572
commit 8ce5c9d317
3 changed files with 71 additions and 63 deletions

View File

@ -322,21 +322,11 @@ bool UTIL_CoopIsBadPlayer( CBaseEntity *plr )
return false; return false;
} }
struct checkpoint_s
{
char str[32];
float time;
Vector origin;
Vector angles;
} g_checkpoints[4];
void COOP_ClearData( void ) void COOP_ClearData( void )
{ {
// nullify // nullify
SavedCoords l_SavedCoords = {0}; SavedCoords l_SavedCoords = {0};
g_SavedCoords = l_SavedCoords; g_SavedCoords = l_SavedCoords;
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
msglimittime1 = msglimittime2 = 0; msglimittime1 = msglimittime2 = 0;
} }
@ -352,7 +342,6 @@ void COOP_ApplyData( void )
} }
g_fPause = false; g_fPause = false;
ALERT( at_console, "^2CoopApplyData()\n" ); ALERT( at_console, "^2CoopApplyData()\n" );
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
msglimittime1 = msglimittime2 = 0; msglimittime1 = msglimittime2 = 0;
} }
@ -366,15 +355,25 @@ struct GGMLandmarkTransition
Vector vecLandmark; Vector vecLandmark;
}; };
struct GGMCheckpoint
{
char szDisplayName[32];
float flTime;
struct GGMPosition pos;
};
// offset for all maps relative to current map // offset for all maps relative to current map
struct GGMMapState struct GGMMapState
{ {
struct GGMMapState *pNext; struct GGMMapState *pNext;
char mapName[32]; char mapName[32];
Vector vecOffset; Vector vecOffset;
struct GGMCheckpoint checkpoints[5];
}; };
GGMMapState *g_pMapOffsets; GGMMapState *g_pMapStates;
GGMMapState *g_pCurrentMap;
GGMLandmarkTransition g_landmarkTransition; GGMLandmarkTransition g_landmarkTransition;
edict_t *COOP_FindLandmark( const char *pLandmarkName ); edict_t *COOP_FindLandmark( const char *pLandmarkName );
bool COOP_ProcessTransition( void ) bool COOP_ProcessTransition( void )
@ -395,25 +394,26 @@ bool COOP_ProcessTransition( void )
return false; return false;
Vector &lm = landmark->v.origin; Vector &lm = landmark->v.origin;
for( GGMMapState *pOffset = g_pMapOffsets; pOffset; pOffset = pOffset->pNext ) for( struct GGMMapState *pMapState = g_pMapStates; pMapState; pMapState = pMapState->pNext )
{ {
if( !strcmp( pOffset->mapName, STRING(gpGlobals->mapname) ) ) if( !strcmp( pMapState->mapName, STRING(gpGlobals->mapname) ) )
{ {
pOffset->vecOffset = Vector( 0, 0, 0 ); pMapState->vecOffset = Vector( 0, 0, 0 );
fAddCurrent = false; fAddCurrent = false;
g_pCurrentMap = pMapState;
continue; continue;
} }
pOffset->vecOffset = pOffset->vecOffset - g_landmarkTransition.vecLandmark + lm; pMapState->vecOffset = pMapState->vecOffset - g_landmarkTransition.vecLandmark + lm;
} }
if( fAddCurrent ) if( fAddCurrent )
{ {
GGMMapState *pNewOffset = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) ); GGMMapState *pNewState = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
pNewOffset->pNext = g_pMapOffsets; pNewState->pNext = g_pMapStates;
pNewOffset->vecOffset = Vector(0, 0, 0); pNewState->vecOffset = Vector(0, 0, 0);
strncpy(pNewOffset->mapName, STRING(gpGlobals->mapname), 31); strncpy(pNewState->mapName, STRING(gpGlobals->mapname), 31);
g_pMapOffsets = pNewOffset; g_pMapStates = g_pCurrentMap = pNewState;
} }
return true; return true;
} }
@ -431,18 +431,18 @@ void COOP_ServerActivate( void )
if( !COOP_ProcessTransition() ) if( !COOP_ProcessTransition() )
{ {
ALERT( at_console, "Transition failed, new game started\n"); ALERT( at_console, "Transition failed, new game started\n");
while( g_pMapOffsets ) while( g_pMapStates )
{ {
GGMMapState *pOffset = g_pMapOffsets; GGMMapState *pMapState = g_pMapStates;
g_pMapOffsets = pOffset->pNext; g_pMapStates = pMapState->pNext;
free( pOffset ); free( pMapState );
} }
GGMMapState *pNewOffset = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) ); GGMMapState *pNewState = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
pNewOffset->pNext = g_pMapOffsets; pNewState->pNext = g_pMapStates;
pNewOffset->vecOffset = Vector(0, 0, 0); pNewState->vecOffset = Vector(0, 0, 0);
strncpy(pNewOffset->mapName, STRING(gpGlobals->mapname), 31); strncpy(pNewState->mapName, STRING(gpGlobals->mapname), 31);
g_pMapOffsets = pNewOffset; g_pMapStates = g_pCurrentMap = pNewState;
if( mp_coop.value ) if( mp_coop.value )
COOP_ClearData(); COOP_ClearData();
} }
@ -470,7 +470,7 @@ void COOP_ServerActivate( void )
bool COOP_GetOrigin( Vector *pvecNewOrigin, const Vector &vecOrigin, const char *pszMapName ) bool COOP_GetOrigin( Vector *pvecNewOrigin, const Vector &vecOrigin, const char *pszMapName )
{ {
for( GGMMapState *pOffset = g_pMapOffsets; pOffset; pOffset = pOffset->pNext ) for( GGMMapState *pOffset = g_pMapStates; pOffset; pOffset = pOffset->pNext )
{ {
if( !strcmp( pOffset->mapName, pszMapName ) ) if( !strcmp( pOffset->mapName, pszMapName ) )
{ {
@ -603,11 +603,10 @@ void COOP_NewCheckpoint( entvars_t *pevPlayer )
{ {
if( !pevPlayer->netname ) if( !pevPlayer->netname )
return; return;
memmove( &g_checkpoints[1], &g_checkpoints[0], sizeof ( g_checkpoints[0] ) * 3 ); memmove( &g_pCurrentMap->checkpoints[1], &g_pCurrentMap->checkpoints[0], sizeof ( g_pCurrentMap->checkpoints[0] ) * 3 );
g_checkpoints[0].time = gpGlobals->time; g_pCurrentMap->checkpoints[0].flTime = gpGlobals->time;
snprintf( g_checkpoints[0].str, 31, "%5s %d", STRING( pevPlayer->netname ), (int)( gpGlobals->time / 60 ) ); snprintf( g_pCurrentMap->checkpoints[0].szDisplayName, 31, "%5s %d", STRING( pevPlayer->netname ), (int)( gpGlobals->time / 60 ) );
g_checkpoints[0].origin = pevPlayer->origin; GGM_SavePosition( (CBasePlayer*)CBaseEntity::Instance( pevPlayer ), &g_pCurrentMap->checkpoints[0].pos );
g_checkpoints[0].angles = pevPlayer->angles;
UTIL_CoopPrintMessage("New checkpoint by %s!\n", STRING( pevPlayer->netname ) ); UTIL_CoopPrintMessage("New checkpoint by %s!\n", STRING( pevPlayer->netname ) );
} }
@ -618,7 +617,7 @@ bool COOP_PlayerDeath( CBasePlayer *pPlayer )
// if( pPlayer->gravgunmod_data.m_iMenuState == MENUSTATE_CHECKPOINT ) // if( pPlayer->gravgunmod_data.m_iMenuState == MENUSTATE_CHECKPOINT )
// return true; // return true;
if( g_checkpoints[0].time ) if( g_pCurrentMap->checkpoints[0].flTime )
{ {
COOP_CheckpointMenu( pPlayer ); COOP_CheckpointMenu( pPlayer );
return true; return true;
@ -790,7 +789,7 @@ bool COOP_ConfirmMenu(CBaseEntity *pTrigger, CBaseEntity *pActivator, int count2
if( mp_coop_strongcheckpoints.value ) if( mp_coop_strongcheckpoints.value )
{ {
// do not allow go back if there are checkpoints, but not near changelevel // do not allow go back if there are checkpoints, but not near changelevel
if( g_checkpoints[0].time && (g_checkpoints[0].origin - VecBModelOrigin(pTrigger->pev)).Length() > 150 ) if( g_pCurrentMap->checkpoints[0].flTime && (g_pCurrentMap->checkpoints[0].pos.vecOrigin - VecBModelOrigin(pTrigger->pev)).Length() > 150 )
{ {
COOP_ResetVote(); COOP_ResetVote();
//UTIL_CoopPlayerMessage( pActivator, 1, 5, 0xFF0000FF, 0xFF0000FF, 0, 0.7, "Changelevel back locked by checkpoint\nCheckpoint here to activate trigger!"); //UTIL_CoopPlayerMessage( pActivator, 1, 5, 0xFF0000FF, 0xFF0000FF, 0, 0.7, "Changelevel back locked by checkpoint\nCheckpoint here to activate trigger!");
@ -836,6 +835,9 @@ void COOP_CheckpointMenu( CBasePlayer *pPlayer )
if( !mp_coop_checkpoints.value ) if( !mp_coop_checkpoints.value )
return; return;
if( !g_pCurrentMap )
return;
GGM_PlayerMenu &m = pPlayer->gravgunmod_data.menu.New("Select checkpoint", false); GGM_PlayerMenu &m = pPlayer->gravgunmod_data.menu.New("Select checkpoint", false);
if( pPlayer->gravgunmod_data.m_state == STATE_SPECTATOR || pPlayer->gravgunmod_data.m_state == STATE_SPECTATOR_BEGIN || pPlayer->pev->health <= 0 ) if( pPlayer->gravgunmod_data.m_state == STATE_SPECTATOR || pPlayer->gravgunmod_data.m_state == STATE_SPECTATOR_BEGIN || pPlayer->pev->health <= 0 )
@ -843,11 +845,11 @@ void COOP_CheckpointMenu( CBasePlayer *pPlayer )
else else
m.Add("New checkpoint", "newcheckpoint"); m.Add("New checkpoint", "newcheckpoint");
for( i = 1; g_checkpoints[i-1].time; i++ ) for( i = 1; g_pCurrentMap->checkpoints[i-1].flTime; i++ )
{ {
char cmd[32]; char cmd[32];
sprintf(cmd, "loadcheckpoint %d", i-1 ); sprintf(cmd, "loadcheckpoint %d", i-1 );
m.Add(g_checkpoints[i-1].str, cmd); m.Add(g_pCurrentMap->checkpoints[i-1].szDisplayName, cmd);
} }
m.Show(); m.Show();
@ -872,7 +874,7 @@ bool COOP_ClientCommand( edict_t *pEntity )
{ {
if( pPlayer->gravgunmod_data.m_state == STATE_SPAWNED ) if( pPlayer->gravgunmod_data.m_state == STATE_SPAWNED )
return false; return false;
if( mp_coop_checkpoints.value && g_checkpoints[0].str[0] ) if( mp_coop_checkpoints.value && g_pCurrentMap && g_pCurrentMap->checkpoints[0].szDisplayName[0] )
COOP_CheckpointMenu( pPlayer ); COOP_CheckpointMenu( pPlayer );
else else
{ {
@ -925,10 +927,9 @@ bool COOP_ClientCommand( edict_t *pEntity )
int i = atoi(CMD_ARGV(1)); int i = atoi(CMD_ARGV(1));
if( i > 4 ) if( i > 4 )
return false; return false;
pPlayer->RemoveAllItems( TRUE ); if( pPlayer->gravgunmod_data.m_state != STATE_SPAWNED )
UTIL_SpawnPlayer( pPlayer ); UTIL_SpawnPlayer( pPlayer );
pPlayer->pev->origin = g_checkpoints[i].origin; GGM_RestorePosition( pPlayer, &g_pCurrentMap->checkpoints[i].pos );
pPlayer->pev->angles = g_checkpoints[i].angles;
return true; return true;
} }
else if( FStrEq( pcmd, "newcheckpoint") ) else if( FStrEq( pcmd, "newcheckpoint") )

View File

@ -860,6 +860,27 @@ void GGM_ServerActivate( void )
COOP_ServerActivate(); COOP_ServerActivate();
} }
void GGM_SavePosition( CBasePlayer *pPlayer, struct GGMPosition *pos )
{
pos->vecOrigin = pPlayer->pev->origin;
pos->vecAngles = pPlayer->pev->angles;
pos->fDuck = !!(pPlayer->pev->flags & FL_DUCKING);
strncpy( pos->mapName, STRING(gpGlobals->mapname), 31 );
CBaseEntity *pTrain = UTIL_CoopGetPlayerTrain(pPlayer);
if( pTrain )
{
strcpy( pos->trainGlobal, STRING( pTrain->pev->globalname ) );
if( pTrain->pev->angles == g_vecZero )
pos->vecTrainOffset = pPlayer->pev->origin - VecBModelOrigin(pTrain->pev);
else
pos->vecTrainOffset = pPlayer->pev->origin - pTrain->pev->origin;
pos->vecTrainAngles = pTrain->pev->angles;
}
else pos->trainGlobal[0] = 0;
}
void GGM_SaveState( CBasePlayer *pPlayer ) void GGM_SaveState( CBasePlayer *pPlayer )
{ {
if( !pPlayer ) if( !pPlayer )
@ -879,23 +900,7 @@ void GGM_SaveState( CBasePlayer *pPlayer )
if( pPlayer->pev->health <= 0 ) if( pPlayer->pev->health <= 0 )
return; return;
pState->t.pos.vecOrigin = pPlayer->pev->origin; GGM_SavePosition( pPlayer, &pState->t.pos );
pState->t.pos.vecAngles = pPlayer->pev->angles;
pState->t.pos.fDuck = !!(pPlayer->pev->flags & FL_DUCKING);
strncpy( pState->t.pos.mapName, STRING(gpGlobals->mapname), 31 );
CBaseEntity *pTrain = UTIL_CoopGetPlayerTrain(pPlayer);
if( pTrain )
{
strcpy( pState->t.pos.trainGlobal, STRING( pTrain->pev->globalname ) );
if( pTrain->pev->angles == g_vecZero )
pState->t.pos.vecTrainOffset = pPlayer->pev->origin - VecBModelOrigin(pTrain->pev);
else
pState->t.pos.vecTrainOffset = pPlayer->pev->origin - pTrain->pev->origin;
pState->t.pos.vecTrainAngles = pTrain->pev->angles;
}
else pState->t.pos.trainGlobal[0] = 0;
pState->t.flHealth = pPlayer->pev->health; pState->t.flHealth = pPlayer->pev->health;
pState->t.flBattery = pPlayer->pev->armorvalue; pState->t.flBattery = pPlayer->pev->armorvalue;
@ -988,7 +993,7 @@ bool GGM_RestoreState( CBasePlayer *pPlayer )
pPlayer->pev->armorvalue = pState->t.flBattery; pPlayer->pev->armorvalue = pState->t.flBattery;
pPlayer->pev->health = pState->t.flHealth; pPlayer->pev->health = pState->t.flHealth;
if( !GGM_RestorePosition( pPlayer, &pPlayer->gravgunmod_data.pState->t.pos ) ) if( !GGM_RestorePosition( pPlayer, &pState->t.pos ) )
return false; return false;
pPlayer->RemoveAllItems( FALSE ); pPlayer->RemoveAllItems( FALSE );

View File

@ -179,6 +179,8 @@ struct GGMData
struct GGMPlayerState *GGM_GetState(const char *uid, const char *name); struct GGMPlayerState *GGM_GetState(const char *uid, const char *name);
bool GGM_RestoreState( CBasePlayer *pPlayer ); bool GGM_RestoreState( CBasePlayer *pPlayer );
bool GGM_RestorePosition( CBasePlayer *pPlayer, struct GGMPosition *pos );
void GGM_SavePosition( CBasePlayer *pPlayer, struct GGMPosition *pos );
void GGM_SaveState( CBasePlayer *pPlayer ); void GGM_SaveState( CBasePlayer *pPlayer );
bool GGM_PlayerSpawn( CBasePlayer *pPlayer ); bool GGM_PlayerSpawn( CBasePlayer *pPlayer );
const char *GGM_GetAuthID( CBasePlayer *pPlayer ); const char *GGM_GetAuthID( CBasePlayer *pPlayer );