@ -119,6 +119,7 @@ private:
} ;
} ;
LINK_ENTITY_TO_CLASS ( monster_scientist , CScientist )
LINK_ENTITY_TO_CLASS ( monster_scientist , CScientist )
LINK_ENTITY_TO_CLASS ( monster_rosenberg , CScientist )
TYPEDESCRIPTION CScientist : : m_SaveData [ ] =
TYPEDESCRIPTION CScientist : : m_SaveData [ ] =
{
{
@ -419,6 +420,9 @@ void CScientist::DeclineFollowing( void )
{
{
Talk ( 10 ) ;
Talk ( 10 ) ;
m_hTalkTarget = m_hEnemy ;
m_hTalkTarget = m_hEnemy ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
PlaySentence ( " RO_POK " , 2 , VOL_NORM , ATTN_NORM ) ;
else
PlaySentence ( " SC_POK " , 2 , VOL_NORM , ATTN_NORM ) ;
PlaySentence ( " SC_POK " , 2 , VOL_NORM , ATTN_NORM ) ;
}
}
@ -428,6 +432,9 @@ void CScientist::Scream( void )
{
{
Talk ( 10 ) ;
Talk ( 10 ) ;
m_hTalkTarget = m_hEnemy ;
m_hTalkTarget = m_hEnemy ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
PlaySentence ( " RO_SCREAM " , RANDOM_FLOAT ( 3.0f , 6.0f ) , VOL_NORM , ATTN_NORM ) ;
else
PlaySentence ( " SC_SCREAM " , RANDOM_FLOAT ( 3.0f , 6.0f ) , VOL_NORM , ATTN_NORM ) ;
PlaySentence ( " SC_SCREAM " , RANDOM_FLOAT ( 3.0f , 6.0f ) , VOL_NORM , ATTN_NORM ) ;
}
}
}
}
@ -447,6 +454,9 @@ void CScientist::StartTask( Task_t *pTask )
//if( FOkToSpeak() )
//if( FOkToSpeak() )
Talk ( 2 ) ;
Talk ( 2 ) ;
m_hTalkTarget = m_hTargetEnt ;
m_hTalkTarget = m_hTargetEnt ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
PlaySentence ( " RO_HEAL " , 2 , VOL_NORM , ATTN_IDLE ) ;
else
PlaySentence ( " SC_HEAL " , 2 , VOL_NORM , ATTN_IDLE ) ;
PlaySentence ( " SC_HEAL " , 2 , VOL_NORM , ATTN_IDLE ) ;
TaskComplete ( ) ;
TaskComplete ( ) ;
break ;
break ;
@ -465,6 +475,12 @@ void CScientist::StartTask( Task_t *pTask )
Talk ( 2 ) ;
Talk ( 2 ) ;
m_hTalkTarget = m_hEnemy ;
m_hTalkTarget = m_hEnemy ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
{
PlaySentence ( " RO_FEAR " , 5 , VOL_NORM , ATTN_NORM ) ;
}
else
{
//The enemy can be null here. - Solokiller
//The enemy can be null here. - Solokiller
//Discovered while testing the barnacle grapple on headcrabs with scientists in view.
//Discovered while testing the barnacle grapple on headcrabs with scientists in view.
if ( m_hEnemy ! = 0 & & m_hEnemy - > IsPlayer ( ) )
if ( m_hEnemy ! = 0 & & m_hEnemy - > IsPlayer ( ) )
@ -472,6 +488,7 @@ void CScientist::StartTask( Task_t *pTask )
else
else
PlaySentence ( " SC_FEAR " , 5 , VOL_NORM , ATTN_NORM ) ;
PlaySentence ( " SC_FEAR " , 5 , VOL_NORM , ATTN_NORM ) ;
}
}
}
TaskComplete ( ) ;
TaskComplete ( ) ;
break ;
break ;
case TASK_HEAL :
case TASK_HEAL :
@ -647,6 +664,9 @@ void CScientist::Spawn( void )
pev - > solid = SOLID_SLIDEBOX ;
pev - > solid = SOLID_SLIDEBOX ;
pev - > movetype = MOVETYPE_STEP ;
pev - > movetype = MOVETYPE_STEP ;
m_bloodColor = BLOOD_COLOR_RED ;
m_bloodColor = BLOOD_COLOR_RED ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
pev - > health = gSkillData . scientistHealth * 2 ;
else
pev - > health = gSkillData . scientistHealth ;
pev - > health = gSkillData . scientistHealth ;
pev - > view_ofs = Vector ( 0 , 0 , 50 ) ; // position of the eyes relative to monster's origin.
pev - > view_ofs = Vector ( 0 , 0 , 50 ) ; // position of the eyes relative to monster's origin.
m_flFieldOfView = VIEW_FIELD_WIDE ; // NOTE: we need a wide field of view so scientists will notice player and say hello
m_flFieldOfView = VIEW_FIELD_WIDE ; // NOTE: we need a wide field of view so scientists will notice player and say hello
@ -679,11 +699,26 @@ void CScientist::Spawn( void )
void CScientist : : Precache ( void )
void CScientist : : Precache ( void )
{
{
PRECACHE_MODEL ( " models/scientist.mdl " ) ;
PRECACHE_MODEL ( " models/scientist.mdl " ) ;
if ( ! FClassnameIs ( pev , " monster_rosenberg " ) )
{
PRECACHE_SOUND ( " scientist/sci_pain1.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain1.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain2.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain2.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain3.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain3.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain4.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain4.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain5.wav " ) ;
PRECACHE_SOUND ( " scientist/sci_pain5.wav " ) ;
}
else
{
PRECACHE_SOUND ( " rosenberg/ro_pain0.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain1.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain2.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain3.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain4.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain5.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain6.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain7.wav " ) ;
PRECACHE_SOUND ( " rosenberg/ro_pain8.wav " ) ;
}
// every new scientist must call this, otherwise
// every new scientist must call this, otherwise
// when a level is loaded, nobody will talk (time is reset to 0)
// when a level is loaded, nobody will talk (time is reset to 0)
@ -698,7 +733,32 @@ void CScientist::TalkInit()
CTalkMonster : : TalkInit ( ) ;
CTalkMonster : : TalkInit ( ) ;
// scientists speach group names (group names are in sentences.txt)
// scientists speach group names (group names are in sentences.txt)
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
{
m_szGrp [ TLK_ANSWER ] = " RO_ANSWER " ;
m_szGrp [ TLK_QUESTION ] = " RO_QUESTION " ;
m_szGrp [ TLK_IDLE ] = " RO_IDLE " ;
m_szGrp [ TLK_STARE ] = " RO_STARE " ;
m_szGrp [ TLK_USE ] = " RO_OK " ;
m_szGrp [ TLK_UNUSE ] = " RO_WAIT " ;
m_szGrp [ TLK_STOP ] = " RO_STOP " ;
m_szGrp [ TLK_NOSHOOT ] = " RO_SCARED " ;
m_szGrp [ TLK_HELLO ] = " RO_HELLO " ;
m_szGrp [ TLK_PLHURT1 ] = " !RO_CUREA " ;
m_szGrp [ TLK_PLHURT2 ] = " !RO_CUREB " ;
m_szGrp [ TLK_PLHURT3 ] = " !RO_CUREC " ;
m_szGrp [ TLK_PHELLO ] = " RO_PHELLO " ;
m_szGrp [ TLK_PIDLE ] = " RO_PIDLE " ;
m_szGrp [ TLK_PQUESTION ] = " RO_PQUEST " ;
m_szGrp [ TLK_SMELL ] = " RO_SMELL " ;
m_szGrp [ TLK_WOUND ] = " RO_WOUND " ;
m_szGrp [ TLK_MORTAL ] = " RO_MORTAL " ;
}
else
{
m_szGrp [ TLK_ANSWER ] = " SC_ANSWER " ;
m_szGrp [ TLK_ANSWER ] = " SC_ANSWER " ;
m_szGrp [ TLK_QUESTION ] = " SC_QUESTION " ;
m_szGrp [ TLK_QUESTION ] = " SC_QUESTION " ;
m_szGrp [ TLK_IDLE ] = " SC_IDLE " ;
m_szGrp [ TLK_IDLE ] = " SC_IDLE " ;
@ -720,6 +780,7 @@ void CScientist::TalkInit()
m_szGrp [ TLK_WOUND ] = " SC_WOUND " ;
m_szGrp [ TLK_WOUND ] = " SC_WOUND " ;
m_szGrp [ TLK_MORTAL ] = " SC_MORTAL " ;
m_szGrp [ TLK_MORTAL ] = " SC_MORTAL " ;
}
// get voice for head
// get voice for head
switch ( pev - > body % 3 )
switch ( pev - > body % 3 )
@ -743,10 +804,13 @@ void CScientist::TalkInit()
int CScientist : : TakeDamage ( entvars_t * pevInflictor , entvars_t * pevAttacker , float flDamage , int bitsDamageType )
int CScientist : : TakeDamage ( entvars_t * pevInflictor , entvars_t * pevAttacker , float flDamage , int bitsDamageType )
{
{
if ( pevInflictor & & pevInflictor - > flags & FL_CLIENT )
if ( pevInflictor & & pevInflictor - > flags & FL_CLIENT )
{
if ( ! FClassnameIs ( pev , " monster_rosenberg " ) )
{
{
Remember ( bits_MEMORY_PROVOKED ) ;
Remember ( bits_MEMORY_PROVOKED ) ;
StopFollowing ( TRUE ) ;
StopFollowing ( TRUE ) ;
}
}
}
// make sure friends talk about it if player hurts scientist...
// make sure friends talk about it if player hurts scientist...
return CTalkMonster : : TakeDamage ( pevInflictor , pevAttacker , flDamage , bitsDamageType ) ;
return CTalkMonster : : TakeDamage ( pevInflictor , pevAttacker , flDamage , bitsDamageType ) ;
@ -770,29 +834,64 @@ int CScientist::ISoundMask( void )
//=========================================================
//=========================================================
void CScientist : : PainSound ( void )
void CScientist : : PainSound ( void )
{
{
const char * pszSound ;
if ( gpGlobals - > time < m_painTime )
if ( gpGlobals - > time < m_painTime )
return ;
return ;
m_painTime = gpGlobals - > time + RANDOM_FLOAT ( 0.5f , 0.75f ) ;
m_painTime = gpGlobals - > time + RANDOM_FLOAT ( 0.5f , 0.75f ) ;
if ( FClassnameIs ( pev , " monster_rosenberg " ) )
switch ( RANDOM_LONG ( 0 , 8 ) )
{
case 0 :
pszSound = " rosenberg/ro_pain0.wav " ;
break ;
case 1 :
pszSound = " rosenberg/ro_pain1.wav " ;
break ;
case 2 :
pszSound = " rosenberg/ro_pain2.wav " ;
break ;
case 3 :
pszSound = " rosenberg/ro_pain3.wav " ;
break ;
case 4 :
pszSound = " rosenberg/ro_pain4.wav " ;
break ;
case 5 :
pszSound = " rosenberg/ro_pain5.wav " ;
break ;
case 6 :
pszSound = " rosenberg/ro_pain6.wav " ;
break ;
case 7 :
pszSound = " rosenberg/ro_pain7.wav " ;
break ;
case 8 :
pszSound = " rosenberg/ro_pain8.wav " ;
break ;
}
else
switch ( RANDOM_LONG ( 0 , 4 ) )
switch ( RANDOM_LONG ( 0 , 4 ) )
{
{
case 0 :
case 0 :
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , " scientist/sci_pain1.wav " , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
pszSound = " scientist/sci_pain1.wav " ;
break ;
break ;
case 1 :
case 1 :
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , " scientist/sci_pain2.wav " , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
pszSound = " scientist/sci_pain2.wav " ;
break ;
break ;
case 2 :
case 2 :
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , " scientist/sci_pain3.wav " , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
pszSound = " scientist/sci_pain3.wav " ;
break ;
break ;
case 3 :
case 3 :
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , " scientist/sci_pain4.wav " , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
pszSound = " scientist/sci_pain4.wav " ;
break ;
break ;
case 4 :
case 4 :
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , " scientist/sci_pain5.wav " , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
pszSound = " scientist/sci_pain5.wav " ;
break ;
break ;
}
}
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_VOICE , pszSound , 1 , ATTN_NORM , 0 , GetVoicePitch ( ) ) ;
}
}
//=========================================================
//=========================================================
@ -952,7 +1051,7 @@ Schedule_t *CScientist::GetSchedule( void )
}
}
return GetScheduleOfType ( SCHED_TARGET_FACE ) ; // Just face and follow.
return GetScheduleOfType ( SCHED_TARGET_FACE ) ; // Just face and follow.
}
}
else // UNDONE: When afraid, scientist won't move out of your way. Keep This? If not, write move away scared
else if ( ! FClassnameIs ( pev , " monster_rosenberg " ) ) // UNDONE: When afraid, scientist won't move out of your way. Keep This? If not, write move away scared
{
{
if ( HasConditions ( bits_COND_NEW_ENEMY ) ) // I just saw something new and scary, react
if ( HasConditions ( bits_COND_NEW_ENEMY ) ) // I just saw something new and scary, react
return GetScheduleOfType ( SCHED_FEAR ) ; // React to something scary
return GetScheduleOfType ( SCHED_FEAR ) ; // React to something scary