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;
}
struct checkpoint_s
{
char str[32];
float time;
Vector origin;
Vector angles;
} g_checkpoints[4];
void COOP_ClearData( void )
{
// nullify
SavedCoords l_SavedCoords = {0};
g_SavedCoords = l_SavedCoords;
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
msglimittime1 = msglimittime2 = 0;
}
@ -352,7 +342,6 @@ void COOP_ApplyData( void )
}
g_fPause = false;
ALERT( at_console, "^2CoopApplyData()\n" );
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
msglimittime1 = msglimittime2 = 0;
}
@ -366,15 +355,25 @@ struct GGMLandmarkTransition
Vector vecLandmark;
};
struct GGMCheckpoint
{
char szDisplayName[32];
float flTime;
struct GGMPosition pos;
};
// offset for all maps relative to current map
struct GGMMapState
{
struct GGMMapState *pNext;
char mapName[32];
Vector vecOffset;
struct GGMCheckpoint checkpoints[5];
};
GGMMapState *g_pMapOffsets;
GGMMapState *g_pMapStates;
GGMMapState *g_pCurrentMap;
GGMLandmarkTransition g_landmarkTransition;
edict_t *COOP_FindLandmark( const char *pLandmarkName );
bool COOP_ProcessTransition( void )
@ -395,25 +394,26 @@ bool COOP_ProcessTransition( void )
return false;
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;
g_pCurrentMap = pMapState;
continue;
}
pOffset->vecOffset = pOffset->vecOffset - g_landmarkTransition.vecLandmark + lm;
pMapState->vecOffset = pMapState->vecOffset - g_landmarkTransition.vecLandmark + lm;
}
if( fAddCurrent )
{
GGMMapState *pNewOffset = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
GGMMapState *pNewState = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
pNewOffset->pNext = g_pMapOffsets;
pNewOffset->vecOffset = Vector(0, 0, 0);
strncpy(pNewOffset->mapName, STRING(gpGlobals->mapname), 31);
g_pMapOffsets = pNewOffset;
pNewState->pNext = g_pMapStates;
pNewState->vecOffset = Vector(0, 0, 0);
strncpy(pNewState->mapName, STRING(gpGlobals->mapname), 31);
g_pMapStates = g_pCurrentMap = pNewState;
}
return true;
}
@ -431,18 +431,18 @@ void COOP_ServerActivate( void )
if( !COOP_ProcessTransition() )
{
ALERT( at_console, "Transition failed, new game started\n");
while( g_pMapOffsets )
while( g_pMapStates )
{
GGMMapState *pOffset = g_pMapOffsets;
g_pMapOffsets = pOffset->pNext;
free( pOffset );
GGMMapState *pMapState = g_pMapStates;
g_pMapStates = pMapState->pNext;
free( pMapState );
}
GGMMapState *pNewOffset = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
GGMMapState *pNewState = (GGMMapState *)calloc(1, sizeof( struct GGMMapState ) );
pNewOffset->pNext = g_pMapOffsets;
pNewOffset->vecOffset = Vector(0, 0, 0);
strncpy(pNewOffset->mapName, STRING(gpGlobals->mapname), 31);
g_pMapOffsets = pNewOffset;
pNewState->pNext = g_pMapStates;
pNewState->vecOffset = Vector(0, 0, 0);
strncpy(pNewState->mapName, STRING(gpGlobals->mapname), 31);
g_pMapStates = g_pCurrentMap = pNewState;
if( mp_coop.value )
COOP_ClearData();
}
@ -470,7 +470,7 @@ void COOP_ServerActivate( void )
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 ) )
{
@ -603,11 +603,10 @@ void COOP_NewCheckpoint( entvars_t *pevPlayer )
{
if( !pevPlayer->netname )
return;
memmove( &g_checkpoints[1], &g_checkpoints[0], sizeof ( g_checkpoints[0] ) * 3 );
g_checkpoints[0].time = gpGlobals->time;
snprintf( g_checkpoints[0].str, 31, "%5s %d", STRING( pevPlayer->netname ), (int)( gpGlobals->time / 60 ) );
g_checkpoints[0].origin = pevPlayer->origin;
g_checkpoints[0].angles = pevPlayer->angles;
memmove( &g_pCurrentMap->checkpoints[1], &g_pCurrentMap->checkpoints[0], sizeof ( g_pCurrentMap->checkpoints[0] ) * 3 );
g_pCurrentMap->checkpoints[0].flTime = gpGlobals->time;
snprintf( g_pCurrentMap->checkpoints[0].szDisplayName, 31, "%5s %d", STRING( pevPlayer->netname ), (int)( gpGlobals->time / 60 ) );
GGM_SavePosition( (CBasePlayer*)CBaseEntity::Instance( pevPlayer ), &g_pCurrentMap->checkpoints[0].pos );
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 )
// return true;
if( g_checkpoints[0].time )
if( g_pCurrentMap->checkpoints[0].flTime )
{
COOP_CheckpointMenu( pPlayer );
return true;
@ -790,7 +789,7 @@ bool COOP_ConfirmMenu(CBaseEntity *pTrigger, CBaseEntity *pActivator, int count2
if( mp_coop_strongcheckpoints.value )
{
// 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();
//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 )
return;
if( !g_pCurrentMap )
return;
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 )
@ -843,11 +845,11 @@ void COOP_CheckpointMenu( CBasePlayer *pPlayer )
else
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];
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();
@ -872,7 +874,7 @@ bool COOP_ClientCommand( edict_t *pEntity )
{
if( pPlayer->gravgunmod_data.m_state == STATE_SPAWNED )
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 );
else
{
@ -925,10 +927,9 @@ bool COOP_ClientCommand( edict_t *pEntity )
int i = atoi(CMD_ARGV(1));
if( i > 4 )
return false;
pPlayer->RemoveAllItems( TRUE );
UTIL_SpawnPlayer( pPlayer );
pPlayer->pev->origin = g_checkpoints[i].origin;
pPlayer->pev->angles = g_checkpoints[i].angles;
if( pPlayer->gravgunmod_data.m_state != STATE_SPAWNED )
UTIL_SpawnPlayer( pPlayer );
GGM_RestorePosition( pPlayer, &g_pCurrentMap->checkpoints[i].pos );
return true;
}
else if( FStrEq( pcmd, "newcheckpoint") )

View File

@ -860,6 +860,27 @@ void GGM_ServerActivate( void )
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 )
{
if( !pPlayer )
@ -879,23 +900,7 @@ void GGM_SaveState( CBasePlayer *pPlayer )
if( pPlayer->pev->health <= 0 )
return;
pState->t.pos.vecOrigin = pPlayer->pev->origin;
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;
GGM_SavePosition( pPlayer, &pState->t.pos );
pState->t.flHealth = pPlayer->pev->health;
pState->t.flBattery = pPlayer->pev->armorvalue;
@ -988,7 +993,7 @@ bool GGM_RestoreState( CBasePlayer *pPlayer )
pPlayer->pev->armorvalue = pState->t.flBattery;
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;
pPlayer->RemoveAllItems( FALSE );

View File

@ -179,6 +179,8 @@ struct GGMData
struct GGMPlayerState *GGM_GetState(const char *uid, const char *name);
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 );
bool GGM_PlayerSpawn( CBasePlayer *pPlayer );
const char *GGM_GetAuthID( CBasePlayer *pPlayer );