Skip to content

Commit

Permalink
minigunner refactoring
Browse files Browse the repository at this point in the history
possibly fixes minigun spinning sound not always playing. Minigunners will never take cover.
  • Loading branch information
wootguy committed Dec 23, 2024
1 parent 057228f commit 8e35ecb
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 133 deletions.
45 changes: 39 additions & 6 deletions dlls/monster/CBaseGrunt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ void CBaseGrunt::Killed(entvars_t* pevAttacker, int iGib)
medic->HealMe(NULL);
}

if (minigunSpinState)
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spindown.wav", 1.0, ATTN_NORM, 0, 90);
if (HasEquipment(MEQUIP_MINIGUN))
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, 100);
minigunSpinState = 0;

RemoveRpgLaser();

SetUse(NULL);
Expand Down Expand Up @@ -167,6 +173,16 @@ void CBaseGrunt :: JustSpoke( void )

void CBaseGrunt :: PrescheduleThink ( void )
{
if (HasEquipment(MEQUIP_MINIGUN)) {
if (minigunSpinState == 2) {
EMIT_SOUND_DYN(edict(), CHAN_ITEM, "hassault/hw_spin.wav", 0.7f, ATTN_STATIC, SND_CHANGE_PITCH, 100);
}
if (pev->sequence == minigunShootSeq && gpGlobals->time >= nextMinigunShoot) {
pev->nextthink = nextMinigunShoot = gpGlobals->time + 0.07f;
Shoot(false);
}
}

if ( InSquad() && m_hEnemy != NULL )
{
if ( HasConditions ( bits_COND_SEE_ENEMY ) )
Expand Down Expand Up @@ -1242,6 +1258,16 @@ void CBaseGrunt :: StartTask ( Task_t *pTask )
m_IdealActivity = ACT_GLIDE;
}
break;
case TASK_GRUNT_MINIGUN_SPINUP:
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spinup.wav", 1.0, ATTN_NORM, 0, 90);

pev->sequence = LookupActivity(ACT_THREAT_DISPLAY);
pev->frame = 0;
m_rpgAimTime = gpGlobals->time;
ResetSequenceInfo();

minigunSpinState = 1;
break;

default:
CTalkSquadMonster :: StartTask( pTask );
Expand Down Expand Up @@ -1278,6 +1304,16 @@ void CBaseGrunt :: RunTask ( Task_t *pTask )
TaskComplete();
}

break;
case TASK_GRUNT_MINIGUN_SPINUP:
if (pev->frame > 180) {
EMIT_SOUND_DYN(edict(), CHAN_ITEM, "hassault/hw_spin.wav", 0.7f, ATTN_STATIC, SND_CHANGE_PITCH, 100);
minigunSpinState = 2;
TaskComplete();
}
MakeIdealYaw(m_vecEnemyLKP);
ChangeYaw(pev->yaw_speed);
PointAtEnemy();
break;
default:
{
Expand All @@ -1293,6 +1329,7 @@ const char* CBaseGrunt::GetTaskName(int taskIdx) {
case TASK_GRUNT_SPEAK_SENTENCE: return "TASK_GRUNT_SPEAK_SENTENCE";
case TASK_GRUNT_CHECK_FIRE: return "TASK_GRUNT_CHECK_FIRE";
case TASK_GRUNT_AIM_RPG: return "TASK_GRUNT_AIM_RPG";
case TASK_GRUNT_MINIGUN_SPINUP: return "TASK_GRUNT_MINIGUN_SPINUP";
default:
return CTalkSquadMonster::GetTaskName(taskIdx);
}
Expand Down Expand Up @@ -1989,19 +2026,15 @@ Task_t tlMinigunSpinup[] =
{ TASK_STOP_MOVING, (float)0 },
{ TASK_FACE_ENEMY, (float)0 },
{ TASK_GRUNT_CHECK_FIRE, (float)0 },
{ TASK_PLAY_SEQUENCE, (float)ACT_THREAT_DISPLAY },
{ TASK_GRUNT_MINIGUN_SPINUP,(float)0 },
};

Schedule_t slMinigunSpinup[] =
{
{
tlMinigunSpinup,
ARRAYSIZE(tlMinigunSpinup),
bits_COND_ENEMY_DEAD |
bits_COND_HEAVY_DAMAGE |
bits_COND_ENEMY_OCCLUDED |
bits_COND_GRUNT_NOFIRE,

bits_COND_HEAVY_DAMAGE,
0,
"GRUNT_MINIGUN_SPINUP"
},
Expand Down
8 changes: 7 additions & 1 deletion dlls/monster/CBaseGrunt.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum
TASK_GRUNT_SPEAK_SENTENCE,
TASK_GRUNT_CHECK_FIRE,
TASK_GRUNT_AIM_RPG, // keep aiming rpg until the rocket hits or taking too long to get a clear shot
TASK_GRUNT_MINIGUN_SPINUP, // mark the minigun as spinning
LAST_BASE_GRUNT_TASK
};

Expand Down Expand Up @@ -154,7 +155,7 @@ class CBaseGrunt : public CTalkSquadMonster
virtual void SetActivity(Activity NewActivity);
virtual int GetActivitySequence(Activity NewActivity);
virtual void StartTask(Task_t* pTask);
void RunTask(Task_t* pTask);
virtual void RunTask(Task_t* pTask) override;
virtual const char* GetTaskName(int taskIdx);
Vector GetGunPosition(void);
bool HasEquipment(int equipItems);
Expand Down Expand Up @@ -234,6 +235,11 @@ class CBaseGrunt : public CTalkSquadMonster
EHANDLE m_hRpgSpot; // rpg laser spot
EHANDLE m_hRpgRocket; // rocket being aimed

int minigunShootSeq;
int minigunSpinupSeq;
float nextMinigunShoot;
int minigunSpinState;

int m_iSentence;

int m_iGruntHead;
Expand Down
64 changes: 17 additions & 47 deletions dlls/monster/CBodyGuard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class CBodyGuard: public CBaseGrunt
void Killed(entvars_t* pevAttacker, int iGib);
void ShuffleSoundArrays();

void SetActivity(Activity NewActivity);
int GetActivitySequence(Activity NewActivity);
Schedule_t* GetScheduleOfType(int Type);

Expand All @@ -67,19 +66,11 @@ class CBodyGuard: public CBaseGrunt
void TalkInit();
void OnTaskComplete(Task_t task);

void PrescheduleThink(void);

MONSTERSTATE GetIdealState()
{
return CTalkSquadMonster::GetIdealState();
}

int minigunShootSeq;
int minigunSpinupSeq;
float nextMinigunShoot;
bool minigunIsSpinning;
float minigunSpinupTime;

private:
static const char* pGruntSentences[];
static const char* pPainSounds[];
Expand Down Expand Up @@ -234,9 +225,6 @@ void CBodyGuard::GibMonster(void)

void CBodyGuard::Killed(entvars_t* pevAttacker, int iGib)
{
// stop minigun spin sound
minigunIsSpinning = false;
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
CBaseGrunt::Killed(pevAttacker, iGib);
}

Expand All @@ -263,21 +251,6 @@ void CBodyGuard::HandleAnimEvent(MonsterEvent_t* pEvent)
}
}

void CBodyGuard::PrescheduleThink(void) {
CBaseGrunt::PrescheduleThink();

if (pev->sequence == minigunShootSeq && gpGlobals->time >= nextMinigunShoot) {
pev->nextthink = nextMinigunShoot = gpGlobals->time + 0.07f;
Shoot(false);
}
if (minigunIsSpinning && minigunSpinupTime && gpGlobals->time - minigunSpinupTime > 1.0f) {
EMIT_SOUND_DYN(edict(), CHAN_ITEM, "hassault/hw_spin.wav", 0.7f, ATTN_STATIC, 0, 100);
minigunSpinupTime = 0; // sound loops automatically, don't need to keep playing
}
if (pev->sequence == minigunSpinupSeq) {
PointAtEnemy();
}
}

void CBodyGuard::OnTaskComplete(Task_t task) {
// the model is missing events for most of the reload animations, so reloading on task completion instead
Expand Down Expand Up @@ -444,33 +417,30 @@ IMPLEMENT_CUSTOM_SCHEDULES(CBodyGuard, CBaseGrunt)

Schedule_t* CBodyGuard::GetScheduleOfType(int Type)
{
bool wasSpinning = minigunSpinState != 0;
if (minigunSpinState && Type != SCHED_RANGE_ATTACK1) {
minigunSpinState = 0;
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spindown.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
}

switch (Type)
{
case SCHED_TAKE_COVER_FROM_ENEMY:
case SCHED_TAKE_COVER_FROM_BEST_SOUND:
if (HasEquipment(MEQUIP_MINIGUN)) {
return CBaseMonster::GetSchedule(); // don't take cover from sounds (too slow to react)
}
else {
break;
}
case SCHED_RANGE_ATTACK1:
if (HasEquipment(MEQUIP_MINIGUN) && !minigunIsSpinning) {
minigunIsSpinning = true;
minigunSpinupTime = gpGlobals->time;
if (HasEquipment(MEQUIP_MINIGUN) && minigunSpinState == 0) {
return &slMinigunSpinup[0];
}
return &slGruntRangeAttack1C[0]; // prevent crouching or angry idle animations
default:
if (minigunIsSpinning) {
minigunIsSpinning = false;
minigunSpinupTime = 0;
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spindown.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
return &slMinigunSpindown[0];
}
return CBaseGrunt::GetScheduleOfType(Type);
}
}

void CBodyGuard::SetActivity(Activity NewActivity) {
CBaseGrunt::SetActivity(NewActivity);

if (NewActivity == ACT_THREAT_DISPLAY) {
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spinup.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
PointAtEnemy();
return wasSpinning ? &slMinigunSpindown[0] : CBaseGrunt::GetScheduleOfType(Type);
}
}

Expand Down
80 changes: 14 additions & 66 deletions dlls/monster/CHWGrunt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,8 @@ class CHWGrunt : public CBaseGrunt
void TraceAttack(entvars_t* pevAttacker, float flDamage, Vector vecDir, TraceResult* ptr, int bitsDamageType);
Schedule_t* GetScheduleOfType(int Type);
const char* GetTaskName(int taskIdx);
void SetActivity(Activity NewActivity);
int GetActivitySequence(Activity NewActivity);
void HandleAnimEvent(MonsterEvent_t* pEvent);
void PrescheduleThink(void);
Schedule_t* GetEnemyOccludedSchedule(void);
int LookupActivity(int activity);
Schedule_t* GetMonsterStateSchedule(void);
void StartTask(Task_t* pTask);
Expand All @@ -91,11 +88,6 @@ class CHWGrunt : public CBaseGrunt
static const char* pDeathSounds[];
static const char* pGruntSentences[];

bool minigunIsSpinning;
float minigunSpinupTime;
int minigunSpinupSeq;
int minigunShootSeq;
float nextMinigunShoot;
int secondaryClipSize;
int secondaryBody;
float nextFindMinigunTime; // next time grunt is allowed to find a minigun
Expand Down Expand Up @@ -181,7 +173,6 @@ void CHWGrunt::Precache()
}
*/

minigunIsSpinning = false;
m_cAmmoLoaded = m_cClipSize = INT_MAX;
nextMinigunShoot = 0;
nextFindMinigunTime = 0;
Expand Down Expand Up @@ -297,9 +288,6 @@ void CHWGrunt::DropMinigun(Vector vecDir) {

void CHWGrunt::Killed(entvars_t* pevAttacker, int iGib)
{
// stop minigun spin sound
minigunIsSpinning = false;
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
CBaseGrunt::Killed(pevAttacker, iGib);
}

Expand Down Expand Up @@ -358,16 +346,18 @@ IMPLEMENT_CUSTOM_SCHEDULES(CHWGrunt, CBaseGrunt)

Schedule_t* CHWGrunt::GetScheduleOfType(int Type)
{
bool wasSpinning = minigunSpinState != 0;
if (minigunSpinState && Type != SCHED_RANGE_ATTACK1 && Type != SCHED_SMALL_FLINCH) {
minigunSpinState = 0;
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spindown.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
}

switch (Type)
{
case SCHED_RANGE_ATTACK1:
if (HasEquipment(MEQUIP_MINIGUN) && !minigunIsSpinning) {
if (!minigunIsSpinning) {
minigunIsSpinning = true;
minigunSpinupTime = gpGlobals->time;
return &slMinigunSpinup[0];
}
return &slGruntRangeAttack1C[0]; // prevent crouching or angry idle animations
if (HasEquipment(MEQUIP_MINIGUN) && minigunSpinState == 0) {
return &slMinigunSpinup[0];
}
return &slGruntRangeAttack1C[0]; // TODO: crouch shooting
case SCHED_HWGRUNT_FIND_MINIGUN:
Expand All @@ -383,21 +373,10 @@ Schedule_t* CHWGrunt::GetScheduleOfType(int Type)
case SCHED_DIE:
return CBaseGrunt::GetScheduleOfType(Type);
case SCHED_TAKE_COVER_FROM_BEST_SOUND:
if (minigunIsSpinning)
return CBaseMonster::GetSchedule(); // don't take cover from sounds (too slow to react)
else
return CBaseGrunt::GetScheduleOfType(Type);
case SCHED_TAKE_COVER_FROM_ENEMY:
return CBaseMonster::GetSchedule(); // don't take cover from sounds (too slow to react)
default:
if (minigunIsSpinning) {
minigunIsSpinning = false;
minigunSpinupTime = 0;
//STOP_SOUND(edict(), CHAN_ITEM, "hassault/hw_spin.wav");
EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "common/null.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spindown.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
return &slMinigunSpindown[0];
}

return CBaseGrunt::GetScheduleOfType(Type);
return wasSpinning ? &slMinigunSpindown[0] : CBaseGrunt::GetScheduleOfType(Type);
}
}

Expand All @@ -409,15 +388,6 @@ const char* CHWGrunt::GetTaskName(int taskIdx) {
}
}

void CHWGrunt::SetActivity(Activity NewActivity) {
CBaseGrunt::SetActivity(NewActivity);

if (NewActivity == ACT_THREAT_DISPLAY) {
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_spinup.wav", 1.0, ATTN_NORM, 0, m_voicePitch);
PointAtEnemy(); // otherwise he looks at the ground when starting the animation
}
}

int CHWGrunt::GetActivitySequence(Activity NewActivity) {
int iSequence = ACTIVITY_NOT_AVAILABLE;

Expand Down Expand Up @@ -483,28 +453,6 @@ void CHWGrunt::HandleAnimEvent(MonsterEvent_t* pEvent)
}
}

void CHWGrunt::PrescheduleThink(void) {
CBaseGrunt::PrescheduleThink();

if (HasEquipment(MEQUIP_MINIGUN)) {
if (pev->sequence == minigunShootSeq && gpGlobals->time >= nextMinigunShoot) {
pev->nextthink = nextMinigunShoot = gpGlobals->time + 0.07f;
Shoot(false);
}
if (minigunIsSpinning && minigunSpinupTime && gpGlobals->time - minigunSpinupTime > 1.0f) {
EMIT_SOUND_DYN(edict(), CHAN_ITEM, "hassault/hw_spin.wav", 0.7f, ATTN_STATIC, 0, 100);
minigunSpinupTime = 0; // sound loops automatically, don't need to keep playing
}
if (pev->sequence == minigunSpinupSeq) {
PointAtEnemy();
}
}
}

Schedule_t* CHWGrunt::GetEnemyOccludedSchedule(void)
{
return CBaseGrunt::GetEnemyOccludedSchedule();
}

int CHWGrunt::LookupActivity(int activity) {
// model only has turning animations for the minigun stance
Expand Down Expand Up @@ -595,15 +543,15 @@ void CHWGrunt::RunTask(Task_t* pTask)
{
case TASK_MOVE_TO_TARGET_RANGE:
{
CBaseMonster::RunTask(pTask);
CBaseGrunt::RunTask(pTask);

// always run when following someone because the walk speed is painfully slow
m_movementActivity = ACT_RUN;
break;
}
default:
{
CBaseMonster::RunTask(pTask);
CBaseGrunt::RunTask(pTask);
}
}
}
Loading

0 comments on commit 8e35ecb

Please sign in to comment.