Пример #1
0
CBurnEffectManager::TBurnPoints::iterator CBurnEffectManager::FindClosestBurnPoint(const Vec3& point, int surfaceType, const uint8 shooterFactionID)
{
	if (m_burnPoints.empty())
		return m_burnPoints.end();
	float minDist = m_burnPoints[0].m_position.GetSquaredDistance(point);
	TBurnPoints::iterator best = m_burnPoints.end();
	if (minDist <= cry_sqr(m_burnPoints[0].m_radius))
		best = m_burnPoints.begin();
	for (TBurnPoints::iterator it = m_burnPoints.begin()+1; it != m_burnPoints.end(); ++it)
	{
		float dist = it->m_position.GetSquaredDistance(point);
		if (dist < minDist && dist <= cry_sqr(it->m_radius) && (it->m_surfaceType == surfaceType) && (it->m_shooterFactionID == shooterFactionID))
		{
			minDist = dist;
			best = it;
		}
	}
	return best;
}
void CMelee::OnFailedHit()
{
	const SCollisionTestParams& collisionParams = m_collisionHelper.GetCollisionTestParams();

	bool collided = PerformCylinderTest(collisionParams.m_pos, collisionParams.m_dir, collisionParams.m_remote);

	CActor* pOwner = m_pWeapon->GetOwnerActor();

	if(pOwner && pOwner->IsClient())
	{
		if(!collided && s_meleeSnapTargetId)
		{
			Vec3 ownerpos = pOwner->GetEntity()->GetWorldPos();
			IEntity* pTarget = gEnv->pEntitySystem->GetEntity(s_meleeSnapTargetId);

			if(pTarget && ownerpos.GetSquaredDistance(pTarget->GetWorldPos()) < cry_sqr(GetRange() * m_pMeleeParams->meleeparams.target_range_mult))
			{
				collided = m_collisionHelper.PerformMeleeOnAutoTarget(s_meleeSnapTargetId);
			}
		}

		s_meleeSnapTargetId = 0;
		CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_SNAP_TARGET);

		if(g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn)
		{
			pOwner->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);
		}
	}

	if(m_pMeleeAction)
	{
		if(pOwner)
		{
			m_pMeleeAction->OnHitResult(pOwner, collided);
		}
		else
		{
			//Owner has dropped weapon (Likely from being killed) so we can stop and release the action
			m_pMeleeAction->ForceFinish();
			SAFE_RELEASE(m_pMeleeAction);
		}
	}
	
	ApplyMeleeEffects(collided);
}
Пример #3
0
//---------------------------------------------------------------------------
IEntity* CFireModePlugin_AutoAim::CalculateBestProjectileAutoAimTarget(const Vec3& attackerPos, const Vec3& attackerDir, const bool bCurrentlyZoomed, const EntityId ownerId) const
{

#if ALLOW_PROJECTILEHELPER_DEBUGGING
	static const ColorB red(127,0,0);
	static const ColorB green(0,127,0);
	static const ColorB brightGreen(0,255,0);
	static const float s_sphereDebugRad = 0.15f;
#endif


	IEntity* pBestTarget = NULL;
	float    fBestScore  = 0.0f;

	const TAutoaimTargets& players = g_pGame->GetAutoAimManager().GetAutoAimTargets();

	// Cache commonly required constants for scoring
	const ConeParams& aimConeSettings = GetAimConeSettings(bCurrentlyZoomed);

	const float minAutoAimDistSqrd   = cry_sqr(aimConeSettings.m_minDistance);
	const float maxAutoAimDistSqrd   = cry_sqr(aimConeSettings.m_maxDistance);
	const float  coneSizeRads		 = aimConeSettings.m_outerConeRads;
	IEntitySystem* pEntitySystem	 = gEnv->pEntitySystem;
	CPlayerVisTable* pVisTable		 = g_pGame->GetPlayerVisTable();

	const float distanceConstant	 = __fres(max(aimConeSettings.m_maxDistance, FLT_EPSILON));
	const float	coneAngleConstant	 = __fres(max(coneSizeRads*0.5f, FLT_EPSILON));

	// For each potential target we do a dist + cone check
	TAutoaimTargets::const_iterator endIter = players.end();
	for(TAutoaimTargets::const_iterator iter = players.begin(); iter != endIter; ++iter)
	{
		// If entity exists and we are allowed to target them
		EntityId targetEntityId = iter->entityId;
		IEntity* pEntity = pEntitySystem->GetEntity(targetEntityId);
		if(pEntity && AllowedToTargetPlayer(ownerId,targetEntityId))
		{
			// If further than allowed dist, discard
			Vec3 targetTestPos;

			// Test against primary Auto aim position
			const SAutoaimTarget* pAutoAimInfo = g_pGame->GetAutoAimManager().GetTargetInfo(targetEntityId);
			if(pAutoAimInfo)
			{
				targetTestPos = pAutoAimInfo->primaryAimPosition; 
			}
			else
			{
				// Then  ABBB centre as backup
				IEntityPhysicalProxy* pPhysProxy = static_cast<IEntityPhysicalProxy*>(pEntity->GetProxy(ENTITY_PROXY_PHYSICS));
				if(pPhysProxy)
				{
					AABB aabb;
					pPhysProxy->GetWorldBounds(aabb);
					targetTestPos = aabb.GetCenter();
				}
				else
				{
					targetTestPos = pEntity->GetWorldPos();
				}
			}

			Vec3 toTarget = targetTestPos - attackerPos;
			float distSqrd = toTarget.GetLengthSquared();
			if( distSqrd >= minAutoAimDistSqrd &&
				distSqrd <= maxAutoAimDistSqrd )
			{

				// If not within cone.. discard
				float theta = 0.0f;
				if(TargetPositionWithinFrontalCone(attackerPos,targetTestPos, attackerDir,coneSizeRads, theta))
				{
					// If cant see them .. next
					if(!pVisTable->CanLocalPlayerSee(targetEntityId, 5))
					{

#if ALLOW_PROJECTILEHELPER_DEBUGGING
						m_lastTargetRejectionReason.append("VISION BLOCKED"); 	
#endif // #if ALLOW_PROJECTILEHELPER_DEBUGGING

						continue;
					}

					// For each candidate, generate their Auto Aim score.

					// 1) [0.0f,1.0f] score comprised of DISTANCE based score (closer is better)
					float targetDistScore    =  1.0f - ( sqrtf(distSqrd) *  distanceConstant );

					// Lets try squaring this to make candidates with only small gaps between them reflect distance scoring better and reduce the importance of distance at super long ranges
					targetDistScore *= targetDistScore;

					// 2) +  [0.0f,1.0f]  cone based score (central is better)
					const float targetConeScore		 =  1.0f - ( theta * coneAngleConstant );

					// Factor in designer controlled multipliers
					const float finalScore = (targetDistScore * g_pGameCVars->pl_pickAndThrow.chargedThrowAutoAimDistanceHeuristicWeighting) +  // TODO - move these weightings into params
						(targetConeScore * g_pGameCVars->pl_pickAndThrow.chargedThrowAutoAimAngleHeuristicWeighting);

					if(finalScore > fBestScore)
					{
						fBestScore  = finalScore;
						pBestTarget = pEntity;
					}

					// Debug rendering!
#if ALLOW_PROJECTILEHELPER_DEBUGGING
					if(g_pGameCVars->pl_debug_projectileAimHelper)
					{
						CryWatch("Entity [%s - %d] DistScore [%.2f] , ConeScore[%.2f], totalScore [%.3f]", pEntity->GetName(), pEntity->GetId(), targetDistScore, targetConeScore, finalScore);
						
						// Draw a green sphere to indicate valid
						gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad,green);
					}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING

				}
#if ALLOW_PROJECTILEHELPER_DEBUGGING
				else
				{
					m_lastTargetRejectionReason.Format("OUTSIDE CONE [%.3f]",RAD2DEG(theta));

					if(g_pGameCVars->pl_debug_projectileAimHelper)
					{
						// Draw a red sphere to indicate not valid
						gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad, red);
					}
				}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING
			}
#if ALLOW_PROJECTILEHELPER_DEBUGGING
			else
			{
				if(distSqrd >= minAutoAimDistSqrd)
				{
					m_lastTargetRejectionReason.Format("TOO CLOSE [%.3f]", cry_sqrtf_fast(distSqrd)); 
				}
				else
				{
					m_lastTargetRejectionReason.Format("TOO FAR [%.3f]",cry_sqrtf_fast(distSqrd));  
				}
			}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING
		}
	}

	// Draw a Really bright sphere on BEST target
#if ALLOW_PROJECTILEHELPER_DEBUGGING
	if(pBestTarget && g_pGameCVars->pl_debug_projectileAimHelper)
	{
		// If further than allowed dist, discard
		Vec3 targetTestPos = pBestTarget->GetPos();

		// We use aabb centre to reduce error
		IEntityPhysicalProxy* pPhysProxy = static_cast<IEntityPhysicalProxy*>(pBestTarget->GetProxy(ENTITY_PROXY_PHYSICS));
		if(pPhysProxy)
		{
			AABB aabb;
			pPhysProxy->GetWorldBounds(aabb);
			targetTestPos = aabb.GetCenter();
		}

		// Draw a bright green sphere to indicate target chosen
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad*1.05f, brightGreen);
	}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING

	return pBestTarget;
}