diff --git a/sp/src/game/client/client_mapbase.vpc b/sp/src/game/client/client_mapbase.vpc index 85f76cc7..f245e322 100644 --- a/sp/src/game/client/client_mapbase.vpc +++ b/sp/src/game/client/client_mapbase.vpc @@ -11,8 +11,6 @@ $Configuration $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS" $PreprocessorDefinitions "$BASE;MAPBASE_RPC;DISCORD_RPC;STEAM_RPC" [$MAPBASE_RPC] - - $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] } } @@ -34,6 +32,7 @@ $Project $File "$SRCDIR\game\shared\mapbase\matchers.cpp" $File "$SRCDIR\game\shared\mapbase\matchers.h" $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT] $File "mapbase\c_func_clientclip.cpp" diff --git a/sp/src/game/server/baseanimating.cpp b/sp/src/game/server/baseanimating.cpp index 26743f80..2b89e5cc 100644 --- a/sp/src/game/server/baseanimating.cpp +++ b/sp/src/game/server/baseanimating.cpp @@ -287,6 +287,9 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" ) DEFINE_SCRIPTFUNC( LookupAttachment, "Get the named attachement id" ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentOrigin, "GetAttachmentOrigin", "Get the attachement id's origin vector" ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentAngles, "GetAttachmentAngles", "Get the attachement id's angles as a p,y,r vector" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentMatrix, "GetAttachmentMatrix", "Get the attachement id's matrix transform" ) +#endif DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" ) DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup") END_SCRIPTDESC(); @@ -2155,6 +2158,16 @@ const Vector& CBaseAnimating::ScriptGetAttachmentAngles( int iAttachment ) return absAngles; } +#ifdef MAPBASE_VSCRIPT +HSCRIPT CBaseAnimating::ScriptGetAttachmentMatrix( int iAttachment ) +{ + static matrix3x4_t matrix; + + CBaseAnimating::GetAttachment( iAttachment, matrix ); + return ScriptCreateMatrixInstance( matrix ); +} +#endif + //----------------------------------------------------------------------------- // Returns the attachment in local space //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/baseanimating.h b/sp/src/game/server/baseanimating.h index 61d0e5a6..c89a1ebe 100644 --- a/sp/src/game/server/baseanimating.h +++ b/sp/src/game/server/baseanimating.h @@ -189,6 +189,9 @@ public: virtual bool GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld ); const Vector& ScriptGetAttachmentOrigin(int iAttachment); const Vector& ScriptGetAttachmentAngles(int iAttachment); +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptGetAttachmentMatrix(int iAttachment); +#endif // These return the attachment in the space of the entity bool GetAttachmentLocal( const char *szName, Vector &origin, QAngle &angles ); diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index c594e9cf..2dccfa9e 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -2161,6 +2161,10 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeft, "GetLeftVector", "Get the left vector of the entity" ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetUp, "GetUpVector", "Get the up vector of the entity" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" ) +#endif + DEFINE_SCRIPTFUNC_NAMED( ScriptSetForward, "SetForwardVector", "Set the orientation of the entity to have this forward vector" ) DEFINE_SCRIPTFUNC_NAMED( GetAbsVelocity, "GetVelocity", "" ) DEFINE_SCRIPTFUNC_NAMED( SetAbsVelocity, "SetVelocity", "" ) @@ -2201,6 +2205,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisibleWithMask, "IsVisibleWithMask", "Check if the specified position can be visible to this entity with a specific trace mask." ) DEFINE_SCRIPTFUNC_NAMED( ScriptTakeDamage, "TakeDamage", "Apply damage to this entity with a given info handle" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptFireBullets, "FireBullets", "Fire bullets from entity with a given info handle" ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetContext, "GetContext", "Get a response context value" ) DEFINE_SCRIPTFUNC_NAMED( ScriptAddContext, "AddContext", "Add a response context value" ) @@ -9547,12 +9552,30 @@ int CBaseEntity::ScriptTakeDamage( HSCRIPT pInfo ) if (pInfo) { CTakeDamageInfo *info = HScriptToClass( pInfo ); //ToDamageInfo( pInfo ); - return OnTakeDamage( *info ); + if (info) + { + return OnTakeDamage( *info ); + } } return 0; } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CBaseEntity::ScriptFireBullets( HSCRIPT pInfo ) +{ + if (pInfo) + { + extern FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo ); + FireBulletsInfo_t *info = GetFireBulletsInfoFromInfo( pInfo ); + if (info) + { + FireBullets( *info ); + } + } +} + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CBaseEntity::ScriptAddContext( const char *name, const char *value, float duration ) diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index 93480385..7e4a83ca 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -1981,6 +1981,10 @@ public: const Vector& ScriptGetLeft(void) { static Vector vecLeft; GetVectors(NULL, &vecLeft, NULL); return vecLeft; } const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; } +#ifdef MAPBASE_VSCRIPT + HSCRIPT ScriptEntityToWorldTransform(void) { return ScriptCreateMatrixInstance( EntityToWorldTransform() ); } +#endif + const char* ScriptGetModelName(void) const; HSCRIPT ScriptGetModelKeyValues(void); @@ -2001,6 +2005,7 @@ public: bool ScriptIsVisibleWithMask( const Vector &vecSpot, int traceMask ) { return FVisible( vecSpot, traceMask ); } int ScriptTakeDamage( HSCRIPT pInfo ); + void ScriptFireBullets( HSCRIPT pInfo ); void ScriptAddContext( const char *name, const char *value, float duration = 0.0f ); const char *ScriptGetContext( const char *name ); diff --git a/sp/src/game/server/server_mapbase.vpc b/sp/src/game/server/server_mapbase.vpc index 0fd586da..7d30a511 100644 --- a/sp/src/game/server/server_mapbase.vpc +++ b/sp/src/game/server/server_mapbase.vpc @@ -9,8 +9,6 @@ $Configuration $Compiler { $PreprocessorDefinitions "$BASE;ASW_PROJECTED_TEXTURES;DYNAMIC_RTT_SHADOWS" - - $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] } } @@ -34,6 +32,7 @@ $Project $File "$SRCDIR\game\shared\mapbase\matchers.cpp" $File "$SRCDIR\game\shared\mapbase\matchers.h" $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.cpp" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT] $File "mapbase\ai_grenade.cpp" diff --git a/sp/src/game/server/vscript_server.cpp b/sp/src/game/server/vscript_server.cpp index 7ab8c3d3..d0ecd54b 100644 --- a/sp/src/game/server/vscript_server.cpp +++ b/sp/src/game/server/vscript_server.cpp @@ -339,6 +339,18 @@ static float FrameTime() return gpGlobals->frametime; } +#ifdef MAPBASE_VSCRIPT +static int MaxPlayers() +{ + return gpGlobals->maxClients; +} + +static float IntervalPerTick() +{ + return gpGlobals->interval_per_tick; +} +#endif + static void SendToConsole( const char *pszCommand ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost(); @@ -532,6 +544,10 @@ bool VScriptServerInit() ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" ); ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the server in the last frame" ); +#ifdef MAPBASE_VSCRIPT + ScriptRegisterFunction( g_pScriptVM, MaxPlayers, "Get the maximum number of players allowed on this server" ); + ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Get the interval used between each tick" ); +#endif ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate and entity i/o event" ) ); ScriptRegisterFunctionNamed( g_pScriptVM, DoEntFireByInstanceHandle, "EntFireByHandle", "Generate and entity i/o event. First parameter is an entity instance." ); 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. Useful for adding data to tables when not sure what keys are already in use in that table." ) ); diff --git a/sp/src/game/shared/baseentity_shared.cpp b/sp/src/game/shared/baseentity_shared.cpp index de825fe1..643b650a 100644 --- a/sp/src/game/shared/baseentity_shared.cpp +++ b/sp/src/game/shared/baseentity_shared.cpp @@ -1599,6 +1599,27 @@ typedef CTraceFilterSimpleList CBulletsTraceFilter; void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) { +#if defined(MAPBASE_VSCRIPT) && defined(GAME_DLL) + if (m_ScriptScope.IsInitialized()) + { + CFireBulletsInfoAccessor pInfo( const_cast(&info) ); + HSCRIPT hInfo = g_pScriptVM->RegisterInstance( &pInfo ); + + g_pScriptVM->SetValue( "info", hInfo ); + + ScriptVariant_t functionReturn; + if ( CallScriptFunction( "FireBullets", &functionReturn ) ) + { + if (!functionReturn.m_bool) + return; + } + + g_pScriptVM->RemoveInstance( hInfo ); + + g_pScriptVM->ClearValue( "info" ); + } +#endif + static int tracerCount; trace_t tr; CAmmoDef* pAmmoDef = GetAmmoDef(); diff --git a/sp/src/game/shared/mapbase/vscript_funcs_math.cpp b/sp/src/game/shared/mapbase/vscript_funcs_math.cpp new file mode 100644 index 00000000..bccf0e8d --- /dev/null +++ b/sp/src/game/shared/mapbase/vscript_funcs_math.cpp @@ -0,0 +1,306 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Shared VScript math functions. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//============================================================================= +// +// matrix3x4_t +// +//============================================================================= + +// +// Exposes matrix3x4_t to VScript +// +class CScriptMatrix3x4 +{ +public: + CScriptMatrix3x4() + { + matrix = new matrix3x4_t(); + m_bFree = true; + } + + ~CScriptMatrix3x4() + { + if (m_bFree == true) + delete matrix; + } + + CScriptMatrix3x4( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } + + matrix3x4_t *GetMatrix() { return matrix; } + void SetMatrix( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } + + void Init( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin ) + { + matrix->Init( xAxis, yAxis, zAxis, vecOrigin ); + } + +private: + matrix3x4_t *matrix; + bool m_bFree = false; +}; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMatrix3x4, "matrix3x4_t", "A 3x4 matrix transform." ) + + DEFINE_SCRIPT_CONSTRUCTOR() + DEFINE_SCRIPTFUNC( Init, "Creates a matrix where the X axis = forward, the Y axis = left, and the Z axis = up." ) + +END_SCRIPTDESC(); + +inline matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass( hMat )->GetMatrix(); } + +HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix ) +{ + CScriptMatrix3x4 *smatrix = new CScriptMatrix3x4( matrix ); + + return g_pScriptVM->RegisterInstance( smatrix ); +} + +void ScriptFreeMatrixInstance( HSCRIPT hMat ) +{ + CScriptMatrix3x4 *smatrix = HScriptToClass( hMat ); + if (smatrix) + { + g_pScriptVM->RemoveInstance( hMat ); + delete smatrix; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void ScriptConcatTransforms( HSCRIPT hMat1, HSCRIPT hMat2, HSCRIPT hOut ) +{ + if (!hMat1 || !hMat2 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + ConcatTransforms( *pMat1, *pMat2, *pOut ); +} + +void ScriptMatrixCopy( HSCRIPT hMat1, HSCRIPT hOut ) +{ + if (!hMat1 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + MatrixCopy( *pMat1, *pOut ); +} + +void ScriptMatrixInvert( HSCRIPT hMat1, HSCRIPT hOut ) +{ + if (!hMat1 || !hOut) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pOut = ToMatrix3x4( hOut ); + + MatrixInvert( *pMat1, *pOut ); +} + +void ScriptMatricesAreEqual( HSCRIPT hMat1, HSCRIPT hMat2 ) +{ + if (!hMat1 || !hMat2) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); + + MatricesAreEqual( *pMat1, *pMat2 ); +} + +const Vector& ScriptMatrixGetColumn( HSCRIPT hMat1, int column ) +{ + static Vector outvec; + outvec.Zero(); + if (!hMat1) + return outvec; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixGetColumn( *pMat1, column, outvec ); + return outvec; +} + +void ScriptMatrixSetColumn( const Vector& vecset, int column, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + static Vector outvec; + MatrixSetColumn( vecset, column, *pMat1 ); +} + +void ScriptMatrixAngles( HSCRIPT hMat1, const QAngle& angset, const Vector& vecset ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + MatrixAngles( *pMat1, *const_cast(&angset), *const_cast(&vecset) ); +} + +void ScriptAngleMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + AngleMatrix( angset, vecset, *pMat1 ); +} + +void ScriptAngleIMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + AngleIMatrix( angset, vecset, *pMat1 ); +} + +void ScriptSetIdentityMatrix( HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + SetIdentityMatrix( *pMat1 ); +} + +void ScriptSetScaleMatrix( float x, float y, float z, HSCRIPT hMat1 ) +{ + if (!hMat1) + return; + + matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); + + SetScaleMatrix( x, y, z, *pMat1 ); +} + +//============================================================================= +// +// Misc. Vector/QAngle functions +// +//============================================================================= + +const Vector& ScriptAngleVectors( const QAngle &angles ) +{ + static Vector forward; + AngleVectors( angles, &forward ); + return forward; +} + +const QAngle& ScriptVectorAngles( const Vector &forward ) +{ + static QAngle angles; + VectorAngles( forward, angles ); + return angles; +} + +const Vector& ScriptCalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point ) +{ + static Vector outvec; + CalcClosestPointOnAABB( mins, maxs, point, outvec ); + return outvec; +} + +const Vector& ScriptCalcClosestPointOnLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + static Vector outvec; + CalcClosestPointOnLine( point, vLineA, vLineB, outvec ); + return outvec; +} + +float ScriptCalcDistanceToLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + return CalcDistanceToLine( point, vLineA, vLineB ); +} + +const Vector& ScriptCalcClosestPointOnLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + static Vector outvec; + CalcClosestPointOnLineSegment( point, vLineA, vLineB, outvec ); + return outvec; +} + +float ScriptCalcDistanceToLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) +{ + return CalcDistanceToLineSegment( point, vLineA, vLineB ); +} + +#ifndef CLIENT_DLL +const Vector& ScriptPredictedPosition( HSCRIPT hTarget, float flTimeDelta ) +{ + static Vector predicted; + UTIL_PredictedPosition( ToEnt(hTarget), flTimeDelta, &predicted ); + return predicted; +} +#endif + +void RegisterMathScriptFunctions() +{ + ScriptRegisterFunction( g_pScriptVM, RandomFloat, "Generate a random floating point number within a range, inclusive." ); + ScriptRegisterFunction( g_pScriptVM, RandomInt, "Generate a random integer within a range, inclusive." ); + + ScriptRegisterFunction( g_pScriptVM, Approach, "Returns a value which approaches the target value from the input value with the specified speed." ); + ScriptRegisterFunction( g_pScriptVM, ApproachAngle, "Returns an angle which approaches the target angle from the input angle with the specified speed." ); + ScriptRegisterFunction( g_pScriptVM, AngleDiff, "Returns the degrees difference between two yaw angles." ); + ScriptRegisterFunction( g_pScriptVM, AngleDistance, "Returns the distance between two angles." ); + ScriptRegisterFunction( g_pScriptVM, AngleNormalize, "Clamps an angle to be in between -360 and 360." ); + ScriptRegisterFunction( g_pScriptVM, AngleNormalizePositive, "Clamps an angle to be in between 0 and 360." ); + ScriptRegisterFunction( g_pScriptVM, AnglesAreEqual, "Checks if two angles are equal based on a given tolerance value." ); + + // + // matrix3x4_t + // + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptFreeMatrixInstance, "FreeMatrixInstance", "Frees an allocated matrix instance." ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptConcatTransforms, "ConcatTransforms", "Concatenates two transformation matrices into another matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixCopy, "MatrixCopy", "Copies a matrix to another matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixInvert, "MatrixInvert", "Inverts a matrix and copies the result to another matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatricesAreEqual, "MatricesAreEqual", "Checks if two matrices are equal." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixGetColumn, "MatrixGetColumn", "Gets the column of a matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixSetColumn, "MatrixSetColumn", "Sets the column of a matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixAngles, "MatrixAngles", "Gets the angles and position of a matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleMatrix, "AngleMatrix", "Sets the angles and position of a matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleIMatrix, "AngleIMatrix", "Sets the inverted angles and position of a matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptSetIdentityMatrix, "SetIdentityMatrix", "Turns a matrix into an identity matrix." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptSetScaleMatrix, "SetScaleMatrix", "Scales a matrix." ); + + // + // Misc. Vector/QAngle functions + // + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleVectors, "AngleVectors", "Turns an angle into a direction vector." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptVectorAngles, "VectorAngles", "Turns a direction vector into an angle." ); + + ScriptRegisterFunction( g_pScriptVM, CalcSqrDistanceToAABB, "Returns the squared distance to a bounding box." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnAABB, "CalcClosestPointOnAABB", "Returns the closest point on a bounding box." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcDistanceToLine, "CalcDistanceToLine", "Returns the distance to a line." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnLine, "CalcClosestPointOnLine", "Returns the closest point on a line." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcDistanceToLineSegment, "CalcDistanceToLineSegment", "Returns the distance to a line segment." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnLineSegment, "CalcClosestPointOnLineSegment", "Returns the closest point on a line segment." ); + +#ifndef CLIENT_DLL + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPredictedPosition, "PredictedPosition", "Predicts what an entity's position will be in a given amount of time." ); +#endif +} diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index 449598bc..538681ff 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -353,8 +353,6 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarLookup, "CConvars", SCRIPT_SINGLETON " END_SCRIPTDESC(); #ifndef CLIENT_DLL -extern ConVar sv_script_think_interval; - void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName ) { CBaseEntity *pEntity = ToEnt( entity ); @@ -366,7 +364,7 @@ void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName ) else pEntity->m_iszScriptThinkFunction = AllocPooledString(pszFuncName); - pEntity->SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime + sv_script_think_interval.GetFloat(), "ScriptThink" ); + pEntity->SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime, "ScriptThink" ); } HSCRIPT EntIndexToHScript( int index ) @@ -436,6 +434,7 @@ HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV ) ParseScriptTableKeyValues( pEntity, hKV ); DispatchSpawn( pEntity ); + pEntity->Activate(); return ToHScript( pEntity ); } @@ -486,6 +485,7 @@ HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) } DispatchSpawn( pEntity ); + pEntity->Activate(); return ToHScript( pEntity ); } @@ -634,8 +634,131 @@ static HSCRIPT ScriptTraceHullComplex( const Vector &vecStart, const Vector &vec return hScript; } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT_NAMED( CFireBulletsInfoAccessor, "FireBulletsInfo_t", "Handle for accessing FireBulletsInfo_t info." ) + DEFINE_SCRIPTFUNC( GetShots, "Gets the number of shots which should be fired." ) + DEFINE_SCRIPTFUNC( SetShots, "Sets the number of shots which should be fired." ) + + DEFINE_SCRIPTFUNC( GetSource, "Gets the source of the bullets." ) + DEFINE_SCRIPTFUNC( SetSource, "Sets the source of the bullets." ) + DEFINE_SCRIPTFUNC( GetDirShooting, "Gets the direction of the bullets." ) + DEFINE_SCRIPTFUNC( SetDirShooting, "Sets the direction of the bullets." ) + DEFINE_SCRIPTFUNC( GetSpread, "Gets the spread of the bullets." ) + DEFINE_SCRIPTFUNC( SetSpread, "Sets the spread of the bullets." ) + + DEFINE_SCRIPTFUNC( GetDistance, "Gets the distance the bullets should travel." ) + DEFINE_SCRIPTFUNC( SetDistance, "Sets the distance the bullets should travel." ) + + DEFINE_SCRIPTFUNC( GetAmmoType, "Gets the ammo type the bullets should use." ) + DEFINE_SCRIPTFUNC( SetAmmoType, "Sets the ammo type the bullets should use." ) + + DEFINE_SCRIPTFUNC( GetTracerFreq, "Gets the tracer frequency." ) + DEFINE_SCRIPTFUNC( SetTracerFreq, "Sets the tracer frequency." ) + + DEFINE_SCRIPTFUNC( GetDamage, "Gets the damage the bullets should deal. 0 = use ammo type" ) + DEFINE_SCRIPTFUNC( SetDamage, "Sets the damage the bullets should deal. 0 = use ammo type" ) + DEFINE_SCRIPTFUNC( GetPlayerDamage, "Gets the damage the bullets should deal when hitting the player. 0 = use regular damage" ) + DEFINE_SCRIPTFUNC( SetPlayerDamage, "Sets the damage the bullets should deal when hitting the player. 0 = use regular damage" ) + + DEFINE_SCRIPTFUNC( GetFlags, "Gets the flags the bullets should use." ) + DEFINE_SCRIPTFUNC( SetFlags, "Sets the flags the bullets should use." ) + + DEFINE_SCRIPTFUNC( GetDamageForceScale, "Gets the scale of the damage force applied by the bullets." ) + DEFINE_SCRIPTFUNC( SetDamageForceScale, "Sets the scale of the damage force applied by the bullets." ) + + DEFINE_SCRIPTFUNC( GetAttacker, "Gets the entity considered to be the one who fired the bullets." ) + DEFINE_SCRIPTFUNC( SetAttacker, "Sets the entity considered to be the one who fired the bullets." ) + DEFINE_SCRIPTFUNC( GetAdditionalIgnoreEnt, "Gets the optional entity which the bullets should ignore." ) + DEFINE_SCRIPTFUNC( SetAdditionalIgnoreEnt, "Sets the optional entity which the bullets should ignore." ) + + DEFINE_SCRIPTFUNC( GetPrimaryAttack, "Gets whether the bullets came from a primary attack." ) + DEFINE_SCRIPTFUNC( SetPrimaryAttack, "Sets whether the bullets came from a primary attack." ) + + //DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." ) +END_SCRIPTDESC(); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +HSCRIPT CFireBulletsInfoAccessor::GetAttacker() +{ + return ToHScript( m_info->m_pAttacker ); +} + +void CFireBulletsInfoAccessor::SetAttacker( HSCRIPT value ) +{ + m_info->m_pAttacker = ToEnt( value ); +} + +HSCRIPT CFireBulletsInfoAccessor::GetAdditionalIgnoreEnt() +{ + return ToHScript( m_info->m_pAdditionalIgnoreEnt ); +} + +void CFireBulletsInfoAccessor::SetAdditionalIgnoreEnt( HSCRIPT value ) +{ + m_info->m_pAdditionalIgnoreEnt = ToEnt( value ); +} + +static HSCRIPT CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Vector &vecDirShooting, + const Vector &vecSpread, float iDamage, HSCRIPT pAttacker ) +{ + // The script is responsible for deleting this via DestroyFireBulletsInfo(). + FireBulletsInfo_t *info = new FireBulletsInfo_t(); + CFireBulletsInfoAccessor *bulletsInfo = new CFireBulletsInfoAccessor( info ); + + HSCRIPT hScript = g_pScriptVM->RegisterInstance( bulletsInfo ); + + bulletsInfo->SetShots( cShots ); + bulletsInfo->SetSource( vecSrc ); + bulletsInfo->SetDirShooting( vecDirShooting ); + bulletsInfo->SetSpread( vecSpread ); + bulletsInfo->SetDamage( iDamage ); + bulletsInfo->SetAttacker( pAttacker ); + + return hScript; +} + +static void DestroyFireBulletsInfo( HSCRIPT hBulletsInfo ) +{ + if (hBulletsInfo) + { + CFireBulletsInfoAccessor *pInfo = (CFireBulletsInfoAccessor*)g_pScriptVM->GetInstanceValue( hBulletsInfo, GetScriptDescForClass( CFireBulletsInfoAccessor ) ); + if (pInfo) + { + g_pScriptVM->RemoveInstance( hBulletsInfo ); + pInfo->Destroy(); + } + } +} + +// For the function in baseentity.cpp +FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo ) +{ + if (hBulletsInfo) + { + CFireBulletsInfoAccessor *pInfo = (CFireBulletsInfoAccessor*)g_pScriptVM->GetInstanceValue( hBulletsInfo, GetScriptDescForClass( CFireBulletsInfoAccessor ) ); + if (pInfo) + { + return pInfo->GetInfo(); + } + } + + return NULL; +} + +//============================================================================= +//============================================================================= + bool ScriptMatcherMatch( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); } +//============================================================================= +//============================================================================= + +extern void RegisterMathScriptFunctions(); + void RegisterSharedScriptFunctions() { // @@ -643,10 +766,6 @@ void RegisterSharedScriptFunctions() // some of the code normally available in games like L4D2 or Valve's original VScript DLL. // Instead, that code is recreated here, shared between server and client. // - ScriptRegisterFunction( g_pScriptVM, RandomFloat, "Generate a random floating point number within a range, inclusive." ); - ScriptRegisterFunction( g_pScriptVM, RandomInt, "Generate a random integer within a range, inclusive." ); - - ScriptRegisterFunction( g_pScriptVM, AngleDiff, "Returns the number of degrees difference between two yaw angles." ); #ifndef CLIENT_DLL ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::BoxDirection, "DebugDrawBoxDirection", "Draw a debug forward box" ); @@ -678,6 +797,9 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateMeleeDamageForce, "CalculateMeleeDamageForce", "Fill out a damage info handle with a damage force for a melee impact." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGuessDamageForce, "GuessDamageForce", "Try and guess the physics force to use." ); + ScriptRegisterFunction( g_pScriptVM, CreateFireBulletsInfo, "Creates FireBullets info." ); + ScriptRegisterFunction( g_pScriptVM, DestroyFireBulletsInfo, "Destroys FireBullets info." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLineComplex, "TraceLineComplex", "Complex version of TraceLine which takes 2 points, an ent to ignore, a trace mask, and a collision group. Returns a handle which can access all trace info." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceHullComplex, "TraceHullComplex", "Takes 2 points, min/max hull bounds, an ent to ignore, a trace mask, and a collision group to trace to a point using a hull. Returns a handle which can access all trace info." ); @@ -685,6 +807,8 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." ); ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." ); + RegisterMathScriptFunctions(); + #ifdef CLIENT_DLL VScriptRunScript( "vscript_client", true ); #else diff --git a/sp/src/game/shared/vscript_shared.h b/sp/src/game/shared/vscript_shared.h index 55e19a61..ba27eaae 100644 --- a/sp/src/game/shared/vscript_shared.h +++ b/sp/src/game/shared/vscript_shared.h @@ -33,6 +33,62 @@ bool IsEntityCreationAllowedInScripts( void ); #ifdef MAPBASE_VSCRIPT void RegisterSharedScriptFunctions(); + +// +// Exposes FireBulletsInfo_t to VScript +// +class CFireBulletsInfoAccessor +{ +public: + CFireBulletsInfoAccessor( FireBulletsInfo_t *info ) { m_info = info; } + + int GetShots() { return m_info->m_iShots; } + void SetShots( int value ) { m_info->m_iShots = value; } + + Vector GetSource() { return m_info->m_vecSrc; } + void SetSource( Vector value ) { m_info->m_vecSrc = value; } + Vector GetDirShooting() { return m_info->m_vecDirShooting; } + void SetDirShooting( Vector value ) { m_info->m_vecDirShooting = value; } + Vector GetSpread() { return m_info->m_vecSpread; } + void SetSpread( Vector value ) { m_info->m_vecSpread = value; } + + float GetDistance() { return m_info->m_flDistance; } + void SetDistance( float value ) { m_info->m_flDistance = value; } + + int GetAmmoType() { return m_info->m_iAmmoType; } + void SetAmmoType( int value ) { m_info->m_iAmmoType = value; } + + int GetTracerFreq() { return m_info->m_iTracerFreq; } + void SetTracerFreq( int value ) { m_info->m_iTracerFreq = value; } + + float GetDamage() { return m_info->m_flDamage; } + void SetDamage( float value ) { m_info->m_flDamage = value; } + int GetPlayerDamage() { return m_info->m_iPlayerDamage; } + void SetPlayerDamage( float value ) { m_info->m_iPlayerDamage = value; } + + int GetFlags() { return m_info->m_nFlags; } + void SetFlags( float value ) { m_info->m_nFlags = value; } + + float GetDamageForceScale() { return m_info->m_flDamageForceScale; } + void SetDamageForceScale( float value ) { m_info->m_flDamageForceScale = value; } + + HSCRIPT GetAttacker(); + void SetAttacker( HSCRIPT value ); + HSCRIPT GetAdditionalIgnoreEnt(); + void SetAdditionalIgnoreEnt( HSCRIPT value ); + + bool GetPrimaryAttack() { return m_info->m_bPrimaryAttack; } + void SetPrimaryAttack( bool value ) { m_info->m_bPrimaryAttack = value; } + + FireBulletsInfo_t *GetInfo() { return m_info; } + + void Destroy() { delete m_info; delete this; } + +private: + FireBulletsInfo_t *m_info; +}; + +HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix ); #endif #endif // VSCRIPT_SHARED_H diff --git a/sp/src/public/vscript/ivscript.h b/sp/src/public/vscript/ivscript.h index aa5c98f3..3acba8b7 100644 --- a/sp/src/public/vscript/ivscript.h +++ b/sp/src/public/vscript/ivscript.h @@ -190,6 +190,10 @@ DECLARE_DEDUCE_FIELDTYPE( FIELD_BOOLEAN, bool ); DECLARE_DEDUCE_FIELDTYPE( FIELD_CHARACTER, char ); DECLARE_DEDUCE_FIELDTYPE( FIELD_HSCRIPT, HSCRIPT ); DECLARE_DEDUCE_FIELDTYPE( FIELD_VARIANT, ScriptVariant_t ); +#ifdef MAPBASE_VSCRIPT +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, QAngle ); +DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, const QAngle& ); +#endif #define ScriptDeduceType( T ) ScriptDeducer::FIELD_TYPE @@ -211,6 +215,10 @@ DECLARE_NAMED_FIELDTYPE( bool, "boolean" ); DECLARE_NAMED_FIELDTYPE( char, "character" ); DECLARE_NAMED_FIELDTYPE( HSCRIPT, "hscript" ); DECLARE_NAMED_FIELDTYPE( ScriptVariant_t, "variant" ); +#ifdef MAPBASE_VSCRIPT +DECLARE_NAMED_FIELDTYPE( QAngle, "vector" ); +DECLARE_NAMED_FIELDTYPE( const QAngle&, "vector" ); +#endif inline const char * ScriptFieldTypeName( int16 eType) { @@ -327,6 +335,11 @@ struct ScriptVariant_t ScriptVariant_t( const Vector *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pVector = val; } else { m_pVector = new Vector( *val ); m_flags |= SV_FREE; } } ScriptVariant_t( const char *val , bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_CSTRING ) { if ( !bCopy ) { m_pszString = val; } else { m_pszString = strdup( val ); m_flags |= SV_FREE; } } +#ifdef MAPBASE_VSCRIPT + ScriptVariant_t( const QAngle &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = &val; } else { m_pAngle = new QAngle( val ); m_flags |= SV_FREE; } } + ScriptVariant_t( const QAngle *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = val; } else { m_pAngle = new QAngle( *val ); m_flags |= SV_FREE; } } +#endif + bool IsNull() const { return (m_type == FIELD_VOID ); } operator int() const { Assert( m_type == FIELD_INTEGER ); return m_int; } @@ -336,6 +349,9 @@ struct ScriptVariant_t operator char() const { Assert( m_type == FIELD_CHARACTER ); return m_char; } operator bool() const { Assert( m_type == FIELD_BOOLEAN ); return m_bool; } operator HSCRIPT() const { Assert( m_type == FIELD_HSCRIPT ); return m_hScript; } +#ifdef MAPBASE_VSCRIPT + operator const QAngle &() const { Assert( m_type == FIELD_VECTOR ); static QAngle vecNull(0, 0, 0); return (m_pAngle) ? *m_pAngle : vecNull; } +#endif void operator=( int i ) { m_type = FIELD_INTEGER; m_int = i; } void operator=( float f ) { m_type = FIELD_FLOAT; m_float = f; } @@ -346,6 +362,10 @@ struct ScriptVariant_t void operator=( char c ) { m_type = FIELD_CHARACTER; m_char = c; } void operator=( bool b ) { m_type = FIELD_BOOLEAN; m_bool = b; } void operator=( HSCRIPT h ) { m_type = FIELD_HSCRIPT; m_hScript = h; } +#ifdef MAPBASE_VSCRIPT + void operator=( const QAngle &vec ) { m_type = FIELD_VECTOR; m_pAngle = &vec; } + void operator=( const QAngle *vec ) { m_type = FIELD_VECTOR; m_pAngle = vec; } +#endif void Free() { if ( ( m_flags & SV_FREE ) && ( m_type == FIELD_HSCRIPT || m_type == FIELD_VECTOR || m_type == FIELD_CSTRING ) ) delete m_pszString; } // Generally only needed for return results @@ -475,6 +495,10 @@ struct ScriptVariant_t char m_char; bool m_bool; HSCRIPT m_hScript; +#ifdef MAPBASE_VSCRIPT + // This uses FIELD_VECTOR, so it's considered a Vector in the VM (just like save/restore) + const QAngle * m_pAngle; +#endif }; int16 m_type; diff --git a/sp/src/vpc_scripts/source_base.vpc b/sp/src/vpc_scripts/source_base.vpc index acf7c9b8..372a257d 100644 --- a/sp/src/vpc_scripts/source_base.vpc +++ b/sp/src/vpc_scripts/source_base.vpc @@ -41,6 +41,7 @@ $Configuration "Debug" // Mapbase base definitions $PreprocessorDefinitions "$BASE;MAPBASE" [$MAPBASE] + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] } } @@ -59,5 +60,6 @@ $Configuration "Release" // Mapbase base definitions $PreprocessorDefinitions "$BASE;MAPBASE" [$MAPBASE] + $PreprocessorDefinitions "$BASE;MAPBASE_VSCRIPT" [$MAPBASE_VSCRIPT] } }