mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 07:15:31 +03:00
Added save/restore to client-side VScript
This commit is contained in:
parent
2ee7845e8d
commit
fa45fffa39
@ -429,6 +429,7 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst )
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" )
|
||||
DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" )
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
@ -6130,6 +6131,9 @@ BEGIN_DATADESC_NO_BASE( C_BaseEntity )
|
||||
DEFINE_FIELD( m_angAbsRotation, FIELD_VECTOR ),
|
||||
DEFINE_ARRAY( m_rgflCoordinateFrame, FIELD_FLOAT, 12 ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)
|
||||
DEFINE_FIELD( m_fFlags, FIELD_INTEGER ),
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_FIELD( m_iszScriptId, FIELD_STRING ),
|
||||
#endif
|
||||
END_DATADESC()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "ivieweffects.h"
|
||||
#include "shake.h"
|
||||
#include "eventlist.h"
|
||||
#ifdef MAPBASE
|
||||
#include "mapentities_shared.h"
|
||||
#endif
|
||||
// NVNT haptic include for notification of world precache
|
||||
#include "haptics/haptic_utils.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -62,9 +65,6 @@ BEGIN_RECV_TABLE( C_World, DT_World )
|
||||
#ifdef MAPBASE
|
||||
RecvPropString(RECVINFO(m_iszChapterTitle)),
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
RecvPropInt(RECVINFO(m_iScriptLanguageClient)),
|
||||
#endif
|
||||
END_RECV_TABLE()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
@ -86,6 +86,11 @@ bool C_World::Init( int entnum, int iSerialNum )
|
||||
ActivityList_Init();
|
||||
EventList_Init();
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
m_iScriptLanguageServer = SL_NONE;
|
||||
m_iScriptLanguageClient = SL_NONE;
|
||||
#endif
|
||||
|
||||
return BaseClass::Init( entnum, iSerialNum );
|
||||
}
|
||||
|
||||
@ -129,11 +134,6 @@ void C_World::OnDataChanged( DataUpdateType_t updateType )
|
||||
engine->SetOcclusionParameters( params );
|
||||
|
||||
modelinfo->SetLevelScreenFadeRange( m_flMinPropScreenSpaceWidth, m_flMaxPropScreenSpaceWidth );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// This is now here so that C_World has time to receive the selected script language
|
||||
VScriptClientInit();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,6 +199,72 @@ void C_World::Spawn( void )
|
||||
Precache();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parse data from a map file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_World::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( FStrEq( szKeyName, "vscriptlanguage" ) )
|
||||
{
|
||||
m_iScriptLanguageServer = atoi( szValue );
|
||||
}
|
||||
else if ( FStrEq( szKeyName, "vscriptlanguage_client" ) )
|
||||
{
|
||||
m_iScriptLanguageClient = atoi( szValue );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parses worldspawn data from BSP on the client
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_World::ParseWorldMapData( const char *pMapData )
|
||||
{
|
||||
char szTokenBuffer[MAPKEY_MAXLENGTH];
|
||||
for ( ; true; pMapData = MapEntity_SkipToNextEntity(pMapData, szTokenBuffer) )
|
||||
{
|
||||
//
|
||||
// Parse the opening brace.
|
||||
//
|
||||
char token[MAPKEY_MAXLENGTH];
|
||||
pMapData = MapEntity_ParseToken( pMapData, token );
|
||||
|
||||
//
|
||||
// Check to see if we've finished or not.
|
||||
//
|
||||
if (!pMapData)
|
||||
break;
|
||||
|
||||
if (token[0] != '{')
|
||||
{
|
||||
Error( "MapEntity_ParseAllEntities: found %s when expecting {", token);
|
||||
continue;
|
||||
}
|
||||
|
||||
CEntityMapData entData( (char*)pMapData );
|
||||
char className[MAPKEY_MAXLENGTH];
|
||||
|
||||
if (!entData.ExtractValue( "classname", className ))
|
||||
{
|
||||
Error( "classname missing from entity!\n" );
|
||||
}
|
||||
|
||||
if ( !Q_strcmp( className, "worldspawn" ) )
|
||||
{
|
||||
// Set up keyvalues.
|
||||
ParseMapData( &entData );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
C_World *GetClientWorldEntity()
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
|
||||
virtual void Precache();
|
||||
virtual void Spawn();
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
// Don't worry about adding the world to the collision list; it's already there
|
||||
virtual CollideType_t GetCollideType( void ) { return ENTITY_SHOULD_NOT_COLLIDE; }
|
||||
@ -41,8 +42,15 @@ public:
|
||||
float GetWaveHeight() const;
|
||||
const char *GetDetailSpriteMaterial() const;
|
||||
|
||||
#ifdef MAPBASE
|
||||
// A special function which parses map data for the client world entity before LevelInitPreEntity().
|
||||
// This can be used to access keyvalues early and without transmitting from the server.
|
||||
void ParseWorldMapData( const char *pMapData );
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)m_iScriptLanguageClient; }
|
||||
// -2 = Use server language
|
||||
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); }
|
||||
#endif
|
||||
|
||||
public:
|
||||
@ -64,6 +72,7 @@ public:
|
||||
char m_iszChapterTitle[64];
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
int m_iScriptLanguageServer;
|
||||
int m_iScriptLanguageClient;
|
||||
#endif
|
||||
|
||||
|
@ -147,6 +147,10 @@
|
||||
#include "fbxsystem/fbxsystem.h"
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "vscript_client.h"
|
||||
#endif
|
||||
|
||||
extern vgui::IInputInternal *g_InputInternal;
|
||||
|
||||
//=============================================================================
|
||||
@ -1104,6 +1108,9 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetEntitySaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetPhysSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetViewEffectsRestoreBlockHandler() );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetVScriptSaveRestoreBlockHandler() );
|
||||
#endif
|
||||
|
||||
ClientWorldFactoryInit();
|
||||
|
||||
@ -1216,6 +1223,9 @@ void CHLClient::Shutdown( void )
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetViewEffectsRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetPhysSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetEntitySaveRestoreBlockHandler() );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetVScriptSaveRestoreBlockHandler() );
|
||||
#endif
|
||||
|
||||
ClientVoiceMgr_Shutdown();
|
||||
|
||||
@ -1635,6 +1645,10 @@ void CHLClient::LevelInitPreEntity( char const* pMapName )
|
||||
tempents->LevelInit();
|
||||
ResetToneMapping(1.0);
|
||||
|
||||
#ifdef MAPBASE
|
||||
GetClientWorldEntity()->ParseWorldMapData( engine->GetMapEntitiesString() );
|
||||
#endif
|
||||
|
||||
IGameSystem::LevelInitPreEntityAllSystems(pMapName);
|
||||
|
||||
#ifdef USES_ECON_ITEMS
|
||||
|
@ -176,7 +176,16 @@ private:
|
||||
HSCRIPT m_hFuncOnBind;
|
||||
};
|
||||
|
||||
class CMaterialProxyScriptInstanceHelper : public IScriptInstanceHelper
|
||||
{
|
||||
bool ToString( void *p, char *pBuf, int bufSize );
|
||||
void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId );
|
||||
};
|
||||
|
||||
CMaterialProxyScriptInstanceHelper g_MaterialProxyScriptInstanceHelper;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMaterialProxy, "CScriptMaterialProxy", "Material proxy for VScript" )
|
||||
DEFINE_SCRIPT_INSTANCE_HELPER( &g_MaterialProxyScriptInstanceHelper )
|
||||
DEFINE_SCRIPTFUNC( GetVarString, "Gets a material var's string value" )
|
||||
DEFINE_SCRIPTFUNC( GetVarInt, "Gets a material var's int value" )
|
||||
DEFINE_SCRIPTFUNC( GetVarFloat, "Gets a material var's float value" )
|
||||
@ -406,6 +415,19 @@ void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
bool CMaterialProxyScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
|
||||
{
|
||||
CScriptMaterialProxy *pProxy = (CScriptMaterialProxy *)p;
|
||||
V_snprintf( pBuf, bufSize, "(proxy: %s)", pProxy->GetMaterial() != NULL ? pProxy->GetMaterial()->GetName() : "<no material>" );
|
||||
return true;
|
||||
}
|
||||
|
||||
void *CMaterialProxyScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId )
|
||||
{
|
||||
// TODO: Material proxy save/restore?
|
||||
return NULL;
|
||||
}
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -616,6 +638,12 @@ bool VScriptClientInit()
|
||||
CGWarning( 1, CON_GROUP_VSCRIPT, "VM Did not start!\n" );
|
||||
}
|
||||
}
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
else
|
||||
{
|
||||
CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Not starting because language is set to 'none'\n" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -657,9 +685,7 @@ public:
|
||||
virtual void LevelInitPreEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = true;
|
||||
#ifndef MAPBASE_VSCRIPT // Now initted in C_World
|
||||
VScriptClientInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void LevelInitPostEntity( void )
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "eventqueue.h"
|
||||
#include "characterset.h"
|
||||
#include "sceneentity.h" // for exposing scene precache function
|
||||
#include "isaverestore.h"
|
||||
#include "gamerules.h"
|
||||
#include "vscript_server.nut"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
@ -601,6 +600,12 @@ bool VScriptServerInit()
|
||||
CGWarning( 1, CON_GROUP_VSCRIPT, "VM Did not start!\n" );
|
||||
}
|
||||
}
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
else
|
||||
{
|
||||
CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT SERVER: Not starting because language is set to 'none'\n" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -777,172 +782,3 @@ bool IsEntityCreationAllowedInScripts( void )
|
||||
|
||||
return g_VScriptGameSystem.m_bAllowEntityCreationInScripts;
|
||||
}
|
||||
|
||||
static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CVScriptSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
|
||||
{
|
||||
public:
|
||||
CVScriptSaveRestoreBlockHandler() :
|
||||
m_InstanceMap( DefLessFunc(const char *) )
|
||||
{
|
||||
}
|
||||
const char *GetBlockName()
|
||||
{
|
||||
return "VScriptServer";
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Save( ISave *pSave )
|
||||
{
|
||||
pSave->StartBlock();
|
||||
|
||||
int temp = g_pScriptVM != NULL;
|
||||
pSave->WriteInt( &temp );
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
temp = g_pScriptVM->GetLanguage();
|
||||
pSave->WriteInt( &temp );
|
||||
CUtlBuffer buffer;
|
||||
g_pScriptVM->WriteState( &buffer );
|
||||
temp = buffer.TellPut();
|
||||
pSave->WriteInt( &temp );
|
||||
if ( temp > 0 )
|
||||
{
|
||||
pSave->WriteData( (const char *)buffer.Base(), temp );
|
||||
}
|
||||
}
|
||||
|
||||
pSave->EndBlock();
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void WriteSaveHeaders( ISave *pSave )
|
||||
{
|
||||
pSave->WriteShort( &VSCRIPT_SERVER_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 == VSCRIPT_SERVER_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Restore( IRestore *pRestore, bool createPlayers )
|
||||
{
|
||||
if ( !m_fDoLoad && g_pScriptVM )
|
||||
{
|
||||
return;
|
||||
}
|
||||
CBaseEntity *pEnt = gEntList.FirstEnt();
|
||||
while ( pEnt )
|
||||
{
|
||||
if ( pEnt->m_iszScriptId != NULL_STRING )
|
||||
{
|
||||
#ifndef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->RegisterClass( pEnt->GetScriptDesc() );
|
||||
#endif
|
||||
m_InstanceMap.Insert( STRING( pEnt->m_iszScriptId ), pEnt );
|
||||
}
|
||||
pEnt = gEntList.NextEnt( pEnt );
|
||||
}
|
||||
|
||||
pRestore->StartBlock();
|
||||
if ( pRestore->ReadInt() && pRestore->ReadInt() == g_pScriptVM->GetLanguage() )
|
||||
{
|
||||
int nBytes = pRestore->ReadInt();
|
||||
if ( nBytes > 0 )
|
||||
{
|
||||
CUtlBuffer buffer;
|
||||
buffer.EnsureCapacity( nBytes );
|
||||
pRestore->ReadData( (char *)buffer.AccessForDirectRead( nBytes ), nBytes, 0 );
|
||||
g_pScriptVM->ReadState( &buffer );
|
||||
}
|
||||
}
|
||||
pRestore->EndBlock();
|
||||
}
|
||||
|
||||
void PostRestore( void )
|
||||
{
|
||||
for ( int i = m_InstanceMap.FirstInorder(); i != m_InstanceMap.InvalidIndex(); i = m_InstanceMap.NextInorder( i ) )
|
||||
{
|
||||
CBaseEntity *pEnt = m_InstanceMap[i];
|
||||
if ( pEnt->m_hScriptInstance )
|
||||
{
|
||||
ScriptVariant_t variant;
|
||||
if ( g_pScriptVM->GetValue( STRING(pEnt->m_iszScriptId), &variant ) && variant.m_type == FIELD_HSCRIPT )
|
||||
{
|
||||
pEnt->m_ScriptScope.Init( variant.m_hScript, false );
|
||||
pEnt->RunPrecacheScripts();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Script system probably has no internal references
|
||||
pEnt->m_iszScriptId = NULL_STRING;
|
||||
}
|
||||
}
|
||||
m_InstanceMap.Purge();
|
||||
}
|
||||
|
||||
|
||||
CUtlMap<const char *, CBaseEntity *> m_InstanceMap;
|
||||
|
||||
private:
|
||||
bool m_fDoLoad;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVScriptSaveRestoreBlockHandler g_VScriptSaveRestoreBlockHandler;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler()
|
||||
{
|
||||
return &g_VScriptSaveRestoreBlockHandler;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CBaseEntityScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
|
||||
{
|
||||
CBaseEntity *pEntity = (CBaseEntity *)p;
|
||||
if ( pEntity->GetEntityName() != NULL_STRING )
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), STRING(pEntity->m_iClassname), STRING( pEntity->GetEntityName() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), STRING(pEntity->m_iClassname) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void *CBaseEntityScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId )
|
||||
{
|
||||
int iEntity = g_VScriptSaveRestoreBlockHandler.m_InstanceMap.Find( pszId );
|
||||
if ( iEntity != g_VScriptSaveRestoreBlockHandler.m_InstanceMap.InvalidIndex() )
|
||||
{
|
||||
CBaseEntity *pEnt = g_VScriptSaveRestoreBlockHandler.m_InstanceMap[iEntity];
|
||||
pEnt->m_hScriptInstance = hInstance;
|
||||
return pEnt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
|
||||
|
@ -15,19 +15,7 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class ISaveRestoreBlockHandler;
|
||||
|
||||
bool VScriptServerReplaceClosures( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing = false );
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler();
|
||||
|
||||
|
||||
class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper
|
||||
{
|
||||
bool ToString( void *p, char *pBuf, int bufSize );
|
||||
void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId );
|
||||
};
|
||||
|
||||
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
// Only allow scripts to create entities during map initialization
|
||||
bool IsEntityCreationAllowedInScripts( void );
|
||||
|
@ -395,7 +395,7 @@ BEGIN_DATADESC( CWorld )
|
||||
DEFINE_KEYFIELD( m_iszDetailSpriteMaterial, FIELD_STRING, "detailmaterial" ),
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_KEYFIELD( m_iScriptLanguage, FIELD_INTEGER, "vscriptlanguage" ),
|
||||
DEFINE_KEYFIELD( m_iScriptLanguageClient, FIELD_INTEGER, "vscriptlanguage_client" ),
|
||||
//DEFINE_KEYFIELD( m_iScriptLanguageClient, FIELD_INTEGER, "vscriptlanguage_client" ),
|
||||
#endif
|
||||
DEFINE_KEYFIELD( m_bColdWorld, FIELD_BOOLEAN, "coldworld" ),
|
||||
|
||||
@ -421,9 +421,6 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD)
|
||||
#ifdef MAPBASE
|
||||
SendPropStringT (SENDINFO(m_iszChapterTitle) ),
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
SendPropInt (SENDINFO(m_iScriptLanguageClient), 4 ), // No SPROP_UNSIGNED to allow -1 (disabled)
|
||||
#endif
|
||||
END_SEND_TABLE()
|
||||
|
||||
//
|
||||
@ -485,7 +482,7 @@ CWorld::CWorld( )
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
m_iScriptLanguage = SL_NONE;
|
||||
m_iScriptLanguageClient = -2;
|
||||
//m_iScriptLanguageClient = -2;
|
||||
#endif
|
||||
|
||||
m_bColdWorld = false;
|
||||
@ -552,14 +549,6 @@ void CWorld::Spawn( void )
|
||||
Precache( );
|
||||
GlobalEntity_Add( "is_console", STRING(gpGlobals->mapname), ( IsConsole() ) ? GLOBAL_ON : GLOBAL_OFF );
|
||||
GlobalEntity_Add( "is_pc", STRING(gpGlobals->mapname), ( !IsConsole() ) ? GLOBAL_ON : GLOBAL_OFF );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (m_iScriptLanguageClient.Get() == -2)
|
||||
{
|
||||
// Clientside language should be regular language by default
|
||||
m_iScriptLanguageClient.Set( m_iScriptLanguage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *g_DefaultLightstyles[] =
|
||||
|
@ -90,7 +90,7 @@ private:
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
int m_iScriptLanguage;
|
||||
CNetworkVar( int, m_iScriptLanguageClient );
|
||||
//CNetworkVar( int, m_iScriptLanguageClient ); // Now entirely on client
|
||||
#endif
|
||||
|
||||
// start flags
|
||||
|
@ -161,6 +161,32 @@ public:
|
||||
|
||||
BaseClass::ClientThink();
|
||||
}
|
||||
|
||||
void OnSave()
|
||||
{
|
||||
// HACKHACK: Save the next think in the VM since the VM is saved
|
||||
if (m_bClientThink)
|
||||
{
|
||||
g_pScriptVM->SetValue( m_ScriptScope, "__c_think", GetNextThink() );
|
||||
}
|
||||
|
||||
BaseClass::OnSave();
|
||||
}
|
||||
|
||||
void OnRestore()
|
||||
{
|
||||
// HACKHACK: See OnSave()
|
||||
if (m_bClientThink)
|
||||
{
|
||||
ScriptVariant_t flNextThink;
|
||||
if (g_pScriptVM->GetValue( m_ScriptScope, "__c_think", &flNextThink ))
|
||||
{
|
||||
SetNextClientThink( flNextThink );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnRestore();
|
||||
}
|
||||
#else
|
||||
void InputCallScriptFunctionClient( inputdata_t &inputdata )
|
||||
{
|
||||
|
@ -757,7 +757,12 @@ public: // IGameSystem
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// On the client, OnRestore() is called before VScript is actually restored, so this has to be called manually from VScript save/restore instead
|
||||
void OnVMRestore()
|
||||
#else
|
||||
void OnRestore()
|
||||
#endif
|
||||
{
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
@ -783,6 +788,13 @@ private:
|
||||
|
||||
} g_ScriptSaveRestoreUtil;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void VScriptSaveRestoreUtil_OnVMRestore()
|
||||
{
|
||||
g_ScriptSaveRestoreUtil.OnVMRestore();
|
||||
}
|
||||
#endif
|
||||
|
||||
CUtlMap< unsigned int, KeyValues* > CScriptSaveRestoreUtil::m_Lookup( DefLessFunc(unsigned int) );
|
||||
StringHashFunctor CScriptSaveRestoreUtil::Hash;
|
||||
|
||||
@ -1164,6 +1176,13 @@ void CNetMsgScriptHelper::RecieveMessage( bf_read &msg )
|
||||
|
||||
word hash = m_MsgIn_()ReadWord();
|
||||
|
||||
// Don't do anything if there's no VM here. This can happen if a message from the server goes to a VM-less client, or vice versa.
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
CGWarning( 0, CON_GROUP_VSCRIPT, "CNetMsgScriptHelper: No VM on receiving side\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptVariant_t hfn;
|
||||
if ( g_pScriptVM->GetValue( m_Hooks, hash, &hfn ) )
|
||||
{
|
||||
|
@ -136,4 +136,8 @@ public:
|
||||
|
||||
extern CNetMsgScriptHelper *g_ScriptNetMsg;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void VScriptSaveRestoreUtil_OnVMRestore();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "characterset.h"
|
||||
#include "isaverestore.h"
|
||||
#include "gamerules.h"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "mapbase/vscript_singletons.h"
|
||||
#endif
|
||||
|
||||
IScriptVM * g_pScriptVM;
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
@ -278,3 +281,187 @@ CON_COMMAND_SHARED( script_dump_all, "Dump the state of the VM to the console" )
|
||||
}
|
||||
g_pScriptVM->DumpState();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CVScriptSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
|
||||
{
|
||||
public:
|
||||
CVScriptSaveRestoreBlockHandler() :
|
||||
m_InstanceMap( DefLessFunc(const char *) )
|
||||
{
|
||||
}
|
||||
const char *GetBlockName()
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
return "VScriptClient";
|
||||
#else
|
||||
return "VScriptServer";
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Save( ISave *pSave )
|
||||
{
|
||||
pSave->StartBlock();
|
||||
|
||||
int temp = g_pScriptVM != NULL;
|
||||
pSave->WriteInt( &temp );
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
temp = g_pScriptVM->GetLanguage();
|
||||
pSave->WriteInt( &temp );
|
||||
CUtlBuffer buffer;
|
||||
g_pScriptVM->WriteState( &buffer );
|
||||
temp = buffer.TellPut();
|
||||
pSave->WriteInt( &temp );
|
||||
if ( temp > 0 )
|
||||
{
|
||||
pSave->WriteData( (const char *)buffer.Base(), temp );
|
||||
}
|
||||
}
|
||||
|
||||
pSave->EndBlock();
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void WriteSaveHeaders( ISave *pSave )
|
||||
{
|
||||
pSave->WriteShort( &VSCRIPT_SERVER_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 == VSCRIPT_SERVER_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Restore( IRestore *pRestore, bool createPlayers )
|
||||
{
|
||||
if ( !m_fDoLoad && g_pScriptVM )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#ifdef CLIENT_DLL
|
||||
C_BaseEntity *pEnt = ClientEntityList().FirstBaseEntity();
|
||||
#else
|
||||
CBaseEntity *pEnt = gEntList.FirstEnt();
|
||||
#endif
|
||||
while ( pEnt )
|
||||
{
|
||||
if ( pEnt->m_iszScriptId != NULL_STRING )
|
||||
{
|
||||
#ifndef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->RegisterClass( pEnt->GetScriptDesc() );
|
||||
#endif
|
||||
m_InstanceMap.Insert( STRING( pEnt->m_iszScriptId ), pEnt );
|
||||
}
|
||||
#ifdef CLIENT_DLL
|
||||
pEnt = ClientEntityList().NextBaseEntity( pEnt );
|
||||
#else
|
||||
pEnt = gEntList.NextEnt( pEnt );
|
||||
#endif
|
||||
}
|
||||
|
||||
pRestore->StartBlock();
|
||||
if ( pRestore->ReadInt() && pRestore->ReadInt() == g_pScriptVM->GetLanguage() )
|
||||
{
|
||||
int nBytes = pRestore->ReadInt();
|
||||
if ( nBytes > 0 )
|
||||
{
|
||||
CUtlBuffer buffer;
|
||||
buffer.EnsureCapacity( nBytes );
|
||||
pRestore->ReadData( (char *)buffer.AccessForDirectRead( nBytes ), nBytes, 0 );
|
||||
g_pScriptVM->ReadState( &buffer );
|
||||
}
|
||||
}
|
||||
pRestore->EndBlock();
|
||||
}
|
||||
|
||||
void PostRestore( void )
|
||||
{
|
||||
for ( int i = m_InstanceMap.FirstInorder(); i != m_InstanceMap.InvalidIndex(); i = m_InstanceMap.NextInorder( i ) )
|
||||
{
|
||||
CBaseEntity *pEnt = m_InstanceMap[i];
|
||||
if ( pEnt->m_hScriptInstance )
|
||||
{
|
||||
ScriptVariant_t variant;
|
||||
if ( g_pScriptVM->GetValue( STRING(pEnt->m_iszScriptId), &variant ) && variant.m_type == FIELD_HSCRIPT )
|
||||
{
|
||||
pEnt->m_ScriptScope.Init( variant.m_hScript, false );
|
||||
#ifndef CLIENT_DLL
|
||||
pEnt->RunPrecacheScripts();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Script system probably has no internal references
|
||||
pEnt->m_iszScriptId = NULL_STRING;
|
||||
}
|
||||
}
|
||||
m_InstanceMap.Purge();
|
||||
|
||||
#if defined(MAPBASE_VSCRIPT) && defined(CLIENT_DLL)
|
||||
VScriptSaveRestoreUtil_OnVMRestore();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
CUtlMap<const char *, CBaseEntity *> m_InstanceMap;
|
||||
|
||||
private:
|
||||
bool m_fDoLoad;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVScriptSaveRestoreBlockHandler g_VScriptSaveRestoreBlockHandler;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler()
|
||||
{
|
||||
return &g_VScriptSaveRestoreBlockHandler;
|
||||
}
|
||||
|
||||
bool CBaseEntityScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
|
||||
{
|
||||
CBaseEntity *pEntity = (CBaseEntity *)p;
|
||||
if ( pEntity->GetEntityName() != NULL_STRING )
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), STRING(pEntity->m_iClassname), STRING( pEntity->GetEntityName() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), STRING(pEntity->m_iClassname) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void *CBaseEntityScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId )
|
||||
{
|
||||
int iEntity = g_VScriptSaveRestoreBlockHandler.m_InstanceMap.Find( pszId );
|
||||
if ( iEntity != g_VScriptSaveRestoreBlockHandler.m_InstanceMap.InvalidIndex() )
|
||||
{
|
||||
CBaseEntity *pEnt = g_VScriptSaveRestoreBlockHandler.m_InstanceMap[iEntity];
|
||||
pEnt->m_hScriptInstance = hInstance;
|
||||
return pEnt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
@ -31,6 +31,17 @@ inline bool VScriptRunScript( const char *pszScriptName, bool bWarnMissing = fal
|
||||
// Only allow scripts to create entities during map initialization
|
||||
bool IsEntityCreationAllowedInScripts( void );
|
||||
|
||||
class ISaveRestoreBlockHandler;
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler();
|
||||
|
||||
class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper
|
||||
{
|
||||
bool ToString( void *p, char *pBuf, int bufSize );
|
||||
void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId );
|
||||
};
|
||||
|
||||
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void RegisterSharedScriptConstants();
|
||||
void RegisterSharedScriptFunctions();
|
||||
|
Loading…
Reference in New Issue
Block a user