2020-05-04 16:25:15 +10:00
//========== Copyright <20> 2008, Valve Corporation, All rights reserved. ========
//
// Purpose:
//
//=============================================================================
# include "cbase.h"
# include "vscript_client.h"
# include "icommandline.h"
# include "tier1/utlbuffer.h"
# include "tier1/fmtstr.h"
# include "filesystem.h"
# include "characterset.h"
# include "isaverestore.h"
# include "gamerules.h"
2020-05-31 15:39:17 +10:00
# include "vscript_client.nut"
2020-05-27 10:22:45 -05:00
# ifdef MAPBASE_VSCRIPT
2020-06-11 23:48:59 -05:00
# include "mapbase/matchers.h"
2020-05-27 10:22:45 -05:00
# include "c_world.h"
2020-05-30 10:48:00 -05:00
# include "proxyentity.h"
# include "materialsystem/imaterial.h"
# include "materialsystem/imaterialvar.h"
2020-12-25 23:07:46 +03:00
# include "mapbase/vscript_singletons.h"
2020-05-27 10:22:45 -05:00
# endif
2020-05-04 16:25:15 +10:00
extern IScriptManager * scriptmanager ;
extern ScriptClassDesc_t * GetScriptDesc ( CBaseEntity * ) ;
// #define VMPROFILE 1
# ifdef VMPROFILE
# define VMPROF_START float debugStartTime = Plat_FloatTime();
# define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
# else // !VMPROFILE
# define VMPROF_START
# define VMPROF_SHOW
# endif // VMPROFILE
2020-05-30 10:48:00 -05:00
# ifdef MAPBASE_VSCRIPT
2020-06-11 23:48:59 -05:00
//-----------------------------------------------------------------------------
// Purpose: A clientside variant of CScriptEntityIterator.
//-----------------------------------------------------------------------------
class CScriptClientEntityIterator
{
public :
2020-12-25 23:07:46 +03:00
HSCRIPT GetLocalPlayer ( )
{
return ToHScript ( C_BasePlayer : : GetLocalPlayer ( ) ) ;
}
2020-06-11 23:48:59 -05:00
HSCRIPT First ( ) { return Next ( NULL ) ; }
HSCRIPT Next ( HSCRIPT hStartEntity )
{
return ToHScript ( ClientEntityList ( ) . NextBaseEntity ( ToEnt ( hStartEntity ) ) ) ;
}
HSCRIPT CreateByClassname ( const char * className )
{
return ToHScript ( CreateEntityByName ( className ) ) ;
}
HSCRIPT FindByClassname ( HSCRIPT hStartEntity , const char * szName )
{
const CEntInfo * pInfo = hStartEntity ? ClientEntityList ( ) . GetEntInfoPtr ( ToEnt ( hStartEntity ) - > GetRefEHandle ( ) ) - > m_pNext : ClientEntityList ( ) . FirstEntInfo ( ) ;
for ( ; pInfo ; pInfo = pInfo - > m_pNext )
{
C_BaseEntity * ent = ( C_BaseEntity * ) pInfo - > m_pEntity ;
if ( ! ent )
continue ;
if ( Matcher_Match ( szName , ent - > GetClassname ( ) ) )
return ToHScript ( ent ) ;
}
return NULL ;
}
HSCRIPT FindByName ( HSCRIPT hStartEntity , const char * szName )
{
const CEntInfo * pInfo = hStartEntity ? ClientEntityList ( ) . GetEntInfoPtr ( ToEnt ( hStartEntity ) - > GetRefEHandle ( ) ) - > m_pNext : ClientEntityList ( ) . FirstEntInfo ( ) ;
for ( ; pInfo ; pInfo = pInfo - > m_pNext )
{
C_BaseEntity * ent = ( C_BaseEntity * ) pInfo - > m_pEntity ;
if ( ! ent )
continue ;
if ( Matcher_Match ( szName , ent - > GetEntityName ( ) ) )
return ToHScript ( ent ) ;
}
return NULL ;
}
private :
} g_ScriptEntityIterator ;
BEGIN_SCRIPTDESC_ROOT_NAMED ( CScriptClientEntityIterator , " CEntities " , SCRIPT_SINGLETON " The global list of entities " )
2020-12-25 23:07:46 +03:00
DEFINE_SCRIPTFUNC ( GetLocalPlayer , " Get local player " )
2020-06-11 23:48:59 -05:00
DEFINE_SCRIPTFUNC ( First , " Begin an iteration over the list of entities " )
DEFINE_SCRIPTFUNC ( Next , " Continue an iteration over the list of entities, providing reference to a previously found entity " )
DEFINE_SCRIPTFUNC ( CreateByClassname , " Creates an entity by classname " )
DEFINE_SCRIPTFUNC ( FindByClassname , " Find entities by class name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search " )
DEFINE_SCRIPTFUNC ( FindByName , " Find entities by name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search " )
END_SCRIPTDESC ( ) ;
2020-05-31 20:58:50 -05:00
//-----------------------------------------------------------------------------
// Purpose: A base class for VScript-utilizing clientside classes which can persist
// across levels, requiring their scripts to be shut down manually.
//-----------------------------------------------------------------------------
abstract_class IClientScriptPersistable
{
public :
virtual void TermScript ( ) = 0 ;
} ;
CUtlVector < IClientScriptPersistable * > g_ScriptPersistableList ;
2020-05-30 10:48:00 -05:00
# define SCRIPT_MAT_PROXY_MAX_VARS 8
//-----------------------------------------------------------------------------
// Purpose: A material proxy which runs a VScript and allows it to read/write
// to material variables.
//-----------------------------------------------------------------------------
2020-05-31 20:58:50 -05:00
class CScriptMaterialProxy : public IMaterialProxy , public IClientScriptPersistable
2020-05-30 10:48:00 -05:00
{
public :
CScriptMaterialProxy ( ) ;
virtual ~ CScriptMaterialProxy ( ) ;
virtual void Release ( void ) ;
virtual bool Init ( IMaterial * pMaterial , KeyValues * pKeyValues ) ;
virtual void OnBind ( void * pRenderable ) ;
virtual IMaterial * GetMaterial ( ) { return NULL ; }
2020-05-31 20:58:50 -05:00
// Proxies can persist across levels and aren't bound to a loaded map.
// The VM, however, is bound to the loaded map, so the proxy's script variables persisting
// causes problems when they're used in a new level with a new VM.
// As a result, we call InitScript() and TermScript() during OnBind and when the level is unloaded respectively.
2020-05-30 10:48:00 -05:00
bool InitScript ( ) ;
2020-05-31 20:58:50 -05:00
void TermScript ( ) ;
2020-05-30 10:48:00 -05:00
bool ValidateIndex ( int i )
{
if ( i > SCRIPT_MAT_PROXY_MAX_VARS | | i < 0 )
{
2020-11-26 02:26:55 +00:00
CGWarning ( 0 , CON_GROUP_VSCRIPT , " VScriptProxy: %i out of range " , i ) ;
2020-05-30 10:48:00 -05:00
return false ;
}
return true ;
}
const char * GetVarString ( int i ) ;
int GetVarInt ( int i ) ;
float GetVarFloat ( int i ) ;
const Vector & GetVarVector ( int i ) ;
void SetVarString ( int i , const char * value ) ;
void SetVarInt ( int i , int value ) ;
void SetVarFloat ( int i , float value ) ;
void SetVarVector ( int i , const Vector & value ) ;
private :
IMaterialVar * m_MaterialVars [ SCRIPT_MAT_PROXY_MAX_VARS ] ;
// Save the keyvalue string for InitScript()
char m_szFilePath [ MAX_PATH ] ;
CScriptScope m_ScriptScope ;
HSCRIPT m_hScriptInstance ;
HSCRIPT m_hFuncOnBind ;
} ;
2021-01-27 11:01:38 -06:00
class CMaterialProxyScriptInstanceHelper : public IScriptInstanceHelper
{
bool ToString ( void * p , char * pBuf , int bufSize ) ;
void * BindOnRead ( HSCRIPT hInstance , void * pOld , const char * pszId ) ;
} ;
CMaterialProxyScriptInstanceHelper g_MaterialProxyScriptInstanceHelper ;
2020-05-30 10:48:00 -05:00
BEGIN_SCRIPTDESC_ROOT_NAMED ( CScriptMaterialProxy , " CScriptMaterialProxy " , " Material proxy for VScript " )
2021-01-27 11:01:38 -06:00
DEFINE_SCRIPT_INSTANCE_HELPER ( & g_MaterialProxyScriptInstanceHelper )
2020-05-30 10:48:00 -05:00
DEFINE_SCRIPTFUNC ( GetVarString , " Gets a material var's string value " )
DEFINE_SCRIPTFUNC ( GetVarInt , " Gets a material var's int value " )
DEFINE_SCRIPTFUNC ( GetVarFloat , " Gets a material var's float value " )
DEFINE_SCRIPTFUNC ( GetVarVector , " Gets a material var's vector value " )
DEFINE_SCRIPTFUNC ( SetVarString , " Sets a material var's string value " )
DEFINE_SCRIPTFUNC ( SetVarInt , " Sets a material var's int value " )
DEFINE_SCRIPTFUNC ( SetVarFloat , " Sets a material var's float value " )
DEFINE_SCRIPTFUNC ( SetVarVector , " Sets a material var's vector value " )
END_SCRIPTDESC ( ) ;
CScriptMaterialProxy : : CScriptMaterialProxy ( )
{
m_hScriptInstance = NULL ;
m_hFuncOnBind = NULL ;
}
CScriptMaterialProxy : : ~ CScriptMaterialProxy ( )
{
}
//-----------------------------------------------------------------------------
// Cleanup
//-----------------------------------------------------------------------------
void CScriptMaterialProxy : : Release ( void )
{
if ( m_hScriptInstance & & g_pScriptVM )
{
g_pScriptVM - > RemoveInstance ( m_hScriptInstance ) ;
m_hScriptInstance = NULL ;
}
delete this ;
}
bool CScriptMaterialProxy : : Init ( IMaterial * pMaterial , KeyValues * pKeyValues )
{
for ( KeyValues * pKey = pKeyValues - > GetFirstSubKey ( ) ; pKey ! = NULL ; pKey = pKey - > GetNextKey ( ) )
{
// Get each variable we're looking for
if ( Q_strnicmp ( pKey - > GetName ( ) , " var " , 3 ) = = 0 )
{
int index = atoi ( pKey - > GetName ( ) + 3 ) ;
if ( index > SCRIPT_MAT_PROXY_MAX_VARS )
{
Warning ( " VScript material proxy only supports 8 vars (not %i) \n " , index ) ;
continue ;
}
bool foundVar ;
m_MaterialVars [ index ] = pMaterial - > FindVar ( pKey - > GetString ( ) , & foundVar ) ;
// Don't init if we didn't find the var
if ( ! foundVar )
return false ;
}
else if ( FStrEq ( pKey - > GetName ( ) , " scriptfile " ) )
{
Q_strncpy ( m_szFilePath , pKey - > GetString ( ) , sizeof ( m_szFilePath ) ) ;
}
}
return true ;
}
bool CScriptMaterialProxy : : InitScript ( )
{
if ( ! m_ScriptScope . IsInitialized ( ) )
{
if ( scriptmanager = = NULL )
{
ExecuteOnce ( DevMsg ( " Cannot execute script because scripting is disabled (-scripting) \n " ) ) ;
return false ;
}
if ( g_pScriptVM = = NULL )
{
ExecuteOnce ( DevMsg ( " Cannot execute script because there is no available VM \n " ) ) ;
return false ;
}
char * iszScriptId = ( char * ) stackalloc ( 1024 ) ;
g_pScriptVM - > GenerateUniqueKey ( " VScriptProxy " , iszScriptId , 1024 ) ;
m_hScriptInstance = g_pScriptVM - > RegisterInstance ( GetScriptDescForClass ( CScriptMaterialProxy ) , this ) ;
g_pScriptVM - > SetInstanceUniqeId ( m_hScriptInstance , iszScriptId ) ;
bool bResult = m_ScriptScope . Init ( iszScriptId ) ;
if ( ! bResult )
{
2020-11-26 02:26:55 +00:00
CGMsg ( 1 , CON_GROUP_VSCRIPT , " VScriptProxy couldn't create ScriptScope! \n " ) ;
2020-05-30 10:48:00 -05:00
return false ;
}
g_pScriptVM - > SetValue ( m_ScriptScope , " self " , m_hScriptInstance ) ;
}
// Don't init if we can't run the script
if ( ! VScriptRunScript ( m_szFilePath , m_ScriptScope , true ) )
return false ;
m_hFuncOnBind = m_ScriptScope . LookupFunction ( " OnBind " ) ;
if ( ! m_hFuncOnBind )
{
// Don't init if we can't find our func
Warning ( " VScript material proxy can't find OnBind function \n " ) ;
return false ;
}
2020-05-31 20:58:50 -05:00
g_ScriptPersistableList . AddToTail ( this ) ;
2020-05-30 10:48:00 -05:00
return true ;
}
2020-05-31 20:58:50 -05:00
void CScriptMaterialProxy : : TermScript ( )
{
if ( m_hScriptInstance )
{
g_pScriptVM - > RemoveInstance ( m_hScriptInstance ) ;
m_hScriptInstance = NULL ;
}
m_hFuncOnBind = NULL ;
m_ScriptScope . Term ( ) ;
}
2020-05-30 10:48:00 -05:00
void CScriptMaterialProxy : : OnBind ( void * pRenderable )
{
if ( ! pRenderable )
return ;
if ( m_hFuncOnBind ! = NULL )
{
IClientRenderable * pRend = ( IClientRenderable * ) pRenderable ;
C_BaseEntity * pEnt = pRend - > GetIClientUnknown ( ) - > GetBaseEntity ( ) ;
if ( pEnt )
{
g_pScriptVM - > SetValue ( m_ScriptScope , " entity " , pEnt - > GetScriptInstance ( ) ) ;
}
else
{
// Needs to register as a null value so the script doesn't break if it looks for an entity
g_pScriptVM - > SetValue ( m_ScriptScope , " entity " , SCRIPT_VARIANT_NULL ) ;
}
m_ScriptScope . Call ( m_hFuncOnBind , NULL ) ;
g_pScriptVM - > ClearValue ( m_ScriptScope , " entity " ) ;
}
else
{
// The VM might not exist if we do it from Init(), so we have to do it here.
// TODO: We have no handling for if this fails, how do you cancel a proxy?
if ( InitScript ( ) )
OnBind ( pRenderable ) ;
}
}
const char * CScriptMaterialProxy : : GetVarString ( int i )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return NULL ;
return m_MaterialVars [ i ] - > GetStringValue ( ) ;
}
int CScriptMaterialProxy : : GetVarInt ( int i )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return 0 ;
return m_MaterialVars [ i ] - > GetIntValue ( ) ;
}
float CScriptMaterialProxy : : GetVarFloat ( int i )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return 0.0f ;
return m_MaterialVars [ i ] - > GetFloatValue ( ) ;
}
const Vector & CScriptMaterialProxy : : GetVarVector ( int i )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return vec3_origin ;
if ( m_MaterialVars [ i ] - > GetType ( ) ! = MATERIAL_VAR_TYPE_VECTOR )
return vec3_origin ;
// This is really bad. Too bad!
return * ( reinterpret_cast < const Vector * > ( m_MaterialVars [ i ] - > GetVecValue ( ) ) ) ;
}
void CScriptMaterialProxy : : SetVarString ( int i , const char * value )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return ;
return m_MaterialVars [ i ] - > SetStringValue ( value ) ;
}
void CScriptMaterialProxy : : SetVarInt ( int i , int value )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return ;
return m_MaterialVars [ i ] - > SetIntValue ( value ) ;
}
void CScriptMaterialProxy : : SetVarFloat ( int i , float value )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return ;
return m_MaterialVars [ i ] - > SetFloatValue ( value ) ;
}
void CScriptMaterialProxy : : SetVarVector ( int i , const Vector & value )
{
if ( ! ValidateIndex ( i ) | | ! m_MaterialVars [ i ] )
return ;
return m_MaterialVars [ i ] - > SetVecValue ( value . Base ( ) , 3 ) ;
}
EXPOSE_INTERFACE ( CScriptMaterialProxy , IMaterialProxy , " VScriptProxy " IMATERIAL_PROXY_INTERFACE_VERSION ) ;
2021-01-27 11:01:38 -06:00
bool CMaterialProxyScriptInstanceHelper : : ToString ( void * p , char * pBuf , int bufSize )
{
CScriptMaterialProxy * pProxy = ( CScriptMaterialProxy * ) p ;
V_snprintf ( pBuf , bufSize , " (proxy: %s) " , pProxy - > GetMaterial ( ) ! = NULL ? pProxy - > GetMaterial ( ) - > GetName ( ) : " <no material> " ) ;
return true ;
}
void * CMaterialProxyScriptInstanceHelper : : BindOnRead ( HSCRIPT hInstance , void * pOld , const char * pszId )
{
// TODO: Material proxy save/restore?
return NULL ;
}
2020-12-25 23:07:46 +03:00
# endif // MAPBASE_VSCRIPT
2020-05-30 10:48:00 -05:00
2020-05-04 16:25:15 +10:00
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static float Time ( )
{
return gpGlobals - > curtime ;
}
static const char * GetMapName ( )
{
return engine - > GetLevelName ( ) ;
}
static const char * DoUniqueString ( const char * pszBase )
{
static char szBuf [ 512 ] ;
g_pScriptVM - > GenerateUniqueKey ( pszBase , szBuf , ARRAYSIZE ( szBuf ) ) ;
return szBuf ;
}
bool DoIncludeScript ( const char * pszScript , HSCRIPT hScope )
{
if ( ! VScriptRunScript ( pszScript , hScope , true ) )
{
g_pScriptVM - > RaiseException ( CFmtStr ( " Failed to include script \" %s \" " , ( pszScript ) ? pszScript : " unknown " ) ) ;
return false ;
}
return true ;
}
2020-12-26 00:00:25 -06:00
# ifdef MAPBASE_VSCRIPT
2020-12-25 23:07:46 +03:00
static bool Con_IsVisible ( )
{
return engine - > Con_IsVisible ( ) ;
}
static bool IsWindowedMode ( )
{
return engine - > IsWindowedMode ( ) ;
}
int ScreenTransform ( const Vector & point , Vector & screen ) ;
//-----------------------------------------------------------------------------
// Input array [x,y], set normalised screen space pos. Return true if on screen
//-----------------------------------------------------------------------------
static bool ScriptScreenTransform ( const Vector & pos , HSCRIPT hArray )
{
if ( g_pScriptVM - > GetNumTableEntries ( hArray ) > = 2 )
{
Vector v ;
bool r = ScreenTransform ( pos , v ) ;
float x = 0.5f * ( 1.0f + v [ 0 ] ) ;
float y = 0.5f * ( 1.0f - v [ 1 ] ) ;
g_pScriptVM - > SetValue ( hArray , ScriptVariant_t ( 0 ) , x ) ;
g_pScriptVM - > SetValue ( hArray , 1 , y ) ;
return ! r ;
}
return false ;
}
2020-12-27 09:23:49 -06:00
2020-12-26 00:00:25 -06:00
// Creates a client-side prop
HSCRIPT CreateProp ( const char * pszEntityName , const Vector & vOrigin , const char * pszModelName , int iAnim )
{
C_BaseAnimating * pBaseEntity = ( C_BaseAnimating * ) CreateEntityByName ( pszEntityName ) ;
if ( ! pBaseEntity )
return NULL ;
pBaseEntity - > SetAbsOrigin ( vOrigin ) ;
pBaseEntity - > SetModelName ( pszModelName ) ;
if ( ! pBaseEntity - > InitializeAsClientEntity ( pszModelName , RENDER_GROUP_OPAQUE_ENTITY ) )
{
Warning ( " Can't initialize %s as client entity \n " , pszEntityName ) ;
return NULL ;
}
pBaseEntity - > SetPlaybackRate ( 1.0f ) ;
int iSequence = pBaseEntity - > SelectWeightedSequence ( ( Activity ) iAnim ) ;
if ( iSequence ! = - 1 )
{
pBaseEntity - > SetSequence ( iSequence ) ;
}
return ToHScript ( pBaseEntity ) ;
}
# endif
2020-05-04 16:25:15 +10:00
bool VScriptClientInit ( )
{
VMPROF_START
if ( scriptmanager ! = NULL )
{
ScriptLanguage_t scriptLanguage = SL_DEFAULT ;
char const * pszScriptLanguage ;
2020-05-27 10:22:45 -05:00
# ifdef MAPBASE_VSCRIPT
if ( GetClientWorldEntity ( ) - > GetScriptLanguage ( ) ! = SL_NONE )
{
// Allow world entity to override script language
scriptLanguage = GetClientWorldEntity ( ) - > GetScriptLanguage ( ) ;
2020-07-16 15:43:30 +00:00
// Less than SL_NONE means the script language should literally be none
if ( scriptLanguage < SL_NONE )
scriptLanguage = SL_NONE ;
2020-05-27 10:22:45 -05:00
}
else
# endif
2020-05-04 16:25:15 +10:00
if ( CommandLine ( ) - > CheckParm ( " -scriptlang " , & pszScriptLanguage ) )
{
if ( ! Q_stricmp ( pszScriptLanguage , " gamemonkey " ) )
{
scriptLanguage = SL_GAMEMONKEY ;
}
else if ( ! Q_stricmp ( pszScriptLanguage , " squirrel " ) )
{
scriptLanguage = SL_SQUIRREL ;
}
else if ( ! Q_stricmp ( pszScriptLanguage , " python " ) )
{
scriptLanguage = SL_PYTHON ;
}
2020-09-23 05:03:47 +00:00
# ifdef MAPBASE_VSCRIPT
else if ( ! Q_stricmp ( pszScriptLanguage , " lua " ) )
{
scriptLanguage = SL_LUA ;
}
# endif
2020-05-04 16:25:15 +10:00
else
{
2020-11-26 02:26:55 +00:00
CGWarning ( 1 , CON_GROUP_VSCRIPT , " -scriptlang does not recognize a language named '%s'. virtual machine did NOT start. \n " , pszScriptLanguage ) ;
2020-05-04 16:25:15 +10:00
scriptLanguage = SL_NONE ;
}
}
if ( scriptLanguage ! = SL_NONE )
{
if ( g_pScriptVM = = NULL )
g_pScriptVM = scriptmanager - > CreateVM ( scriptLanguage ) ;
if ( g_pScriptVM )
{
2020-07-16 15:43:30 +00:00
# ifdef MAPBASE_VSCRIPT
2020-11-26 02:26:55 +00:00
CGMsg ( 0 , CON_GROUP_VSCRIPT , " VSCRIPT CLIENT: Started VScript virtual machine using script language '%s' \n " , g_pScriptVM - > GetLanguageName ( ) ) ;
2020-07-16 15:43:30 +00:00
# else
2020-05-04 16:25:15 +10:00
Log ( " VSCRIPT: Started VScript virtual machine using script language '%s' \n " , g_pScriptVM - > GetLanguageName ( ) ) ;
2020-07-16 15:43:30 +00:00
# endif
2020-05-04 16:25:15 +10:00
ScriptRegisterFunction ( g_pScriptVM , GetMapName , " Get the name of the map. " ) ;
ScriptRegisterFunction ( g_pScriptVM , Time , " Get the current server time " ) ;
2020-12-25 23:07:46 +03:00
ScriptRegisterFunction ( g_pScriptVM , DoUniqueString , SCRIPT_ALIAS ( " UniqueString " , " Generate a string guaranteed to be unique across the life of the script VM, with an optional root string. " ) ) ;
2020-05-04 16:25:15 +10:00
ScriptRegisterFunction ( g_pScriptVM , DoIncludeScript , " Execute a script (internal) " ) ;
2020-12-26 00:00:25 -06:00
# ifdef MAPBASE_VSCRIPT
2020-12-25 23:07:46 +03:00
ScriptRegisterFunction ( g_pScriptVM , Con_IsVisible , " Returns true if the console is visible " ) ;
ScriptRegisterFunction ( g_pScriptVM , ScreenWidth , " Width of the screen in pixels " ) ;
ScriptRegisterFunction ( g_pScriptVM , ScreenHeight , " Height of the screen in pixels " ) ;
ScriptRegisterFunction ( g_pScriptVM , IsWindowedMode , " " ) ;
ScriptRegisterFunctionNamed ( g_pScriptVM , ScriptScreenTransform , " ScreenTransform " , " Get the x & y positions of a world position in screen space. Returns true if it's onscreen " ) ;
2020-12-27 09:23:49 -06:00
2020-12-26 00:00:25 -06:00
ScriptRegisterFunction ( g_pScriptVM , CreateProp , " Create an animating prop " ) ;
# endif
2020-12-25 23:07:46 +03:00
2020-05-04 16:25:15 +10:00
if ( GameRules ( ) )
{
GameRules ( ) - > RegisterScriptFunctions ( ) ;
}
2020-05-22 20:26:31 -05:00
# ifdef MAPBASE_VSCRIPT
2020-07-12 11:46:43 +10:00
g_pScriptVM - > RegisterAllClasses ( ) ;
Mapbase v5.0
- Added keyvalue to hl2_gamerules which allows respawning in singleplayer
- Added the game instructor system (including env_instructor_hint) from later Valve games using a VDC tutorial which adjusts the version from the Alien Swarm SDK to FPS rules and a Source 2013 environment; Also added new KV and icons for further control from mappers (tutorial mentioned by Maestra Fenix)
- Added L4D/TF2 glows + point_glow entity as an all-purpose SDK-based off-shoot of tf_glow
- Fixed weapon pickup sound not playing (reported by Sl0th and later Cvoxulary)
- Fixed env_projectedtextures not updating on save/load
- Added func_fake_worldportal, a spatial point_camera inspired by linked_portal_door based on SDK code alone (WIP, may be changed a lot in future updates)
- Added option for point_camera and func_reflective_glass to use different render targets, therefore allowing multiple cameras and mirrors to be active at the same time
- Added additional RT camera textures to choose from with a default of 3, but also controllable through a -numcameratextures command line param
- Added adjustable convars for main view NearZ and skybox NearZ (suggested by someone recently, also suggested by Klems over a year ago)
- Fixed map-specific localization files, cleaned up map-specific file code
- Added a new block to gameinfo.txt which allows mods to automatically append their own command line parameters
- Fixed math_lightpattern corruption when setting pattern/style while active
- Fixed the "Touch" input crashing when given no entity
- Added a way to add EFlags via keyvalue (suggested by Niker107)
- Fixed ai_script_conditions not working without a NPC actor (reported by MetroHam)
- Fixed point_radiation_source causing huge problems when intensity is 0, even though it was already advised against (reported by beefbacon)
- Added "Mapbase" header to Mapbase-specific code files
- Fixed an issue with updating sky_camera not obtaining area correctly, causing some entities to not draw in the skybox
- Added "CopyFogController" and "CopyFogControllerWithScale" inputs to sky_camera, which copy fog parameters directly from a fog controller
- Added "SetScale" input to sky_camera for live scale changing
- Added convar to control player crouch speed multiplier (suggested by ArtyIF)
- Added a ton of fixes for people running the Debug configuration of the codebase (partial credit to stepa2)
- Added support for pre-defined enums and constants in VScript, starting with various values from the SDK code (damage types, trace masks, etc.)
- Added limited support for Valve's Quaternion class in VScript
- Added new instance helper capabilities, destructible game instances, and other misc. changes to VScript library
- Replaced most of the VScript "accessor" classes with direct references to the original classes, as they were getting complicated fast and adding new VScript-only functions to the original classes might not be as bad as previously thought
- Added base NPC hooks for AI sensing in VScript (allows control over sight and hearing), also exposed CSound for it
- Added various functions and hooks for VPhysics integration in VScript
- Added VScript-based custom suit devices
- Expanded trace info exposed to VScript to allow plane and surface access (suggested by krassell)
- Added ability to insert localization strings through VScript
- Added various misc. VScript functions with various purposes, including reading/writing EFlags, movetypes, collision groups, etc.
- Fixed VBSP not being able to correctly parse parallax corrected cubemaps in maps with instances
2020-08-14 21:21:25 +00:00
g_pScriptVM - > RegisterAllEnums ( ) ;
2020-07-12 11:46:43 +10:00
2020-06-11 23:48:59 -05:00
g_pScriptVM - > RegisterInstance ( & g_ScriptEntityIterator , " Entities " ) ;
2020-05-22 20:26:31 -05:00
IGameSystem : : RegisterVScriptAllSystems ( ) ;
Mapbase v5.0
- Added keyvalue to hl2_gamerules which allows respawning in singleplayer
- Added the game instructor system (including env_instructor_hint) from later Valve games using a VDC tutorial which adjusts the version from the Alien Swarm SDK to FPS rules and a Source 2013 environment; Also added new KV and icons for further control from mappers (tutorial mentioned by Maestra Fenix)
- Added L4D/TF2 glows + point_glow entity as an all-purpose SDK-based off-shoot of tf_glow
- Fixed weapon pickup sound not playing (reported by Sl0th and later Cvoxulary)
- Fixed env_projectedtextures not updating on save/load
- Added func_fake_worldportal, a spatial point_camera inspired by linked_portal_door based on SDK code alone (WIP, may be changed a lot in future updates)
- Added option for point_camera and func_reflective_glass to use different render targets, therefore allowing multiple cameras and mirrors to be active at the same time
- Added additional RT camera textures to choose from with a default of 3, but also controllable through a -numcameratextures command line param
- Added adjustable convars for main view NearZ and skybox NearZ (suggested by someone recently, also suggested by Klems over a year ago)
- Fixed map-specific localization files, cleaned up map-specific file code
- Added a new block to gameinfo.txt which allows mods to automatically append their own command line parameters
- Fixed math_lightpattern corruption when setting pattern/style while active
- Fixed the "Touch" input crashing when given no entity
- Added a way to add EFlags via keyvalue (suggested by Niker107)
- Fixed ai_script_conditions not working without a NPC actor (reported by MetroHam)
- Fixed point_radiation_source causing huge problems when intensity is 0, even though it was already advised against (reported by beefbacon)
- Added "Mapbase" header to Mapbase-specific code files
- Fixed an issue with updating sky_camera not obtaining area correctly, causing some entities to not draw in the skybox
- Added "CopyFogController" and "CopyFogControllerWithScale" inputs to sky_camera, which copy fog parameters directly from a fog controller
- Added "SetScale" input to sky_camera for live scale changing
- Added convar to control player crouch speed multiplier (suggested by ArtyIF)
- Added a ton of fixes for people running the Debug configuration of the codebase (partial credit to stepa2)
- Added support for pre-defined enums and constants in VScript, starting with various values from the SDK code (damage types, trace masks, etc.)
- Added limited support for Valve's Quaternion class in VScript
- Added new instance helper capabilities, destructible game instances, and other misc. changes to VScript library
- Replaced most of the VScript "accessor" classes with direct references to the original classes, as they were getting complicated fast and adding new VScript-only functions to the original classes might not be as bad as previously thought
- Added base NPC hooks for AI sensing in VScript (allows control over sight and hearing), also exposed CSound for it
- Added various functions and hooks for VPhysics integration in VScript
- Added VScript-based custom suit devices
- Expanded trace info exposed to VScript to allow plane and surface access (suggested by krassell)
- Added ability to insert localization strings through VScript
- Added various misc. VScript functions with various purposes, including reading/writing EFlags, movetypes, collision groups, etc.
- Fixed VBSP not being able to correctly parse parallax corrected cubemaps in maps with instances
2020-08-14 21:21:25 +00:00
RegisterSharedScriptConstants ( ) ;
2020-05-22 20:26:31 -05:00
RegisterSharedScriptFunctions ( ) ;
2020-06-11 23:48:59 -05:00
# else
//g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
2020-05-31 15:39:17 +10:00
# endif
if ( scriptLanguage = = SL_SQUIRREL )
2020-05-04 16:25:15 +10:00
{
2020-05-31 15:39:17 +10:00
g_pScriptVM - > Run ( g_Script_vscript_client ) ;
2020-05-04 16:25:15 +10:00
}
2020-12-25 23:07:46 +03:00
VScriptRunScript ( " vscript_client " , true ) ;
2020-05-04 16:25:15 +10:00
VScriptRunScript ( " mapspawn " , false ) ;
VMPROF_SHOW ( pszScriptLanguage , " virtual machine startup " ) ;
return true ;
}
else
{
2020-11-26 02:26:55 +00:00
CGWarning ( 1 , CON_GROUP_VSCRIPT , " VM Did not start! \n " ) ;
2020-05-04 16:25:15 +10:00
}
}
2021-01-27 11:01:38 -06:00
# ifdef MAPBASE_VSCRIPT
else
{
CGMsg ( 0 , CON_GROUP_VSCRIPT , " VSCRIPT CLIENT: Not starting because language is set to 'none' \n " ) ;
}
# endif
2020-05-04 16:25:15 +10:00
}
else
{
2020-11-26 02:26:55 +00:00
CGWarning ( 0 , CON_GROUP_VSCRIPT , " \n VSCRIPT: Scripting is disabled. \n " ) ;
2020-05-04 16:25:15 +10:00
}
g_pScriptVM = NULL ;
return false ;
}
void VScriptClientTerm ( )
{
if ( g_pScriptVM ! = NULL )
{
2020-05-31 20:58:50 -05:00
# ifdef MAPBASE_VSCRIPT
// Things like proxies can persist across levels, so we have to shut down their scripts manually
for ( int i = g_ScriptPersistableList . Count ( ) - 1 ; i > = 0 ; i - - )
{
if ( g_ScriptPersistableList [ i ] )
{
g_ScriptPersistableList [ i ] - > TermScript ( ) ;
g_ScriptPersistableList . FastRemove ( i ) ;
}
}
# endif
2020-05-04 16:25:15 +10:00
if ( g_pScriptVM )
{
scriptmanager - > DestroyVM ( g_pScriptVM ) ;
g_pScriptVM = NULL ;
}
}
}
class CVScriptGameSystem : public CAutoGameSystemPerFrame
{
public :
// Inherited from IAutoServerSystem
virtual void LevelInitPreEntity ( void )
{
m_bAllowEntityCreationInScripts = true ;
VScriptClientInit ( ) ;
}
virtual void LevelInitPostEntity ( void )
{
m_bAllowEntityCreationInScripts = false ;
}
virtual void LevelShutdownPostEntity ( void )
{
2020-12-25 23:07:46 +03:00
# ifdef MAPBASE_VSCRIPT
g_ScriptNetMsg - > LevelShutdownPreVM ( ) ;
# endif
2020-05-04 16:25:15 +10:00
VScriptClientTerm ( ) ;
}
virtual void FrameUpdatePostEntityThink ( )
{
if ( g_pScriptVM )
g_pScriptVM - > Frame ( gpGlobals - > frametime ) ;
}
bool m_bAllowEntityCreationInScripts ;
} ;
CVScriptGameSystem g_VScriptGameSystem ;
bool IsEntityCreationAllowedInScripts ( void )
{
return g_VScriptGameSystem . m_bAllowEntityCreationInScripts ;
}