mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 12:06:07 +08:00
First version of the SOurce SDK 2013
This commit is contained in:
191
game/server/ai_saverestore.cpp
Normal file
191
game/server/ai_saverestore.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "isaverestore.h"
|
||||
#include "saverestore_utlvector.h"
|
||||
#include "ai_saverestore.h"
|
||||
#include "ai_basenpc.h"
|
||||
#include "ai_squad.h"
|
||||
#include "ai_network.h"
|
||||
#include "ai_networkmanager.h"
|
||||
|
||||
#ifdef HL2_DLL
|
||||
#include "npc_playercompanion.h"
|
||||
#endif // HL2_DLL
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static short AI_SAVE_RESTORE_VERSION = 2;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CAI_SaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
|
||||
{
|
||||
public:
|
||||
const char *GetBlockName()
|
||||
{
|
||||
return "AI";
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Save( ISave *pSave )
|
||||
{
|
||||
pSave->StartBlock( "Squads" );
|
||||
short nSquads = (short)g_AI_SquadManager.NumSquads();
|
||||
pSave->WriteShort( &nSquads );
|
||||
|
||||
AISquadsIter_t iter;
|
||||
string_t squadName;
|
||||
CAI_Squad* pSquad = g_AI_SquadManager.GetFirstSquad( &iter );
|
||||
while (pSquad)
|
||||
{
|
||||
squadName = MAKE_STRING( pSquad->GetName() );
|
||||
pSave->WriteString( "", &squadName ); // Strings require a header to be read properly
|
||||
pSave->WriteAll( pSquad );
|
||||
pSquad = g_AI_SquadManager.GetNextSquad( &iter );
|
||||
}
|
||||
|
||||
pSave->EndBlock();
|
||||
|
||||
//---------------------------------
|
||||
|
||||
pSave->StartBlock( "Enemies" );
|
||||
short nMemories = 0;
|
||||
|
||||
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < g_AI_Manager.NumAIs(); i++ )
|
||||
{
|
||||
if ( ppAIs[i]->GetEnemies() )
|
||||
nMemories++;
|
||||
}
|
||||
|
||||
pSave->WriteShort( &nMemories );
|
||||
|
||||
for ( i = 0; i < g_AI_Manager.NumAIs(); i++ )
|
||||
{
|
||||
if ( ppAIs[i]->GetEnemies() )
|
||||
{
|
||||
CBaseEntity *p = ppAIs[i];
|
||||
pSave->WriteEntityPtr( &p );
|
||||
pSave->WriteAll( ppAIs[i]->GetEnemies() );
|
||||
}
|
||||
}
|
||||
pSave->EndBlock();
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void WriteSaveHeaders( ISave *pSave )
|
||||
{
|
||||
pSave->WriteShort( &AI_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void ReadRestoreHeaders( IRestore *pRestore )
|
||||
{
|
||||
// No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so.
|
||||
short version;
|
||||
pRestore->ReadShort( &version );
|
||||
m_fDoLoad = ( version == AI_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Restore( IRestore *pRestore, bool createPlayers )
|
||||
{
|
||||
// Initialize the squads (as there's no spawn)
|
||||
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < g_AI_Manager.NumAIs(); i++ )
|
||||
{
|
||||
ppAIs[i]->InitSquad();
|
||||
}
|
||||
|
||||
if ( m_fDoLoad )
|
||||
{
|
||||
pRestore->StartBlock();
|
||||
// Fixup all the squads
|
||||
CAI_Squad ignored;
|
||||
CAI_Squad *pSquad;
|
||||
string_t squadName;
|
||||
int nSavedSquads = pRestore->ReadShort();
|
||||
|
||||
while ( nSavedSquads-- )
|
||||
{
|
||||
int sizeData = pRestore->SkipHeader();
|
||||
pRestore->ReadString( &squadName, 1, sizeData );
|
||||
pSquad = g_AI_SquadManager.FindSquad( squadName );
|
||||
if ( !pSquad )
|
||||
pSquad = &ignored; // if all of the AIs in a squad failed to spawn, there would be no squad
|
||||
pRestore->ReadAll( pSquad );
|
||||
}
|
||||
pRestore->EndBlock();
|
||||
|
||||
//---------------------------------
|
||||
// Now load memories for unsquadded npcs
|
||||
|
||||
pRestore->StartBlock();
|
||||
CAI_Enemies ignoredMem;
|
||||
short nMemories = pRestore->ReadShort();
|
||||
|
||||
CBaseEntity *pAI;
|
||||
|
||||
while ( nMemories-- )
|
||||
{
|
||||
pRestore->ReadEntityPtr( &pAI );
|
||||
|
||||
if ( pAI )
|
||||
pRestore->ReadAll( ((CAI_BaseNPC *)pAI)->GetEnemies() );
|
||||
else
|
||||
pRestore->ReadAll( &ignoredMem ); // AI probably failed to spawn
|
||||
}
|
||||
|
||||
pRestore->EndBlock();
|
||||
}
|
||||
|
||||
if ( g_AI_Manager.NumAIs() && g_pBigAINet->NumNodes() == 0 && !g_pAINetworkManager->NetworksLoaded() )
|
||||
{
|
||||
Msg( "***\n");
|
||||
Msg( "ERROR: Loaded save game with no node graph. Load map and build node graph first!\n");
|
||||
Msg( "***\n");
|
||||
CAI_BaseNPC::m_nDebugBits |= bits_debugDisableAI;
|
||||
g_pAINetworkManager->MarkDontSaveGraph();
|
||||
}
|
||||
}
|
||||
|
||||
void PostRestore( void )
|
||||
{
|
||||
#ifdef HL2_DLL
|
||||
// We need this list to be regenerated
|
||||
OverrideMoveCache_ForceRepopulateList();
|
||||
#endif // HL2_DLL
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_fDoLoad;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CAI_SaveRestoreBlockHandler g_AI_SaveRestoreBlockHandler;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
ISaveRestoreBlockHandler *GetAISaveRestoreBlockHandler()
|
||||
{
|
||||
return &g_AI_SaveRestoreBlockHandler;
|
||||
}
|
||||
|
||||
//=============================================================================
|
Reference in New Issue
Block a user