Added misc. new VScript hooks/constants and the code required to implement them

This commit is contained in:
Blixibon 2021-06-28 23:55:42 -05:00
parent 29075a2c90
commit 0fb0a3319c
9 changed files with 96 additions and 1 deletions

View File

@ -151,6 +151,9 @@ BEGIN_DATADESC( CBaseCombatCharacter )
END_DATADESC() END_DATADESC()
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
ScriptHook_t CBaseCombatCharacter::g_Hook_RelationshipType;
ScriptHook_t CBaseCombatCharacter::g_Hook_RelationshipPriority;
BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by players and NPCs." ) BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by players and NPCs." )
DEFINE_SCRIPTFUNC_NAMED( GetScriptActiveWeapon, "GetActiveWeapon", "Get the character's active weapon entity." ) DEFINE_SCRIPTFUNC_NAMED( GetScriptActiveWeapon, "GetActiveWeapon", "Get the character's active weapon entity." )
@ -192,6 +195,19 @@ BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by
DEFINE_SCRIPTFUNC( EyeDirection2D, "Get the eyes' 2D direction." ) DEFINE_SCRIPTFUNC( EyeDirection2D, "Get the eyes' 2D direction." )
DEFINE_SCRIPTFUNC( EyeDirection3D, "Get the eyes' 3D direction." ) DEFINE_SCRIPTFUNC( EyeDirection3D, "Get the eyes' 3D direction." )
//
// Hooks
//
BEGIN_SCRIPTHOOK( CBaseCombatCharacter::g_Hook_RelationshipType, "RelationshipType", FIELD_INTEGER, "Called when a character's relationship to another entity is requested. Returning a disposition will make the game use that disposition instead of the default relationship. (note: 'default' in this case includes overrides from ai_relationship/SetRelationship)" )
DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT )
DEFINE_SCRIPTHOOK_PARAM( "def", FIELD_INTEGER )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseCombatCharacter::g_Hook_RelationshipPriority, "RelationshipPriority", FIELD_INTEGER, "Called when a character's relationship priority for another entity is requested. Returning a number will make the game use that priority instead of the default priority. (note: 'default' in this case includes overrides from ai_relationship/SetRelationship)" )
DEFINE_SCRIPTHOOK_PARAM( "entity", FIELD_HSCRIPT )
DEFINE_SCRIPTHOOK_PARAM( "def", FIELD_INTEGER )
END_SCRIPTHOOK()
END_SCRIPTDESC(); END_SCRIPTDESC();
#endif #endif
@ -3283,7 +3299,24 @@ Relationship_t *CBaseCombatCharacter::FindEntityRelationship( CBaseEntity *pTarg
Disposition_t CBaseCombatCharacter::IRelationType ( CBaseEntity *pTarget ) Disposition_t CBaseCombatCharacter::IRelationType ( CBaseEntity *pTarget )
{ {
if ( pTarget ) if ( pTarget )
{
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_RelationshipType.CanRunInScope( m_ScriptScope ))
{
// entity, default
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { ScriptVariant_t( pTarget->GetScriptInstance() ), FindEntityRelationship( pTarget )->disposition };
if (g_Hook_RelationshipType.Call( m_ScriptScope, &functionReturn, args ) && (functionReturn.m_type == FIELD_INTEGER && functionReturn.m_int != D_ER))
{
// Use the disposition returned by the script
return (Disposition_t)functionReturn.m_int;
}
}
#endif
return FindEntityRelationship( pTarget )->disposition; return FindEntityRelationship( pTarget )->disposition;
}
return D_NU; return D_NU;
} }
@ -3295,7 +3328,24 @@ Disposition_t CBaseCombatCharacter::IRelationType ( CBaseEntity *pTarget )
int CBaseCombatCharacter::IRelationPriority( CBaseEntity *pTarget ) int CBaseCombatCharacter::IRelationPriority( CBaseEntity *pTarget )
{ {
if ( pTarget ) if ( pTarget )
{
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_RelationshipPriority.CanRunInScope( m_ScriptScope ))
{
// entity, default
ScriptVariant_t functionReturn;
ScriptVariant_t args[] = { ScriptVariant_t( pTarget->GetScriptInstance() ), FindEntityRelationship( pTarget )->priority };
if (g_Hook_RelationshipPriority.Call( m_ScriptScope, &functionReturn, args ) && functionReturn.m_type == FIELD_INTEGER)
{
// Use the priority returned by the script
return functionReturn.m_int;
}
}
#endif
return FindEntityRelationship( pTarget )->priority; return FindEntityRelationship( pTarget )->priority;
}
return 0; return 0;
} }

View File

@ -445,6 +445,9 @@ public:
bool ScriptEntInAimCone( HSCRIPT pEntity ) { return FInAimCone( ToEnt( pEntity ) ); } bool ScriptEntInAimCone( HSCRIPT pEntity ) { return FInAimCone( ToEnt( pEntity ) ); }
const Vector& ScriptBodyAngles( void ) { static Vector vec; QAngle qa = BodyAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; } const Vector& ScriptBodyAngles( void ) { static Vector vec; QAngle qa = BodyAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; }
static ScriptHook_t g_Hook_RelationshipType;
static ScriptHook_t g_Hook_RelationshipPriority;
#endif #endif
// Interactions // Interactions

View File

@ -1758,6 +1758,22 @@ void CBaseEntity::SendOnKilledGameEvent( const CTakeDamageInfo &info )
} }
} }
void CBaseEntity::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info )
{
#ifdef MAPBASE_VSCRIPT
if (m_ScriptScope.IsInitialized() && g_Hook_OnKilledOther.CanRunInScope( m_ScriptScope ))
{
HSCRIPT hInfo = g_pScriptVM->RegisterInstance( const_cast<CTakeDamageInfo*>(&info) );
// victim, info
ScriptVariant_t args[] = { ScriptVariant_t( pVictim->GetScriptInstance() ), ScriptVariant_t( hInfo ) };
g_Hook_OnKilledOther.Call( m_ScriptScope, NULL, args );
g_pScriptVM->RemoveInstance( hInfo );
}
#endif
}
bool CBaseEntity::HasTarget( string_t targetname ) bool CBaseEntity::HasTarget( string_t targetname )
{ {
@ -2196,6 +2212,7 @@ ScriptHook_t CBaseEntity::g_Hook_UpdateOnRemove;
ScriptHook_t CBaseEntity::g_Hook_VPhysicsCollision; ScriptHook_t CBaseEntity::g_Hook_VPhysicsCollision;
ScriptHook_t CBaseEntity::g_Hook_FireBullets; ScriptHook_t CBaseEntity::g_Hook_FireBullets;
ScriptHook_t CBaseEntity::g_Hook_OnDeath; ScriptHook_t CBaseEntity::g_Hook_OnDeath;
ScriptHook_t CBaseEntity::g_Hook_OnKilledOther;
ScriptHook_t CBaseEntity::g_Hook_HandleInteraction; ScriptHook_t CBaseEntity::g_Hook_HandleInteraction;
#endif #endif
@ -2462,6 +2479,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT ) DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT )
END_SCRIPTHOOK() END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_OnKilledOther, "OnKilledOther", FIELD_VOID, "Called when the entity kills another entity." )
DEFINE_SCRIPTHOOK_PARAM( "victim", FIELD_HSCRIPT )
DEFINE_SCRIPTHOOK_PARAM( "info", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_HandleInteraction, "HandleInteraction", FIELD_BOOLEAN, "Called for internal game interactions. See the g_interaction set of constants for more information. Returning true or false will return that value without falling to any internal handling. Returning nothing will allow the interaction to fall to any internal handling." ) BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_HandleInteraction, "HandleInteraction", FIELD_BOOLEAN, "Called for internal game interactions. See the g_interaction set of constants for more information. Returning true or false will return that value without falling to any internal handling. Returning nothing will allow the interaction to fall to any internal handling." )
DEFINE_SCRIPTHOOK_PARAM( "interaction", FIELD_INTEGER ) DEFINE_SCRIPTHOOK_PARAM( "interaction", FIELD_INTEGER )
//DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT ) //DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT )

View File

@ -1093,7 +1093,7 @@ public:
void SendOnKilledGameEvent( const CTakeDamageInfo &info ); void SendOnKilledGameEvent( const CTakeDamageInfo &info );
// Notifier that I've killed some other entity. (called from Victim's Event_Killed). // Notifier that I've killed some other entity. (called from Victim's Event_Killed).
virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) { return; } virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info );
// UNDONE: Make this data? // UNDONE: Make this data?
virtual int BloodColor( void ); virtual int BloodColor( void );
@ -2151,6 +2151,7 @@ public:
static ScriptHook_t g_Hook_VPhysicsCollision; static ScriptHook_t g_Hook_VPhysicsCollision;
static ScriptHook_t g_Hook_FireBullets; static ScriptHook_t g_Hook_FireBullets;
static ScriptHook_t g_Hook_OnDeath; static ScriptHook_t g_Hook_OnDeath;
static ScriptHook_t g_Hook_OnKilledOther;
static ScriptHook_t g_Hook_HandleInteraction; static ScriptHook_t g_Hook_HandleInteraction;
#endif #endif

View File

@ -1069,6 +1069,13 @@ void CNPC_Alyx::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &
pMemory->timeFirstSeen = gpGlobals->curtime - 10.0f; pMemory->timeFirstSeen = gpGlobals->curtime - 10.0f;
} }
} }
#ifdef MAPBASE
// This call has a side effect of causing Alyx to speak a regular companion TLK_ENEMY_DEAD, which may conflict with the TLK_ALYX_ENEMY_DEAD
// further up, but this is fine because concepts are protected against interrupting each other and Alyx may even be overridden
// to use TLK_ENEMY_DEAD instead, which is used by other NPCs and appends more modifiers.
BaseClass::Event_KilledOther( pVictim, info );
#endif
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -4183,6 +4183,8 @@ void CNPC_PlayerCompanion::OnPlayerKilledOther( CBaseEntity *pVictim, const CTak
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CNPC_PlayerCompanion::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) void CNPC_PlayerCompanion::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info )
{ {
BaseClass::Event_KilledOther( pVictim, info );
if ( pVictim ) if ( pVictim )
{ {
if (pVictim->IsPlayer() || (pVictim->IsNPC() && if (pVictim->IsPlayer() || (pVictim->IsNPC() &&

View File

@ -1519,6 +1519,8 @@ void CProtoSniper::Event_Killed( const CTakeDamageInfo &info )
void CProtoSniper::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) void CProtoSniper::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info )
{ {
#ifdef MAPBASE #ifdef MAPBASE
BaseClass::Event_KilledOther( pVictim, info );
if (pVictim == GetEnemy()) if (pVictim == GetEnemy())
SetCondition(COND_SNIPER_KILLED_ENEMY); SetCondition(COND_SNIPER_KILLED_ENEMY);
#endif #endif

View File

@ -509,6 +509,12 @@ void RegisterSharedScriptConstants()
ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WALK_TO_MARK, "SCRIPT_WALK_TO_MARK", "Walking to the scripted sequence position." ); ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_WALK_TO_MARK, "SCRIPT_WALK_TO_MARK", "Walking to the scripted sequence position." );
ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_RUN_TO_MARK, "SCRIPT_RUN_TO_MARK", "Running to the scripted sequence position." ); ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_RUN_TO_MARK, "SCRIPT_RUN_TO_MARK", "Running to the scripted sequence position." );
ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Moving to the scripted sequence position while playing a custom movement animation." ); ScriptRegisterConstantNamed( g_pScriptVM, CAI_BaseNPC::SCRIPT_PLAYING, "SCRIPT_PLAYING", "Moving to the scripted sequence position while playing a custom movement animation." );
ScriptRegisterConstant( g_pScriptVM, D_ER, "'Error' relationship definition. Used by NPCs and players for relationship disposition." );
ScriptRegisterConstant( g_pScriptVM, D_HT, "Denotes a 'Hate' relationship. Used by NPCs and players for relationship disposition." );
ScriptRegisterConstant( g_pScriptVM, D_FR, "Denotes a 'Fear' relationship. Used by NPCs and players for relationship disposition." );
ScriptRegisterConstant( g_pScriptVM, D_LI, "Denotes a 'Like' relationship. Used by NPCs and players for relationship disposition." );
ScriptRegisterConstant( g_pScriptVM, D_NU, "Denotes a 'Neutral' relationship. Used by NPCs and players for relationship disposition." );
#endif #endif
// //

View File

@ -459,6 +459,8 @@ void RegisterBaseBindings( IScriptVM *pVM )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ScriptRegisterConstant( pVM, MAPBASE_VERSION, "The current Mapbase version according to when the VScript library was last compiled." );
// //
// Math/world // Math/world
// //