diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index b78fc117..8b7f9108 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -40,6 +40,60 @@ HSCRIPT EntIndexToHScript( int index ) { return ToHScript( UTIL_EntityByIndex( index ) ); } + +void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV ) +{ + int nIterator = -1; + ScriptVariant_t varKey, varValue; + while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1) + { + switch (varValue.m_type) + { + case FIELD_CSTRING: pEntity->KeyValue( varKey.m_pszString, varValue.m_pszString ); break; + case FIELD_FLOAT: pEntity->KeyValue( varKey.m_pszString, varValue.m_float ); break; + case FIELD_VECTOR: pEntity->KeyValue( varKey.m_pszString, *varValue.m_pVector ); break; + } + + g_pScriptVM->ReleaseValue( varKey ); + g_pScriptVM->ReleaseValue( varValue ); + } +} + +void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV ) +{ + // This is similar to UTIL_PrecacheOther(), but we can't check if we can only precache it once. + // Probably for the best anyway, as similar classes can still have different precachable properties. + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); + if (!pEntity) + { + Assert( !"PrecacheEntityFromTable: only works for CBaseEntities" ); + return; + } + + ParseScriptTableKeyValues( pEntity, hKV ); + + pEntity->Precache(); + + UTIL_RemoveImmediate( pEntity ); +} + +HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV ) +{ + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); + if ( !pEntity ) + { + Assert( !"SpawnEntityFromTable: only works for CBaseEntities" ); + return NULL; + } + + gEntList.NotifyCreateEntity( pEntity ); + + ParseScriptTableKeyValues( pEntity, hKV ); + + DispatchSpawn( pEntity ); + + return ToHScript( pEntity ); +} #endif //----------------------------------------------------------------------------- @@ -52,13 +106,12 @@ inline CScriptKeyValues *ToScriptKeyValues( HSCRIPT hKV ) return (hKV) ? (CScriptKeyValues*)g_pScriptVM->GetInstanceValue( hKV, GetScriptDescForClass( CScriptKeyValues ) ) : NULL; } -// Since IScriptVM::GetKeyValue() is unsupported, Mapbase uses this CScriptKeyValues version HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) { CBaseEntity *pEntity = CreateEntityByName( pszClassname ); if ( !pEntity ) { - Assert( !"SpawnEntityFromTable: only works for CBaseEntities" ); + Assert( !"SpawnEntityFromKeyValues: only works for CBaseEntities" ); return NULL; } @@ -70,7 +123,6 @@ HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) KeyValues *pKV = pScriptKV->m_pKeyValues; for (pKV = pKV->GetFirstSubKey(); pKV != NULL; pKV = pKV->GetNextKey()) { - //g_pScriptVM->GetKeyValue( hKV, i, &varKey, &varValue ); pEntity->KeyValue( pKV->GetName(), pKV->GetString() ); } } @@ -79,6 +131,15 @@ HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) return ToHScript( pEntity ); } + +void ScriptDispatchSpawn( HSCRIPT hEntity ) +{ + CBaseEntity *pEntity = ToEnt( hEntity ); + if (pEntity) + { + DispatchSpawn( pEntity ); + } +} #endif void RegisterSharedScriptFunctions() @@ -97,11 +158,14 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunction( g_pScriptVM, AddThinkToEnt, "This will put a think function onto an entity, or pass null to remove it. This is NOT chained, so be careful." ); ScriptRegisterFunction( g_pScriptVM, EntIndexToHScript, "Returns the script handle for the given entity index." ); + ScriptRegisterFunction( g_pScriptVM, PrecacheEntityFromTable, "Precache an entity from KeyValues in a table." ); + ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromTable, "Native function for entity spawning." ); #endif // Functions unique to Mapbase #ifndef CLIENT_DLL ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromKeyValues, "Spawns an entity with the keyvalues in a CScriptKeyValues handle." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchSpawn, "DispatchSpawn", "Spawns an unspawned entity." ); #endif #ifdef CLIENT_DLL diff --git a/sp/src/game/shared/vscript_shared.cpp b/sp/src/game/shared/vscript_shared.cpp index 860dc591..987359fd 100644 --- a/sp/src/game/shared/vscript_shared.cpp +++ b/sp/src/game/shared/vscript_shared.cpp @@ -85,7 +85,11 @@ HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing ) { bool bResult = filesystem->ReadFile( scriptPath, "GAME", bufferScript ); +#ifdef MAPBASE_VSCRIPT + if ( !bResult && bWarnMissing ) +#else if( !bResult ) +#endif { Warning( "Script not found (%s) \n", scriptPath.operator const char *() ); Assert( "Error running script" );