From 46105b7ab4fa8e87aec6ed1f1660a68712fb09cb Mon Sep 17 00:00:00 2001 From: Bronzehawk75 Date: Fri, 20 Jun 2025 14:52:32 -0400 Subject: [PATCH 1/2] Added code to dynamically set an NPC's jump variables --- sp/src/game/server/ai_basenpc.cpp | 29 ++++++++++++++++++++++ sp/src/game/server/ai_basenpc.h | 11 ++++++++ sp/src/game/server/ai_basenpc_movement.cpp | 13 +++++++--- sp/src/game/server/hl2/npc_monk.cpp | 4 ++- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index b690f9a06d5..c11e87b9a9b 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -12429,6 +12429,12 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_KEYFIELD( m_flSpeedModifier, FIELD_FLOAT, "BaseSpeedModifier" ), DEFINE_FIELD( m_FakeSequenceGestureLayer, FIELD_INTEGER ), + + // Jump override keyvalues + DEFINE_KEYFIELD( m_jumpUpOverride, FIELD_FLOAT, "JumpUpOverride" ), + DEFINE_KEYFIELD( m_jumpDownOverride, FIELD_FLOAT, "JumpDownOverride" ), + DEFINE_KEYFIELD( m_jumpDistOverride, FIELD_FLOAT, "JumpDistOverride" ), + #endif // Satisfy classcheck @@ -12539,6 +12545,11 @@ BEGIN_DATADESC( CAI_BaseNPC ) DEFINE_OUTPUT( m_OnStateChange, "OnStateChange" ), #endif + // Change jump height + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpUp", InputSetJumpUp), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpDown", InputSetJumpDown), + DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpDist", InputSetJumpDist), + // Function pointers DEFINE_USEFUNC( NPCUse ), DEFINE_THINKFUNC( CallNPCThink ), @@ -17047,3 +17058,21 @@ bool CAI_BaseNPC::IsInChoreo() const { return m_bInChoreo; } + +//----------------------------------------------------------------------------- +// Purpose: Override the NPC's default jump values +//----------------------------------------------------------------------------- +void CAI_BaseNPC::InputSetJumpUp(inputdata_t& inputdata) +{ + m_jumpUpOverride = inputdata.value.Float(); +} + +void CAI_BaseNPC::InputSetJumpDown(inputdata_t& inputdata) +{ + m_jumpDownOverride = inputdata.value.Float(); +} + +void CAI_BaseNPC::InputSetJumpDist(inputdata_t& inputdata) +{ + m_jumpDistOverride = inputdata.value.Float(); +} diff --git a/sp/src/game/server/ai_basenpc.h b/sp/src/game/server/ai_basenpc.h index 71b340cf7e0..80a9877f3ad 100644 --- a/sp/src/game/server/ai_basenpc.h +++ b/sp/src/game/server/ai_basenpc.h @@ -2132,6 +2132,11 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void InputIgnoreDangerSounds( inputdata_t &inputdata ); void InputUpdateEnemyMemory( inputdata_t &inputdata ); + // Overwrite jump height + void InputSetJumpUp( inputdata_t& inputdata ); + void InputSetJumpDown( inputdata_t& inputdata ); + void InputSetJumpDist( inputdata_t& inputdata ); + //--------------------------------- virtual void NotifyDeadFriend( CBaseEntity *pFriend ) { return; } @@ -2488,6 +2493,12 @@ class CAI_BaseNPC : public CBaseCombatCharacter, void GetPlayerAvoidBounds( Vector *pMins, Vector *pMaxs ); void StartPingEffect( void ) { m_flTimePingEffect = gpGlobals->curtime + 2.0f; DispatchUpdateTransmitState(); } + +protected: // Jump override variables + float m_jumpUpOverride = 0.0f; + float m_jumpDownOverride = 0.0f; + float m_jumpDistOverride = 0.0f; + }; diff --git a/sp/src/game/server/ai_basenpc_movement.cpp b/sp/src/game/server/ai_basenpc_movement.cpp index 142b11e23cd..c538229c3e8 100644 --- a/sp/src/game/server/ai_basenpc_movement.cpp +++ b/sp/src/game/server/ai_basenpc_movement.cpp @@ -297,16 +297,21 @@ bool CAI_BaseNPC::CanStandOn( CBaseEntity *pSurface ) const bool CAI_BaseNPC::IsJumpLegal( const Vector &startPos, const Vector &apex, const Vector &endPos, float maxUp, float maxDown, float maxDist ) const { - if ((endPos.z - startPos.z) > maxUp + 0.1) + // Always use the jump override values + float localMaxUp = m_jumpUpOverride > 0.0 ? m_jumpUpOverride : maxUp; + float localMaxDown = m_jumpDownOverride > 0.0 ? m_jumpDownOverride : maxDown; + float localMaxDist = m_jumpDistOverride > 0.0 ? m_jumpDistOverride : maxDist; + + if ((endPos.z - startPos.z) > localMaxUp + 0.1) return false; - if ((startPos.z - endPos.z) > maxDown + 0.1) + if ((startPos.z - endPos.z) > localMaxDown + 0.1) return false; - if ((apex.z - startPos.z) > maxUp * 1.25 ) + if ((apex.z - startPos.z) > localMaxUp * 1.25) return false; float dist = (startPos - endPos).Length(); - if ( dist > maxDist + 0.1) + if (dist > localMaxDist + 0.1) return false; return true; } diff --git a/sp/src/game/server/hl2/npc_monk.cpp b/sp/src/game/server/hl2/npc_monk.cpp index 7f8407713f2..d643267ef3a 100644 --- a/sp/src/game/server/hl2/npc_monk.cpp +++ b/sp/src/game/server/hl2/npc_monk.cpp @@ -744,7 +744,9 @@ int CNPC_Monk::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFa //----------------------------------------------------------------------------- bool CNPC_Monk::IsJumpLegal( const Vector &startPos, const Vector &apex, const Vector &endPos ) const { - if ( startPos.z - endPos.z < 0 ) + // This disables jumping up (probably to hack around some silly behavior Valve found in d1_town_02a) + // If the mapper is setting jumpUpOverride, they probably want father to jump up + if ( startPos.z - endPos.z < 0 && m_jumpUpOverride < 0 ) return false; return BaseClass::IsJumpLegal( startPos, apex, endPos ); } From f24eab71a156cdb87371633cb0049afdaa503152 Mon Sep 17 00:00:00 2001 From: Bronzehawk75 Date: Fri, 20 Jun 2025 15:02:39 -0400 Subject: [PATCH 2/2] Clean up --- sp/src/game/server/ai_basenpc.cpp | 12 ++++++------ sp/src/game/server/ai_basenpc_movement.cpp | 8 ++++---- sp/src/game/server/hl2/npc_monk.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index c11e87b9a9b..6cff9950fbf 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -12546,9 +12546,9 @@ BEGIN_DATADESC( CAI_BaseNPC ) #endif // Change jump height - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpUp", InputSetJumpUp), - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpDown", InputSetJumpDown), - DEFINE_INPUTFUNC(FIELD_FLOAT, "SetMaxJumpDist", InputSetJumpDist), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxJumpUp", InputSetJumpUp ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxJumpDown", InputSetJumpDown ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxJumpDist", InputSetJumpDist ), // Function pointers DEFINE_USEFUNC( NPCUse ), @@ -17062,17 +17062,17 @@ bool CAI_BaseNPC::IsInChoreo() const //----------------------------------------------------------------------------- // Purpose: Override the NPC's default jump values //----------------------------------------------------------------------------- -void CAI_BaseNPC::InputSetJumpUp(inputdata_t& inputdata) +void CAI_BaseNPC::InputSetJumpUp( inputdata_t& inputdata ) { m_jumpUpOverride = inputdata.value.Float(); } -void CAI_BaseNPC::InputSetJumpDown(inputdata_t& inputdata) +void CAI_BaseNPC::InputSetJumpDown( inputdata_t& inputdata ) { m_jumpDownOverride = inputdata.value.Float(); } -void CAI_BaseNPC::InputSetJumpDist(inputdata_t& inputdata) +void CAI_BaseNPC::InputSetJumpDist( inputdata_t& inputdata ) { m_jumpDistOverride = inputdata.value.Float(); } diff --git a/sp/src/game/server/ai_basenpc_movement.cpp b/sp/src/game/server/ai_basenpc_movement.cpp index c538229c3e8..ed7603bccdb 100644 --- a/sp/src/game/server/ai_basenpc_movement.cpp +++ b/sp/src/game/server/ai_basenpc_movement.cpp @@ -302,16 +302,16 @@ bool CAI_BaseNPC::IsJumpLegal( const Vector &startPos, const Vector &apex, const float localMaxDown = m_jumpDownOverride > 0.0 ? m_jumpDownOverride : maxDown; float localMaxDist = m_jumpDistOverride > 0.0 ? m_jumpDistOverride : maxDist; - if ((endPos.z - startPos.z) > localMaxUp + 0.1) + if ((endPos.z - startPos.z) > localMaxUp + 0.1 ) return false; - if ((startPos.z - endPos.z) > localMaxDown + 0.1) + if ((startPos.z - endPos.z) > localMaxDown + 0.1 ) return false; - if ((apex.z - startPos.z) > localMaxUp * 1.25) + if ((apex.z - startPos.z) > localMaxUp * 1.25 ) return false; float dist = (startPos - endPos).Length(); - if (dist > localMaxDist + 0.1) + if ( dist > localMaxDist + 0.1 ) return false; return true; } diff --git a/sp/src/game/server/hl2/npc_monk.cpp b/sp/src/game/server/hl2/npc_monk.cpp index d643267ef3a..743c225945e 100644 --- a/sp/src/game/server/hl2/npc_monk.cpp +++ b/sp/src/game/server/hl2/npc_monk.cpp @@ -744,7 +744,7 @@ int CNPC_Monk::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFa //----------------------------------------------------------------------------- bool CNPC_Monk::IsJumpLegal( const Vector &startPos, const Vector &apex, const Vector &endPos ) const { - // This disables jumping up (probably to hack around some silly behavior Valve found in d1_town_02a) + // `startPos.z - endPos.z < 0` disables jumping up (probably to hack around some silly behavior Valve found in d1_town_02a) // If the mapper is setting jumpUpOverride, they probably want father to jump up if ( startPos.z - endPos.z < 0 && m_jumpUpOverride < 0 ) return false;