Пример #1
0
Vector CNPC_Hydra::TestPosition( float t )
{
	// return GetAbsOrigin( ) + Vector( sin( (m_seed + t) * 2.3 ) * 15, cos( (m_seed + t) * 2.4 ) * 150, sin( ( m_seed + t ) * 1.8 ) * 50 ) + m_vecOutward * sv_hydraLength.GetFloat();;
	t = (int)(t * 0.2);
#if 1
	Vector tmp = Vector( sin( (m_seed + t) * 0.8 ) * 15, cos( (m_seed + t) * 0.9 ) * 150, sin( ( m_seed + t ) * 0.4 ) * 50 );
	tmp += 	Vector( sin( (m_seed + t) * 1.0 ) * 4, cos( (m_seed + t) * 0.9 ) * 4, sin( ( m_seed + t ) * 1.1 ) * 6 );
	tmp += 	GetAbsOrigin( ) + m_vecOutward * sv_hydraLength.GetFloat();
	return tmp;
#else
	
	Vector tmp;
	tmp.Init;
	CBaseEntity *pPlayer = (CBaseEntity *)UTIL_GetLocalPlayer();
	if ( pPlayer )
	{
		tmp = pPlayer->EyePosition( );

		Vector delta = (tmp - GetAbsOrigin( ));
		
		if (delta.Length() > 200)
		{
			tmp = GetAbsOrigin( ) + Vector( 0, 0, 200 );
		}
		m_vecHeadDir = (pPlayer->EyePosition( ) - m_body[m_body.Count()-2].vecPos);
		VectorNormalize( m_vecHeadDir );
	}

	return tmp;
#endif
		// m_vecHeadGoal = GetAbsOrigin( ) + Vector( sin( gpGlobals->curtime * 0.3 ) * 15, cos( gpGlobals->curtime * 0.4 ) * 150, sin( gpGlobals->curtime * 0.2 ) * 50 + dt );
}
Пример #2
0
//---------------------------------------------------------
//---------------------------------------------------------
bool CAI_FreePass::ShouldAllowFVisible(bool bBaseResult )
{
	CBaseEntity *	pTarget 	= GetPassTarget();
	AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget );
	
	if ( !bBaseResult || HasPass() )
		return false;
		
	bool bIsVisible = true;
		
	// Peek logic
	if ( m_Params.peekTime > 0.1 )
	{
		float lastTimeSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME;
		float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME;
		
		if ( ( lastTimeSeen == AI_INVALID_TIME || gpGlobals->curtime - lastTimeSeen > m_Params.peekTime ) &&
			 ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.peekTimeAfterDamage ) )
		{
			Vector vToTarget;

			VectorSubtract( pTarget->EyePosition(), GetOuter()->EyePosition(), vToTarget );
			vToTarget.z = 0.0f;
			VectorNormalize( vToTarget );

			Vector vecRight( -vToTarget.y, vToTarget.x, 0.0f );
			trace_t	tr;

			UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_OPAQUE, GetOuter(), COLLISION_GROUP_NONE, &tr );
			if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget )
			{
				if ( free_pass_peek_debug.GetBool() )
					NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 );
				bIsVisible = false;
			}
			
			if ( bIsVisible )
			{
				UTIL_TraceLine( GetOuter()->EyePosition(), pTarget->EyePosition() + (-vecRight * m_Params.peekEyeDist - Vector( 0, 0, m_Params.peekEyeDistZ )), MASK_OPAQUE, GetOuter(), COLLISION_GROUP_NONE, &tr );
				if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget )
				{
					if ( free_pass_peek_debug.GetBool() )
						NDebugOverlay::Line( tr.startpos, tr.endpos - Vector( 0, 0, 2), 0, 255, 0, false, 0.1 );
					bIsVisible = false;
				}
			}
		}
		
		if ( bIsVisible && free_pass_peek_debug.GetBool() )
			NDebugOverlay::Line( GetOuter()->EyePosition(), pTarget->EyePosition() - Vector( 0, 0, 2), 255, 0, 0, false, 0.1 );
	}

	return bIsVisible;
}
Пример #3
0
Vector CCalcPosition::CalcPosition( CBaseEntity *pLocus )
{
	CBaseEntity *pSubject = UTIL_FindEntityByTargetname(NULL, STRING(pev->netname), pLocus);

	Vector vecOffset = CalcLocus_Velocity( this, pLocus, STRING(pev->message));

	Vector vecPosition;
	Vector vecJunk;

	Vector vecResult;
	switch (pev->impulse)
	{
	case 1: //eyes
		vecResult = vecOffset + pSubject->EyePosition();
		//ALERT(at_console, "calc_subpos returns %f %f %f\n", vecResult.x, vecResult.y, vecResult.z);
		return vecResult;
		//return vecOffset + pLocus->EyePosition();
	case 2: // top
		return vecOffset + pSubject->pev->origin + Vector(
			(pSubject->pev->mins.x + pSubject->pev->maxs.x)/2,
			(pSubject->pev->mins.y + pSubject->pev->maxs.y)/2,
			pSubject->pev->maxs.z
		);
	case 3: // centre
		return vecOffset + pSubject->pev->origin + Vector(
			(pSubject->pev->mins.x + pSubject->pev->maxs.x)/2,
			(pSubject->pev->mins.y + pSubject->pev->maxs.y)/2,
			(pSubject->pev->mins.z + pSubject->pev->maxs.z)/2
		);
	case 4: // bottom
		return vecOffset + pSubject->pev->origin + Vector(
			(pSubject->pev->mins.x + pSubject->pev->maxs.x)/2,
			(pSubject->pev->mins.y + pSubject->pev->maxs.y)/2,
			pSubject->pev->mins.z
		);
	case 5:
		// this could cause problems.
		// is there a good way to check whether it's really a CBaseAnimating?
		((CBaseAnimating*)pSubject)->GetAttachment( 0, vecPosition, vecJunk );
		return vecOffset + vecPosition;
	case 6:
		((CBaseAnimating*)pSubject)->GetAttachment( 1, vecPosition, vecJunk );
		return vecOffset + vecPosition;
	case 7:
		((CBaseAnimating*)pSubject)->GetAttachment( 2, vecPosition, vecJunk );
		return vecOffset + vecPosition;
	case 8:
		((CBaseAnimating*)pSubject)->GetAttachment( 3, vecPosition, vecJunk );
		return vecOffset + vecPosition;
	case 9:
		return vecOffset + pSubject->pev->origin + Vector(
			RANDOM_FLOAT(pSubject->pev->mins.x, pSubject->pev->maxs.x),
			RANDOM_FLOAT(pSubject->pev->mins.y, pSubject->pev->maxs.y),
			RANDOM_FLOAT(pSubject->pev->mins.z, pSubject->pev->maxs.z)
		);
	default:
		return vecOffset + pSubject->pev->origin;
	}
}
Пример #4
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponMedigun::MaintainTargetInSlot()
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() );
	if ( !pOwner )
		return;

	CBaseEntity *pTarget = m_hHealingTarget;
	Assert( pTarget );

	// Make sure the guy didn't go out of range.
	bool bLostTarget = true;
	Vector vecSrc = pOwner->Weapon_ShootPosition( );
	Vector vecTargetPoint = pTarget->WorldSpaceCenter();
	Vector vecPoint;

	// If it's brush built, use absmins/absmaxs
	pTarget->CollisionProp()->CalcNearestPoint( vecSrc, &vecPoint );

	float flDistance = (vecPoint - vecSrc).Length();
	if ( flDistance < GetStickRange() )
	{
		if ( m_flNextTargetCheckTime > gpGlobals->curtime )
			return;

		m_flNextTargetCheckTime = gpGlobals->curtime + 1.0f;

		trace_t tr;
		CMedigunFilter drainFilter( pOwner );

		Vector vecAiming;
		pOwner->EyeVectors( &vecAiming );

		Vector vecEnd = vecSrc + vecAiming * GetTargetRange();
		UTIL_TraceLine( vecSrc, vecEnd, (MASK_SHOT & ~CONTENTS_HITBOX), pOwner, DMG_GENERIC, &tr );

		// Still visible?
		if ( tr.m_pEnt == pTarget )
			return;

		UTIL_TraceLine( vecSrc, vecTargetPoint, MASK_SHOT, &drainFilter, &tr );

		// Still visible?
		if (( tr.fraction == 1.0f) || (tr.m_pEnt == pTarget))
			return;

		// If we failed, try the target's eye point as well
		UTIL_TraceLine( vecSrc, pTarget->EyePosition(), MASK_SHOT, &drainFilter, &tr );
		if (( tr.fraction == 1.0f) || (tr.m_pEnt == pTarget))
			return;
	}

	// We've lost this guy
	if ( bLostTarget )
	{
		RemoveHealingTarget();
	}
}
Пример #5
0
int CASW_Parasite::RangeAttack1Conditions( float flDot, float flDist )
{
	if ( gpGlobals->curtime < m_flNextAttack )
		return 0;

	if ( ( GetFlags() & FL_ONGROUND ) == false )
		return 0;

	// This code stops lots of headcrabs swarming you and blocking you
	// whilst jumping up and down in your face over and over. It forces
	// them to back up a bit. If this causes problems, consider using it
	// for the fast headcrabs only, rather than just removing it.(sjb)
	if ( flDist < ASW_PARASITE_MIN_JUMP_DIST )
		return COND_TOO_CLOSE_TO_ATTACK;

	if ( flDist > ASW_PARASITE_MAX_JUMP_DIST )
		return COND_TOO_FAR_TO_ATTACK;

	// Make sure the way is clear!
	CBaseEntity *pEnemy = GetEnemy();
	if( pEnemy )
	{
		bool bEnemyIsBullseye = ( dynamic_cast<CNPC_Bullseye *>(pEnemy) != NULL );

		trace_t tr;
		AI_TraceLine( EyePosition(), pEnemy->EyePosition(), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

		if ( tr.m_pEnt != GetEnemy() )
		{
			if ( !bEnemyIsBullseye || tr.m_pEnt != NULL )
				return COND_NONE;
		}

		if( GetEnemy()->EyePosition().z - 36.0f > GetAbsOrigin().z )
		{
			// Only run this test if trying to jump at a player who is higher up than me, else this 
			// code will always prevent a headcrab from jumping down at an enemy, and sometimes prevent it
			// jumping just slightly up at an enemy.
			Vector vStartHullTrace = GetAbsOrigin();
			vStartHullTrace.z += 1.0;

			Vector vEndHullTrace = GetEnemy()->EyePosition() - GetAbsOrigin();
			vEndHullTrace.NormalizeInPlace();
			vEndHullTrace *= 8.0;
			vEndHullTrace += GetAbsOrigin();

			AI_TraceHull( vStartHullTrace, vEndHullTrace,GetHullMins(), GetHullMaxs(), MASK_NPCSOLID, this, GetCollisionGroup(), &tr );

			if ( tr.m_pEnt != NULL && tr.m_pEnt != GetEnemy() )
			{
				return COND_TOO_CLOSE_TO_ATTACK;
			}
		}
	}

	return COND_CAN_RANGE_ATTACK1;
}
Пример #6
0
void CASW_Parasite::HandleAnimEvent( animevent_t *pEvent )
{
	int nEvent = pEvent->Event();

	if ( nEvent == AE_HEADCRAB_JUMPATTACK )
	{
		// Ignore if we're in mid air
		if ( m_bMidJump )
			return;

		CBaseEntity *pEnemy = GetEnemy();
			
		if ( pEnemy )
		{
			if ( m_bCommittedToJump )
			{
				JumpAttack( false, m_vecCommittedJumpPos );
			}
			else
			{
				// Jump at my enemy's eyes.
				JumpAttack( false, pEnemy->EyePosition() );
			}

			m_bCommittedToJump = false;
			
		}
		else
		{
			// Jump hop, don't care where.
			JumpAttack( true );
		}

		return;
	}
	else if ( nEvent == AE_PARASITE_INFEST_SPURT)
	{
		// spurt some blood from our front claws
		Vector vecBloodPos;
		if( GetAttachment( "leftclaw", vecBloodPos ) )
			UTIL_ASW_BloodDrips( vecBloodPos, Vector(1,0,0), BLOOD_COLOR_RED, 1 );
		if( GetAttachment( "rightclaw", vecBloodPos ) )
			UTIL_ASW_BloodDrips( vecBloodPos, Vector(1,0,0), BLOOD_COLOR_RED, 1 );
		return;
	}
	else if ( nEvent == AE_PARASITE_INFEST)
	{
		// we're done infesting, make ourselves vanish
		FinishedInfesting();
		return;
	}

	BaseClass::HandleAnimEvent( pEvent );
}
Пример #7
0
void C_SDKPlayer::ClientThink()
{
	UpdateSoundEvents();

	// Pass on through to the base class.
	BaseClass::ClientThink();

	bool bFoundViewTarget = false;
	
	Vector vForward;
	AngleVectors( GetLocalAngles(), &vForward );

	for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
	{
		CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
		if(!pEnt || !pEnt->IsPlayer())
			continue;

		if ( pEnt->entindex() == entindex() )
			continue;

		Vector vTargetOrigin = pEnt->GetAbsOrigin();
		Vector vMyOrigin =  GetAbsOrigin();

		Vector vDir = vTargetOrigin - vMyOrigin;
		
		if ( vDir.Length() > 128 ) 
			continue;

		VectorNormalize( vDir );

		if ( DotProduct( vForward, vDir ) < 0.0f )
			 continue;

		m_vLookAtTarget = pEnt->EyePosition();
		bFoundViewTarget = true;
		break;
	}

	if ( bFoundViewTarget == false )
	{
		m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
	}

	UpdateIDTarget();

	// Avoidance
	if ( gpGlobals->curtime >= m_fNextThinkPushAway )
	{
		PerformObstaclePushaway( this );
		m_fNextThinkPushAway =  gpGlobals->curtime + PUSHAWAY_THINK_INTERVAL;
	}
}
Пример #8
0
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;
}
Пример #9
0
//=========================================================
// CheckRangeAttack2 - check bravery and try to resurect dead comrades
//=========================================================
BOOL CISlave :: CheckRangeAttack2 ( float flDot, float flDist )
{
//	if ( mp_am_movecorpses.value = 0  ) //si DESACTIVADO
//	{
//		return FALSE;
//	}

//SP: regeneracion de colegas activada!
	if (m_flNextAttack > gpGlobals->time)
	{
		return FALSE;
	}

	m_hDead = NULL;
	m_iBravery = 0;

	CBaseEntity *pEntity = NULL;
//	while (pEntity = UTIL_FindEntityByClassname( pEntity, m_IslaveFriends ))

	while ((pEntity = UTIL_FindEntityByClassname( pEntity, "monster_alien_slave" )) != NULL)
	{
		TraceResult tr;

		UTIL_TraceLine( EyePosition( ), pEntity->EyePosition( ), ignore_monsters, ENT(pev), &tr );
		if (tr.flFraction == 1.0 || tr.pHit == pEntity->edict())
		{
			if (pEntity->pev->deadflag == DEAD_DEAD)
			{
				float d = (pev->origin - pEntity->pev->origin).Length();
				if (d < flDist)
				{
					m_hDead = pEntity;
					flDist = d;
				}
				m_iBravery--;
			}
			else
			{
				m_iBravery++;
			}
		}
	}
	if (m_hDead != NULL)
		return TRUE;
	else
		return FALSE;
}
Пример #10
0
//=========================================================
// CheckRangeAttack2 - check bravery and try to resurect dead comrades
//=========================================================
BOOL CISlave::CheckRangeAttack2(float flDot, float flDist)
{
	return FALSE;

	if(m_flNextAttack > gpGlobals->time)
	{
		return FALSE;
	}

	m_hDead    = NULL;
	m_iBravery = 0;

	CBaseEntity *pEntity = NULL;
	while((pEntity = UTIL_FindEntityByClassname(pEntity, "monster_alien_slave")) != NULL)
	{
		TraceResult tr;

		UTIL_TraceLine(EyePosition(), pEntity->EyePosition(), ignore_monsters, ENT(pev), &tr);
		if(tr.flFraction == 1.0 || tr.pHit == pEntity->edict())
		{
			if(pEntity->pev->deadflag == DEAD_DEAD)
			{
				float d = (pev->origin - pEntity->pev->origin).Length();
				if(d < flDist)
				{
					m_hDead = pEntity;
					flDist  = d;
				}
				m_iBravery--;
			}
			else
			{
				m_iBravery++;
			}
		}
	}
	if(m_hDead != NULL)
		return TRUE;
	else
		return FALSE;
}
Пример #11
0
void C_MSS_Player::ClientThink( void )
{
	bool bFoundViewTarget = false;
	
	Vector vForward;
	AngleVectors( GetLocalAngles(), &vForward );

	for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
	{
		CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
		if(!pEnt || !pEnt->IsPlayer())
			continue;

		if ( pEnt->entindex() == entindex() )
			continue;

		Vector vTargetOrigin = pEnt->GetAbsOrigin();
		Vector vMyOrigin =  GetAbsOrigin();

		Vector vDir = vTargetOrigin - vMyOrigin;
		
		if ( vDir.Length() > 128 ) 
			continue;

		VectorNormalize( vDir );

		if ( DotProduct( vForward, vDir ) < 0.0f )
			 continue;

		m_vLookAtTarget = pEnt->EyePosition();
		bFoundViewTarget = true;
		break;
	}

	if ( bFoundViewTarget == false )
	{
		m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
	}

	UpdateIDTarget();
}
void CWalkerMiniStrider::FireMachineGun()
{
	CBaseEntity *pDriver = GetPassenger( VEHICLE_DRIVER );
	if ( pDriver )
	{
		// Alternate the gun we're firing
		char *attachmentNames[2] = { "MachineGun_Left", "MachineGun_Right" };
		int iAttachment = LookupAttachment( attachmentNames[!m_bFiringLeftGun] );
		m_bFiringLeftGun = !m_bFiringLeftGun;

		Vector vAttachmentPos;
		QAngle vAttachmentAngles;
		GetAttachment( iAttachment, vAttachmentPos, vAttachmentAngles );

		Vector vEyePos = pDriver->EyePosition();
		Vector vEyeForward;
		QAngle vecAngles = pDriver->LocalEyeAngles();
		// Use the skirmisher's yaw
		vecAngles[YAW] = GetAbsAngles()[YAW];
		AngleVectors( vecAngles, &vEyeForward );

		// Trace ahead to find out where the crosshair is aiming 
		trace_t trace;
		float flMaxRange = tf_skirmisher_machinegun_range.GetFloat();
		UTIL_TraceLine( 
			vEyePos, 
			vEyePos + vEyeForward * flMaxRange,
			MASK_SOLID, 
			this, 
			COLLISION_GROUP_NONE, 
			&trace );

		Vector vecDir;
		if ( trace.fraction < 1.0 )
		{
			vecDir = (trace.endpos - vAttachmentPos );
			VectorNormalize( vecDir );
		}
		else
		{
			vecDir = vEyeForward;
		}

		// Shoot!
		TFGameRules()->FireBullets( CTakeDamageInfo( this, pDriver, tf_skirmisher_machinegun_damage.GetFloat(), DMG_BULLET ), 
			1,						// Num shots
			vAttachmentPos, 
			vecDir, 
			VECTOR_CONE_3DEGREES,	// Spread
			flMaxRange,				// Range
			DMG_BULLET,
			1,						// Tracer freq
			entindex(), 
			iAttachment,			// Attachment ID
			"MinigunTracer" );

		m_flNextShootTime += (1.0f / tf_skirmisher_machinegun_rof.GetFloat());

		// Play the fire sound.
		Vector vCenter = WorldSpaceCenter();
		CPASAttenuationFilter filter( this, "Skirmisher.GunSound" );
		EmitSound( filter, 0, "Skirmisher.GunSound", &vCenter );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Catches the monster-specific messages that occur when tagged
//			animation frames are played.
// Input  : *pEvent - 
//-----------------------------------------------------------------------------
void CNPC_Headcrab::HandleAnimEvent( animevent_t *pEvent )
{
	switch ( pEvent->event )
	{
		case HC_AE_JUMPATTACK:
		{
			RemoveFlag( FL_ONGROUND );

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

			Vector vecJumpDir;
			CBaseEntity *pEnemy = GetEnemy();
			if ( pEnemy )
			{
				Vector vecEnemyEyePos = pEnemy->EyePosition();

				float gravity = sv_gravity.GetFloat();
				if ( gravity <= 1 )
				{
					gravity = 1;
				}

				//
				// How fast does the headcrab need to travel to reach my enemy's eyes given gravity?
				//
				float height = ( vecEnemyEyePos.z - GetAbsOrigin().z );
				if ( height < 16 )
				{
					height = 16;
				}
				else if ( height > 120 )
				{
					height = 120;
				}
				float speed = sqrt( 2 * gravity * height );
				float time = speed / gravity;

				//
				// Scale the sideways velocity to get there at the right time
				//
				vecJumpDir = vecEnemyEyePos - GetAbsOrigin();
				vecJumpDir = vecJumpDir / time;

				//
				// Speed to offset gravity at the desired height.
				//
				vecJumpDir.z = speed;

				//
				// Don't jump too far/fast.
				//
				float distance = vecJumpDir.Length();
				if ( distance > 650 )
				{
					vecJumpDir = vecJumpDir * ( 650.0 / distance );
				}
			}
			else
			{
				//
				// Jump hop, don't care where.
				//
				Vector forward, up;
				AngleVectors( GetAbsAngles(), &forward, NULL, &up );
				vecJumpDir = Vector( forward.x, forward.y, up.z ) * 350;
			}

			int iSound = random->RandomInt( 0 , 1 );
			if ( iSound != 0 )
			{
				AttackSound();
			}

			SetAbsVelocity( vecJumpDir );
			m_flNextAttack = gpGlobals->curtime + 2;
			break;
		}

		default:
		{
			CAI_BaseNPC::HandleAnimEvent( pEvent );
			break;
		}
	}
}
Пример #14
0
void CNPC_Hydra::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
	case TASK_HYDRA_DEPLOY:
		{
			m_flHeadGoalInfluence = 1.0;
			float dist = (EyePosition() - m_vecHeadGoal).Length();

			if (dist < m_idealSegmentLength)
			{
				TaskComplete();
			}

			AimHeadInTravelDirection( 0.2 );
		}
		break;

	case TASK_HYDRA_PREP_STAB:
		{
			int i;

			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}

			CBaseEntity *pTarget = GetTarget();
			if (pTarget == NULL)
			{
				TaskFail( FAIL_NO_TARGET );
			}

			if (pTarget->IsPlayer())
			{
				m_vecTarget = pTarget->EyePosition( );
			}
			else
			{
				m_vecTarget = pTarget->BodyTarget( EyePosition( ) );
			}

			float distToTarget = (m_vecTarget - m_vecHeadGoal).Length();
			float distToBase = (m_vecHeadGoal - GetAbsOrigin()).Length();
			m_idealLength = distToTarget + distToBase * 0.5;

			if (m_idealLength > HYDRA_MAX_LENGTH)
				m_idealLength = HYDRA_MAX_LENGTH;

			if (distToTarget < 100.0)
			{
				m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
				VectorNormalize( m_vecTargetDir );
				m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (100 - distToTarget) * 0.5;
			}
			else if (distToTarget > 200.0)
			{
				m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
				VectorNormalize( m_vecTargetDir );
				m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (200.0 - distToTarget) * 0.5;
			}

			// face enemy
			m_vecTargetDir = (m_vecTarget - m_body[m_body.Count()-1].vecPos);
			VectorNormalize( m_vecTargetDir );
			m_vecHeadDir = m_vecHeadDir * 0.6 + m_vecTargetDir * 0.4;
			VectorNormalize( m_vecHeadDir.GetForModify() );

			// build tension towards strike time
			float influence = 1.0 - (m_flTaskEndTime - gpGlobals->curtime) / pTask->flTaskData;
			if (influence > 1)
				influence = 1.0;

			influence = influence * influence * influence;

			m_flHeadGoalInfluence = influence;

			// keep head segment straight
			i = m_body.Count() - 2;
			m_body[i].vecGoalPos = m_vecHeadGoal - m_vecHeadDir * m_body[i].flActualLength;
			m_body[i].flGoalInfluence = influence;

			// curve neck into spiral
			float distBackFromHead = m_body[i].flActualLength;
			Vector right, up;
			VectorVectors( m_vecHeadDir, right, up );

			for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--)
			{
				distBackFromHead += m_body[i].flActualLength;

				float r = (distBackFromHead / 200) * 3.1415 * 2;

				// spiral
				Vector p0 = m_vecHeadGoal 
							- m_vecHeadDir * distBackFromHead * 0.5 
							+ cos( r ) * m_body[i].flActualLength * right 
							+ sin( r ) * m_body[i].flActualLength * up;

				// base
				r = (distBackFromHead / m_idealLength) * 3.1415 * 0.2;
				r = sin( r );
				p0 = p0 * (1 - r) + r * GetAbsOrigin();

				m_body[i].vecGoalPos = p0;

				m_body[i].flGoalInfluence = influence * (1.0 - (distBackFromHead / distToTarget));

				/*
				if ( (pEnemy->EyePosition( ) - m_body[i].vecPos).Length() < distBackFromHead)
				{
					if ( gpGlobals->curtime - m_flLastAttackTime > 4.0)
					{
						TaskComplete();
					}
					return;
				}
				*/
			}

			// look to see if any of the goal positions are stuck
			for (i = i; i < m_body.Count() - 1; i++)
			{
				if (m_body[i].bStuck)
				{
					Vector delta = DotProduct( m_body[i].vecGoalPos - m_body[i].vecPos, m_vecHeadDir) * m_vecHeadDir;
					m_vecHeadGoal -= delta * m_body[i].flGoalInfluence;
					break;
				}
			}

			if ( gpGlobals->curtime >= m_flTaskEndTime )
			{
				if (distToTarget < 500)
				{
					TaskComplete( );
					return;
				}
				else
				{
					TaskFail( "target is too far away" );
					return;
				}
			}
		}
		return;

	case TASK_HYDRA_STAB:
		{
			int i;

			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}

			if (m_flTaskEndTime <= gpGlobals->curtime)
			{
				TaskComplete( );
				return;
			}

			m_flHeadGoalInfluence = 1.0;

			// face enemy
			//m_vecHeadDir = (pEnemy->EyePosition( ) - m_body[m_body.Count()-1].vecPos);
			//VectorNormalize( m_vecHeadDir.GetForModify() );

			// keep head segment straight
			i = m_body.Count() - 2;
			m_body[i].vecGoalPos = m_vecHeadGoal + m_vecHeadDir * m_body[i].flActualLength;
			m_body[i].flGoalInfluence = 1.0;

			Vector vecToTarget = (m_vecTarget - EyePosition( ));

			// check to see if we went past target
			if (DotProduct( vecToTarget, m_vecHeadDir ) < 0.0)
			{
				TaskComplete( );
				return;
			}

			float distToTarget = vecToTarget.Length();
			float distToBase = (EyePosition( ) - GetAbsOrigin()).Length();
			m_idealLength = distToTarget + distToBase;

			/*
			if (distToTarget < 20)
			{
				m_vecHeadGoal = m_vecTarget;
				SetLastAttackTime( gpGlobals->curtime );
				TaskComplete();
				return;
			}
			else
			*/
			{
				// hit enemy
				m_vecHeadGoal = m_vecTarget + m_vecHeadDir * 300;
			}

			if (m_idealLength > HYDRA_MAX_LENGTH)
				m_idealLength = HYDRA_MAX_LENGTH;

			// curve neck into spiral
			float distBackFromHead = m_body[i].flActualLength;
			Vector right, up;
			VectorVectors( m_vecHeadDir, right, up );

#if 1
			for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--)
			{
				Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 1.0; 

				m_body[i].vecGoalPos = p0;

				if ((m_vecTarget - m_body[i].vecPos).Length() > distToTarget + distBackFromHead)
				{
					m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget);
				}
				else
				{
					m_body[i].vecGoalPos = EyePosition( ) - m_vecHeadDir * distBackFromHead;
					m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget);
				}

				distBackFromHead += m_body[i].flActualLength;
			}
#endif
		}
		return;

	case TASK_HYDRA_PULLBACK:
		{
			if (m_body.Count() < 2)
			{
				TaskFail( "hydra is too short to begin stab" );
				return;
			}
			CBaseEntity *pEnemy = (CBaseEntity *)UTIL_GetLocalPlayer();
			if (GetEnemy() != NULL)
			{
				pEnemy = GetEnemy();
			}

			AimHeadInTravelDirection( 0.2 );

			// float dist = (EyePosition() - m_vecHeadGoal).Length();

			if (m_flCurrentLength < m_idealLength + m_idealSegmentLength)
			{
				TaskComplete();
			}
		}
		break;

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

}
void CFuncTank::TrackTarget( void )
{
	trace_t tr;
	bool updateTime = FALSE, lineOfSight;
	QAngle angles;
	Vector barrelEnd;
	CBaseEntity *pTarget = NULL;

	barrelEnd.Init();

	// Get a position to aim for
	if (m_pController)
	{
		// Tanks attempt to mirror the player's angles
		angles = m_pController->EyeAngles();
		SetNextThink( gpGlobals->curtime + 0.05 );
	}
	else
	{
		if ( IsActive() )
		{
			SetNextThink( gpGlobals->curtime + 0.1f );
		}
		else
		{
			return;
		}

		// -----------------------------------
		//  Get world target position
		// -----------------------------------
		barrelEnd = WorldBarrelPosition();
		Vector worldTargetPosition;
		if (m_spawnflags & SF_TANK_AIM_AT_POS)
		{
			worldTargetPosition = m_vTargetPosition;
		}
		else
		{
			CBaseEntity *pEntity = (CBaseEntity *)m_hTarget;
			if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) )
			{
				if ( m_targetEntityName != NULL_STRING )	// New HL2 behavior
				{
					m_hTarget = FindTarget( m_targetEntityName, NULL );
				}
				else	// HL1 style
				{
					m_hTarget = ToBasePlayer( GetContainingEntity( UTIL_FindClientInPVS( edict() ) ) );
				}

				if ( m_hTarget != NULL )
				{
					SetNextThink( gpGlobals->curtime );	// Think again immediately
				}
				else
				{
					if ( IsActive() )
					{
						SetNextThink( gpGlobals->curtime + 2 );	// Wait 2 secs
					}

					if ( m_fireLast !=0 )
					{
						m_OnLoseTarget.FireOutput(this, this);
						m_fireLast = 0;
					}
				}

				return;
			}
			pTarget = pEntity;

			// Calculate angle needed to aim at target
			worldTargetPosition = pEntity->EyePosition();
		}

		float range = (worldTargetPosition - barrelEnd).Length();
		
		if ( !InRange( range ) )
		{
			m_fireLast = 0;
			return;
		}

		UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

		if (m_spawnflags & SF_TANK_AIM_AT_POS)
		{
			updateTime		= TRUE;
			m_sightOrigin	= m_vTargetPosition;
		}
		else
		{
			lineOfSight = FALSE;
			// No line of sight, don't track
			if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget )
			{
				lineOfSight = TRUE;

				CBaseEntity *pInstance = pTarget;
				if ( InRange( range ) && pInstance && pInstance->IsAlive() )
				{
					updateTime = TRUE;

					// Sight position is BodyTarget with no noise (so gun doesn't bob up and down)
					m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false );
				}
			}
		}

		// Convert targetPosition to parent
		angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) );
	}

	// Force the angles to be relative to the center position
	float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter );
	float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter );
	angles.y = m_yawCenter + offsetY;
	angles.x = m_pitchCenter + offsetX;

	// Limit against range in y

	// MDB - don't check pitch! If two func_tanks are meant to align,
	// and one can pitch and the other cannot, this can lead to them getting 
	// different values for angles.y. Nothing is lost by not updating yaw
	// because the target is not in pitch range.

	bool bOutsideYawRange = ( fabs( offsetY ) > m_yawRange + m_yawTolerance );
	bool bOutsidePitchRange = ( fabs( offsetX ) > m_pitchRange + m_pitchTolerance );

	Vector vecToTarget = m_sightOrigin - GetLocalOrigin();

	// if target is outside yaw range
	if ( bOutsideYawRange )
	{
		if ( angles.y > m_yawCenter + m_yawRange )
		{
			angles.y = m_yawCenter + m_yawRange;
		}
		else if ( angles.y < (m_yawCenter - m_yawRange) )
		{
			angles.y = (m_yawCenter - m_yawRange);
		}
	}

	if ( bOutsidePitchRange || bOutsideYawRange || ( vecToTarget.Length() < ( barrelEnd - GetAbsOrigin() ).Length() ) )
	{
		// Don't update if you saw the player, but out of range
		updateTime = false;
	}

	if ( updateTime )
	{
		m_lastSightTime = gpGlobals->curtime;
		m_persist2burst = 0;
	}

	// Move toward target at rate or less
	float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y );

	QAngle vecAngVel = GetLocalAngularVelocity();
	vecAngVel.y = distY * 10;
	vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate );

	// Limit against range in x
	angles.x = clamp( angles.x, m_pitchCenter - m_pitchRange, m_pitchCenter + m_pitchRange );

	// Move toward target at rate or less
	float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x );
	vecAngVel.x = distX  * 10;
	vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate );
	SetLocalAngularVelocity( vecAngVel );

	SetMoveDoneTime( 0.1 );
	if ( m_pController )
		return;

	if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (m_spawnflags & SF_TANK_LINEOFSIGHT) ) )
	{
		bool fire = FALSE;
		Vector forward;
		AngleVectors( GetLocalAngles(), &forward );
		forward = m_parentMatrix.ApplyRotation( forward );


		if ( m_spawnflags & SF_TANK_LINEOFSIGHT )
		{
			float length = (m_maxRange > 0) ? m_maxRange : MAX_TRACE_LENGTH;
			UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

			if ( tr.m_pEnt == pTarget )
				fire = TRUE;
		}
		else
			fire = TRUE;

		if ( fire )
		{
			if (m_fireLast == 0)
			{
				m_OnAquireTarget.FireOutput(this, this);
			}
			FiringSequence( barrelEnd, forward, this );
		}
		else 
		{
			if (m_fireLast !=0)
			{
				m_OnLoseTarget.FireOutput(this, this);
			}
			m_fireLast = 0;
		}
	}
	else 
	{
		if (m_fireLast !=0)
		{
			m_OnLoseTarget.FireOutput(this, this);
		}
		m_fireLast = 0;
	}
}
Пример #16
0
void CAI_FreePass::Update( )
{
	CBaseEntity *pTarget = GetPassTarget();
	if ( !pTarget || m_Params.duration < 0.1 )
		return;

	//---------------------------------
	//
	// Free pass logic
	//
	AI_EnemyInfo_t *pTargetInfo = GetOuter()->GetEnemies()->Find( pTarget );

	// This works with old data because need to do before base class so as to not choose as enemy
	if ( !HasPass() )
	{
		float timePlayerLastSeen = (pTargetInfo) ? pTargetInfo->timeLastSeen : AI_INVALID_TIME;
		float lastTimeDamagedBy = (pTargetInfo) ? pTargetInfo->timeLastReceivedDamageFrom : AI_INVALID_TIME;

		if ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > .15 ) // If didn't see the player last think
		{
			trace_t tr;
			UTIL_TraceLine( pTarget->EyePosition(), GetOuter()->EyePosition(), MASK_OPAQUE, GetOuter(), COLLISION_GROUP_NONE, &tr );
			if ( tr.fraction != 1.0 && tr.m_pEnt != pTarget )
			{
				float dist = (tr.endpos - tr.startpos).Length() * tr.fraction;

				if ( dist < m_Params.coverDist )
				{
					if ( ( timePlayerLastSeen == AI_INVALID_TIME || gpGlobals->curtime - timePlayerLastSeen > m_Params.timeToTrigger ) &&
						 ( lastTimeDamagedBy == AI_INVALID_TIME || gpGlobals->curtime - lastTimeDamagedBy > m_Params.timeToTrigger ) )
					{
						m_FreePassTimeRemaining = m_Params.duration;
						m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance );
					}
				}
			}
		}
	}
	else
	{
		float temp = m_FreePassTimeRemaining;
		m_FreePassTimeRemaining = 0;
		CAI_Senses *pSenses = GetOuter()->GetSenses();
		bool bCanSee = ( pSenses && pSenses->ShouldSeeEntity( pTarget ) && pSenses->CanSeeEntity( pTarget ) );
		m_FreePassTimeRemaining = temp;

		if ( bCanSee )
		{
			if ( !m_FreePassMoveMonitor.TargetMoved( pTarget ) )
				m_FreePassTimeRemaining -= 0.1;
			else
				Revoke( true );
		}
		else
		{
			m_FreePassTimeRemaining += 0.1 * m_Params.refillRate;
			if ( m_FreePassTimeRemaining > m_Params.duration )
				m_FreePassTimeRemaining = m_Params.duration;
			m_FreePassMoveMonitor.SetMark( pTarget, m_Params.moveTolerance );
		}
	}
}
void CAI_StandoffBehavior::StartTask( const Task_t *pTask )
{
	bool fCallBase = false;
	
	switch ( pTask->iTask )
	{
		case TASK_RANGE_ATTACK1:
		{
			m_ShotRegulator.OnFiredWeapon();
			fCallBase = true;
			break;
		}
		
		case TASK_FIND_COVER_FROM_ENEMY:
		{
			StandoffMsg( "TASK_FIND_COVER_FROM_ENEMY\n" );

			// If within time window to force change
			if ( !m_params.fStayAtCover && (!m_TimeForceCoverHint.Expired() || m_RandomCoverChangeTimer.Expired()) )
			{
				m_TimeForceCoverHint.Force();
				m_RandomCoverChangeTimer.Set( 8, 16, false );

				// @TODO (toml 03-24-03):  clean this up be tool-izing base tasks. Right now, this is here to force to not use lateral cover search
				CBaseEntity *pEntity = GetEnemy();

				if ( pEntity == NULL )
				{
					// Find cover from self if no enemy available
					pEntity = GetOuter();
				}

				CBaseEntity *pLeader = GetPlayerLeader();
				if ( pLeader )
				{
					m_PlayerMoveMonitor.SetMark( pLeader, 60 );
				}

				Vector					coverPos			= vec3_origin;
				CAI_TacticalServices *	pTacticalServices	= GetTacticalServices();
				const Vector &			enemyPos			= pEntity->GetAbsOrigin();
				Vector					enemyEyePos			= pEntity->EyePosition();
				float					coverRadius			= GetOuter()->CoverRadius();
				const Vector &			goalPos				= GetStandoffGoalPosition();
				bool					bTryGoalPosFirst	= true;

				if( pLeader && m_vecStandoffGoalPosition == GOAL_POSITION_INVALID )
				{
					if( random->RandomInt(1, 100) <= 50 )
					{
						// Half the time, if the player is leading, try to find a spot near them
						bTryGoalPosFirst = false;
						StandoffMsg( "Not trying goal pos\n" );
					}
				}

				if( bTryGoalPosFirst )
				{
					// Firstly, try to find cover near the goal position.
					pTacticalServices->FindCoverPos( goalPos, enemyPos, enemyEyePos, 0, 15*12, &coverPos );

					if ( coverPos == vec3_origin )
						pTacticalServices->FindCoverPos( goalPos, enemyPos, enemyEyePos, 15*12-0.1, 40*12, &coverPos );

					StandoffMsg1( "Trying goal pos, %s\n", ( coverPos == vec3_origin  ) ? "failed" :  "succeeded" );
				}

				if ( coverPos == vec3_origin  ) 
				{
					// Otherwise, find a node near to self
					StandoffMsg( "Looking for near cover\n" );
					if ( !GetTacticalServices()->FindCoverPos( enemyPos, enemyEyePos, 0, coverRadius, &coverPos ) ) 
					{
						// Try local lateral cover
						if ( !GetTacticalServices()->FindLateralCover( enemyEyePos, &coverPos ) )
						{
							// At this point, try again ignoring front lines. Any cover probably better than hanging out in the open
							m_fIgnoreFronts = true;
							if ( !GetTacticalServices()->FindCoverPos( enemyPos, enemyEyePos, 0, coverRadius, &coverPos ) ) 
							{
								if ( !GetTacticalServices()->FindLateralCover( enemyEyePos, &coverPos ) )
								{
									Assert( coverPos == vec3_origin );
								}
							}
							m_fIgnoreFronts = false;
						}
					}
				}

				if ( coverPos != vec3_origin )
				{
					AI_NavGoal_t goal(GOALTYPE_COVER, coverPos, ACT_RUN, AIN_HULL_TOLERANCE, AIN_DEF_FLAGS);
					GetNavigator()->SetGoal( goal );

					GetOuter()->m_flMoveWaitFinished = gpGlobals->curtime + pTask->flTaskData;
					TaskComplete();
				}
				else
					TaskFail(FAIL_NO_COVER);
			}
			else
			{
				fCallBase = true;
			}
			break;
		}

		default:
		{
			fCallBase = true;
		}
	}
	
	if ( fCallBase )
		BaseClass::StartTask( pTask );
}
Пример #18
0
void RadiusFlash(
    Vector vecSrc,
    CBaseEntity *pevInflictor,
    CBaseEntity *pevAttacker,
    float flDamage,
    int iClassIgnore,
    int bitsDamageType)
{
    vecSrc.z += 1;// in case grenade is lying on the ground

    if (!pevAttacker)
        pevAttacker = pevInflictor;

    trace_t		tr;
    float		flAdjustedDamage;
    variant_t	var;
    Vector		vecEyePos;
    float		fadeTime, fadeHold;
    Vector		vForward;
    Vector		vecLOS;
    float		flDot;

    CBaseEntity		*pEntity = NULL;
    static float	flRadius = 1500;
    float			falloff = flDamage / flRadius;

    bool bInWater = (UTIL_PointContents(vecSrc) == CONTENTS_WATER);

    // iterate on all entities in the vicinity.
    while ((pEntity = gEntList.FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL)
    {
        bool bPlayer = pEntity->IsPlayer();
        bool bHostage = (Q_stricmp(pEntity->GetClassname(), "hostage_entity") == 0);

        if (!bPlayer && !bHostage)
            continue;

        vecEyePos = pEntity->EyePosition();

        // blasts don't travel into or out of water
        if (bInWater && pEntity->GetWaterLevel() == 0)
            continue;
        if (!bInWater && pEntity->GetWaterLevel() == 3)
            continue;

        float percentageOfFlash = PercentageOfFlashForPlayer(pEntity, vecSrc, pevInflictor);

        if (percentageOfFlash > 0.0)
        {
            // decrease damage for an ent that's farther from the grenade
            flAdjustedDamage = flDamage - (vecSrc - pEntity->EyePosition()).Length() * falloff;

            if (flAdjustedDamage > 0)
            {
                // See if we were facing the flash
                AngleVectors(pEntity->EyeAngles(), &vForward);

                vecLOS = (vecSrc - vecEyePos);

                //float flDistance = vecLOS.Length();

                // Normalize both vectors so the dotproduct is in the range -1.0 <= x <= 1.0 
                vecLOS.NormalizeInPlace();

                flDot = DotProduct(vecLOS, vForward);

                float startingAlpha = 255;

                // if target is facing the bomb, the effect lasts longer
                if (flDot >= 0.5)
                {
                    // looking at the flashbang
                    fadeTime = flAdjustedDamage * 2.5f;
                    fadeHold = flAdjustedDamage * 1.25f;
                }
                else if (flDot >= -0.5)
                {
                    // looking to the side
                    fadeTime = flAdjustedDamage * 1.75f;
                    fadeHold = flAdjustedDamage * 0.8f;
                }
                else
                {
                    // facing away
                    fadeTime = flAdjustedDamage * 1.0f;
                    fadeHold = flAdjustedDamage * 0.75f;
                    startingAlpha = 200;
                }

                fadeTime *= percentageOfFlash;
                fadeHold *= percentageOfFlash;

                if (bPlayer)
                {
                    //MOM_TODO: do we want this functionality?
                    // blind players and bots
                    //CMomentumPlayer *player = static_cast<CMomentumPlayer *>(pEntity);
                    //player->Blind( fadeHold, fadeTime, startingAlpha );

                    // deafen players and bots
                    //player->Deafen( flDistance );
                }
                else if (bHostage)
                {
                    variant_t val;
                    val.SetFloat(fadeTime);
                    pEntity->AcceptInput("flashbang", pevInflictor, pevAttacker, val, 0);
                }
            }
        }
    }

    CPVSFilter filter(vecSrc);
    te->DynamicLight(filter, 0.0, &vecSrc, 255, 255, 255, 2, 400, 0.1, 768);
}
Пример #19
0
void C_SDKPlayer::ClientThink()
{
	UpdateSoundEvents();

	// Pass on through to the base class.
	BaseClass::ClientThink();

	bool bFoundViewTarget = false;
	
	Vector vForward;
	AngleVectors( GetLocalAngles(), &vForward );

	for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
	{
		CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
		if(!pEnt || !pEnt->IsPlayer())
			continue;

		if ( pEnt->entindex() == entindex() )
			continue;

		Vector vTargetOrigin = pEnt->GetAbsOrigin();
		Vector vMyOrigin =  GetAbsOrigin();

		Vector vDir = vTargetOrigin - vMyOrigin;
		
		if ( vDir.Length() > 128 ) 
			continue;

		VectorNormalize( vDir );

		if ( DotProduct( vForward, vDir ) < 0.0f )
			 continue;

		m_vLookAtTarget = pEnt->EyePosition();
		bFoundViewTarget = true;
		break;
	}

	if ( bFoundViewTarget == false )
	{
		m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
	}

	UpdateIDTarget();

	// Avoidance
	if ( gpGlobals->curtime >= m_fNextThinkPushAway )
	{
		PerformObstaclePushaway( this );
		m_fNextThinkPushAway =  gpGlobals->curtime + PUSHAWAY_THINK_INTERVAL;
	}

	if (Q_strcmp(m_szColorCorrectionFile, cl_colorcorrection_file.GetString()))
	{
		if (m_hColorCorrection != INVALID_CLIENT_CCHANDLE)
			g_pColorCorrectionMgr->RemoveColorCorrection(m_hColorCorrection);

		m_hColorCorrection = g_pColorCorrectionMgr->AddColorCorrection(VarArgs("materials/correction/%s.raw", cl_colorcorrection_file.GetString()));
		Q_strncpy(m_szColorCorrectionFile, cl_colorcorrection_file.GetString(), sizeof(m_szColorCorrectionFile));
	}

	g_pColorCorrectionMgr->SetColorCorrectionWeight(m_hColorCorrection, cl_colorcorrection_weight.GetFloat());
}
Пример #20
0
void C_SDKPlayer::ClientThink()
{
	UpdateSoundEvents();

	// Pass on through to the base class.
	BaseClass::ClientThink();

	bool bFoundViewTarget = false;
	
	Vector vForward;
	AngleVectors( GetLocalAngles(), &vForward );

	

	for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
	{
		CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
		if(!pEnt || !pEnt->IsPlayer())
			continue;

		if ( pEnt->entindex() == entindex() )
			continue;

		Vector vTargetOrigin = pEnt->GetAbsOrigin();
		Vector vMyOrigin =  GetAbsOrigin();

		Vector vDir = vTargetOrigin - vMyOrigin;
		
		if ( vDir.Length() > 128 ) 
			continue;

		VectorNormalize( vDir );

		if ( DotProduct( vForward, vDir ) < 0.0f )
			 continue;

		m_vLookAtTarget = pEnt->EyePosition();
		bFoundViewTarget = true;
		break;
	}

	if ( bFoundViewTarget == false )
	{
		m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
	}

	UpdateIDTarget();


	
	if(isInvisible){
		float iAlpha;
		if(invEnd < gpGlobals->curtime){
			GetViewModel()->SetRenderColorA(255);
			GetViewModel()->SetRenderMode( kRenderNormal );
			isInvisible = false;
		}
		else if (gpGlobals->curtime-invStart > 0){
			
			iAlpha = min((gpGlobals->curtime-invStart),0.8f)/ 0.8f; 
			GetViewModel()->SetRenderMode( kRenderTransAlpha );
			GetViewModel()->SetRenderColorA(255- 200.0f * iAlpha);
		}
	}

	// Avoidance
	if ( gpGlobals->curtime >= m_fNextThinkPushAway )
	{
		PerformObstaclePushaway( this );
		m_fNextThinkPushAway =  gpGlobals->curtime + PUSHAWAY_THINK_INTERVAL;
	}
}
Пример #21
0
//-----------------------------------------------------------------------------
// Purpose: Jump at the enemy!! (stole this from the headcrab)
//
//
//-----------------------------------------------------------------------------
void CFastZombie::LeapAttack( void )
{
    RemoveFlag( FL_ONGROUND );

    BeginAttackJump();

    LeapAttackSound();

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

    Vector vecJumpDir;
    CBaseEntity *pEnemy = GetEnemy();

    if ( pEnemy )
    {
        Vector vecEnemyEyePos = pEnemy->EyePosition();

        float gravity = sv_gravity.GetFloat();
        if ( gravity <= 1 )
        {
            gravity = 1;
        }

        //
        // How fast does the zombie need to travel to reach my enemy's eyes given gravity?
        //
        float height = ( vecEnemyEyePos.z - GetAbsOrigin().z );
        if ( height < 16 )
        {
            height = 16;
        }
        else if ( height > 120 )
        {
            height = 120;
        }
        float speed = sqrt( 2 * gravity * height );
        float time = speed / gravity;

        //
        // Scale the sideways velocity to get there at the right time
        //
        vecJumpDir = vecEnemyEyePos - GetAbsOrigin();
        vecJumpDir = vecJumpDir / time;

        //
        // Speed to offset gravity at the desired height.
        //
        vecJumpDir.z = speed * 0.75; // quick fix for now. ZOmbie is jumping too high! (sjb)

        //
        // Don't jump too far/fast.
        //
#define CLAMP 1000.0
        float distance = vecJumpDir.Length();
        if ( distance > CLAMP )
        {
            vecJumpDir = vecJumpDir * ( CLAMP / distance );
        }

        // try speeding up a bit.
        SetAbsVelocity( vecJumpDir );
        m_flNextAttack = gpGlobals->curtime + 2;
    }
}
Пример #22
0
void CAPCController::TrackTarget( void )
{
	trace_t tr;
	bool updateTime = FALSE, lineOfSight;
	QAngle angles;
	Vector barrelEnd;
	CBaseEntity *pTarget = NULL;

	barrelEnd.Init();

	if ( IsActive() )
	{
		SetNextThink( gpGlobals->curtime + 0.1f );
	}
	else
	{
		return;
	}

	// -----------------------------------
	//  Get world target position
	// -----------------------------------
	barrelEnd = WorldBarrelPosition();
	Vector worldTargetPosition;
	CBaseEntity *pEntity = (CBaseEntity *)m_hTarget;
	if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) )
	{
		m_hTarget = FindTarget( m_targetEntityName, NULL );
		if ( IsActive() )
		{
			SetNextThink( gpGlobals->curtime + 2 );	// Wait 2 sec s
		}

		return;
	}
	pTarget = pEntity;

	// Calculate angle needed to aim at target
	worldTargetPosition = pEntity->EyePosition();

	float range = (worldTargetPosition - barrelEnd).Length();

	if ( !InRange( range ) )
	{
		m_bFireDelayed = false;
		return;
	}

	UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr );

	lineOfSight = FALSE;
	// No line of sight, don't track
	if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget )
	{
		lineOfSight = TRUE;

		CBaseEntity *pInstance = pTarget;
		if ( InRange( range ) && pInstance && pInstance->IsAlive() )
		{
			updateTime = TRUE;

			// Sight position is BodyTarget with no noise (so gun doesn't bob up and down)
			m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false );
		}
	}

	// Convert targetPosition to parent
	angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) );


	// Force the angles to be relative to the center position
	float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter );
	float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter );
	angles.y = m_yawCenter + offsetY;
	angles.x = m_pitchCenter + offsetX;

	// Move toward target at rate or less
	float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y );

	QAngle vecAngVel = GetLocalAngularVelocity();
	vecAngVel.y = distY * 10;
	vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate );

	// Move toward target at rate or less
	float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x );
	vecAngVel.x = distX  * 10;
	vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate );
	SetLocalAngularVelocity( vecAngVel );

	SetMoveDoneTime( 0.1 );

	Vector forward;
	AngleVectors( GetLocalAngles(), &forward );
	forward = m_parentMatrix.ApplyRotation( forward );

	AngleVectors(angles, &forward);

	if ( lineOfSight == TRUE )
	{
		// FIXME: This will ultimately have to deal with NPCs being in the vehicle as well
		// See if the target is in a vehicle. If so, check its relationship
		CBasePlayer *pPlayer = ToBasePlayer( pTarget );
		if ( pPlayer && pPlayer->IsInAVehicle() )
		{
			IServerVehicle *pVehicle = pPlayer->GetVehicle();
			if ( pVehicle->ClassifyPassenger( pPlayer, CLASS_PLAYER ) == CLASS_PLAYER)
			{
				if ( !m_bFireDelayed )
				{
					m_bFireDelayed = true;
					m_flFiringDelay = gpGlobals->curtime + 1.5;	// setup delay time before we start firing
					return;
				}
				if ( gpGlobals->curtime > m_flFiringDelay )
				{
					m_OnFireAtTarget.Set(forward, this, this);		// tell apc to fire rockets, and what direction
				}
			}
		}
	}
	else
	{
		m_bFireDelayed = false;		// reset flag since we can no longer see target
	}
}
Пример #23
0
//-----------------------------------------------------------------------------
// Purpose: Catches the monster-specific events that occur when tagged animation
//			frames are played.
// Input  : pEvent - 
//-----------------------------------------------------------------------------
void CNPC_PoisonZombie::HandleAnimEvent( animevent_t *pEvent )
{
	
	if ( pEvent->event == AE_ZOMBIE_POISON_PICKUP_CRAB )
	{
		EnableCrab( m_nThrowCrab, false );
		SetBodygroup( ZOMBIE_BODYGROUP_THROW, 1 );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_WARN_SOUND )
	{
		BreatheOffShort();
		EmitSound( "NPC_PoisonZombie.ThrowWarn" );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_SOUND )
	{
		BreatheOffShort();
		EmitSound( "NPC_PoisonZombie.Throw" );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_CRAB )
	{
		SetBodygroup( ZOMBIE_BODYGROUP_THROW, 0 );

		CBlackHeadcrab *pCrab = (CBlackHeadcrab *)CreateNoSpawn( GetHeadcrabClassname(), EyePosition(), vec3_angle, this );
		pCrab->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );
		
		// Fade if our parent is supposed to
		if ( HasSpawnFlags( SF_NPC_FADE_CORPSE ) )
		{
			pCrab->AddSpawnFlags( SF_NPC_FADE_CORPSE );
		}

		// make me the crab's owner to avoid collision issues
		pCrab->SetOwnerEntity( this );

		pCrab->Spawn();

		pCrab->SetLocalAngles( GetLocalAngles() );
		pCrab->SetActivity( ACT_RANGE_ATTACK1 );
		pCrab->SetNextThink( gpGlobals->curtime );
		pCrab->PhysicsSimulate();

		pCrab->GetMotor()->SetIdealYaw( GetAbsAngles().y );

		if ( IsOnFire() )
		{
			pCrab->Ignite( 100.0 );
		}

		CBaseEntity *pEnemy = GetEnemy();
		if ( pEnemy )
		{
			Vector vecEnemyEyePos = pEnemy->EyePosition();
			pCrab->ThrowAt( vecEnemyEyePos );
		}

		if (m_nCrabCount == 0)
		{
			CapabilitiesRemove( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_RANGE_ATTACK2 );
		}

		m_flNextCrabThrowTime = gpGlobals->curtime + random->RandomInt( ZOMBIE_THROW_MIN_DELAY, ZOMBIE_THROW_MAX_DELAY );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_SPIT )
	{
		Vector forward;
		QAngle qaPunch( 45, random->RandomInt(-5, 5), random->RandomInt(-5, 5) );
		AngleVectors( GetLocalAngles(), &forward );
		forward = forward * 200;
		ClawAttack( GetClawAttackRange(), sk_zombie_poison_dmg_spit.GetFloat(), qaPunch, forward, ZOMBIE_BLOOD_BITE );
		return;
	}

	BaseClass::HandleAnimEvent( pEvent );
}
Пример #24
0
//=========================================================
//=========================================================
void CBarnacle :: BarnacleThink ( void )
{
	CBaseEntity *pTouchEnt;
	CBaseMonster *pVictim;
	float flLength;

	SetNextThink( 0.1 );

	if ( m_hEnemy != NULL )
	{
// barnacle has prey.

		if ( !m_hEnemy->IsAlive() )
		{
			// someone (maybe even the barnacle) killed the prey. Reset barnacle.
			m_fLiftingPrey = FALSE;// indicate that we're not lifting prey.
			m_hEnemy = NULL;
			return;
		}

		if ( m_fLiftingPrey )
		{
			if ( m_hEnemy != NULL && m_hEnemy->pev->deadflag != DEAD_NO )
			{
				// crap, someone killed the prey on the way up.
				m_hEnemy = NULL;
				m_fLiftingPrey = FALSE;
				return;
			}

	// still pulling prey.
			Vector vecNewEnemyOrigin = m_hEnemy->pev->origin;
			vecNewEnemyOrigin.x = pev->origin.x;
			vecNewEnemyOrigin.y = pev->origin.y;

			// guess as to where their neck is
			vecNewEnemyOrigin.x -= 6 * cos(m_hEnemy->pev->angles.y * M_PI/180.0);	
			vecNewEnemyOrigin.y -= 6 * sin(m_hEnemy->pev->angles.y * M_PI/180.0);

			m_flAltitude -= BARNACLE_PULL_SPEED;
			vecNewEnemyOrigin.z += BARNACLE_PULL_SPEED;

			if ( fabs( pev->origin.z - ( vecNewEnemyOrigin.z + m_hEnemy->pev->view_ofs.z - 8 ) ) < BARNACLE_BODY_HEIGHT )
			{
	// prey has just been lifted into position ( if the victim origin + eye height + 8 is higher
	// than the bottom of the barnacle, it is assumed that the head is within barnacle's body )
				m_fLiftingPrey = FALSE;

				EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_bite3.wav", 1, ATTN_NORM );	

				pVictim = m_hEnemy->MyMonsterPointer();

				m_flKillVictimTime = gpGlobals->time + 10;// now that the victim is in place, the killing bite will be administered in 10 seconds.

				if ( pVictim )
				{
					pVictim->BarnacleVictimBitten( pev );
					SetActivity ( ACT_EAT );
				}
			}

			UTIL_SetOrigin ( m_hEnemy, vecNewEnemyOrigin );
		}
		else
		{
	// prey is lifted fully into feeding position and is dangling there.

			pVictim = m_hEnemy->MyMonsterPointer();

			if ( m_flKillVictimTime != -1 && gpGlobals->time > m_flKillVictimTime )
			{
				// kill!
				if ( pVictim )
				{
					pVictim->TakeDamage ( pev, pev, pVictim->pev->health, DMG_SLASH | DMG_ALWAYSGIB );
					m_cGibs = 3;
				}

				return;
			}

			// bite prey every once in a while
			if ( pVictim && ( RANDOM_LONG(0,49) == 0 ) )
			{
				switch ( RANDOM_LONG(0,2) )
				{
				case 0:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM );	break;
				case 1:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM );	break;
				case 2:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM );	break;
				}

				pVictim->BarnacleVictimBitten( pev );
			}

		}
	}
	else
	{
// barnacle has no prey right now, so just idle and check to see if anything is touching the tongue.

		// If idle and no nearby client, don't think so often
         		if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) && !HaveCamerasInPVS( edict() ) )
			SetNextThink(  RANDOM_FLOAT(1,1.5) );	// Stagger a bit to keep barnacles from thinking on the same frame

		if ( m_fSequenceFinished )
		{// this is done so barnacle will fidget.
			SetActivity ( ACT_IDLE );
			m_flTongueAdj = -100;
		}

		if ( m_cGibs && RANDOM_LONG(0,99) == 1 )
		{
			// cough up a gib.
			CGib::SpawnRandomGibs( this, 1, 1 );
			m_cGibs--;

			switch ( RANDOM_LONG(0,2) )
			{
			case 0:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM );	break;
			case 1:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM );	break;
			case 2:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM );	break;
			}
		}

		pTouchEnt = TongueTouchEnt( &flLength );

		if ( pTouchEnt != NULL && m_fTongueExtended )
		{
			// tongue is fully extended, and is touching someone.
			if ( pTouchEnt->FBecomeProne() )
			{
				EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_alert2.wav", 1, ATTN_NORM );	

				SetSequenceByName ( "attack1" );
				m_flTongueAdj = -20;

				m_hEnemy = pTouchEnt;

				pTouchEnt->pev->movetype = MOVETYPE_FLY;
				pTouchEnt->pev->velocity = pev->velocity; //LRC- make him come _with_ me
				pTouchEnt->pev->basevelocity = pev->velocity; //LRC
				pTouchEnt->pev->origin.x = pev->origin.x;
				pTouchEnt->pev->origin.y = pev->origin.y;

				m_fLiftingPrey = TRUE;// indicate that we should be lifting prey.
				m_flKillVictimTime = -1;// set this to a bogus time while the victim is lifted.

				m_flAltitude = (pev->origin.z - pTouchEnt->EyePosition().z);
			}
		}
		else
		{
			// calculate a new length for the tongue to be clear of anything else that moves under it. 
			if ( m_flAltitude < flLength )
			{
				// if tongue is higher than is should be, lower it kind of slowly.
				m_flAltitude += BARNACLE_PULL_SPEED;
				m_fTongueExtended = FALSE;
			}
			else
			{
				m_flAltitude = flLength;
				m_fTongueExtended = TRUE;
			}

		}

	}

	// ALERT( at_console, "tounge %f\n", m_flAltitude + m_flTongueAdj );
	SetBoneController( 0, -(m_flAltitude + m_flTongueAdj) );
	StudioFrameAdvance( 0.1 );
}