From e552d2cc06d303335def49075e5cf152eaed623b Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin <15944199+nekonomicon@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:33:15 +0000 Subject: [PATCH] Make cycler and func_button speakable targets for scripted_sentence. (#434) --- cl_dll/hl/hl_baseentity.cpp | 6 +-- dlls/basemonster.h | 7 +--- dlls/cbase.h | 11 ++++- dlls/h_cycler.cpp | 2 + dlls/monsters.cpp | 23 +---------- dlls/scripted.cpp | 80 +++++++++++++++++++++---------------- dlls/subs.cpp | 21 ++++++++++ 7 files changed, 85 insertions(+), 65 deletions(-) diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index 2e2ec2d6..a47078e5 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -207,9 +207,9 @@ BOOL CBaseMonster::FindLateralCover( const Vector &vecThreat, const Vector &vecV Vector CBaseMonster::ShootAtEnemy( const Vector &shootOrigin ) { return g_vecZero; } BOOL CBaseMonster::FacingIdeal( void ) { return FALSE; } BOOL CBaseMonster::FCanActiveIdle( void ) { return FALSE; } -void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { } -void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { } -void CBaseMonster::SentenceStop( void ) { } +void CBaseToggle::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { } +void CBaseToggle::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { } +void CBaseToggle::SentenceStop( void ) { } void CBaseMonster::CorpseFallThink( void ) { } void CBaseMonster::MonsterInitDead( void ) { } BOOL CBaseMonster::BBoxFlat( void ) { return TRUE; } diff --git a/dlls/basemonster.h b/dlls/basemonster.h index ea145a93..dc642a6c 100644 --- a/dlls/basemonster.h +++ b/dlls/basemonster.h @@ -120,6 +120,7 @@ public: virtual int BloodColor( void ) { return m_bloodColor; } virtual CBaseMonster *MyMonsterPointer( void ) { return this; } + virtual BOOL IsAllowedToSpeak( void ) { return IsAlive(); } virtual void Look( int iDistance );// basic sight function for monsters virtual void RunAI( void );// core ai function! void Listen( void ); @@ -186,11 +187,7 @@ public: virtual void ScheduleChange( void ) {} // virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); } virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel ); - virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAlive(); } - virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ); - virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ); - - virtual void SentenceStop( void ); + virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAllowedToSpeak(); } Task_t *GetTask( void ); virtual MONSTERSTATE GetIdealState( void ); diff --git a/dlls/cbase.h b/dlls/cbase.h index 88a161e0..caf301d9 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -107,6 +107,7 @@ typedef void(CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCalle #define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures. class CBaseEntity; +class CBaseToggle; class CBaseMonster; class CBasePlayerItem; class CSquadMonster; @@ -173,6 +174,7 @@ public: virtual int BloodColor( void ) { return DONT_BLEED; } virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE; } + virtual CBaseToggle *MyTogglePointer( void ) { return NULL; } virtual CBaseMonster *MyMonsterPointer( void ) { return NULL; } virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL; } virtual int GetToggleState( void ) { return TS_AT_TOP; } @@ -251,7 +253,6 @@ public: int Intersects( CBaseEntity *pOther ); void MakeDormant( void ); int IsDormant( void ); - BOOL IsLockedByMaster( void ) { return FALSE; } static CBaseEntity *Instance( edict_t *pent ) { @@ -524,9 +525,15 @@ public: static TYPEDESCRIPTION m_SaveData[]; + CBaseToggle *MyTogglePointer( void ) { return this; } virtual int GetToggleState( void ) { return m_toggle_state; } virtual float GetDelay( void ) { return m_flWait; } + virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ); + virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ); + virtual void SentenceStop( void ); + virtual BOOL IsAllowedToSpeak( void ) { return FALSE; } + // common member functions void LinearMove( Vector vecDest, float flSpeed ); void EXPORT LinearMoveDone( void ); @@ -693,6 +700,8 @@ public: // Buttons that don't take damage can be IMPULSE used virtual int ObjectCaps( void ) { return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage?0:FCAP_IMPULSE_USE); } + BOOL IsAllowedToSpeak( void ) { return TRUE; } + BOOL m_fStayPushed; // button stays pushed in until touched again? BOOL m_fRotating; // a rotating button? default is a sliding button. diff --git a/dlls/h_cycler.cpp b/dlls/h_cycler.cpp index 49eff1d8..16d15855 100644 --- a/dlls/h_cycler.cpp +++ b/dlls/h_cycler.cpp @@ -49,6 +49,8 @@ public: virtual int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; + BOOL IsAllowedToSpeak( void ) { return TRUE; } + int m_animate; }; diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 8b8643a6..f995dff5 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -1392,7 +1392,7 @@ float CBaseMonster::OpenDoorAndWait( entvars_t *pevDoor ) //ALERT( at_aiconsole, "A door. " ); CBaseEntity *pcbeDoor = CBaseEntity::Instance( pevDoor ); - if( pcbeDoor && !pcbeDoor->IsLockedByMaster() ) + if( pcbeDoor ) { //ALERT( at_aiconsole, "unlocked! " ); pcbeDoor->Use( this, this, USE_ON, 0.0 ); @@ -3189,27 +3189,6 @@ BOOL CBaseMonster::FCanActiveIdle( void ) return FALSE; } -void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) -{ - if( pszSentence && IsAlive() ) - { - if( pszSentence[0] == '!' ) - EMIT_SOUND_DYN( edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM ); - else - SENTENCEG_PlayRndSz( edict(), pszSentence, volume, attenuation, 0, PITCH_NORM ); - } -} - -void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) -{ - PlaySentence( pszSentence, duration, volume, attenuation ); -} - -void CBaseMonster::SentenceStop( void ) -{ - EMIT_SOUND( edict(), CHAN_VOICE, "common/null.wav", 1.0, ATTN_IDLE ); -} - void CBaseMonster::CorpseFallThink( void ) { if( pev->flags & FL_ONGROUND ) diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index da495f98..bdaa85c0 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -902,9 +902,9 @@ public: static TYPEDESCRIPTION m_SaveData[]; - CBaseMonster *FindEntity( void ); - BOOL AcceptableSpeaker( CBaseMonster *pMonster ); - BOOL StartSentence( CBaseMonster *pTarget ); + CBaseToggle *FindEntity( void ); + BOOL AcceptableSpeaker( CBaseToggle *pTarget ); + BOOL StartSentence( CBaseToggle *pTarget ); private: string_t m_iszSentence; // string index for idle animation @@ -1036,20 +1036,20 @@ void CScriptedSentence::Spawn( void ) void CScriptedSentence::FindThink( void ) { - CBaseMonster *pMonster = FindEntity(); - if( pMonster ) + CBaseToggle *pTarget = FindEntity(); + if( pTarget ) { - StartSentence( pMonster ); + StartSentence( pTarget ); if( pev->spawnflags & SF_SENTENCE_ONCE ) UTIL_Remove( this ); SetThink( &CScriptedSentence::DelayThink ); pev->nextthink = gpGlobals->time + m_flDuration + m_flRepeat; m_active = FALSE; - //ALERT( at_console, "%s: found monster %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) ); + //ALERT( at_console, "%s: found target %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) ); } else { - //ALERT( at_console, "%s: can't find monster %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) ); + //ALERT( at_console, "%s: can't find target %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) ); pev->nextthink = gpGlobals->time + m_flRepeat + 0.5f; } } @@ -1062,45 +1062,57 @@ void CScriptedSentence::DelayThink( void ) SetThink( &CScriptedSentence::FindThink ); } -BOOL CScriptedSentence::AcceptableSpeaker( CBaseMonster *pMonster ) +BOOL CScriptedSentence::AcceptableSpeaker( CBaseToggle *pTarget ) { - if( pMonster ) + CBaseMonster *pMonster; + EHANDLE hTarget; + + if( pTarget ) { - if( pev->spawnflags & SF_SENTENCE_FOLLOWERS ) + hTarget = pTarget->MyMonsterPointer(); + + if( hTarget != 0 ) { - if( pMonster->m_hTargetEnt == 0 || !pMonster->m_hTargetEnt->IsPlayer() ) - return FALSE; + CBaseMonster *pMonster = (CBaseMonster*)( (CBaseEntity*)hTarget ); + if( pev->spawnflags & SF_SENTENCE_FOLLOWERS ) + { + if( pMonster->m_hTargetEnt == 0 || !pMonster->m_hTargetEnt->IsPlayer() ) + return FALSE; + } + + BOOL override; + + if( pev->spawnflags & SF_SENTENCE_INTERRUPT ) + override = TRUE; + else + override = FALSE; + + if( pMonster->CanPlaySentence( override ) ) + return TRUE; } - - BOOL override; - - if( pev->spawnflags & SF_SENTENCE_INTERRUPT ) - override = TRUE; else - override = FALSE; - - if( pMonster->CanPlaySentence( override ) ) - return TRUE; + return pTarget->IsAllowedToSpeak(); } + return FALSE; } -CBaseMonster *CScriptedSentence::FindEntity( void ) +CBaseToggle *CScriptedSentence::FindEntity( void ) { edict_t *pentTarget; - CBaseMonster *pMonster; + CBaseToggle *pTarget; pentTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING( m_iszEntity ) ); - pMonster = NULL; + pTarget = NULL; while( !FNullEnt( pentTarget ) ) { - pMonster = GetMonsterPointer( pentTarget ); - if( pMonster != NULL ) + pTarget = (CBaseToggle*)CBaseEntity::Instance( pentTarget ); + if( pTarget != NULL ) { - if( AcceptableSpeaker( pMonster ) ) - return pMonster; - //ALERT( at_console, "%s (%s), not acceptable\n", STRING( pMonster->pev->classname ), STRING( pMonster->pev->targetname ) ); + if( AcceptableSpeaker( pTarget ) ) + return pTarget; + //ALERT( at_console, "%s (%s), not acceptable\n", STRING( pTarget->pev->classname ), STRING( pTarget->pev->targetname ) ); } pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING( m_iszEntity ) ); } @@ -1112,9 +1124,9 @@ CBaseMonster *CScriptedSentence::FindEntity( void ) { if( FBitSet( pEntity->pev->flags, FL_MONSTER ) ) { - pMonster = pEntity->MyMonsterPointer(); - if( AcceptableSpeaker( pMonster ) ) - return pMonster; + pTarget = pEntity->MyTogglePointer(); + if( AcceptableSpeaker( pTarget ) ) + return pTarget; } } } @@ -1122,7 +1134,7 @@ CBaseMonster *CScriptedSentence::FindEntity( void ) return NULL; } -BOOL CScriptedSentence::StartSentence( CBaseMonster *pTarget ) +BOOL CScriptedSentence::StartSentence( CBaseToggle *pTarget ) { if( !pTarget ) { diff --git a/dlls/subs.cpp b/dlls/subs.cpp index 118554d4..9cdb6010 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -520,6 +520,27 @@ float CBaseToggle::AxisDelta( int flags, const Vector &angle1, const Vector &ang return angle1.y - angle2.y; } +void CBaseToggle::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) +{ + if( pszSentence && IsAllowedToSpeak()) + { + if( pszSentence[0] == '!' ) + EMIT_SOUND_DYN( edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM ); + else + SENTENCEG_PlayRndSz( edict(), pszSentence, volume, attenuation, 0, PITCH_NORM ); + } +} + +void CBaseToggle::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) +{ + PlaySentence( pszSentence, duration, volume, attenuation ); +} + +void CBaseToggle::SentenceStop( void ) +{ + EMIT_SOUND( edict(), CHAN_VOICE, "common/null.wav", 1.0, ATTN_IDLE ); +} + /* ============= FEntIsVisible