//========================================================= // RunTask //========================================================= void CNPC_Controller::RunTask ( const Task_t *pTask ) { if (m_flShootEnd > gpGlobals->curtime) { Vector vecHand; QAngle vecAngle; GetAttachment( 2, vecHand, vecAngle ); while (m_flShootTime < m_flShootEnd && m_flShootTime < gpGlobals->curtime) { Vector vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime); Vector vecDir; if (GetEnemy() != NULL) { if (HasCondition( COND_SEE_ENEMY )) { m_vecEstVelocity = m_vecEstVelocity * 0.5 + GetEnemy()->GetAbsVelocity() * 0.5; } else { m_vecEstVelocity = m_vecEstVelocity * 0.8; } vecDir = Intersect( vecSrc, GetEnemy()->BodyTarget( GetAbsOrigin() ), m_vecEstVelocity, sk_controller_speedball.GetFloat() ); float delta = 0.03490; // +-2 degree vecDir = vecDir + Vector( random->RandomFloat( -delta, delta ), random->RandomFloat( -delta, delta ), random->RandomFloat( -delta, delta ) ) * sk_controller_speedball.GetFloat(); vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime); CAI_BaseNPC *pBall = (CAI_BaseNPC*)Create( "controller_energy_ball", vecSrc, GetAbsAngles(), this ); pBall->SetAbsVelocity( vecDir ); // DevMsg( 2, "controller shooting energy ball\n" ); } m_flShootTime += 0.2; } if (m_flShootTime > m_flShootEnd) { m_iBall[0] = 64; m_iBallTime[0] = m_flShootEnd; m_iBall[1] = 64; m_iBallTime[1] = m_flShootEnd; m_fInCombat = FALSE; } } switch ( pTask->iTask ) { case TASK_WAIT_FOR_MOVEMENT: case TASK_WAIT: case TASK_WAIT_FACE_ENEMY: case TASK_WAIT_PVS: { if( GetEnemy() ) { float idealYaw = UTIL_VecToYaw( GetEnemy()->GetAbsOrigin() - GetAbsOrigin() ); GetMotor()->SetIdealYawAndUpdate( idealYaw ); } if ( IsSequenceFinished() || GetActivity() == ACT_IDLE) { m_fInCombat = false; } BaseClass::RunTask ( pTask ); if (!m_fInCombat) { if( HasCondition( COND_CAN_RANGE_ATTACK1 )) { SetActivity( ACT_RANGE_ATTACK1 ); SetCycle( 0 ); ResetSequenceInfo( ); m_fInCombat = true; } else if( HasCondition( COND_CAN_RANGE_ATTACK2 ) ) { SetActivity( ACT_RANGE_ATTACK2 ); SetCycle( 0 ); ResetSequenceInfo( ); m_fInCombat = true; } else { int iFloatActivity = LookupFloat(); if( IsSequenceFinished() || iFloatActivity != GetActivity() ) { SetActivity( (Activity)iFloatActivity ); } } } } break; default: BaseClass::RunTask ( pTask ); break; } }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. //========================================================= void CNPC_Controller::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { case CONTROLLER_AE_HEAD_OPEN: { Vector vecStart; QAngle angleGun; GetAttachment( 0, vecStart, angleGun ); // BUGBUG - attach to attachment point! CBroadcastRecipientFilter filter; te->DynamicLight( filter, 0.0, &vecStart, 255, 192, 64, 0, 1 /*radius*/, 0.2, -32 ); m_iBall[0] = 192; m_iBallTime[0] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; m_iBall[1] = 255; m_iBallTime[1] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; } break; case CONTROLLER_AE_BALL_SHOOT: { Vector vecStart; QAngle angleGun; GetAttachment( 1, vecStart, angleGun ); CBroadcastRecipientFilter filter; te->DynamicLight( filter, 0.0, &vecStart, 255, 192, 64, 0, 1 /*radius*/, 0.1, 32 ); CAI_BaseNPC *pBall = (CAI_BaseNPC*)Create( "controller_head_ball", vecStart, angleGun ); pBall->SetAbsVelocity( Vector(0,0,32) ); pBall->SetEnemy( GetEnemy() ); // DevMsg( 1, "controller shooting head ball\n" ); m_iBall[0] = 0; m_iBall[1] = 0; } break; case CONTROLLER_AE_SMALL_SHOOT: { AttackSound( ); m_flShootTime = gpGlobals->curtime; m_flShootEnd = m_flShootTime + atoi( pEvent->options ) / 15.0; } break; case CONTROLLER_AE_POWERUP_FULL: { m_iBall[0] = 255; m_iBallTime[0] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; m_iBall[1] = 255; m_iBallTime[1] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; } break; case CONTROLLER_AE_POWERUP_HALF: { m_iBall[0] = 192; m_iBallTime[0] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; m_iBall[1] = 192; m_iBallTime[1] = gpGlobals->curtime + atoi( pEvent->options ) / 15.0; } break; default: BaseClass::HandleAnimEvent( pEvent ); break; } }