From e44f60e8d8c06df37f691e1cd5d976a75c90c82f Mon Sep 17 00:00:00 2001 From: "ALLEN-PC\\acj30" Date: Wed, 3 Jan 2024 12:47:29 -0600 Subject: [PATCH 1/2] Add new VScript and particle anim events --- sp/src/game/client/c_baseanimating.cpp | 102 +++++++++++++++++++++++++ sp/src/game/server/baseanimating.cpp | 14 +++- sp/src/game/shared/eventlist.cpp | 8 ++ sp/src/game/shared/eventlist.h | 8 ++ 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/sp/src/game/client/c_baseanimating.cpp b/sp/src/game/client/c_baseanimating.cpp index 7afc4d22556..edde6282016 100644 --- a/sp/src/game/client/c_baseanimating.cpp +++ b/sp/src/game/client/c_baseanimating.cpp @@ -4042,6 +4042,92 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int } break; +#ifdef MAPBASE // From Alien Swarm SDK + case AE_CL_STOP_PARTICLE_EFFECT: + { + char token[256]; + char szParticleEffect[256]; + + // Get the particle effect name + const char *p = options; + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + Q_strncpy( szParticleEffect, token, sizeof(szParticleEffect) ); + } + + // Get the attachment point index + p = nexttoken(token, p, ' ', sizeof(token)); + bool bStopInstantly = ( token && !Q_stricmp( token, "instantly" ) ); + + ParticleProp()->StopParticlesNamed( szParticleEffect, bStopInstantly ); + } + break; + + case AE_CL_ADD_PARTICLE_EFFECT_CP: + { + int iControlPoint = 1; + int iAttachment = -1; + int iAttachType = PATTACH_ABSORIGIN_FOLLOW; + int iEffectIndex = -1; + char token[256]; + char szParticleEffect[256]; + + // Get the particle effect name + const char *p = options; + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + Q_strncpy( szParticleEffect, token, sizeof(szParticleEffect) ); + } + + // Get the control point number + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + iControlPoint = atoi( token ); + } + + // Get the attachment type + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + iAttachType = GetAttachTypeFromString( token ); + if ( iAttachType == -1 ) + { + Warning("Invalid attach type specified for particle effect anim event. Trying to spawn effect '%s' with attach type of '%s'\n", szParticleEffect, token ); + return; + } + } + + // Get the attachment point index + p = nexttoken(token, p, ' ', sizeof(token)); + if ( token ) + { + iAttachment = atoi(token); + + // See if we can find any attachment points matching the name + if ( token[0] != '0' && iAttachment == 0 ) + { + iAttachment = LookupAttachment( token ); + if ( iAttachment == -1 ) + { + Warning("Failed to find attachment point specified for particle effect anim event. Trying to spawn effect '%s' on attachment named '%s'\n", szParticleEffect, token ); + return; + } + } + } + iEffectIndex = ParticleProp()->FindEffect( szParticleEffect ); + if ( iEffectIndex == -1 ) + { + Warning("Failed to find specified particle effect. Trying to add CP to '%s' on attachment named '%s'\n", szParticleEffect, token ); + return; + } + ParticleProp()->AddControlPoint( iEffectIndex, iControlPoint, this, (ParticleAttachment_t)iAttachType, iAttachment ); + } + break; +#endif + case AE_CL_PLAYSOUND: { CLocalPlayerFilter filter; @@ -4291,6 +4377,22 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int } break; +#ifdef MAPBASE + case AE_VSCRIPT_RUN: + { + if (!RunScript( options )) + Warning( "%s failed to run AE_VSCRIPT_RUN on client with \"%s\"\n", GetDebugName(), options ); + } + break; + + case AE_VSCRIPT_RUN_FILE: + { + if (!RunScriptFile( options )) + Warning( "%s failed to run AE_VSCRIPT_RUN_FILE on client with \"%s\"\n", GetDebugName(), options ); + } + break; +#endif + default: break; } diff --git a/sp/src/game/server/baseanimating.cpp b/sp/src/game/server/baseanimating.cpp index be4d6b73d82..0e2262094d8 100644 --- a/sp/src/game/server/baseanimating.cpp +++ b/sp/src/game/server/baseanimating.cpp @@ -1333,7 +1333,7 @@ void CBaseAnimating::HandleAnimEvent( animevent_t *pEvent ) #ifdef MAPBASE else if ( pEvent->event == AE_NPC_RESPONSE ) { - if (!MyNPCPointer()->GetExpresser()->IsSpeaking()) + if (MyNPCPointer() && MyNPCPointer()->GetExpresser() && !MyNPCPointer()->GetExpresser()->IsSpeaking()) { DispatchResponse( pEvent->options ); } @@ -1344,6 +1344,18 @@ void CBaseAnimating::HandleAnimEvent( animevent_t *pEvent ) DispatchResponse( pEvent->options ); return; } + else if ( pEvent->event == AE_VSCRIPT_RUN ) + { + if (!RunScript( pEvent->options )) + Warning( "%s failed to run AE_VSCRIPT_RUN on server with \"%s\"\n", GetDebugName(), pEvent->options ); + return; + } + else if ( pEvent->event == AE_VSCRIPT_RUN_FILE ) + { + if (!RunScriptFile( pEvent->options )) + Warning( "%s failed to run AE_VSCRIPT_RUN_FILE on server with \"%s\"\n", GetDebugName(), pEvent->options ); + return; + } #endif else if ( pEvent->event == AE_RAGDOLL ) { diff --git a/sp/src/game/shared/eventlist.cpp b/sp/src/game/shared/eventlist.cpp index 043293bca32..2776aa8f39b 100644 --- a/sp/src/game/shared/eventlist.cpp +++ b/sp/src/game/shared/eventlist.cpp @@ -233,6 +233,11 @@ void EventList_RegisterSharedEvents( void ) REGISTER_SHARED_ANIMEVENT( AE_SV_DUSTTRAIL, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_CREATE_PARTICLE_EFFECT, AE_TYPE_CLIENT ); +#ifdef MAPBASE // From Alien Swarm SDK + REGISTER_SHARED_ANIMEVENT( AE_CL_STOP_PARTICLE_EFFECT, AE_TYPE_CLIENT ); + REGISTER_SHARED_ANIMEVENT( AE_CL_ADD_PARTICLE_EFFECT_CP, AE_TYPE_CLIENT ); + //REGISTER_SHARED_ANIMEVENT( AE_CL_CREATE_PARTICLE_BRASS, AE_TYPE_CLIENT ); +#endif REGISTER_SHARED_ANIMEVENT( AE_RAGDOLL, AE_TYPE_SERVER ); @@ -252,5 +257,8 @@ void EventList_RegisterSharedEvents( void ) #ifdef MAPBASE REGISTER_SHARED_ANIMEVENT( AE_NPC_RESPONSE, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_RESPONSE_FORCED, AE_TYPE_SERVER ); + + REGISTER_SHARED_ANIMEVENT( AE_VSCRIPT_RUN, AE_TYPE_CLIENT | AE_TYPE_SERVER ); + REGISTER_SHARED_ANIMEVENT( AE_VSCRIPT_RUN_FILE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); #endif } \ No newline at end of file diff --git a/sp/src/game/shared/eventlist.h b/sp/src/game/shared/eventlist.h index ee8b38df064..7d810bd4a99 100644 --- a/sp/src/game/shared/eventlist.h +++ b/sp/src/game/shared/eventlist.h @@ -69,6 +69,11 @@ typedef enum AE_SV_DUSTTRAIL, AE_CL_CREATE_PARTICLE_EFFECT, +#ifdef MAPBASE // From Alien Swarm SDK + AE_CL_STOP_PARTICLE_EFFECT, + AE_CL_ADD_PARTICLE_EFFECT_CP, + //AE_CL_CREATE_PARTICLE_BRASS, +#endif AE_RAGDOLL, @@ -88,6 +93,9 @@ typedef enum #ifdef MAPBASE AE_NPC_RESPONSE, // Play a response system concept if we're not speaking AE_NPC_RESPONSE_FORCED, // Always play a response system concept + + AE_VSCRIPT_RUN, // Run vscript code (server + client) + AE_VSCRIPT_RUN_FILE, // Run vscript file (server + client) #endif LAST_SHARED_ANIMEVENT, From 0d37ded0eb0cc0cd3bd716419dc8e72a0865abf2 Mon Sep 17 00:00:00 2001 From: "ALLEN-PC\\acj30" Date: Wed, 3 Jan 2024 12:49:10 -0600 Subject: [PATCH 2/2] Add OnScriptEvent outputs to ai_hint --- sp/src/game/server/ai_basenpc.cpp | 6 ++++++ sp/src/game/server/ai_hint.cpp | 24 ++++++++++++++++++++++++ sp/src/game/server/ai_hint.h | 7 +++++++ 3 files changed, 37 insertions(+) diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index acfebf14a85..81229c5d941 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -9526,6 +9526,12 @@ void CAI_BaseNPC::HandleAnimEvent( animevent_t *pEvent ) { m_hCine->FireScriptEvent( atoi( pEvent->options ) ); } +#ifdef MAPBASE + else if ( GetHintNode() ) + { + GetHintNode()->FireScriptEvent( atoi( pEvent->options ) ); + } +#endif else { // FIXME: look so see if it's playing a vcd and fire those instead diff --git a/sp/src/game/server/ai_hint.cpp b/sp/src/game/server/ai_hint.cpp index e9844a0182f..10d9d7282b1 100644 --- a/sp/src/game/server/ai_hint.cpp +++ b/sp/src/game/server/ai_hint.cpp @@ -902,6 +902,17 @@ BEGIN_DATADESC( CAI_Hint ) DEFINE_OUTPUT( m_OnNPCStartedUsing, "OnNPCStartedUsing" ), DEFINE_OUTPUT( m_OnNPCStoppedUsing, "OnNPCStoppedUsing" ), +#ifdef MAPBASE + DEFINE_OUTPUT( m_OnScriptEvent[0], "OnScriptEvent01" ), + DEFINE_OUTPUT( m_OnScriptEvent[1], "OnScriptEvent02" ), + DEFINE_OUTPUT( m_OnScriptEvent[2], "OnScriptEvent03" ), + DEFINE_OUTPUT( m_OnScriptEvent[3], "OnScriptEvent04" ), + DEFINE_OUTPUT( m_OnScriptEvent[4], "OnScriptEvent05" ), + DEFINE_OUTPUT( m_OnScriptEvent[5], "OnScriptEvent06" ), + DEFINE_OUTPUT( m_OnScriptEvent[6], "OnScriptEvent07" ), + DEFINE_OUTPUT( m_OnScriptEvent[7], "OnScriptEvent08" ), +#endif + END_DATADESC( ); #ifdef MAPBASE_VSCRIPT @@ -1705,6 +1716,19 @@ void CAI_Hint::NPCStoppedUsing( CAI_BaseNPC *pNPC ) m_OnNPCStoppedUsing.Set( pNPC, pNPC, this ); } +#ifdef MAPBASE +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CAI_Hint::FireScriptEvent( int nEvent ) +{ + if ( ( nEvent >= 1 ) && ( nEvent <= 8 ) ) + { + m_OnScriptEvent[nEvent - 1].FireOutput( m_hHintOwner, this ); + } +} +#endif + CON_COMMAND(ai_dump_hints, "") { diff --git a/sp/src/game/server/ai_hint.h b/sp/src/game/server/ai_hint.h index fc23f9c3cb7..b18be429fa1 100644 --- a/sp/src/game/server/ai_hint.h +++ b/sp/src/game/server/ai_hint.h @@ -323,6 +323,9 @@ class CAI_Hint : public CServerOnlyEntity void FixupTargetNode(); void NPCStartedUsing( CAI_BaseNPC *pNPC ); void NPCStoppedUsing( CAI_BaseNPC *pNPC ); +#ifdef MAPBASE + void FireScriptEvent( int nEvent ); +#endif HintIgnoreFacing_t GetIgnoreFacing() const { return m_NodeData.fIgnoreFacing; } @@ -385,6 +388,10 @@ class CAI_Hint : public CServerOnlyEntity float m_nodeFOV; Vector m_vecForward; +#ifdef MAPBASE + COutputEvent m_OnScriptEvent[8]; +#endif + // The next hint in list of all hints friend class CAI_HintManager;