Skip to content

Commit fa45fff

Browse files
committed
Added save/restore to client-side VScript
1 parent 2ee7845 commit fa45fff

14 files changed

Lines changed: 386 additions & 207 deletions

sp/src/game/client/c_baseentity.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst )
429429
END_RECV_TABLE()
430430

431431
BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" )
432+
DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper )
432433
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
433434
DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" )
434435
#ifdef MAPBASE_VSCRIPT
@@ -6130,6 +6131,9 @@ BEGIN_DATADESC_NO_BASE( C_BaseEntity )
61306131
DEFINE_FIELD( m_angAbsRotation, FIELD_VECTOR ),
61316132
DEFINE_ARRAY( m_rgflCoordinateFrame, FIELD_FLOAT, 12 ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)
61326133
DEFINE_FIELD( m_fFlags, FIELD_INTEGER ),
6134+
#ifdef MAPBASE_VSCRIPT
6135+
DEFINE_FIELD( m_iszScriptId, FIELD_STRING ),
6136+
#endif
61336137
END_DATADESC()
61346138

61356139
//-----------------------------------------------------------------------------

sp/src/game/client/c_world.cpp

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include "ivieweffects.h"
1414
#include "shake.h"
1515
#include "eventlist.h"
16+
#ifdef MAPBASE
17+
#include "mapentities_shared.h"
18+
#endif
1619
// NVNT haptic include for notification of world precache
1720
#include "haptics/haptic_utils.h"
1821
// memdbgon must be the last include file in a .cpp file!!!
@@ -62,9 +65,6 @@ BEGIN_RECV_TABLE( C_World, DT_World )
6265
#ifdef MAPBASE
6366
RecvPropString(RECVINFO(m_iszChapterTitle)),
6467
#endif
65-
#ifdef MAPBASE_VSCRIPT
66-
RecvPropInt(RECVINFO(m_iScriptLanguageClient)),
67-
#endif
6868
END_RECV_TABLE()
6969

7070
#ifdef MAPBASE_VSCRIPT
@@ -86,6 +86,11 @@ bool C_World::Init( int entnum, int iSerialNum )
8686
ActivityList_Init();
8787
EventList_Init();
8888

89+
#ifdef MAPBASE_VSCRIPT
90+
m_iScriptLanguageServer = SL_NONE;
91+
m_iScriptLanguageClient = SL_NONE;
92+
#endif
93+
8994
return BaseClass::Init( entnum, iSerialNum );
9095
}
9196

@@ -129,11 +134,6 @@ void C_World::OnDataChanged( DataUpdateType_t updateType )
129134
engine->SetOcclusionParameters( params );
130135

131136
modelinfo->SetLevelScreenFadeRange( m_flMinPropScreenSpaceWidth, m_flMaxPropScreenSpaceWidth );
132-
133-
#ifdef MAPBASE_VSCRIPT
134-
// This is now here so that C_World has time to receive the selected script language
135-
VScriptClientInit();
136-
#endif
137137
}
138138
}
139139

@@ -199,6 +199,72 @@ void C_World::Spawn( void )
199199
Precache();
200200
}
201201

202+
//-----------------------------------------------------------------------------
203+
// Parse data from a map file
204+
//-----------------------------------------------------------------------------
205+
bool C_World::KeyValue( const char *szKeyName, const char *szValue )
206+
{
207+
#ifdef MAPBASE_VSCRIPT
208+
if ( FStrEq( szKeyName, "vscriptlanguage" ) )
209+
{
210+
m_iScriptLanguageServer = atoi( szValue );
211+
}
212+
else if ( FStrEq( szKeyName, "vscriptlanguage_client" ) )
213+
{
214+
m_iScriptLanguageClient = atoi( szValue );
215+
}
216+
else
217+
#endif
218+
return BaseClass::KeyValue( szKeyName, szValue );
219+
220+
return true;
221+
}
222+
223+
#ifdef MAPBASE
224+
//-----------------------------------------------------------------------------
225+
// Parses worldspawn data from BSP on the client
226+
//-----------------------------------------------------------------------------
227+
void C_World::ParseWorldMapData( const char *pMapData )
228+
{
229+
char szTokenBuffer[MAPKEY_MAXLENGTH];
230+
for ( ; true; pMapData = MapEntity_SkipToNextEntity(pMapData, szTokenBuffer) )
231+
{
232+
//
233+
// Parse the opening brace.
234+
//
235+
char token[MAPKEY_MAXLENGTH];
236+
pMapData = MapEntity_ParseToken( pMapData, token );
237+
238+
//
239+
// Check to see if we've finished or not.
240+
//
241+
if (!pMapData)
242+
break;
243+
244+
if (token[0] != '{')
245+
{
246+
Error( "MapEntity_ParseAllEntities: found %s when expecting {", token);
247+
continue;
248+
}
249+
250+
CEntityMapData entData( (char*)pMapData );
251+
char className[MAPKEY_MAXLENGTH];
252+
253+
if (!entData.ExtractValue( "classname", className ))
254+
{
255+
Error( "classname missing from entity!\n" );
256+
}
257+
258+
if ( !Q_strcmp( className, "worldspawn" ) )
259+
{
260+
// Set up keyvalues.
261+
ParseMapData( &entData );
262+
return;
263+
}
264+
}
265+
}
266+
#endif
267+
202268

203269

204270
C_World *GetClientWorldEntity()

sp/src/game/client/c_world.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class C_World : public C_BaseEntity
3131

3232
virtual void Precache();
3333
virtual void Spawn();
34+
virtual bool KeyValue( const char *szKeyName, const char *szValue );
3435

3536
// Don't worry about adding the world to the collision list; it's already there
3637
virtual CollideType_t GetCollideType( void ) { return ENTITY_SHOULD_NOT_COLLIDE; }
@@ -41,8 +42,15 @@ class C_World : public C_BaseEntity
4142
float GetWaveHeight() const;
4243
const char *GetDetailSpriteMaterial() const;
4344

45+
#ifdef MAPBASE
46+
// A special function which parses map data for the client world entity before LevelInitPreEntity().
47+
// This can be used to access keyvalues early and without transmitting from the server.
48+
void ParseWorldMapData( const char *pMapData );
49+
#endif
50+
4451
#ifdef MAPBASE_VSCRIPT
45-
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)m_iScriptLanguageClient; }
52+
// -2 = Use server language
53+
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); }
4654
#endif
4755

4856
public:
@@ -64,6 +72,7 @@ class C_World : public C_BaseEntity
6472
char m_iszChapterTitle[64];
6573
#endif
6674
#ifdef MAPBASE_VSCRIPT
75+
int m_iScriptLanguageServer;
6776
int m_iScriptLanguageClient;
6877
#endif
6978

sp/src/game/client/cdll_client_int.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@
147147
#include "fbxsystem/fbxsystem.h"
148148
#endif
149149

150+
#ifdef MAPBASE_VSCRIPT
151+
#include "vscript_client.h"
152+
#endif
153+
150154
extern vgui::IInputInternal *g_InputInternal;
151155

152156
//=============================================================================
@@ -1104,6 +1108,9 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
11041108
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetEntitySaveRestoreBlockHandler() );
11051109
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetPhysSaveRestoreBlockHandler() );
11061110
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetViewEffectsRestoreBlockHandler() );
1111+
#ifdef MAPBASE_VSCRIPT
1112+
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetVScriptSaveRestoreBlockHandler() );
1113+
#endif
11071114

11081115
ClientWorldFactoryInit();
11091116

@@ -1216,6 +1223,9 @@ void CHLClient::Shutdown( void )
12161223
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetViewEffectsRestoreBlockHandler() );
12171224
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetPhysSaveRestoreBlockHandler() );
12181225
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetEntitySaveRestoreBlockHandler() );
1226+
#ifdef MAPBASE_VSCRIPT
1227+
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetVScriptSaveRestoreBlockHandler() );
1228+
#endif
12191229

12201230
ClientVoiceMgr_Shutdown();
12211231

@@ -1635,6 +1645,10 @@ void CHLClient::LevelInitPreEntity( char const* pMapName )
16351645
tempents->LevelInit();
16361646
ResetToneMapping(1.0);
16371647

1648+
#ifdef MAPBASE
1649+
GetClientWorldEntity()->ParseWorldMapData( engine->GetMapEntitiesString() );
1650+
#endif
1651+
16381652
IGameSystem::LevelInitPreEntityAllSystems(pMapName);
16391653

16401654
#ifdef USES_ECON_ITEMS

sp/src/game/client/vscript_client.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,16 @@ class CScriptMaterialProxy : public IMaterialProxy, public IClientScriptPersista
176176
HSCRIPT m_hFuncOnBind;
177177
};
178178

179+
class CMaterialProxyScriptInstanceHelper : public IScriptInstanceHelper
180+
{
181+
bool ToString( void *p, char *pBuf, int bufSize );
182+
void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId );
183+
};
184+
185+
CMaterialProxyScriptInstanceHelper g_MaterialProxyScriptInstanceHelper;
186+
179187
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMaterialProxy, "CScriptMaterialProxy", "Material proxy for VScript" )
188+
DEFINE_SCRIPT_INSTANCE_HELPER( &g_MaterialProxyScriptInstanceHelper )
180189
DEFINE_SCRIPTFUNC( GetVarString, "Gets a material var's string value" )
181190
DEFINE_SCRIPTFUNC( GetVarInt, "Gets a material var's int value" )
182191
DEFINE_SCRIPTFUNC( GetVarFloat, "Gets a material var's float value" )
@@ -406,6 +415,19 @@ void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
406415
}
407416

408417
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
418+
419+
bool CMaterialProxyScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
420+
{
421+
CScriptMaterialProxy *pProxy = (CScriptMaterialProxy *)p;
422+
V_snprintf( pBuf, bufSize, "(proxy: %s)", pProxy->GetMaterial() != NULL ? pProxy->GetMaterial()->GetName() : "<no material>" );
423+
return true;
424+
}
425+
426+
void *CMaterialProxyScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId )
427+
{
428+
// TODO: Material proxy save/restore?
429+
return NULL;
430+
}
409431
#endif // MAPBASE_VSCRIPT
410432

411433
//-----------------------------------------------------------------------------
@@ -616,6 +638,12 @@ bool VScriptClientInit()
616638
CGWarning( 1, CON_GROUP_VSCRIPT, "VM Did not start!\n" );
617639
}
618640
}
641+
#ifdef MAPBASE_VSCRIPT
642+
else
643+
{
644+
CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Not starting because language is set to 'none'\n" );
645+
}
646+
#endif
619647
}
620648
else
621649
{
@@ -657,9 +685,7 @@ class CVScriptGameSystem : public CAutoGameSystemPerFrame
657685
virtual void LevelInitPreEntity( void )
658686
{
659687
m_bAllowEntityCreationInScripts = true;
660-
#ifndef MAPBASE_VSCRIPT // Now initted in C_World
661688
VScriptClientInit();
662-
#endif
663689
}
664690

665691
virtual void LevelInitPostEntity( void )

0 commit comments

Comments
 (0)