diff --git a/sp/src/game/client/vscript_client.cpp b/sp/src/game/client/vscript_client.cpp index 1a5c59be..faf35c16 100644 --- a/sp/src/game/client/vscript_client.cpp +++ b/sp/src/game/client/vscript_client.cpp @@ -707,6 +707,10 @@ bool VScriptClientInit() VScriptRunScript( "vscript_client", true ); VScriptRunScript( "mapspawn", false ); +#ifdef MAPBASE_VSCRIPT + RunAddonScripts(); +#endif + VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" ); return true; diff --git a/sp/src/game/server/ai_baseactor.cpp b/sp/src/game/server/ai_baseactor.cpp index ddf3da70..df0a5aaa 100644 --- a/sp/src/game/server/ai_baseactor.cpp +++ b/sp/src/game/server/ai_baseactor.cpp @@ -1149,8 +1149,14 @@ void CAI_BaseActor::UpdateHeadControl( const Vector &vHeadTarget, float flHeadIn Warning( "================================================================================\n" "!!!!! %s tried to set a NaN head angle (can happen when look targets have >1 importance) !!!!!\n" "================================================================================\n", GetDebugName() ); - vTargetAngles.x = 0; - vTargetAngles.y = 0; + m_goalHeadCorrection.Init(); + Set( m_FlexweightHeadRightLeft, 0.0f ); + Set( m_FlexweightHeadUpDown, 0.0f ); + Set( m_FlexweightHeadTilt, 0.0f ); + Set( m_ParameterHeadYaw, 0.0f ); + Set( m_ParameterHeadPitch, 0.0f ); + Set( m_ParameterHeadRoll, 0.0f ); + return; } #endif diff --git a/sp/src/game/server/globalstate.cpp b/sp/src/game/server/globalstate.cpp index 7ade7762..720e8906 100644 --- a/sp/src/game/server/globalstate.cpp +++ b/sp/src/game/server/globalstate.cpp @@ -131,6 +131,9 @@ public: entity.name = m_nameList.AddString( pGlobalname ); entity.levelName = m_nameList.AddString( pMapName ); entity.state = state; +#ifdef MAPBASE + entity.counter = 0; +#endif int index = GetIndex( m_nameList.String( entity.name ) ); if ( index >= 0 ) diff --git a/sp/src/game/server/vscript_server.cpp b/sp/src/game/server/vscript_server.cpp index 25c8281a..40e35f00 100644 --- a/sp/src/game/server/vscript_server.cpp +++ b/sp/src/game/server/vscript_server.cpp @@ -672,6 +672,8 @@ bool VScriptServerInit() VScriptRunScript( "mapspawn", false ); #ifdef MAPBASE_VSCRIPT + RunAddonScripts(); + // Since the world entity spawns before VScript is initted, RunVScripts() is called before the VM has started, so no scripts are run. // This gets around that by calling the same function right after the VM is initted. GetWorldEntity()->RunVScripts(); diff --git a/sp/src/game/server/vscript_server.nut b/sp/src/game/server/vscript_server.nut index 0a2d75d7..ad48da19 100644 --- a/sp/src/game/server/vscript_server.nut +++ b/sp/src/game/server/vscript_server.nut @@ -93,7 +93,7 @@ function __ReplaceClosures( script, scope ) local tempParent = { getroottable = function() { return null; } }; local temp = { runscript = script }; - temp.set_delegate(tempParent); + temp.setdelegate(tempParent); temp.runscript() foreach( key,val in temp ) diff --git a/sp/src/game/shared/mapbase/mapbase_shared.cpp b/sp/src/game/shared/mapbase/mapbase_shared.cpp index 47e83ada..43790ca5 100644 --- a/sp/src/game/shared/mapbase/mapbase_shared.cpp +++ b/sp/src/game/shared/mapbase/mapbase_shared.cpp @@ -473,7 +473,7 @@ public: void LoadFromValue( const char *value, int type, bool bDontWarn ) { - if (!filesystem->FileExists(value, "MOD")) + if (type != MANIFEST_VSCRIPT && !filesystem->FileExists(value, "MOD")) { if (!bDontWarn) { diff --git a/sp/src/game/shared/vscript_shared.cpp b/sp/src/game/shared/vscript_shared.cpp index 4f20b7c6..ec41c566 100644 --- a/sp/src/game/shared/vscript_shared.cpp +++ b/sp/src/game/shared/vscript_shared.cpp @@ -40,6 +40,15 @@ extern int vscript_token; int vscript_token_hack = vscript_token; #endif +static const char *pszExtensions[] = +{ + "", // SL_NONE + ".gm", // SL_GAMEMONKEY + ".nut", // SL_SQUIRREL + ".lua", // SL_LUA + ".py", // SL_PYTHON +}; + HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing ) @@ -49,15 +58,6 @@ HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing ) return NULL; } - static const char *pszExtensions[] = - { - "", // SL_NONE - ".gm", // SL_GAMEMONKEY - ".nut", // SL_SQUIRREL - ".lua", // SL_LUA - ".py", // SL_PYTHON - }; - const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()]; const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) @@ -171,6 +171,113 @@ bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMiss } +#ifdef MAPBASE_VSCRIPT + +// +// These functions are currently only used for "mapspawn_addon" scripts. +// +HSCRIPT VScriptCompileScriptAbsolute( const char *pszScriptName, bool bWarnMissing, const char *pszRootFolderName ) +{ + if ( !g_pScriptVM ) + { + return NULL; + } + + const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()]; + const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' ); + if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Script file type does not match VM type\n" ); + return NULL; + } + + CFmtStr scriptPath; + if ( pszIncomingExtension ) + { + scriptPath = pszScriptName; + } + else + { + scriptPath.sprintf( "%s%s", pszScriptName, pszVMExtension ); + } + + const char *pBase; + CUtlBuffer bufferScript; + + if ( g_pScriptVM->GetLanguage() == SL_PYTHON ) + { + // python auto-loads raw or precompiled modules - don't load data here + pBase = NULL; + } + else + { + bool bResult = filesystem->ReadFile( scriptPath, NULL, bufferScript ); + + if ( !bResult && bWarnMissing ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Script not found (%s) \n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + + pBase = (const char *) bufferScript.Base(); + + if ( !pBase || !*pBase ) + { + return NULL; + } + } + + // Attach the folder to the script ID + const char *pszFilename = V_strrchr( scriptPath, '/' ); + scriptPath.sprintf( "%s%s", pszRootFolderName, pszFilename ); + + HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, scriptPath ); + if ( !hScript ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() ); + Assert( "Error running script" ); + } + return hScript; +} + +bool VScriptRunScriptAbsolute( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing, const char *pszRootFolderName ) +{ + if ( !g_pScriptVM ) + { + return false; + } + + if ( !pszScriptName || !*pszScriptName ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "Cannot run script: NULL script name\n" ); + return false; + } + + // Prevent infinite recursion in VM + if ( g_ScriptServerRunScriptDepth > 16 ) + { + CGWarning( 0, CON_GROUP_VSCRIPT, "IncludeScript stack overflow\n" ); + return false; + } + + g_ScriptServerRunScriptDepth++; + HSCRIPT hScript = VScriptCompileScriptAbsolute( pszScriptName, bWarnMissing, pszRootFolderName ); + bool bSuccess = false; + if ( hScript ) + { + bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR ); + if ( !bSuccess ) + { + Warning( "Error running script named %s\n", pszScriptName ); + Assert( "Error running script" ); + } + } + g_ScriptServerRunScriptDepth--; + return bSuccess; +} +#endif + + #ifdef GAME_DLL #define IsCommandIssuedByServerAdmin() UTIL_IsCommandIssuedByServerAdmin() #else @@ -321,6 +428,74 @@ CON_COMMAND_F( script_dump_all, "Dump the state of the VM to the console", FCVAR //----------------------------------------------------------------------------- +#ifdef MAPBASE_VSCRIPT +void RunAddonScripts() +{ + char searchPaths[4096]; + filesystem->GetSearchPath( "ADDON", true, searchPaths, sizeof( searchPaths ) ); + + for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) ) + { + char folderName[MAX_PATH]; + Q_FileBase( path, folderName, sizeof( folderName ) ); + + // mapspawn_addon + char fullpath[MAX_PATH]; + Q_snprintf( fullpath, sizeof( fullpath ), "%sscripts/vscripts/mapspawn_addon", path ); + Q_FixSlashes( fullpath ); + + VScriptRunScriptAbsolute( fullpath, NULL, false, folderName ); + } +} + +// UNDONE: "autorun" folder +/* +void RunAutorunScripts() +{ + FileFindHandle_t fileHandle; + char szDirectory[MAX_PATH]; + char szFileName[MAX_PATH]; + char szPartialScriptPath[MAX_PATH]; + + // TODO: Scanning for VM extension would make this more efficient + Q_strncpy( szDirectory, "scripts/vscripts/autorun/*", sizeof( szDirectory ) ); + + const char *pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle ); + while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE) + { + Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) ); + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/%s", szFileName ); + VScriptRunScript( szPartialScriptPath ); + + pszScriptFile = filesystem->FindNext( fileHandle ); + } + + // Non-shared scripts +#ifdef CLIENT_DLL + Q_strncpy( szDirectory, "scripts/vscripts/autorun/client/*", sizeof( szDirectory ) ); +#else + Q_strncpy( szDirectory, "scripts/vscripts/autorun/server/*", sizeof( szDirectory ) ); +#endif + + pszScriptFile = filesystem->FindFirst( szDirectory, &fileHandle ); + while (pszScriptFile && fileHandle != FILESYSTEM_INVALID_FIND_HANDLE) + { + Q_FileBase( pszScriptFile, szFileName, sizeof( szFileName ) ); +#ifdef CLIENT_DLL + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/client/%s", szFileName ); +#else + Q_snprintf( szPartialScriptPath, sizeof( szPartialScriptPath ), "autorun/server/%s", szFileName ); +#endif + VScriptRunScript( szPartialScriptPath ); + + pszScriptFile = filesystem->FindNext( fileHandle ); + } +} +*/ +#endif + +//----------------------------------------------------------------------------- + static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2; //----------------------------------------------------------------------------- diff --git a/sp/src/game/shared/vscript_shared.h b/sp/src/game/shared/vscript_shared.h index 8bf23d54..50834220 100644 --- a/sp/src/game/shared/vscript_shared.h +++ b/sp/src/game/shared/vscript_shared.h @@ -45,6 +45,8 @@ extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper; #ifdef MAPBASE_VSCRIPT void RegisterSharedScriptConstants(); void RegisterSharedScriptFunctions(); + +void RunAddonScripts(); #endif #endif // VSCRIPT_SHARED_H