void CHellKnight :: CheckContinueCharge( void ) { if (gpGlobals->time > m_flAttackFinished) { AttackFinished (3); MonsterRun (); return; // done charging } EMIT_SOUND_ARRAY_DYN( CHAN_WEAPON, pAttackSounds, ATTN_NORM ); }
BOOL CSoldier::MonsterCheckAttack( void ) { Vector spot1, spot2; CBaseEntity *pTarg; float chance; pTarg = m_hEnemy; // see if any entities are in the way of the shot spot1 = EyePosition(); spot2 = pTarg->EyePosition(); TraceResult tr; UTIL_TraceLine( spot1, spot2, dont_ignore_monsters, dont_ignore_glass, ENT(pev), &tr ); if (tr.fInOpen && tr.fInWater) return FALSE; // sight line crossed contents if (tr.pHit != pTarg->edict()) return FALSE; // don't have a clear shot // missile attack if (gpGlobals->time < m_flAttackFinished) return FALSE; if (m_iEnemyRange == RANGE_FAR) return FALSE; if (m_iEnemyRange == RANGE_MELEE) chance = 0.9f; else if (m_iEnemyRange == RANGE_NEAR) chance = 0.4f; else if (m_iEnemyRange == RANGE_MID) chance = 0.05f; else chance = 0; if (RANDOM_FLOAT(0, 1) < chance) { MonsterMissileAttack(); AttackFinished (1 + RANDOM_FLOAT(0, 1)); if (RANDOM_FLOAT(0, 1) < 0.3f) m_fLeftY = !m_fLeftY; return TRUE; } return FALSE; }
void HuntTarget (edict_t *self) { vec3_t vec; self->goalentity = self->enemy; if (self->monsterinfo.aiflags & AI_STAND_GROUND) self->monsterinfo.stand (self); else self->monsterinfo.run (self); VectorSubtract (self->enemy->s.origin, self->s.origin, vec); self->ideal_yaw = vectoyaw(vec); // wait a while before first attack if (!(self->monsterinfo.aiflags & AI_STAND_GROUND)) AttackFinished (self, 1000); }
BOOL CShambler::MonsterCheckAttack( void ) { if (m_iEnemyRange == RANGE_MELEE) { if (Q_CanDamage (m_hEnemy, this)) { m_iAttackState = ATTACK_MELEE; return TRUE; } } if (gpGlobals->time < m_flAttackFinished) return FALSE; if (!m_fEnemyVisible) return FALSE; // see if any entities are in the way of the shot Vector spot1 = EyePosition(); Vector spot2 = m_hEnemy->EyePosition(); if ((spot1 - spot2).Length() > 600) return FALSE; TraceResult tr; UTIL_TraceLine(spot1, spot2, dont_ignore_monsters, dont_ignore_glass, ENT(pev), &tr); if (tr.fInOpen && tr.fInWater) return FALSE; // sight line crossed contents if (tr.pHit != m_hEnemy->edict()) { return FALSE; // don't have a clear shot } // missile attack if (m_iEnemyRange == RANGE_FAR) return FALSE; m_iAttackState = ATTACK_MISSILE; AttackFinished (2 + RANDOM_FLOAT( 0.0f, 2.0f )); return TRUE; }
void CHellKnight :: CheckForCharge( void ) { // check for mad charge if (!m_fEnemyVisible) return; if (gpGlobals->time < m_flAttackFinished) return; if ( fabs(pev->origin.z - m_hEnemy->pev->origin.z) > 20) return; // too much height change if ( (pev->origin - m_hEnemy->pev->origin).Length() < 80) return; // use regular attack // charge AttackFinished (2); MonsterChargeAttack (); }