diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index 28c767c5..6fd1c504 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -498,6 +498,7 @@ END_DATADESC() #ifdef MAPBASE_VSCRIPT // TODO: Better placement? ScriptHook_t g_Hook_PlayerRunCommand; +ScriptHook_t g_Hook_FindUseEntity; BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) @@ -552,6 +553,9 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetEyeUp, "GetEyeUp", "Gets the player's up eye vector." ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetViewModel, "GetViewModel", "Returns the viewmodel of the specified index." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetUseEntity, "GetUseEntity", "Gets the player's current use entity." ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetHeldObject, "GetHeldObject", "Gets the player's currently held object IF it is being held by a gravity gun. To check for the player's held +USE object, use the standalone GetPlayerHeldEntity function." ) // // Hooks @@ -559,6 +563,11 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) BEGIN_SCRIPTHOOK( g_Hook_PlayerRunCommand, "PlayerRunCommand", FIELD_VOID, "Called when running a player command on the server." ) DEFINE_SCRIPTHOOK_PARAM( "command", FIELD_HSCRIPT ) END_SCRIPTHOOK() + + BEGIN_SCRIPTHOOK( g_Hook_FindUseEntity, "FindUseEntity", FIELD_HSCRIPT, "Called when finding an entity to use. The 'entity' parameter is for the entity found by the default function. If 'is_radius' is true, then this entity was found by searching in a radius around the cursor, rather than being directly used. Return a different entity to use something else." ) + DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT ) + DEFINE_SCRIPTHOOK_PARAM( "is_radius", FIELD_BOOLEAN ) + END_SCRIPTHOOK() END_SCRIPTDESC(); #else diff --git a/sp/src/game/server/player.h b/sp/src/game/server/player.h index 72a1e38e..c3ef666a 100644 --- a/sp/src/game/server/player.h +++ b/sp/src/game/server/player.h @@ -414,6 +414,9 @@ public: const Vector& ScriptGetEyeUp() { static Vector vecUp; EyeVectors( NULL, NULL, &vecUp ); return vecUp; } HSCRIPT ScriptGetViewModel( int viewmodelindex ); + + HSCRIPT ScriptGetUseEntity() { return ToHScript( GetUseEntity() ); } + HSCRIPT ScriptGetHeldObject() { return ToHScript( GetHeldObject() ); } #endif // View model prediction setup diff --git a/sp/src/game/shared/baseplayer_shared.cpp b/sp/src/game/shared/baseplayer_shared.cpp index 5ad7d453..9296bfcf 100644 --- a/sp/src/game/shared/baseplayer_shared.cpp +++ b/sp/src/game/shared/baseplayer_shared.cpp @@ -1069,6 +1069,10 @@ float IntervalDistance( float x, float x0, float x1 ) return 0; } +#if !defined(CLIENT_DLL) && defined(MAPBASE_VSCRIPT) +extern ScriptHook_t g_Hook_FindUseEntity; +#endif + CBaseEntity *CBasePlayer::FindUseEntity() { Vector forward, up; @@ -1160,7 +1164,24 @@ CBaseEntity *CBasePlayer::FindUseEntity() // if this is directly under the cursor just return it now if ( i == 0 ) + { +#if !defined(CLIENT_DLL) && defined(MAPBASE_VSCRIPT) + if (m_ScriptScope.IsInitialized() && g_Hook_FindUseEntity.CanRunInScope( m_ScriptScope )) + { + // entity, is_radius + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pNearest ), false }; + if (g_Hook_FindUseEntity.Call( m_ScriptScope, &functionReturn, args )) + { + pObject = ToEnt( functionReturn.m_hScript ); + pNearest = pObject; + } + } + + if (pObject) +#endif return pObject; + } } } } @@ -1245,6 +1266,19 @@ CBaseEntity *CBasePlayer::FindUseEntity() { pNearest = DoubleCheckUseNPC( pNearest, searchCenter, forward ); } + +#ifdef MAPBASE_VSCRIPT + if (m_ScriptScope.IsInitialized() && g_Hook_FindUseEntity.CanRunInScope(m_ScriptScope)) + { + // entity, is_radius + ScriptVariant_t functionReturn; + ScriptVariant_t args[] = { ToHScript( pNearest ), true }; + if (g_Hook_FindUseEntity.Call( m_ScriptScope, &functionReturn, args )) + { + pNearest = ToEnt( functionReturn.m_hScript ); + } + } +#endif if ( sv_debug_player_use.GetBool() ) { diff --git a/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp b/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp index 189f8883..529d0291 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp @@ -10,6 +10,8 @@ #include "hl2_gamerules.h" #ifndef CLIENT_DLL #include "eventqueue.h" +#include "weapon_physcannon.h" +#include "player_pickup.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -47,6 +49,48 @@ bool ScriptMegaPhyscannonActive() { return HL2GameRules()->MegaPhyscannonActive(); } + +void ScriptPickup_ForcePlayerToDropThisObject( HSCRIPT hTarget ) +{ + Pickup_ForcePlayerToDropThisObject( ToEnt( hTarget ) ); +} + +float ScriptPlayerPickupGetHeldObjectMass( HSCRIPT hPickupControllerEntity, HSCRIPT hHeldObject ) +{ + IPhysicsObject *pPhysObj = HScriptToClass( hHeldObject ); + if (!pPhysObj) + { + CBaseEntity *pEnt = ToEnt( hHeldObject ); + if (pEnt) + pPhysObj = pEnt->VPhysicsGetObject(); + } + + if (!pPhysObj) + { + Warning( "PlayerPickupGetHeldObjectMass: Invalid physics object\n" ); + return 0.0f; + } + + return PlayerPickupGetHeldObjectMass( ToEnt( hPickupControllerEntity ), pPhysObj ); +} + +HSCRIPT ScriptGetPlayerHeldEntity( HSCRIPT hPlayer ) +{ + CBasePlayer *pPlayer = ToBasePlayer( ToEnt( hPlayer ) ); + if (!pPlayer) + return NULL; + + return ToHScript( GetPlayerHeldEntity( pPlayer ) ); +} + +HSCRIPT ScriptPhysCannonGetHeldEntity( HSCRIPT hWeapon ) +{ + CBaseEntity *pEnt = ToEnt( hWeapon ); + if (!pEnt) + return NULL; + + return ToHScript( PhysCannonGetHeldEntity( pEnt->MyCombatWeaponPointer() ) ); +} #endif //----------------------------------------------------------------------------- @@ -59,5 +103,10 @@ void CHalfLife2::RegisterScriptFunctions( void ) #ifndef CLIENT_DLL ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGameOver, "GameOver", "Ends the game and reloads the last save." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMegaPhyscannonActive, "MegaPhyscannonActive", "Checks if supercharged gravity gun mode is enabled." ); + + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPickup_ForcePlayerToDropThisObject, "Pickup_ForcePlayerToDropThisObject", "If the specified entity is being carried, instantly drops it." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPlayerPickupGetHeldObjectMass, "PlayerPickupGetHeldObjectMass", "Gets the mass of the specified player_pickup controller, with the second parameter the held object's physics object." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGetPlayerHeldEntity, "GetPlayerHeldEntity", "Gets the specified player's currently held entity." ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysCannonGetHeldEntity, "PhysCannonGetHeldEntity", "Gets the specified gravity gun's currently held entity." ); #endif } diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index 4c6d4817..227103df 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -771,6 +771,26 @@ static void AddPhysVelocity( HSCRIPT hPhys, const Vector& vecVelocity, const Vec pPhys->AddVelocity( &vecVelocity, &vecAngVelocity ); } +static void ScriptPhysEnableEntityCollisions( HSCRIPT hPhys1, HSCRIPT hPhys2 ) +{ + IPhysicsObject *pPhys1 = HScriptToClass( hPhys1 ); + IPhysicsObject *pPhys2 = HScriptToClass( hPhys2 ); + if (!pPhys1 || !pPhys2) + return; + + PhysEnableEntityCollisions( pPhys1, pPhys2 ); +} + +static void ScriptPhysDisableEntityCollisions( HSCRIPT hPhys1, HSCRIPT hPhys2 ) +{ + IPhysicsObject *pPhys1 = HScriptToClass( hPhys1 ); + IPhysicsObject *pPhys2 = HScriptToClass( hPhys2 ); + if (!pPhys1 || !pPhys2) + return; + + PhysDisableEntityCollisions( pPhys1, pPhys2 ); +} + //============================================================================= //============================================================================= @@ -1045,6 +1065,8 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunction( g_pScriptVM, GetPhysAngVelocity, "Gets physics angular velocity for the given VPhysics object" ); ScriptRegisterFunction( g_pScriptVM, SetPhysVelocity, "Sets physics velocity for the given VPhysics object" ); ScriptRegisterFunction( g_pScriptVM, AddPhysVelocity, "Adds physics velocity for the given VPhysics object" ); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysEnableEntityCollisions, "PhysEnableEntityCollisions", "Enables collisions between two VPhysics objects"); + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPhysDisableEntityCollisions, "PhysDisableEntityCollisions", "Disables collisions between two VPhysics objects"); // // Precaching