Add sentences support.

This commit is contained in:
Giegue
2023-05-02 23:40:00 -03:00
parent c782c2aaf5
commit 95461427b2
8 changed files with 40 additions and 39 deletions

View File

@@ -105,7 +105,7 @@ Current milestones are separated by "Tiers", which are as follows:
- Global Sound Replacement. **[DONE]** - Global Sound Replacement. **[DONE]**
- Miscellaneous customization options, such as blood color. **[DONE]** - Miscellaneous customization options, such as blood color. **[DONE]**
- Individual sound replacement: "soundlist" keyvalue for monsters. **[DONE]** - Individual sound replacement: "soundlist" keyvalue for monsters. **[DONE]**
- Sentences support for speakable monsters. - Sentences support for speakable monsters. **[DONE]**
- Attempt to fix bugs as they appear. - Attempt to fix bugs as they appear.
### Tier 5 ### Tier 5

View File

@@ -1687,14 +1687,11 @@ class CMRGrunt : public CMHGrunt
public: public:
int Classify(void); int Classify(void);
BOOL FOkToSpeak(void);
void Spawn( void ); void Spawn( void );
void Precache( void ); void Precache( void );
void DeathSound(void); void DeathSound(void);
void PainSound(void); void PainSound(void);
void IdleSound(void);
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
@@ -1712,6 +1709,8 @@ public:
float m_flActiveDischarge; float m_flActiveDischarge;
int m_iBodyGibs; int m_iBodyGibs;
static const char *pRobotSentences[];
}; };
//========================================================= //=========================================================

View File

@@ -62,6 +62,9 @@ extern cvar_t *monster_spawn;
extern cvar_t *monster_show_deaths; extern cvar_t *monster_show_deaths;
extern cvar_t *monster_show_info; extern cvar_t *monster_show_info;
// compiler does not like util.h being included here so i'll just extern the function
extern void SENTENCEG_Init();
// Player TakeDamage and Killed // Player TakeDamage and Killed
int g_DamageMsg; int g_DamageMsg;
bool g_DamageActive; bool g_DamageActive;
@@ -1293,6 +1296,7 @@ int mmDispatchSpawn( edict_t *pent )
// precache last in the event of a GMR being present // precache last in the event of a GMR being present
world_precache(); world_precache();
SENTENCEG_Init();
// node support. -Giegue // node support. -Giegue
// init the WorldGraph. // init the WorldGraph.

View File

@@ -163,7 +163,7 @@ void CMHGrunt :: SpeakSentence( void )
if (FOkToSpeak()) if (FOkToSpeak())
{ {
SENTENCEG_PlayRndSz( ENT(pev), pGruntSentences[ m_iSentence ], HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch); SENTENCEG_PlayRndSz( ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? pGruntSentences[ m_iSentence ] : CMRGrunt::pRobotSentences[ m_iSentence ], HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch);
JustSpoke(); JustSpoke();
} }
} }
@@ -546,21 +546,22 @@ void CMHGrunt :: IdleSound( void )
{ {
if (FOkToSpeak() && (g_fGruntQuestion || RANDOM_LONG(0,1))) if (FOkToSpeak() && (g_fGruntQuestion || RANDOM_LONG(0,1)))
{ {
// there has to be a better way than spamming ternary operators... -Giegue
if (!g_fGruntQuestion) if (!g_fGruntQuestion)
{ {
// ask question or make statement // ask question or make statement
switch (RANDOM_LONG(0,2)) switch (RANDOM_LONG(0,2))
{ {
case 0: // check in case 0: // check in
SENTENCEG_PlayRndSz(ENT(pev), "HG_CHECK", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_CHECK" : "RB_CHECK", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch);
g_fGruntQuestion = 1; g_fGruntQuestion = 1;
break; break;
case 1: // question case 1: // question
SENTENCEG_PlayRndSz(ENT(pev), "HG_QUEST", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_QUEST" : "RB_QUEST", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch);
g_fGruntQuestion = 2; g_fGruntQuestion = 2;
break; break;
case 2: // statement case 2: // statement
SENTENCEG_PlayRndSz(ENT(pev), "HG_IDLE", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_IDLE" : "RB_IDLE", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch);
break; break;
} }
} }
@@ -569,10 +570,10 @@ void CMHGrunt :: IdleSound( void )
switch (g_fGruntQuestion) switch (g_fGruntQuestion)
{ {
case 1: // check in case 1: // check in
SENTENCEG_PlayRndSz(ENT(pev), "HG_CLEAR", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_CLEAR" : "RB_CLEAR", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch);
break; break;
case 2: // question case 2: // question
SENTENCEG_PlayRndSz(ENT(pev), "HG_ANSWER", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_ANSWER" : "RB_ANSWER", HGRUNT_SENTENCE_VOLUME, ATTN_NORM, 0, m_voicePitch);
break; break;
} }
g_fGruntQuestion = 0; g_fGruntQuestion = 0;
@@ -808,7 +809,7 @@ void CMHGrunt :: HandleAnimEvent( MonsterEvent_t *pEvent )
{ {
if ( FOkToSpeak() ) if ( FOkToSpeak() )
{ {
SENTENCEG_PlayRndSz(ENT(pev), "HG_ALERT", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch); SENTENCEG_PlayRndSz(ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_ALERT" : "RB_ALERT", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch);
JustSpoke(); JustSpoke();
} }
@@ -1948,9 +1949,9 @@ Schedule_t *CMHGrunt :: GetSchedule( void )
//!!!KELLY - this grunt was hit and is going to run to cover. //!!!KELLY - this grunt was hit and is going to run to cover.
if (FOkToSpeak()) // && RANDOM_LONG(0,1)) if (FOkToSpeak()) // && RANDOM_LONG(0,1))
{ {
//SENTENCEG_PlayRndSz( ENT(pev), "HG_COVER", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch); SENTENCEG_PlayRndSz( ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_COVER" : "RB_COVER", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch);
m_iSentence = HGRUNT_SENT_COVER; m_iSentence = HGRUNT_SENT_COVER;
//JustSpoke(); JustSpoke();
} }
return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY ); return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY );
} }
@@ -1995,14 +1996,14 @@ Schedule_t *CMHGrunt :: GetSchedule( void )
else if ( HasConditions( bits_COND_ENEMY_OCCLUDED ) ) else if ( HasConditions( bits_COND_ENEMY_OCCLUDED ) )
{ {
// missing CSquadMonster functions means that the monster will stand still if its enemy is out of sight // missing CSquadMonster functions means that the monster will stand still if its enemy is out of sight
// and if it is impossible to throw a grenade. force it to chase the enemy if attack isn't possible // AND if it is impossible to throw a grenade. force it to chase the enemy if attack isn't possible
// -Giegue // -Giegue
if ( HasConditions( bits_COND_CAN_RANGE_ATTACK2 ) ) if ( HasConditions( bits_COND_CAN_RANGE_ATTACK2 ) )
{ {
//!!!KELLY - this grunt is about to throw or fire a grenade at the player. Great place for "fire in the hole" "frag out" etc //!!!KELLY - this grunt is about to throw or fire a grenade at the player. Great place for "fire in the hole" "frag out" etc
if (FOkToSpeak()) if (FOkToSpeak())
{ {
SENTENCEG_PlayRndSz( ENT(pev), "HG_THROW", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch); SENTENCEG_PlayRndSz( ENT(pev), !FClassnameIs(pev, "monster_robogrunt") ? "HG_THROW" : "RB_THROW", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch);
JustSpoke(); JustSpoke();
} }
return GetScheduleOfType( SCHED_RANGE_ATTACK2 ); return GetScheduleOfType( SCHED_RANGE_ATTACK2 );

View File

@@ -253,10 +253,7 @@ void CMHWGrunt::Precache()
PRECACHE_SOUND("hassault/hw_spindown.wav"); PRECACHE_SOUND("hassault/hw_spindown.wav");
// get voice pitch // get voice pitch
if (RANDOM_LONG(0, 1)) m_voicePitch = 95 + RANDOM_LONG(0, 3); // slighly lower than normal grunt
m_voicePitch = 102 + RANDOM_LONG(0, 7);
else
m_voicePitch = 93; // slight voice change for hwgrunt
CMHGrunt hgrunt; CMHGrunt hgrunt;
hgrunt.Precache(); hgrunt.Precache();

View File

@@ -872,7 +872,7 @@ void scan_extra_cfg(FILE *fp)
if (dllapi_log->value) if (dllapi_log->value)
LOG_CONSOLE(PLID, "[DEBUG] Using global model replacement file: %s", value); LOG_CONSOLE(PLID, "[DEBUG] Using global model replacement file: %s", value);
} }
else if (strcmp(cmd, "globalsoundlist") == 0) if (strcmp(cmd, "globalsoundlist") == 0)
{ {
//globalsoundlist->string = value; //globalsoundlist->string = value;
CVAR_SET_STRING( "monster_gsr", value ); CVAR_SET_STRING( "monster_gsr", value );

View File

@@ -53,21 +53,26 @@
#define RGRUNT_MAX_SPARKS 5 #define RGRUNT_MAX_SPARKS 5
//========================================================= //=========================================================
// These sounds are muted for Robo Grunts // This sound is muted for Robo Grunts
//========================================================= //=========================================================
BOOL CMRGrunt::FOkToSpeak(void)
{
return FALSE;
}
void CMRGrunt::IdleSound(void)
{
}
void CMRGrunt::PainSound(void) void CMRGrunt::PainSound(void)
{ {
} }
// This is a gross hack: RGRUNT inherits from HGRUNT, so...
// to avoid duplicating code, I'm going to define it here
// then use it in hgrunt whenever speech is needed. -Giegue
const char *CMRGrunt::pRobotSentences[] =
{
"RB_GREN", // Sven Co-op uses "RB_" for rgrunt sentences
"RB_ALERT",
"RB_MONSTER",
"RB_COVER",
"RB_THROW",
"RB_CHARGE",
"RB_TAUNT",
};
//========================================================= //=========================================================
// DeathSound // DeathSound
//========================================================= //=========================================================
@@ -411,13 +416,8 @@ void CMRGrunt::Precache()
PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event
/*
// get voice pitch // get voice pitch
if (RANDOM_LONG(0, 1)) m_voicePitch = 115; // always the same
m_voicePitch = 109 + RANDOM_LONG(0, 7);
else
m_voicePitch = 100;
*/
m_iBrassShell = PRECACHE_MODELINDEX("models/shell.mdl");// brass shell m_iBrassShell = PRECACHE_MODELINDEX("models/shell.mdl");// brass shell
} }

View File

@@ -792,9 +792,9 @@ Schedule_t *CMStrooper::GetSchedule(void)
//!!!KELLY - this grunt was hit and is going to run to cover. //!!!KELLY - this grunt was hit and is going to run to cover.
if (FOkToSpeak()) // && RANDOM_LONG(0,1)) if (FOkToSpeak()) // && RANDOM_LONG(0,1))
{ {
//SENTENCEG_PlayRndSz( ENT(pev), "HG_COVER", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch); SENTENCEG_PlayRndSz( ENT(pev), "ST_COVER", STROOPER_SENTENCE_VOLUME, STROOPER_ATTN, 0, m_voicePitch);
m_iSentence = STROOPER_SENT_COVER; m_iSentence = STROOPER_SENT_COVER;
//JustSpoke(); JustSpoke();
} }
return GetScheduleOfType(SCHED_TAKE_COVER_FROM_ENEMY); return GetScheduleOfType(SCHED_TAKE_COVER_FROM_ENEMY);
} }