void CNPC_Cremator::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_CREMATOR_RANGE_ATTACK1:
		{
			SetActivity( ACT_RANGE_ATTACK1 );

			Vector flEnemyLKP = GetEnemyLKP();
			GetMotor()->SetIdealYawToTargetAndUpdate( flEnemyLKP );

			if( m_iAmmo < 1 && IsActivityFinished() )
			{
				SetCondition( COND_CREMATOR_OUT_OF_AMMO );
								
				DevMsg( "NO PRIMARY AMMO\n" );

				StopParticleEffects(this);
				StopSound( "Weapon_Immolator.Single" );
				EmitSound( "Weapon_Immolator.Stop" );
				
				TaskComplete();
				SetNextThink( gpGlobals->curtime + 0.1f );
			}

			// THIS fixes the combat issue with the Cremator continuing to fire at a target that moved out of his reach
			if( GetEnemyLKP().DistTo( GetAbsOrigin()) > CREMATOR_MAX_RANGE )
			{
				// Cremator stops firing and attempts to close the distance.
				SetActivity( ACT_CREMATOR_DISARM );
				TaskComplete();
				Msg( "Enemy is too far\n" );

				SetNextThink( gpGlobals->curtime + 0.1f );
				return;
			}
	/*		// This is bugged and shouldn't be used. Necessary checks are made below, in OnChangeActivity( ).	
			if( IsActivityMovementPhased( ACT_WALK ) || IsActivityMovementPhased( ACT_RUN ) )
			{
				TaskFail( NULL );
				SetActivity( ACT_CREMATOR_DISARM );
				
				DevMsg( "ACT_CREMATOR_DISARM\n" );
				return;
			}
	*/
			break;
		}
		default:
		BaseClass::RunTask( pTask );
		break;
	}
}
Example #2
0
// make the harvester look at his enemy
bool CASW_Harvester::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval )
{
  	Vector		vecFacePosition = vec3_origin;
	CBaseEntity	*pFaceTarget = NULL;
	bool		bFaceTarget = false;

	if ( GetEnemy() && GetNavigator()->GetMovementActivity() == ACT_RUN )
  	{
		Vector vecEnemyLKP = GetEnemyLKP();
		
		// Only start facing when we're close enough
		if ( ( UTIL_DistApprox( vecEnemyLKP, GetAbsOrigin() ) < 1500 ) )
		{
			vecFacePosition = vecEnemyLKP;
			pFaceTarget = GetEnemy();
			bFaceTarget = true;
		}
	}

	// Face
	if ( bFaceTarget )
	{
		AddFacingTarget( pFaceTarget, vecFacePosition, 1.0, 0.2 );
	}

	return BaseClass::OverrideMoveFacing( move, flInterval );
}
Example #3
0
void CNPC_Infected::RunAttackTask( int task )
{
	AutoMovement( );

	Vector vecEnemyLKP = GetEnemyLKP();

	// If our enemy was killed, but I'm not done animating, the last known position comes
	// back as the origin and makes the me face the world origin if my attack schedule
	// doesn't break when my enemy dies. (sjb)
	if( vecEnemyLKP != vec3_origin )
	{
		if ( ( task == TASK_RANGE_ATTACK1 || task == TASK_RELOAD ) && 
			 ( CapabilitiesGet() & bits_CAP_AIM_GUN ) && 
			 FInAimCone( vecEnemyLKP ) )
		{
			// Arms will aim, so leave body yaw as is
			GetMotor()->SetIdealYawAndUpdate( GetMotor()->GetIdealYaw(), AI_KEEP_YAW_SPEED );
		}
		else
		{
			GetMotor()->SetIdealYawToTargetAndUpdate( vecEnemyLKP, AI_KEEP_YAW_SPEED );
		}
	}

	CAnimationLayer *pPlayer = GetAnimOverlay( m_iAttackLayer );
	if ( pPlayer->m_bSequenceFinished )
	{
		if ( task == TASK_RELOAD && GetShotRegulator() )
		{
			GetShotRegulator()->Reset( false );
		}

		TaskComplete();
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flInterval - 
//-----------------------------------------------------------------------------
void CNPC_WpnScanner::MoveToAttack(float flInterval)
{
	if (GetEnemy() == NULL)
		return;

	if ( flInterval <= 0 )
		return;

	Vector vTargetPos = GetEnemyLKP();
	Vector idealPos = IdealGoalForMovement( vTargetPos, GetAbsOrigin(), GetGoalDistance(), 128 );

	NDebugOverlay::Box( idealPos, -Vector(4,4,4), Vector(4,4,4), 0,255,0,8, 0.1 );

	MoveToTarget( flInterval, idealPos );

	//FIXME: Re-implement?

	/*
	// ---------------------------------------------------------
	//  Add evasion if I have taken damage recently
	// ---------------------------------------------------------
	if ((m_flLastDamageTime + SCANNER_EVADE_TIME) > gpGlobals->curtime)
	{
	vFlyDirection = vFlyDirection + VelocityToEvade(GetEnemyCombatCharacterPointer());
	}
	*/
}
//=========================================================
// RunTask 
//=========================================================
void CNPC_HAssassin::RunTask ( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_ASSASSIN_FALL_TO_GROUND:
		GetMotor()->SetIdealYawAndUpdate( GetEnemyLKP() );

		if ( IsSequenceFinished() )
		{
			if ( GetAbsVelocity().z > 0)
			{
				SetActivity( ACT_ASSASSIN_FLY_UP );
			}
			else if ( HasCondition ( COND_SEE_ENEMY ))
			{
				SetActivity( ACT_ASSASSIN_FLY_ATTACK );
				SetCycle( 0 );
			}
			else
			{
				SetActivity( ACT_ASSASSIN_FLY_DOWN );
				SetCycle( 0 );
			}
						
			ResetSequenceInfo( );
		}

		if ( GetFlags() & FL_ONGROUND)
		{
			TaskComplete( );
		}
		else if( gpGlobals->curtime > m_flWaitFinished || GetAbsVelocity().z == 0.0 )
		{
			// I've waited two seconds and haven't hit the ground. Try to force it.
			trace_t trace;
			UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1 ), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &trace );

			if( trace.DidHitWorld() )
			{
				SetGroundEntity( trace.m_pEnt );
			}
			else
			{
				// Try again in a couple of seconds.
				m_flWaitFinished = gpGlobals->curtime + 2.0f;
			}
		}
		break;
	default: 
		BaseClass::RunTask ( pTask );
		break;
	}
}
Example #6
0
void CNPC_Stalker::UpdateAttackBeam( void )
{
	CBaseEntity *pEnemy = GetEnemy();
	// If not burning at a target 
	if (pEnemy)
	{
		if (gpGlobals->curtime > m_fBeamEndTime)
		{
			TaskComplete();
		}
		else 
		{
			Vector enemyLKP = GetEnemyLKP();
			m_vLaserTargetPos = enemyLKP + pEnemy->GetViewOffset();

			// Face my enemy
			GetMotor()->SetIdealYawToTargetAndUpdate( enemyLKP );

			// ---------------------------------------------
			//	Get beam end point
			// ---------------------------------------------
			Vector vecSrc = LaserStartPosition(GetAbsOrigin());
			Vector targetDir = m_vLaserTargetPos - vecSrc;
			VectorNormalize(targetDir);
			// --------------------------------------------------------
			//	If beam position and laser dir are way off, end attack
			// --------------------------------------------------------
			if ( DotProduct(targetDir,m_vLaserDir) < 0.5 )
			{
				TaskComplete();
				return;
			}

			trace_t tr;
			AI_TraceLine( vecSrc, vecSrc + m_vLaserDir * MAX_STALKER_FIRE_RANGE, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr);
			// ---------------------------------------------
			//  If beam not long enough, stop attacking
			// ---------------------------------------------
			if (tr.fraction == 1.0)
			{
				TaskComplete();
				return;
			}

			CSoundEnt::InsertSound(SOUND_DANGER, tr.endpos, 60, 0.025, this);
		}
	}
	else
	{
		TaskFail(FAIL_NO_ENEMY);
	}
}
Example #7
0
//-----------------------------------------------------------------------------
// TASK_RANGE_ATTACK1 / TASK_RANGE_ATTACK2 / etc.
//-----------------------------------------------------------------------------
void CAI_BaseHumanoid::RunTaskRangeAttack1( const Task_t *pTask )
{
	if ( ( CapabilitiesGet() & bits_CAP_USE_SHOT_REGULATOR ) == 0 )
	{
		BaseClass::RunTask( pTask );
		return;
	}

	AutoMovement( );

	Vector vecEnemyLKP = GetEnemyLKP();

	// If our enemy was killed, but I'm not done animating, the last known position comes
	// back as the origin and makes the me face the world origin if my attack schedule
	// doesn't break when my enemy dies. (sjb)
	if( vecEnemyLKP != vec3_origin )
	{
		if ( ( pTask->iTask == TASK_RANGE_ATTACK1 || pTask->iTask == TASK_RELOAD ) && 
			 ( CapabilitiesGet() & bits_CAP_AIM_GUN ) && 
			 FInAimCone( vecEnemyLKP ) )
		{
			// Arms will aim, so leave body yaw as is
			GetMotor()->SetIdealYawAndUpdate( GetMotor()->GetIdealYaw(), AI_KEEP_YAW_SPEED );
		}
		else
		{
			GetMotor()->SetIdealYawToTargetAndUpdate( vecEnemyLKP, AI_KEEP_YAW_SPEED );
		}
	}

	if ( IsActivityFinished() )
	{
		if ( !GetEnemy() || !GetEnemy()->IsAlive() )
		{
			TaskComplete();
			return;
		}

		if ( !GetShotRegulator()->IsInRestInterval() )
		{
			if ( GetShotRegulator()->ShouldShoot() )
			{
				OnRangeAttack1();
				ResetIdealActivity( ACT_RANGE_ATTACK1 );
			}
			return;
		}
		TaskComplete();
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CAI_RappelBehavior::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
	case TASK_RAPPEL:
		{
			// If we don't do this, the beam won't show up sometimes. Ideally, all beams would update their
			// bboxes correctly, but we're close to shipping and we can't change that now.
			if ( m_hLine )
			{
				m_hLine->RelinkBeam();
			}

			if( GetEnemy() )
			{
				// Face the enemy if there's one.
				Vector vecEnemyLKP = GetEnemyLKP();
				GetOuter()->GetMotor()->SetIdealYawToTargetAndUpdate( vecEnemyLKP );
			}

			SetDescentSpeed();
			if( GetOuter()->GetFlags() & FL_ONGROUND )
			{
				CBaseEntity *pGroundEnt = GetOuter()->GetGroundEntity();

				if( pGroundEnt && pGroundEnt->IsPlayer() )
				{
					// try to shove the player in the opposite direction as they are facing (so they'll see me)
					Vector vecForward;
					pGroundEnt->GetVectors( &vecForward, NULL, NULL );
					pGroundEnt->SetAbsVelocity( vecForward * -500 );
					break;
				}

				GetOuter()->m_OnRappelTouchdown.FireOutput( GetOuter(), GetOuter(), 0 );
				GetOuter()->RemoveFlag( FL_FLY );
				
				CutZipline();

				TaskComplete();
			}
		}
		break;

	default:
		BaseClass::RunTask( pTask );
		break;
	}
}
Example #9
0
void CZombie::GatherConditions( void )
{
	BaseClass::GatherConditions();

	static int conditionsToClear[] = 
	{
		COND_BLOCKED_BY_DOOR,
		COND_DOOR_OPENED,
		COND_ZOMBIE_CHARGE_TARGET_MOVED,
	};

	ClearConditions( conditionsToClear, ARRAYSIZE( conditionsToClear ) );

	if ( m_hBlockingDoor == NULL || 
		 ( m_hBlockingDoor->m_toggle_state == TS_AT_TOP || 
		   m_hBlockingDoor->m_toggle_state == TS_GOING_UP )  )
	{
		ClearCondition( COND_BLOCKED_BY_DOOR );

		if ( m_hBlockingDoor != NULL )
		{
			SetCondition( COND_DOOR_OPENED );
			m_hBlockingDoor = NULL;
		}
	}
	else
		SetCondition( COND_BLOCKED_BY_DOOR );

	if ( ConditionInterruptsCurSchedule( COND_ZOMBIE_CHARGE_TARGET_MOVED ) )
	{
		if ( GetNavigator()->IsGoalActive() )
		{
			const float CHARGE_RESET_TOLERANCE = 60.0;
			if ( !GetEnemy() ||
				 ( m_vPositionCharged - GetEnemyLKP()  ).Length() > CHARGE_RESET_TOLERANCE )
			{
				SetCondition( COND_ZOMBIE_CHARGE_TARGET_MOVED );
			}
				 
		}
	}
}
Example #10
0
//=========================================================
// RunTask 
//=========================================================
void CNPC_Houndeye::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_HOUND_THREAT_DISPLAY:
		{
			GetMotor()->SetIdealYawToTargetAndUpdate( GetEnemyLKP(), AI_KEEP_YAW_SPEED );

			if ( IsActivityFinished() )
			{
				TaskComplete();
			}
			
			break;
		}
	case TASK_HOUND_CLOSE_EYE:
		{
			/*//<<TEMP>>
			if ( pev->skin < HOUNDEYE_EYE_FRAMES - 1 )
			{
				pev->skin++;
			}
			*/
			break;
		}
	case TASK_HOUND_HOP_BACK:
		{
			if ( IsActivityFinished() )
			{
				TaskComplete();
			}
			break;
		}
	default:
		{
			BaseClass::RunTask(pTask);
			break;
		}
	}
}
Example #11
0
//-----------------------------------------------------------------------------
// Purpose:
// Input  : *pTask -
//-----------------------------------------------------------------------------
void CAI_RappelBehavior::RunTask( const Task_t *pTask )
{
    switch( pTask->iTask )
    {
    case TASK_RAPPEL:
    {
        // If we don't do this, the beam won't show up sometimes. Ideally, all beams would update their
        // bboxes correctly, but we're close to shipping and we can't change that now.
        if ( m_hLine )
        {
            m_hLine->RelinkBeam();
        }

        if( GetEnemy() )
        {
            // Face the enemy if there's one.
            Vector vecEnemyLKP = GetEnemyLKP();
            GetOuter()->GetMotor()->SetIdealYawToTargetAndUpdate( vecEnemyLKP );
        }

        SetDescentSpeed();
        if( GetOuter()->GetFlags() & FL_ONGROUND )
        {
            GetOuter()->m_OnRappelTouchdown.FireOutput( GetOuter(), GetOuter(), 0 );
            GetOuter()->RemoveFlag( FL_FLY );

            CutZipline();

            TaskComplete();
        }
    }
    break;

    default:
        BaseClass::RunTask( pTask );
        break;
    }
}
//-----------------------------------------------------------------------------
// 
//-----------------------------------------------------------------------------
void CNPC_Cremator::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_CREMATOR_IDLE:
		{
			SetActivity( ACT_IDLE );
			if( IsActivityFinished() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_CREMATOR_RANGE_ATTACK1:
		{
			Vector flEnemyLKP = GetEnemyLKP();
			GetMotor()->SetIdealYawToTarget( flEnemyLKP );
			break;
		}
		default:
		BaseClass::StartTask( pTask );
		break;
	}
}
//=========================================================
// Hornet is flying, gently tracking target
//=========================================================
void CNPC_Hornet::TrackTarget ( void )
{
	Vector	vecFlightDir;
	Vector	vecDirToEnemy;
	float	flDelta;
	Vector  vecEnemyLKP;

	StudioFrameAdvance( );

	if (gpGlobals->curtime > m_flStopAttack)
	{
		SetTouch( NULL );
		SetThink( SUB_Remove );
		SetNextThink( gpGlobals->curtime + 0.1f );
		return;
	}

	// UNDONE: The player pointer should come back after returning from another level
	if ( GetEnemy() == NULL )
	{// enemy is dead.
		GetSenses()->Look( 512 );
		SetEnemy( BestEnemy() );
	}
	
	if ( GetEnemy() != NULL && FVisible( GetEnemy() ))
	{
		vecEnemyLKP = GetEnemy()->BodyTarget( GetAbsOrigin() );
	}
	else
	{
		vecEnemyLKP = GetEnemyLKP() + GetAbsVelocity() * m_flFlySpeed * 0.1;
	}

	vecDirToEnemy = vecEnemyLKP - GetAbsOrigin();
	VectorNormalize( vecDirToEnemy );

	if ( GetAbsVelocity().Length() < 0.1 )
		vecFlightDir = vecDirToEnemy;
	else 
	{
		vecFlightDir = GetAbsVelocity();
		VectorNormalize( vecFlightDir );
	}

	SetAbsVelocity( vecFlightDir + vecDirToEnemy );

	// measure how far the turn is, the wider the turn, the slow we'll go this time.
	flDelta = DotProduct ( vecFlightDir, vecDirToEnemy );
	
	if ( flDelta < 0.5 )
	{// hafta turn wide again. play sound
		CPASAttenuationFilter filter( this );
		switch (random->RandomInt(0,2))
		{
		case 0:	enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "hornet/ag_buzz1.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
		case 1:	enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "hornet/ag_buzz2.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
		case 2:	enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "hornet/ag_buzz3.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
		}
	}

	if ( flDelta <= 0 && m_iHornetType == HORNET_TYPE_RED )
	{// no flying backwards, but we don't want to invert this, cause we'd go fast when we have to turn REAL far.
		flDelta = 0.25;
	}

	Vector vecVel = GetAbsVelocity();
	VectorNormalize( vecVel );

	if ( GetOwnerEntity() && (GetOwnerEntity()->GetFlags() & FL_NPC) )
	{
		// random pattern only applies to hornets fired by monsters, not players. 

		vecVel.x += random->RandomFloat ( -0.10, 0.10 );// scramble the flight dir a bit.
		vecVel.y += random->RandomFloat ( -0.10, 0.10 );
		vecVel.z += random->RandomFloat ( -0.10, 0.10 );
	}

	SetAbsVelocity( vecVel );
	
	switch ( m_iHornetType )
	{
		case HORNET_TYPE_RED:
			SetAbsVelocity( GetAbsVelocity() * ( m_flFlySpeed * flDelta ) );// scale the dir by the ( speed * width of turn )
			SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.3 ) );
			break;
		case HORNET_TYPE_ORANGE:
			SetAbsVelocity( GetAbsVelocity() * m_flFlySpeed );// do not have to slow down to turn.
			SetNextThink( gpGlobals->curtime + 0.1f );// fixed think time
			break;
	}

	QAngle angNewAngles;
	VectorAngles( GetAbsVelocity(), angNewAngles );
	SetAbsAngles( angNewAngles );
	
	SetSolid( SOLID_BBOX );

	// if hornet is close to the enemy, jet in a straight line for a half second.
	// (only in the single player game)
	if ( GetEnemy() != NULL && !g_pGameRules->IsMultiplayer() )
	{
		if ( flDelta >= 0.4 && ( GetAbsOrigin() - vecEnemyLKP ).Length() <= 300 )
		{
			CPVSFilter filter( GetAbsOrigin() );
			te->Sprite( filter, 0.0,
				&GetAbsOrigin(), // pos
				iHornetPuff,	// model
				0.2,				//size
				128				// brightness
			);

			CPASAttenuationFilter filter2( this );
			switch ( random->RandomInt(0,2))
			{
			case 0:	enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "hornet/ag_buzz1.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
			case 1:	enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "hornet/ag_buzz2.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
			case 2:	enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "hornet/ag_buzz3.wav", HORNET_BUZZ_VOLUME, ATTN_NORM );	break;
			}
			SetAbsVelocity( GetAbsVelocity() * 2 );
			SetNextThink( gpGlobals->curtime + 1.0f );
			// don't attack again
			m_flStopAttack = gpGlobals->curtime;
		}
	}
}
Example #14
0
//=========================================================
// CheckRangeAttack1
//=========================================================
bool CNPC_HL1Barney::CheckRangeAttack1 ( float flDot, float flDist )
{
	if ( gpGlobals->curtime > m_flCheckAttackTime )
	{
		trace_t tr;
		
		Vector shootOrigin = GetAbsOrigin() + Vector( 0, 0, 55 );
		CBaseEntity *pEnemy = GetEnemy();
		Vector shootTarget = ( (pEnemy->BodyTarget( shootOrigin ) - pEnemy->GetAbsOrigin()) + GetEnemyLKP() );
		
		UTIL_TraceLine ( shootOrigin, shootTarget, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
		m_flCheckAttackTime = gpGlobals->curtime + 1;
		if ( tr.fraction == 1.0 || ( tr.m_pEnt != NULL && tr.m_pEnt == pEnemy) )
			m_fLastAttackCheck = TRUE;
		else
			m_fLastAttackCheck = FALSE;

		m_flCheckAttackTime = gpGlobals->curtime + 1.5;
	}
	
	return m_fLastAttackCheck;
}
// Здесь происходит назначение различных ф-ций во время анимации. Аним-ивенты назначаются в .qc.
void CNPC_Cremator::HandleAnimEvent( animevent_t *pEvent )
{
	switch( pEvent->event )
	{
		case CREMATOR_AE_FLLEFT: // левый шаг
			{	
				LeftFootHit( pEvent->eventtime );
			}
			break;

		case CREMATOR_AE_FLRIGHT: // правый шаг
			{				
				RightFootHit( pEvent->eventtime );
			}
			break;

		case CREMATOR_AE_IMMO_START: // начало анимации атаки
			{
				//CBaseEntity *pEntity;

				DispatchSpray( this );
				DevMsg( "%i ammo left\n", m_iAmmo );

				Vector flEnemyLKP = GetEnemyLKP();
				GetMotor()->SetIdealYawToTargetAndUpdate( flEnemyLKP );
			}
			break;

		case CREMATOR_AE_IMMO_PARTICLE: // Маркер для запуска системы частиц огнемета
			{				
				DispatchParticleEffect( "flamethrower", PATTACH_POINT_FOLLOW, this, "muzzle" ); 
				// Если нужно заменить зеленый огонь оранжевым, замени "flamethrower" на "flamethrower_orange".
				EmitSound( "Weapon_Immolator.Single" );
			}
			break;

		case CREMATOR_AE_IMMO_PARTICLEOFF: // Маркер для отключения системы частиц огнемета
			{				
				StopParticleEffects( this );
				StopSound( "Weapon_Immolator.Single" );
				EmitSound( "Weapon_Immolator.Stop" );
			}
			break;

		case CREMATOR_AE_RELOAD:
			{
				ClearCondition( COND_CREMATOR_OUT_OF_AMMO );
				ClearCondition( COND_NO_PRIMARY_AMMO );
				m_iAmmo += 54; // Put your own int here. This defines for how long a cremator would be able to fire at an enemy.
				
				DevMsg( "AE_RELOAD\n" );
			}
			break;

		case CREMATOR_AE_THROWGRENADE: // Маркер для броска гранаты
			{				
				DevMsg( "Throwing incendiary grenade!\n" );
				ThrowIncendiaryGrenade();

				if( g_pGameRules->IsSkillLevel(SKILL_EASY) )
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 15.0f, 30.0f );
				}
				else if( g_pGameRules->IsSkillLevel(SKILL_HARD) )
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 5.0f, 10.0f );
				}
				else if (g_pGameRules->IsSkillLevel(SKILL_VERYHARD))
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat(3.0f, 5.0f);
				}
				else if (g_pGameRules->IsSkillLevel(SKILL_NIGHTMARE))
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat(1.0f, 3.0f);
				}
				else
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 10.0f, 20.0f );
				}
			}
			break;

		default:
			BaseClass::HandleAnimEvent( pEvent );
			break;
	}
}
Example #16
0
//=========================================================
// start task
//=========================================================
void CNPC_Stalker::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_STALKER_SCREAM:
	{
		if( gpGlobals->curtime > m_flNextScreamTime )
		{
			EmitSound( "NPC_Stalker.Scream" );
			m_flNextScreamTime = gpGlobals->curtime + random->RandomFloat( 10.0, 15.0 );
		}

		TaskComplete();
	}

	case TASK_ANNOUNCE_ATTACK:
	{
		// If enemy isn't facing me and I haven't attacked in a while
		// annouce my attack before I start wailing away
		CBaseCombatCharacter *pBCC = GetEnemyCombatCharacterPointer();

		if	(pBCC && (!pBCC->FInViewCone ( this )) &&
			 (gpGlobals->curtime - m_flLastAttackTime > 1.0) )
		{
				m_flLastAttackTime = gpGlobals->curtime;

				// Always play this sound
				EmitSound( "NPC_Stalker.Scream" );
				m_flNextScrambleSoundTime = gpGlobals->curtime + 2;
				m_flNextBreatheSoundTime = gpGlobals->curtime + 2;

				// Wait two seconds
				SetWait( 2.0 );
				SetActivity(ACT_IDLE);
		}
		break;
	}
	case TASK_STALKER_ZIGZAG:
			break;
	case TASK_RANGE_ATTACK1:
		{
			CBaseEntity *pEnemy = GetEnemy();
			if (pEnemy)
			{
				m_vLaserTargetPos = GetEnemyLKP() + pEnemy->GetViewOffset();

				// Never hit target on first try
				Vector missPos = m_vLaserTargetPos;
				
				if( pEnemy->Classify() == CLASS_BULLSEYE && hl2_episodic.GetBool() )
				{
					missPos.x += 60 + 120*random->RandomInt(-1,1);
					missPos.y += 60 + 120*random->RandomInt(-1,1);
				}
				else
				{
					missPos.x += 80*random->RandomInt(-1,1);
					missPos.y += 80*random->RandomInt(-1,1);
				}

				// ----------------------------------------------------------------------
				// If target is facing me and not running towards me shoot below his feet
				// so he can see the laser coming
				// ----------------------------------------------------------------------
				CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(pEnemy);
				if (pBCC)
				{
					Vector targetToMe = (pBCC->GetAbsOrigin() - GetAbsOrigin());
					Vector vBCCFacing = pBCC->BodyDirection2D( );
					if ((DotProduct(vBCCFacing,targetToMe) < 0) &&
						(pBCC->GetSmoothedVelocity().Length() < 50))
					{
						missPos.z -= 150;
					}
					// --------------------------------------------------------
					// If facing away or running towards laser,
					// shoot above target's head 
					// --------------------------------------------------------
					else
					{
						missPos.z += 60;
					}
				}
				m_vLaserDir = missPos - LaserStartPosition(GetAbsOrigin());
				VectorNormalize(m_vLaserDir);	
			}
			else
			{
				TaskFail(FAIL_NO_ENEMY);
				return;
			}

			StartAttackBeam();
			SetActivity(ACT_RANGE_ATTACK1);
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_LOS:
		{
			if ( GetEnemy() != NULL )
			{
				BaseClass:: StartTask( pTask );
				return;
			}

			Vector posLos;

			if (GetTacticalServices()->FindLos(m_vLaserCurPos, m_vLaserCurPos, MIN_STALKER_FIRE_RANGE, MAX_STALKER_FIRE_RANGE, 1.0, &posLos))
			{
				AI_NavGoal_t goal( posLos, ACT_RUN, AIN_HULL_TOLERANCE );
				GetNavigator()->SetGoal( goal );
			}
			else
			{
				TaskFail(FAIL_NO_SHOOT);
			}
			break;
		}
	case TASK_FACE_ENEMY:
		{
			if ( GetEnemy() != NULL )
			{
				BaseClass:: StartTask( pTask );
				return;
			}
			GetMotor()->SetIdealYawToTarget( m_vLaserCurPos );
			break;
		}
	default: 
		BaseClass:: StartTask( pTask );
		break;
	}
}
Example #17
0
//=========================================================
// start task
//=========================================================
void CNPC_Houndeye::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_HOUND_GET_PATH_TO_CIRCLE:
	{
		if (GetEnemy() == NULL)
		{
			TaskFail(FAIL_NO_ENEMY);
		}
		else 
		{
			Vector vTargetPos = GetEnemyLKP();
			vTargetPos.z	= GetFloorZ(vTargetPos);

			if (GetNavigator()->SetRadialGoal(vTargetPos, random->RandomInt(50,500), 90, 175, m_bLoopClockwise))
			{
				TaskComplete();
				return;
			}
			TaskFail(FAIL_NO_ROUTE);
		}
		break;
	}
	case TASK_HOUND_REVERSE_STRAFE_DIR:
	{
		// Try the other direction
		m_bLoopClockwise = (m_bLoopClockwise) ? false : true;
		TaskComplete();
		break;
	}

	// Override to set appropriate distances
	case TASK_GET_PATH_TO_ENEMY_LOS:
	{
		float			flMaxRange	= HOUNDEYE_MAX_ATTACK_RADIUS * 0.9;
		float			flMinRange	= HOUNDEYE_MIN_ATTACK_RADIUS;
		Vector 			posLos;
		bool			foundLos	= false;
		
		if (GetEnemy() != NULL)
		{
			foundLos = GetTacticalServices()->FindLos(GetEnemyLKP(),GetEnemy()->EyePosition(), flMinRange, flMaxRange, 0.0, &posLos);
		}
		else
		{
			TaskFail(FAIL_NO_TARGET);
			return;
		}

		if (foundLos)
		{
			GetNavigator()->SetGoal( AI_NavGoal_t( posLos, ACT_RUN, AIN_HULL_TOLERANCE ) );
		}
		else
		{
			TaskFail(FAIL_NO_SHOOT);
		}
		break;
	}

	case TASK_HOUND_FALL_ASLEEP:
		{
			m_fAsleep = true; // signal that hound is lying down (must stand again before doing anything else!)
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_WAKE_UP:
		{
			m_fAsleep = false; // signal that hound is standing again
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_OPEN_EYE:
		{
			m_fDontBlink = false; // turn blinking back on and that code will automatically open the eye
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_CLOSE_EYE:
		{
//<<TEMP>>			pev->skin = 0;
			m_fDontBlink = true; // tell blink code to leave the eye alone.
			break;
		}
	case TASK_HOUND_THREAT_DISPLAY:
		{
			SetIdealActivity( ACT_IDLE_ANGRY );
			break;
		}
	case TASK_HOUND_HOP_BACK:
		{
			SetIdealActivity( ACT_LEAP );
			break;
		}
	case TASK_RANGE_ATTACK1:
		{
			SetIdealActivity( ACT_RANGE_ATTACK1 );
			break;
		}
	default: 
		{
			BaseClass::StartTask(pTask);
			break;
		}
	}
}
Example #18
0
void CNPC_AlienGrunt::StartTask ( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_AGRUNT_RANGE_ATTACK1_NOTURN:
		{
			SetLastAttackTime( gpGlobals->curtime );
			ResetIdealActivity( ACT_RANGE_ATTACK1 );
		}
		break;

	case TASK_AGRUNT_GET_PATH_TO_ENEMY_CORPSE:
		{
			Vector forward;
			AngleVectors( GetAbsAngles(), &forward );
			Vector flEnemyLKP = GetEnemyLKP();

			GetNavigator()->SetGoal( flEnemyLKP - forward * 64, AIN_CLEAR_TARGET);

			if ( GetNavigator()->SetGoal( flEnemyLKP - forward * 64, AIN_CLEAR_TARGET) )
			{
				TaskComplete();
			}
			else
			{
				Msg ( "AGruntGetPathToEnemyCorpse failed!!\n" );
				TaskFail( FAIL_NO_ROUTE );
			}
		}
		break;

	case TASK_AGRUNT_SETUP_HIDE_ATTACK:
		// alien grunt shoots hornets back out into the open from a concealed location. 
		// try to find a spot to throw that gives the smart weapon a good chance of finding the enemy.
		// ideally, this spot is along a line that is perpendicular to a line drawn from the agrunt to the enemy.

		CHL1BaseNPC	*pEnemyMonsterPtr;

		pEnemyMonsterPtr = (CHL1BaseNPC *)GetEnemy()->MyNPCPointer();

		if ( pEnemyMonsterPtr )
		{
			Vector		vecCenter, vForward, vRight, vecEnemyLKP;
			QAngle		angTmp;
			trace_t		tr;
			BOOL		fSkip;

			fSkip = FALSE;
			vecCenter = WorldSpaceCenter();
			vecEnemyLKP = GetEnemyLKP();

			VectorAngles( vecEnemyLKP - GetAbsOrigin(), angTmp );
			SetAbsAngles( angTmp );
			AngleVectors( GetAbsAngles(), &vForward, &vRight, NULL );

			UTIL_TraceLine( WorldSpaceCenter() + vForward * 128, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
			if ( tr.fraction == 1.0 )
			{
				GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() + vRight * 128 );
				fSkip = TRUE;
				TaskComplete();
			}
			
			if ( !fSkip )
			{
				UTIL_TraceLine( WorldSpaceCenter() - vForward * 128, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
				if ( tr.fraction == 1.0 )
				{
					GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() - vRight * 128 );
					fSkip = TRUE;
					TaskComplete();
				}
			}
			
			if ( !fSkip )
			{
				UTIL_TraceLine( WorldSpaceCenter() + vForward * 256, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
				if ( tr.fraction == 1.0 )
				{
					GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() + vRight * 256 );
					fSkip = TRUE;
					TaskComplete();
				}
			}
			
			if ( !fSkip )
			{
				UTIL_TraceLine( WorldSpaceCenter() - vForward * 256, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
				if ( tr.fraction == 1.0 )
				{
					GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() - vRight * 256 );
					fSkip = TRUE;
					TaskComplete();
				}
			}
			
			if ( !fSkip )
			{
				TaskFail( FAIL_NO_COVER );
			}
		}
		else
		{
			Msg ( "AGRunt - no enemy monster ptr!!!\n" );
			TaskFail( FAIL_NO_ENEMY );
		}
		break;

	default:
		BaseClass::StartTask ( pTask );
		break;
	}
}
Example #19
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CFastZombie::StartTask( const Task_t *pTask )
{
    switch( pTask->iTask )
    {
    case TASK_FASTZOMBIE_VERIFY_ATTACK:
        // Simply ensure that the zombie still has a valid melee attack
        if( HasCondition( COND_CAN_MELEE_ATTACK1 ) )
        {
            TaskComplete();
        }
        else
        {
            TaskFail("");
        }
        break;

    case TASK_FASTZOMBIE_JUMP_BACK:
    {
        SetActivity( ACT_IDLE );

        RemoveFlag( FL_ONGROUND );

        BeginAttackJump();

        Vector forward;
        AngleVectors( GetLocalAngles(), &forward );

        //
        // Take him off ground so engine doesn't instantly reset FL_ONGROUND.
        //
        UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 ));

        ApplyAbsVelocityImpulse( forward * -200 + Vector( 0, 0, 200 ) );
    }
    break;

    case TASK_FASTZOMBIE_UNSTICK_JUMP:
    {
        RemoveFlag( FL_ONGROUND );

        // Call begin attack jump. A little bit later if we fail to pathfind, we check
        // this value to see if we just jumped. If so, we assume we've jumped
        // to someplace that's not pathing friendly, and so must jump again to get out.
        BeginAttackJump();

        //
        // Take him off ground so engine doesn't instantly reset FL_ONGROUND.
        //
        UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 ));

        CBaseEntity *pEnemy = GetEnemy();
        Vector vecJumpDir;

        if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN )
        {
            // Jump off the pipe backwards!
            Vector forward;

            GetVectors( &forward, NULL, NULL );

            ApplyAbsVelocityImpulse( forward * -200 );
        }
        else if( pEnemy )
        {
            vecJumpDir = pEnemy->GetLocalOrigin() - GetLocalOrigin();
            VectorNormalize( vecJumpDir );
            vecJumpDir.z = 0;

            ApplyAbsVelocityImpulse( vecJumpDir * 300 + Vector( 0, 0, 200 ) );
        }
        else
        {
            Msg("UNHANDLED CASE! Stuck Fast Zombie with no enemy!\n");
        }
    }
    break;

    case TASK_WAIT_FOR_MOVEMENT:
        // If we're waiting for movement, that means that pathfinding succeeded, and
        // we're about to be moving. So we aren't stuck. So clear this flag.
        m_fJustJumped = false;

        BaseClass::StartTask( pTask );
        break;

    case TASK_FACE_ENEMY:
    {
        // We don't use the base class implementation of this, because GetTurnActivity
        // stomps our landing scrabble animations (sjb)
        Vector flEnemyLKP = GetEnemyLKP();
        GetMotor()->SetIdealYawToTarget( flEnemyLKP );
    }
    break;

    case TASK_FASTZOMBIE_LAND_RECOVER:
    {
        // Set the ideal yaw
        Vector flEnemyLKP = GetEnemyLKP();
        GetMotor()->SetIdealYawToTarget( flEnemyLKP );

        // figure out which way to turn.
        float flDeltaYaw = GetMotor()->DeltaIdealYaw();

        if( flDeltaYaw < 0 )
        {
            SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_RIGHT );
        }
        else
        {
            SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_LEFT );
        }


        TaskComplete();
    }
    break;

    case TASK_RANGE_ATTACK1:

        // Make melee attacks impossible until we land!
        m_flNextMeleeAttack = gpGlobals->curtime + 60;

        SetTouch( LeapAttackTouch );
        break;

    case TASK_FASTZOMBIE_DO_ATTACK:
        SetActivity( (Activity)ACT_FASTZOMBIE_LEAP_SOAR );
        break;

    default:
        BaseClass::StartTask( pTask );
        break;
    }
}