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
565 lines
18 KiB
//===== Copyright © Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose: Defines scripting system.
|
|
//
|
|
//===========================================================================//
|
|
|
|
#include "gameuiscriptInterface.h"
|
|
#include "gameuisystemmgr.h"
|
|
#include "gameuidefinition.h"
|
|
#include "gamelayer.h"
|
|
#include "gamegraphic.h"
|
|
#include "fmtstr.h"
|
|
#include "gameuiscript.h"
|
|
#include "gameuisystem.h"
|
|
#include "gametext.h"
|
|
#include "dynamicrect.h"
|
|
|
|
#include "tier2/tier2.h"
|
|
#include "matchmaking/imatchframework.h"
|
|
|
|
BEGIN_SCRIPTDESC_ROOT_NAMED( CGameUIScriptInterface, "CGameUIScriptInterface", SCRIPT_SINGLETON "" )
|
|
// HSCRIPT table-kv functions
|
|
DEFINE_SCRIPTFUNC( LoadMenu, "LoadMenu( name, {params} ) : Load a menu." )
|
|
DEFINE_SCRIPTFUNC( CreateGraphic, "CreateGraphic( classname, {params} ) : Create a graphic." )
|
|
DEFINE_SCRIPTFUNC( CallScript, "CallScript( scripthandle, function, {params} ) : Execute other script function (scripthandle=0 will run local script)." )
|
|
DEFINE_SCRIPTFUNC( CallGraphic, "CallGraphic( graphichandle, commandname, {params} ) : Execute a graphic function." )
|
|
DEFINE_SCRIPTFUNC( Nugget, "Nugget( action, {params} ) : Interface with nuggets." )
|
|
END_SCRIPTDESC()
|
|
|
|
|
|
static ConVar ui_script_spew_level( "ui_script_spew_level", 0, FCVAR_DEVELOPMENTONLY );
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CGameUIScriptInterface::CGameUIScriptInterface( IScriptVM *pScriptVM, CGameUIDefinition *pDef ) :
|
|
m_Nuggets( UtlStringLessFunc ),
|
|
m_GraphicScriptInstances( UtlStringLessFunc ),
|
|
m_pScriptVM( pScriptVM ),
|
|
m_pMenu( pDef )
|
|
{
|
|
m_Scope = m_pScriptVM->RegisterInstance( this, "c" );
|
|
}
|
|
|
|
CGameUIScriptInterface::~CGameUIScriptInterface()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
void CGameUIScriptInterface::Shutdown()
|
|
{
|
|
// Unload all nuggets
|
|
for ( unsigned short k = m_Nuggets.FirstInorder(); k != m_Nuggets.InvalidIndex(); k = m_Nuggets.NextInorder( k ) )
|
|
{
|
|
IGameUIScreenController *pNugget = m_Nuggets.Element( k );
|
|
pNugget->OnScreenDisconnected( m_pMenu->GetGameUISystem() );
|
|
}
|
|
m_Nuggets.Purge();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Show the ID menu next frame, and hide this menu next frame.
|
|
//-----------------------------------------------------------------------------
|
|
HSCRIPT CGameUIScriptInterface::LoadMenu( const char *szMenuName, HSCRIPT hParams )
|
|
{
|
|
if ( !szMenuName || !*szMenuName )
|
|
return NULL;
|
|
|
|
// Build the key values for the command and broadcast (deleted inside broadcast system)
|
|
KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szMenuName, hParams );
|
|
KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "CGameUIScriptInterface::LoadMenu\n" );
|
|
KeyValuesDumpAsDevMsg( kvCommand );
|
|
}
|
|
|
|
IGameUISystem *pUI = g_pGameUISystemMgrImpl->LoadGameUIScreen( kvCommand );
|
|
if ( !pUI )
|
|
return NULL;
|
|
|
|
KeyValues *kvResult = new KeyValues( "" );
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
kvResult->SetInt( "scripthandle", pUI->GetScriptHandle() );
|
|
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HSCRIPT CGameUIScriptInterface::CreateGraphic( const char *szGraphicClassName, HSCRIPT hParams )
|
|
{
|
|
if ( !szGraphicClassName || !*szGraphicClassName )
|
|
return NULL;
|
|
|
|
if ( !m_pMenu || !m_pMenu->GetGameUISystem() )
|
|
{
|
|
DevWarning( "Scripts not connected to game UI system and cannot create graphics!\n" );
|
|
return NULL;
|
|
}
|
|
|
|
// Build the key values for the command
|
|
KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szGraphicClassName, hParams );
|
|
KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "CGameUIScriptInterface::CreateGraphic\n" );
|
|
KeyValuesDumpAsDevMsg( kvCommand );
|
|
}
|
|
|
|
const char* szGraphicName = kvCommand->GetString( "name", NULL );
|
|
// Check if this instance is already created
|
|
if ( szGraphicName == NULL )
|
|
{
|
|
DevWarning( "A must have a name!\n", szGraphicName );
|
|
return NULL;
|
|
}
|
|
|
|
// Check if an instance of this graphic already exists
|
|
CGameGraphic *pGraphic = m_pMenu->GraphicExists( szGraphicName );
|
|
if ( pGraphic )
|
|
{
|
|
DevWarning( "A graphic with this name %s is already loaded!\n", szGraphicName );
|
|
return NULL;
|
|
}
|
|
|
|
IGameUIGraphicClassFactory *pFactory = g_pGameUISystemMgrImpl->GetGraphicClassFactory( szGraphicClassName );
|
|
if ( !pFactory )
|
|
{
|
|
DevWarning( "No graphic class factory for %s!\n", szGraphicClassName );
|
|
return NULL;
|
|
}
|
|
|
|
CGameGraphic *pNewGraphic = pFactory->CreateNewGraphicClass( kvCommand, m_pMenu );
|
|
if ( !pNewGraphic )
|
|
{
|
|
DevWarning( "No graphic in factory %s!\n", szGraphicClassName );
|
|
return NULL;
|
|
}
|
|
|
|
KeyValues *kvResult = new KeyValues( "" );
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
kvResult->SetInt( "scripthandle", pNewGraphic->GetScriptHandle() );
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
HSCRIPT CGameUIScriptInterface::CallScript( int32 iScriptHandle, const char *szCommandName, HSCRIPT hParams )
|
|
{
|
|
if ( !szCommandName || !*szCommandName )
|
|
return NULL;
|
|
|
|
// Try to resolve other script handle specified
|
|
CGameUISystem *pOtherScript = iScriptHandle ? CGameUISystem::FromScriptHandle( iScriptHandle ) : ( CGameUISystem * ) m_pMenu->GetGameUISystem();
|
|
if ( !pOtherScript )
|
|
{
|
|
Warning( "CGameUIScriptInterface::CallScript with invalid script handle %d!\n", iScriptHandle );
|
|
return NULL;
|
|
}
|
|
|
|
// Build the key values for the command and call other script
|
|
KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
|
|
KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "CGameUIScriptInterface::CallScript( %d : %s )\n", iScriptHandle, pOtherScript->GetName() );
|
|
KeyValuesDumpAsDevMsg( kvCommand );
|
|
}
|
|
|
|
// Pass the command to another script
|
|
KeyValues *kvResult = NULL;
|
|
pOtherScript->ExecuteScript( kvCommand, &kvResult );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
KeyValuesDumpAsDevMsg( kvResult );
|
|
}
|
|
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
HSCRIPT CGameUIScriptInterface::CallGraphic( int32 iGraphicHandle, const char *szCommandName, HSCRIPT hParams )
|
|
{
|
|
if ( !szCommandName || !*szCommandName || !iGraphicHandle )
|
|
return NULL;
|
|
|
|
CGameGraphic *pGraphic = CGameGraphic::FromScriptHandle( iGraphicHandle );
|
|
if ( !pGraphic )
|
|
{
|
|
Warning( "CGameUIScriptInterface::CallGraphic with invalid graphic handle %d!\n", iGraphicHandle );
|
|
return NULL;
|
|
}
|
|
|
|
// Build the key values for the command and call other script
|
|
KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
|
|
KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "CGameUIScriptInterface::CallGraphic( %d : %s )\n", iGraphicHandle, pGraphic->GetName() );
|
|
KeyValuesDumpAsDevMsg( kvCommand );
|
|
}
|
|
|
|
// Pass the command to graphic
|
|
KeyValues *kvResult = pGraphic->HandleScriptCommand( kvCommand);
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
KeyValuesDumpAsDevMsg( kvResult );
|
|
}
|
|
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
|
|
HSCRIPT CGameUIScriptInterface::Nugget( const char *szCommandName, HSCRIPT hParams )
|
|
{
|
|
if ( !szCommandName || !*szCommandName )
|
|
return NULL;
|
|
|
|
if ( !m_pMenu || !m_pMenu->GetGameUISystem() )
|
|
{
|
|
DevWarning( "Scripts not connected to game UI system and cannot use nuggets!\n" );
|
|
return NULL;
|
|
}
|
|
|
|
// Build the key values for the command
|
|
KeyValues *kvCommand = ScriptTableToKeyValues( m_pScriptVM, szCommandName, hParams );
|
|
KeyValues::AutoDelete autodelete_kvCommand( kvCommand );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "CGameUIScriptInterface::Nugget\n" );
|
|
KeyValuesDumpAsDevMsg( kvCommand );
|
|
}
|
|
|
|
// Parse the command
|
|
if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "load:" ) )
|
|
{
|
|
char const *szNuggetName = szUseName;
|
|
szUseName = kvCommand->GetString( "usename", szNuggetName );
|
|
|
|
// Check if the nugget is already loaded
|
|
if ( m_Nuggets.Find( szUseName ) != m_Nuggets.InvalidIndex() )
|
|
{
|
|
DevWarning( "Nugget factory %s is already loaded!\n", szUseName );
|
|
return NULL;
|
|
}
|
|
|
|
IGameUIScreenControllerFactory *pFactory = g_pGameUISystemMgrImpl->GetScreenControllerFactory( szNuggetName );
|
|
if ( !pFactory )
|
|
{
|
|
DevWarning( "No nugget factory for %s!\n", szNuggetName );
|
|
return NULL;
|
|
}
|
|
|
|
kvCommand->SetName( szNuggetName );
|
|
IGameUIScreenController *pNugget = pFactory->GetController( kvCommand );
|
|
if ( !pNugget )
|
|
{
|
|
DevWarning( "No nugget in factory %s!\n", szNuggetName );
|
|
return NULL;
|
|
}
|
|
|
|
// Connect the nugget with our screen
|
|
m_Nuggets.Insert( szUseName, pNugget );
|
|
pNugget->OnScreenConnected( m_pMenu->GetGameUISystem() );
|
|
|
|
KeyValues *kvResult = new KeyValues( "" );
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
kvResult->SetInt( "scripthandle", m_pMenu->GetGameUISystem()->GetScriptHandle() );
|
|
kvResult->SetString( "usename", szUseName );
|
|
kvResult->SetInt( "ptr", reinterpret_cast< int >( pNugget ) );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "Loaded nugget %s\n", szNuggetName );
|
|
KeyValuesDumpAsDevMsg( kvResult );
|
|
}
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "ref:" ) )
|
|
{
|
|
int iRefScriptHandle = kvCommand->GetInt( "scripthandle" );
|
|
char const *szRefUseName = kvCommand->GetString( "usename", szUseName );
|
|
|
|
// Check if the nugget is already loaded
|
|
if ( m_Nuggets.Find( szUseName ) != m_Nuggets.InvalidIndex() )
|
|
{
|
|
DevWarning( "Nugget factory %s is already loaded!\n", szUseName );
|
|
return NULL;
|
|
}
|
|
|
|
CGameUISystem *pMenu = iRefScriptHandle ? CGameUISystem::FromScriptHandle( iRefScriptHandle ) : ( CGameUISystem * ) m_pMenu->GetGameUISystem();
|
|
if ( !pMenu )
|
|
{
|
|
DevWarning( "Nugget reference request %s with invalid script handle %d!\n", szUseName, iRefScriptHandle );
|
|
return NULL;
|
|
}
|
|
|
|
CGameUIScriptInterface *pRefInterface = NULL;
|
|
if ( CGameUIScript *pScript = pMenu->Definition().GetScript() )
|
|
pRefInterface = pScript->GetScriptInterface();
|
|
|
|
if ( !pRefInterface )
|
|
{
|
|
DevWarning( "Nugget reference request %s with script handle %d(%s) which has no scripts!\n", szUseName, iRefScriptHandle, pMenu->GetName() );
|
|
return NULL;
|
|
}
|
|
|
|
unsigned short usIdx = pRefInterface->m_Nuggets.Find( szRefUseName );
|
|
if ( usIdx == pRefInterface->m_Nuggets.InvalidIndex() )
|
|
{
|
|
DevWarning( "Nugget reference request %s with script handle %d(%s) which has no nugget %s!\n", szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName );
|
|
return NULL;
|
|
}
|
|
|
|
IGameUIScreenController *pNugget = pRefInterface->m_Nuggets.Element( usIdx );
|
|
if ( reinterpret_cast< int >( pNugget ) != kvCommand->GetInt( "ptr" ) )
|
|
{
|
|
DevWarning( "Nugget reference request %s with script handle %d(%s) for nugget %s yielding %08X instead of expected %08X!\n",
|
|
szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName, reinterpret_cast< int >( pNugget ), kvCommand->GetInt( "ptr" ) );
|
|
}
|
|
|
|
// Connect the nugget with our screen
|
|
m_Nuggets.Insert( szUseName, pNugget );
|
|
pNugget->OnScreenConnected( m_pMenu->GetGameUISystem() );
|
|
|
|
KeyValues *kvResult = new KeyValues( "" );
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
kvResult->SetInt( "scripthandle", m_pMenu->GetGameUISystem()->GetScriptHandle() );
|
|
kvResult->SetString( "usename", szUseName );
|
|
kvResult->SetInt( "ptr", reinterpret_cast< int >( pNugget ) );
|
|
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "Referenced nugget %s from %d(%s):%s\n", szUseName, iRefScriptHandle, pMenu->GetName(), szRefUseName );
|
|
KeyValuesDumpAsDevMsg( kvResult );
|
|
}
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
if ( char const *szUseName = StringAfterPrefix( kvCommand->GetName(), "free:" ) )
|
|
{
|
|
// Check if the nugget is already loaded
|
|
unsigned short usIdx = m_Nuggets.Find( szUseName );
|
|
if ( usIdx == m_Nuggets.InvalidIndex() )
|
|
{
|
|
DevWarning( "Nugget factory %s is not loaded!\n", szUseName );
|
|
return NULL;
|
|
}
|
|
|
|
// Unload the nugget
|
|
IGameUIScreenController *pNugget = m_Nuggets.Element( usIdx );
|
|
m_Nuggets.RemoveAt( usIdx );
|
|
|
|
pNugget->OnScreenDisconnected( m_pMenu->GetGameUISystem() );
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
DevMsg( "Unloaded nugget %s\n", szUseName );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
if ( char const *szUse = StringAfterPrefix( kvCommand->GetName(), "use:" ) )
|
|
{
|
|
char const *szUseName = szUse;
|
|
// Split off nugget name by :
|
|
if ( char const *pch = strchr( szUseName, ':' ) )
|
|
{
|
|
char *buf = ( char * ) stackalloc( pch - szUseName + 1 );
|
|
Q_strncpy( buf, szUseName, pch - szUseName + 1 );
|
|
szUseName = buf;
|
|
kvCommand->SetName( pch + 1 );
|
|
}
|
|
else
|
|
{
|
|
kvCommand->SetName( "" );
|
|
}
|
|
|
|
// Check if the nugget is already loaded
|
|
unsigned short usIdx = m_Nuggets.Find( szUseName );
|
|
if ( usIdx == m_Nuggets.InvalidIndex() )
|
|
{
|
|
DevWarning( "Nugget factory %s is not loaded!\n", szUseName );
|
|
return NULL;
|
|
}
|
|
|
|
// Nugget operation
|
|
IGameUIScreenController *pNugget = m_Nuggets.Element( usIdx );
|
|
KeyValues *kvResult = pNugget->OnScreenEvent( m_pMenu->GetGameUISystem(), kvCommand );
|
|
|
|
KeyValues::AutoDelete autodelete_kvResult( kvResult );
|
|
if ( ui_script_spew_level.GetInt() > 0 )
|
|
{
|
|
KeyValuesDumpAsDevMsg( kvResult );
|
|
}
|
|
|
|
// Push results for the script
|
|
return ScriptTableFromKeyValues( m_pScriptVM, kvResult );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool CGameUIScriptInterface::ScriptVmKeyValueToVariant( IScriptVM *pVM, KeyValues *val, ScriptVariant_t &varValue, char chScratchBuffer[KV_VARIANT_SCRATCH_BUF_SIZE] )
|
|
{
|
|
switch ( val->GetDataType() )
|
|
{
|
|
case KeyValues::TYPE_STRING:
|
|
varValue = val->GetString();
|
|
return true;
|
|
case KeyValues::TYPE_INT:
|
|
varValue = val->GetInt();
|
|
return true;
|
|
case KeyValues::TYPE_FLOAT:
|
|
varValue = val->GetFloat();
|
|
return true;
|
|
case KeyValues::TYPE_UINT64:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%llu", val->GetUint64() );
|
|
varValue = chScratchBuffer;
|
|
return true;
|
|
case KeyValues::TYPE_NONE:
|
|
varValue = ScriptTableFromKeyValues( pVM, val );
|
|
return true;
|
|
default:
|
|
Warning( "ScriptVmKeyValueToVariant failed to package parameter %s (type %d)\n", val->GetName(), val->GetDataType() );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool CGameUIScriptInterface::ScriptVmStringFromVariant( ScriptVariant_t &varValue, char chScratchBuffer[KV_VARIANT_SCRATCH_BUF_SIZE] )
|
|
{
|
|
switch ( varValue.m_type )
|
|
{
|
|
case FIELD_INTEGER:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%d", varValue.m_int );
|
|
return true;
|
|
case FIELD_FLOAT:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%f", varValue.m_float );
|
|
return true;
|
|
case FIELD_BOOLEAN:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%d", varValue.m_bool );
|
|
return true;
|
|
case FIELD_CHARACTER:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%c", varValue.m_char );
|
|
return true;
|
|
case FIELD_CSTRING:
|
|
Q_snprintf( chScratchBuffer, KV_VARIANT_SCRATCH_BUF_SIZE, "%s", varValue.m_pszString ? varValue.m_pszString : "" );
|
|
return true;
|
|
default:
|
|
Warning( "ScriptVmStringFromVariant failed to unpack parameter variant type %d\n", varValue.m_type );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
KeyValues * CGameUIScriptInterface::ScriptVmKeyValueFromVariant( IScriptVM *pVM, ScriptVariant_t &varValue )
|
|
{
|
|
KeyValues *val = NULL;
|
|
|
|
switch ( varValue.m_type )
|
|
{
|
|
case FIELD_INTEGER:
|
|
val = new KeyValues( "" );
|
|
val->SetInt( NULL, varValue.m_int );
|
|
return val;
|
|
case FIELD_FLOAT:
|
|
val = new KeyValues( "" );
|
|
val->SetFloat( NULL, varValue.m_float );
|
|
return val;
|
|
case FIELD_BOOLEAN:
|
|
val = new KeyValues( "" );
|
|
val->SetInt( NULL, varValue.m_bool ? 1 : 0 );
|
|
return val;
|
|
case FIELD_CHARACTER:
|
|
val = new KeyValues( "" );
|
|
val->SetString( NULL, CFmtStr( "%c", varValue.m_char ) );
|
|
return val;
|
|
case FIELD_CSTRING:
|
|
val = new KeyValues( "" );
|
|
val->SetString( NULL, varValue.m_pszString ? varValue.m_pszString : "" );
|
|
return val;
|
|
case FIELD_HSCRIPT:
|
|
return ScriptTableToKeyValues( pVM, "", varValue.m_hScript );
|
|
default:
|
|
Warning( "ScriptVmKeyValueFromVariant failed to unpack parameter variant type %d\n", varValue.m_type );
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
KeyValues * CGameUIScriptInterface::ScriptTableToKeyValues( IScriptVM *pVM, char const *szName, HSCRIPT hTable )
|
|
{
|
|
if ( !szName )
|
|
szName = "";
|
|
|
|
KeyValues *kv = new KeyValues( szName );
|
|
|
|
if ( hTable && pVM )
|
|
{
|
|
int numKeys = pVM->GetNumTableEntries( hTable );
|
|
for ( int k = 0; k < numKeys; ++ k )
|
|
{
|
|
ScriptVariant_t varKey, varValue;
|
|
pVM->GetKeyValue( hTable, k, &varKey, &varValue );
|
|
|
|
char chScratchBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
|
|
if ( !ScriptVmStringFromVariant( varKey, chScratchBuffer ) )
|
|
{
|
|
Assert( 0 );
|
|
continue;
|
|
}
|
|
|
|
KeyValues *sub = ScriptVmKeyValueFromVariant( pVM, varValue );
|
|
if ( !sub )
|
|
{
|
|
Assert( 0 );
|
|
// sub->deleteThis();
|
|
// continue;
|
|
// still proceed - it will be a key with no data
|
|
sub = new KeyValues( "" );
|
|
}
|
|
sub->SetName( chScratchBuffer );
|
|
|
|
kv->AddSubKey( sub );
|
|
}
|
|
}
|
|
|
|
return kv;
|
|
}
|
|
|
|
HSCRIPT CGameUIScriptInterface::ScriptTableFromKeyValues( IScriptVM *pVM, KeyValues *kv )
|
|
{
|
|
if ( !kv || !pVM )
|
|
return NULL;
|
|
|
|
ScriptVariant_t varTable;
|
|
pVM->CreateTable( varTable );
|
|
|
|
for ( KeyValues *val = kv->GetFirstSubKey(); val; val = val->GetNextKey() )
|
|
{
|
|
ScriptVariant_t varValue;
|
|
char chScratchBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
|
|
if ( !ScriptVmKeyValueToVariant( pVM, val, varValue, chScratchBuffer ) )
|
|
continue;
|
|
|
|
#ifdef GAMEUI_SCRIPT_LOWERCASE_ALL_TABLE_KEYS
|
|
char chNameBuffer[ KV_VARIANT_SCRATCH_BUF_SIZE ];
|
|
Q_strncpy( chNameBuffer, val->GetName(), KV_VARIANT_SCRATCH_BUF_SIZE );
|
|
Q_strlower( chNameBuffer );
|
|
#else
|
|
char const *chNameBuffer = val->GetName();
|
|
#endif
|
|
|
|
pVM->SetValue( varTable.m_hScript, chNameBuffer, varValue );
|
|
}
|
|
|
|
return varTable.m_hScript;
|
|
}
|
|
|