Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

565 lines
18 KiB

  1. //===== Copyright � Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Defines scripting system.
  4. //
  5. //===========================================================================//
  6. #include "gameuiscriptInterface.h"
  7. #include "gameuisystemmgr.h"
  8. #include "gameuidefinition.h"
  9. #include "gamelayer.h"
  10. #include "gamegraphic.h"
  11. #include "fmtstr.h"
  12. #include "gameuiscript.h"
  13. #include "gameuisystem.h"
  14. #include "gametext.h"
  15. #include "dynamicrect.h"
  16. #include "tier2/tier2.h"
  17. #include "matchmaking/imatchframework.h"
  18. BEGIN_SCRIPTDESC_ROOT_NAMED( CGameUIScriptInterface, "CGameUIScriptInterface", SCRIPT_SINGLETON "" )
  19. // HSCRIPT table-kv functions
  20. DEFINE_SCRIPTFUNC( LoadMenu, "LoadMenu( name, {params} ) : Load a menu." )
  21. DEFINE_SCRIPTFUNC( CreateGraphic, "CreateGraphic( classname, {params} ) : Create a graphic." )
  22. DEFINE_SCRIPTFUNC( CallScript, "CallScript( scripthandle, function, {params} ) : Execute other script function (scripthandle=0 will run local script)." )
  23. DEFINE_SCRIPTFUNC( CallGraphic, "CallGraphic( graphichandle, commandname, {params} ) : Execute a graphic function." )
  24. DEFINE_SCRIPTFUNC( Nugget, "Nugget( action, {params} ) : Interface with nuggets." )
  25. END_SCRIPTDESC()
  26. static ConVar ui_script_spew_level( "ui_script_spew_level", 0, FCVAR_DEVELOPMENTONLY );
  27. //-----------------------------------------------------------------------------
  28. // Constructor
  29. //-----------------------------------------------------------------------------
  30. CGameUIScriptInterface::CGameUIScriptInterface( IScriptVM *pScriptVM, CGameUIDefinition *pDef ) :
  31. m_Nuggets( UtlStringLessFunc ),
  32. m_GraphicScriptInstances( UtlStringLessFunc ),
  33. m_pScriptVM( pScriptVM ),
  34. m_pMenu( pDef )
  35. {
  36. m_Scope = m_pScriptVM->RegisterInstance( this, "c" );
  37. }
  38. CGameUIScriptInterface::~CGameUIScriptInterface()
  39. {
  40. Shutdown();
  41. }
  42. void CGameUIScriptInterface::Shutdown()
  43. {
  44. // Unload all nuggets
  45. for ( unsigned short k = m_Nuggets.FirstInorder(); k != m_Nuggets.InvalidIndex(); k = m_Nuggets.NextInorder( k ) )
  46. {
  47. IGameUIScreenController *pNugget = m_Nuggets.Element( k );
  48. pNugget->OnScreenDisconnected( m_pMenu->GetGameUISystem() );
  49. }
  50. m_Nuggets.Purge();
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Show the ID menu next frame, and hide this menu next frame.
  54. //-----------------------------------------------------------------------------
  55. HSCRIPT CGameUIScriptInterface::LoadMenu( const char *szMenuName, HSCRIPT hParams )
  56. {
  57. if ( !szMenuName || !*szMenuName )
  58. return NULL;
  59. // Build the key values for the command and broadcast (deleted inside broadcast system)
  60. KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szMenuName, hParams );
  61. KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
  62. if ( ui_script_spew_level.GetInt() > 0 )
  63. {
  64. DevMsg( "CGameUIScriptInterface::LoadMenu\n" );
  65. KeyValuesDumpAsDevMsg( kvCommand );
  66. }
  67. IGameUISystem *pUI = g_pGameUISystemMgrImpl->LoadGameUIScreen( kvCommand );
  68. if ( !pUI )
  69. return NULL;
  70. KeyValues *kvResult = new KeyValues( "" );
  71. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  72. kvResult->SetInt( "scripthandle", pUI->GetScriptHandle() );
  73. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  74. }
  75. //-----------------------------------------------------------------------------
  76. //
  77. //-----------------------------------------------------------------------------
  78. HSCRIPT CGameUIScriptInterface::CreateGraphic( const char *szGraphicClassName, HSCRIPT hParams )
  79. {
  80. if ( !szGraphicClassName || !*szGraphicClassName )
  81. return NULL;
  82. if ( !m_pMenu || !m_pMenu->GetGameUISystem() )
  83. {
  84. DevWarning( "Scripts not connected to game UI system and cannot create graphics!\n" );
  85. return NULL;
  86. }
  87. // Build the key values for the command
  88. KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szGraphicClassName, hParams );
  89. KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
  90. if ( ui_script_spew_level.GetInt() > 0 )
  91. {
  92. DevMsg( "CGameUIScriptInterface::CreateGraphic\n" );
  93. KeyValuesDumpAsDevMsg( kvCommand );
  94. }
  95. const char* szGraphicName = kvCommand->GetString( "name", NULL );
  96. // Check if this instance is already created
  97. if ( szGraphicName == NULL )
  98. {
  99. DevWarning( "A must have a name!\n", szGraphicName );
  100. return NULL;
  101. }
  102. // Check if an instance of this graphic already exists
  103. CGameGraphic *pGraphic = m_pMenu->GraphicExists( szGraphicName );
  104. if ( pGraphic )
  105. {
  106. DevWarning( "A graphic with this name %s is already loaded!\n", szGraphicName );
  107. return NULL;
  108. }
  109. IGameUIGraphicClassFactory *pFactory = g_pGameUISystemMgrImpl->GetGraphicClassFactory( szGraphicClassName );
  110. if ( !pFactory )
  111. {
  112. DevWarning( "No graphic class factory for %s!\n", szGraphicClassName );
  113. return NULL;
  114. }
  115. CGameGraphic *pNewGraphic = pFactory->CreateNewGraphicClass( kvCommand, m_pMenu );
  116. if ( !pNewGraphic )
  117. {
  118. DevWarning( "No graphic in factory %s!\n", szGraphicClassName );
  119. return NULL;
  120. }
  121. KeyValues *kvResult = new KeyValues( "" );
  122. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  123. kvResult->SetInt( "scripthandle", pNewGraphic->GetScriptHandle() );
  124. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  125. }
  126. HSCRIPT CGameUIScriptInterface::CallScript( int32 iScriptHandle, const char *szCommandName, HSCRIPT hParams )
  127. {
  128. if ( !szCommandName || !*szCommandName )
  129. return NULL;
  130. // Try to resolve other script handle specified
  131. CGameUISystem *pOtherScript = iScriptHandle ? CGameUISystem::FromScriptHandle( iScriptHandle ) : ( CGameUISystem * ) m_pMenu->GetGameUISystem();
  132. if ( !pOtherScript )
  133. {
  134. Warning( "CGameUIScriptInterface::CallScript with invalid script handle %d!\n", iScriptHandle );
  135. return NULL;
  136. }
  137. // Build the key values for the command and call other script
  138. KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
  139. KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
  140. if ( ui_script_spew_level.GetInt() > 0 )
  141. {
  142. DevMsg( "CGameUIScriptInterface::CallScript( %d : %s )\n", iScriptHandle, pOtherScript->GetName() );
  143. KeyValuesDumpAsDevMsg( kvCommand );
  144. }
  145. // Pass the command to another script
  146. KeyValues *kvResult = NULL;
  147. pOtherScript->ExecuteScript( kvCommand, &kvResult );
  148. if ( ui_script_spew_level.GetInt() > 0 )
  149. {
  150. KeyValuesDumpAsDevMsg( kvResult );
  151. }
  152. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  153. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  154. }
  155. HSCRIPT CGameUIScriptInterface::CallGraphic( int32 iGraphicHandle, const char *szCommandName, HSCRIPT hParams )
  156. {
  157. if ( !szCommandName || !*szCommandName || !iGraphicHandle )
  158. return NULL;
  159. CGameGraphic *pGraphic = CGameGraphic::FromScriptHandle( iGraphicHandle );
  160. if ( !pGraphic )
  161. {
  162. Warning( "CGameUIScriptInterface::CallGraphic with invalid graphic handle %d!\n", iGraphicHandle );
  163. return NULL;
  164. }
  165. // Build the key values for the command and call other script
  166. KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
  167. KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
  168. if ( ui_script_spew_level.GetInt() > 0 )
  169. {
  170. DevMsg( "CGameUIScriptInterface::CallGraphic( %d : %s )\n", iGraphicHandle, pGraphic->GetName() );
  171. KeyValuesDumpAsDevMsg( kvCommand );
  172. }
  173. // Pass the command to graphic
  174. KeyValues *kvResult = pGraphic->HandleScriptCommand( kvCommand);
  175. if ( ui_script_spew_level.GetInt() > 0 )
  176. {
  177. KeyValuesDumpAsDevMsg( kvResult );
  178. }
  179. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  180. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  181. }
  182. HSCRIPT CGameUIScriptInterface::Nugget( const char *szCommandName, HSCRIPT hParams )
  183. {
  184. if ( !szCommandName || !*szCommandName )
  185. return NULL;
  186. if ( !m_pMenu || !m_pMenu->GetGameUISystem() )
  187. {
  188. DevWarning( "Scripts not connected to game UI system and cannot use nuggets!\n" );
  189. return NULL;
  190. }
  191. // Build the key values for the command
  192. KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
  193. KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
  194. if ( ui_script_spew_level.GetInt() > 0 )
  195. {
  196. DevMsg( "CGameUIScriptInterface::Nugget\n" );
  197. KeyValuesDumpAsDevMsg( kvCommand );
  198. }
  199. // Parse the command
  200. if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "load:" ) )
  201. {
  202. char const *szNuggetName = szUseName;
  203. szUseName = kvCommand->GetString( "usename", szNuggetName );
  204. // Check if the nugget is already loaded
  205. if ( m_Nuggets.Find( szUseName ) != m_Nuggets.InvalidIndex() )
  206. {
  207. DevWarning( "Nugget factory %s is already loaded!\n", szUseName );
  208. return NULL;
  209. }
  210. IGameUIScreenControllerFactory *pFactory = g_pGameUISystemMgrImpl->GetScreenControllerFactory( szNuggetName );
  211. if ( !pFactory )
  212. {
  213. DevWarning( "No nugget factory for %s!\n", szNuggetName );
  214. return NULL;
  215. }
  216. kvCommand->SetName( szNuggetName );
  217. IGameUIScreenController *pNugget = pFactory->GetController( kvCommand );
  218. if ( !pNugget )
  219. {
  220. DevWarning( "No nugget in factory %s!\n", szNuggetName );
  221. return NULL;
  222. }
  223. // Connect the nugget with our screen
  224. m_Nuggets.Insert( szUseName, pNugget );
  225. pNugget->OnScreenConnected( m_pMenu->GetGameUISystem() );
  226. KeyValues *kvResult = new KeyValues( "" );
  227. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  228. kvResult->SetInt( "scripthandle", m_pMenu->GetGameUISystem()->GetScriptHandle() );
  229. kvResult->SetString( "usename", szUseName );
  230. kvResult->SetInt( "ptr", reinterpret_cast< int >( pNugget ) );
  231. if ( ui_script_spew_level.GetInt() > 0 )
  232. {
  233. DevMsg( "Loaded nugget %s\n", szNuggetName );
  234. KeyValuesDumpAsDevMsg( kvResult );
  235. }
  236. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  237. }
  238. if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "ref:" ) )
  239. {
  240. int iRefScriptHandle = kvCommand->GetInt( "scripthandle" );
  241. char const *szRefUseName = kvCommand->GetString( "usename", szUseName );
  242. // Check if the nugget is already loaded
  243. if ( m_Nuggets.Find( szUseName ) != m_Nuggets.InvalidIndex() )
  244. {
  245. DevWarning( "Nugget factory %s is already loaded!\n", szUseName );
  246. return NULL;
  247. }
  248. CGameUISystem *pMenu = iRefScriptHandle ? CGameUISystem::FromScriptHandle( iRefScriptHandle ) : ( CGameUISystem * ) m_pMenu->GetGameUISystem();
  249. if ( !pMenu )
  250. {
  251. DevWarning( "Nugget reference request %s with invalid script handle %d!\n", szUseName, iRefScriptHandle );
  252. return NULL;
  253. }
  254. CGameUIScriptInterface *pRefInterface = NULL;
  255. if ( CGameUIScript *pScript = pMenu->Definition().GetScript() )
  256. pRefInterface = pScript->GetScriptInterface();
  257. if ( !pRefInterface )
  258. {
  259. DevWarning( "Nugget reference request %s with script handle %d(%s) which has no scripts!\n", szUseName, iRefScriptHandle, pMenu->GetName() );
  260. return NULL;
  261. }
  262. unsigned short usIdx = pRefInterface->m_Nuggets.Find( szRefUseName );
  263. if ( usIdx == pRefInterface->m_Nuggets.InvalidIndex() )
  264. {
  265. DevWarning( "Nugget reference request %s with script handle %d(%s) which has no nugget %s!\n", szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName );
  266. return NULL;
  267. }
  268. IGameUIScreenController *pNugget = pRefInterface->m_Nuggets.Element( usIdx );
  269. if ( reinterpret_cast< int >( pNugget ) != kvCommand->GetInt( "ptr" ) )
  270. {
  271. DevWarning( "Nugget reference request %s with script handle %d(%s) for nugget %s yielding %08X instead of expected %08X!\n",
  272. szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName, reinterpret_cast< int >( pNugget ), kvCommand->GetInt( "ptr" ) );
  273. }
  274. // Connect the nugget with our screen
  275. m_Nuggets.Insert( szUseName, pNugget );
  276. pNugget->OnScreenConnected( m_pMenu->GetGameUISystem() );
  277. KeyValues *kvResult = new KeyValues( "" );
  278. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  279. kvResult->SetInt( "scripthandle", m_pMenu->GetGameUISystem()->GetScriptHandle() );
  280. kvResult->SetString( "usename", szUseName );
  281. kvResult->SetInt( "ptr", reinterpret_cast< int >( pNugget ) );
  282. if ( ui_script_spew_level.GetInt() > 0 )
  283. {
  284. DevMsg( "Referenced nugget %s from %d(%s):%s\n", szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName );
  285. KeyValuesDumpAsDevMsg( kvResult );
  286. }
  287. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  288. }
  289. if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "free:" ) )
  290. {
  291. // Check if the nugget is already loaded
  292. unsigned short usIdx = m_Nuggets.Find( szUseName );
  293. if ( usIdx == m_Nuggets.InvalidIndex() )
  294. {
  295. DevWarning( "Nugget factory %s is not loaded!\n", szUseName );
  296. return NULL;
  297. }
  298. // Unload the nugget
  299. IGameUIScreenController *pNugget = m_Nuggets.Element( usIdx );
  300. m_Nuggets.RemoveAt( usIdx );
  301. pNugget->OnScreenDisconnected( m_pMenu->GetGameUISystem() );
  302. if ( ui_script_spew_level.GetInt() > 0 )
  303. {
  304. DevMsg( "Unloaded nugget %s\n", szUseName );
  305. }
  306. return NULL;
  307. }
  308. if ( char const *szUse = StringAfterPrefix( kvCommand->GetName(), "use:" ) )
  309. {
  310. char const *szUseName = szUse;
  311. // Split off nugget name by :
  312. if ( char const *pch = strchr( szUseName, ':' ) )
  313. {
  314. char *buf = ( char * ) stackalloc( pch - szUseName + 1 );
  315. Q_strncpy( buf, szUseName, pch - szUseName + 1 );
  316. szUseName = buf;
  317. kvCommand->SetName( pch + 1 );
  318. }
  319. else
  320. {
  321. kvCommand->SetName( "" );
  322. }
  323. // Check if the nugget is already loaded
  324. unsigned short usIdx = m_Nuggets.Find( szUseName );
  325. if ( usIdx == m_Nuggets.InvalidIndex() )
  326. {
  327. DevWarning( "Nugget factory %s is not loaded!\n", szUseName );
  328. return NULL;
  329. }
  330. // Nugget operation
  331. IGameUIScreenController *pNugget = m_Nuggets.Element( usIdx );
  332. KeyValues *kvResult = pNugget->OnScreenEvent( m_pMenu->GetGameUISystem(), kvCommand );
  333. KeyValues::AutoDelete autodelete_kvResult( kvResult );
  334. if ( ui_script_spew_level.GetInt() > 0 )
  335. {
  336. KeyValuesDumpAsDevMsg( kvResult );
  337. }
  338. // Push results for the script
  339. return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
  340. }
  341. return NULL;
  342. }
  343. bool CGameUIScriptInterface::ScriptVmKeyValueToVariant( IScriptVM *pVM, KeyValues *val, ScriptVariant_t &varValue, char chScratchBuffer[KV_VARIANT_SCRATCH_BUF_SIZE] )
  344. {
  345. switch ( val->GetDataType() )
  346. {
  347. case KeyValues::TYPE_STRING:
  348. varValue = val->GetString();
  349. return true;
  350. case KeyValues::TYPE_INT:
  351. varValue = val->GetInt();
  352. return true;
  353. case KeyValues::TYPE_FLOAT:
  354. varValue = val->GetFloat();
  355. return true;
  356. case KeyValues::TYPE_UINT64:
  357. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%llu", val->GetUint64() );
  358. varValue = chScratchBuffer;
  359. return true;
  360. case KeyValues::TYPE_NONE:
  361. varValue = ScriptTableFromKeyValues( pVM, val );
  362. return true;
  363. default:
  364. Warning( "ScriptVmKeyValueToVariant failed to package parameter %s (type %d)\n", val->GetName(), val->GetDataType() );
  365. return false;
  366. }
  367. }
  368. bool CGameUIScriptInterface::ScriptVmStringFromVariant( ScriptVariant_t &varValue, char chScratchBuffer[KV_VARIANT_SCRATCH_BUF_SIZE] )
  369. {
  370. switch ( varValue.m_type )
  371. {
  372. case FIELD_INTEGER:
  373. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%d", varValue.m_int );
  374. return true;
  375. case FIELD_FLOAT:
  376. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%f", varValue.m_float );
  377. return true;
  378. case FIELD_BOOLEAN:
  379. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%d", varValue.m_bool );
  380. return true;
  381. case FIELD_CHARACTER:
  382. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%c", varValue.m_char );
  383. return true;
  384. case FIELD_CSTRING:
  385. Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%s", varValue.m_pszString ? varValue.m_pszString : "" );
  386. return true;
  387. default:
  388. Warning( "ScriptVmStringFromVariant failed to unpack parameter variant type %d\n", varValue.m_type );
  389. return false;
  390. }
  391. }
  392. KeyValues * CGameUIScriptInterface::ScriptVmKeyValueFromVariant( IScriptVM *pVM, ScriptVariant_t &varValue )
  393. {
  394. KeyValues *val = NULL;
  395. switch ( varValue.m_type )
  396. {
  397. case FIELD_INTEGER:
  398. val = new KeyValues( "" );
  399. val->SetInt( NULL, varValue.m_int );
  400. return val;
  401. case FIELD_FLOAT:
  402. val = new KeyValues( "" );
  403. val->SetFloat( NULL, varValue.m_float );
  404. return val;
  405. case FIELD_BOOLEAN:
  406. val = new KeyValues( "" );
  407. val->SetInt( NULL, varValue.m_bool ? 1 : 0 );
  408. return val;
  409. case FIELD_CHARACTER:
  410. val = new KeyValues( "" );
  411. val->SetString( NULL, CFmtStr( "%c", varValue.m_char ) );
  412. return val;
  413. case FIELD_CSTRING:
  414. val = new KeyValues( "" );
  415. val->SetString( NULL, varValue.m_pszString ? varValue.m_pszString : "" );
  416. return val;
  417. case FIELD_HSCRIPT:
  418. return ScriptTableToKeyValues( pVM, "", varValue.m_hScript );
  419. default:
  420. Warning( "ScriptVmKeyValueFromVariant failed to unpack parameter variant type %d\n", varValue.m_type );
  421. return NULL;
  422. }
  423. }
  424. KeyValues * CGameUIScriptInterface::ScriptTableToKeyValues( IScriptVM *pVM, char const *szName, HSCRIPT hTable )
  425. {
  426. if ( !szName )
  427. szName = "";
  428. KeyValues *kv = new KeyValues( szName );
  429. if ( hTable && pVM )
  430. {
  431. int numKeys = pVM->GetNumTableEntries( hTable );
  432. for ( int k = 0; k < numKeys; ++ k )
  433. {
  434. ScriptVariant_t varKey, varValue;
  435. pVM->GetKeyValue( hTable, k, &varKey, &varValue );
  436. char chScratchBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
  437. if ( !ScriptVmStringFromVariant( varKey, chScratchBuffer ) )
  438. {
  439. Assert( 0 );
  440. continue;
  441. }
  442. KeyValues *sub = ScriptVmKeyValueFromVariant( pVM, varValue );
  443. if ( !sub )
  444. {
  445. Assert( 0 );
  446. // sub->deleteThis();
  447. // continue;
  448. // still proceed - it will be a key with no data
  449. sub = new KeyValues( "" );
  450. }
  451. sub->SetName( chScratchBuffer );
  452. kv->AddSubKey( sub );
  453. }
  454. }
  455. return kv;
  456. }
  457. HSCRIPT CGameUIScriptInterface::ScriptTableFromKeyValues( IScriptVM *pVM, KeyValues *kv )
  458. {
  459. if ( !kv || !pVM )
  460. return NULL;
  461. ScriptVariant_t varTable;
  462. pVM->CreateTable( varTable );
  463. for ( KeyValues *val = kv->GetFirstSubKey(); val; val = val->GetNextKey() )
  464. {
  465. ScriptVariant_t varValue;
  466. char chScratchBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
  467. if ( !ScriptVmKeyValueToVariant( pVM, val, varValue, chScratchBuffer ) )
  468. continue;
  469. #ifdef GAMEUI_SCRIPT_LOWERCASE_ALL_TABLE_KEYS
  470. char chNameBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
  471. Q_strncpy( chNameBuffer, val->GetName(), KV_VARIANT_SCRATCH_BUF_SIZE );
  472. Q_strlower( chNameBuffer );
  473. #else
  474. char const *chNameBuffer = val->GetName();
  475. #endif
  476. pVM->SetValue( varTable.m_hScript, chNameBuffer, varValue );
  477. }
  478. return varTable.m_hScript;
  479. }