Make cycler and func_button speakable targets for scripted_sentence. (#434)

This commit is contained in:
Andrey Akhmichin 2024-02-03 22:33:15 +00:00 committed by GitHub
parent b37078f019
commit e552d2cc06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 85 additions and 65 deletions

View File

@ -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; }

View File

@ -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 );

View File

@ -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.

View File

@ -49,6 +49,8 @@ public:
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BOOL IsAllowedToSpeak( void ) { return TRUE; }
int m_animate;
};

View File

@ -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 )

View File

@ -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 )
{

View File

@ -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