From 1e529268980f59c337f0f149fd57b0ecbba4db3e Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 13 Jan 2018 15:04:16 +0500 Subject: [PATCH] Fix monster_generic. --- dlls/genericmonster.cpp | 89 ++++++++++++++++++++++++++++++++++++++--- dlls/talkmonster.cpp | 2 +- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/dlls/genericmonster.cpp b/dlls/genericmonster.cpp index 4483085d..2df9ddc4 100644 --- a/dlls/genericmonster.cpp +++ b/dlls/genericmonster.cpp @@ -20,7 +20,6 @@ #include "cbase.h" #include "monsters.h" #include "schedule.h" -#include "talkmonster.h" // For holograms, make them not solid so the player can walk through them #define SF_GENERICMONSTER_NOTSOLID 4 @@ -29,8 +28,7 @@ //========================================================= // Monster's Anim Events Go Here //========================================================= - -class CGenericMonster : public CTalkMonster +class CGenericMonster : public CBaseMonster { public: void Spawn( void ); @@ -39,10 +37,33 @@ public: int Classify( void ); void HandleAnimEvent( MonsterEvent_t *pEvent ); int ISoundMask( void ); + void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ); + void IdleHeadTurn( Vector &vecFriend ); + void EXPORT MonsterThink(); + + int Save( CSave &save ); + int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + +private: + float m_talkTime; + EHANDLE m_hTalkTarget; + float m_flIdealYaw; + float m_flCurrentYaw; }; LINK_ENTITY_TO_CLASS( monster_generic, CGenericMonster ) +TYPEDESCRIPTION CGenericMonster::m_SaveData[] = +{ + DEFINE_FIELD( CGenericMonster, m_talkTime, FIELD_FLOAT ), + DEFINE_FIELD( CGenericMonster, m_hTalkTarget, FIELD_EHANDLE ), + DEFINE_FIELD( CGenericMonster, m_flIdealYaw, FIELD_FLOAT ), + DEFINE_FIELD( CGenericMonster, m_flCurrentYaw, FIELD_FLOAT ), +}; + +IMPLEMENT_SAVERESTORE( CGenericMonster, CBaseMonster ) + //========================================================= // Classify - indicates this monster's place in the // relationship table. @@ -126,6 +147,8 @@ void CGenericMonster::Spawn() m_afCapability = bits_CAP_TURN_HEAD; } + m_flIdealYaw = m_flCurrentYaw = 0; + if( pev->spawnflags & SF_GENERICMONSTER_NOTSOLID ) { pev->solid = SOLID_NOT; @@ -138,11 +161,67 @@ void CGenericMonster::Spawn() //========================================================= void CGenericMonster::Precache() { - CTalkMonster::Precache(); - TalkInit(); PRECACHE_MODEL( STRING( pev->model ) ); } +void CGenericMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) +{ + m_talkTime = gpGlobals->time + duration; + PlaySentence( pszSentence, duration, volume, attenuation ); + + m_hTalkTarget = pListener; +} + +void CGenericMonster::IdleHeadTurn( Vector &vecFriend ) +{ + // turn head in desired direction only if ent has a turnable head + if( m_afCapability & bits_CAP_TURN_HEAD ) + { + float yaw = VecToYaw( vecFriend - pev->origin ) - pev->angles.y; + + if( yaw > 180 ) + yaw -= 360; + if( yaw < -180 ) + yaw += 360; + + m_flIdealYaw = yaw; + } +} + +void CGenericMonster::MonsterThink() +{ + if( m_afCapability & bits_CAP_TURN_HEAD ) + { + if( m_hTalkTarget != 0 ) + { + if( gpGlobals->time > m_talkTime ) + { + m_flIdealYaw = 0; + m_hTalkTarget = 0; + } + else + { + IdleHeadTurn( m_hTalkTarget->pev->origin ); + } + } + + if( m_flCurrentYaw != m_flIdealYaw ) + { + if( m_flCurrentYaw <= m_flIdealYaw ) + { + m_flCurrentYaw += Q_min( m_flIdealYaw - m_flCurrentYaw, 20.0f ); + } + else + { + m_flCurrentYaw -= Q_min( m_flCurrentYaw - m_flIdealYaw, 20.0f ); + } + SetBoneController( 0, m_flCurrentYaw ); + } + } + + CBaseMonster::MonsterThink(); +} + //========================================================= // AI Schedules Specific to this monster //========================================================= diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index e755c4b0..03fb40fc 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -880,7 +880,7 @@ int CTalkMonster::FOkToSpeak( void ) return FALSE; // monster generic can speak always - if( pev->spawnflags & SF_MONSTER_GAG && !FClassnameIs( pev, "monster_generic" ) ) + if( pev->spawnflags & SF_MONSTER_GAG ) return FALSE; if( m_MonsterState == MONSTERSTATE_PRONE )