Пример #1
0
//-----------------------------------------------------------------------
bool CSpectacularKill::CanExecuteOnTarget(const CActor* pTarget, const SSpectacularKillAnimation& anim) const
{
	CRY_ASSERT(pTarget);

	// can't spectacular kill actors in vehicles
	if(pTarget->GetLinkedVehicle())
		return false;

	// can't spectacular kill when in a hit/death reaction
	if (pTarget->GetActorClass() == CPlayer::GetActorClassType())
	{
		 CHitDeathReactionsConstPtr pHitDeathReactions = static_cast<const CPlayer*>(pTarget)->GetHitDeathReactions();
		 if (pHitDeathReactions && pHitDeathReactions->IsInReaction() && pHitDeathReactions->AreReactionsForbidden())
		 {
			 SK_DEBUG_LOG("Can't start from %s to %s: the target is playing an uninterruptible hit/death reaction", m_pOwner->GetEntity()->GetName(), pTarget->GetEntity()->GetName());

			 return false;
		 }
	}

	if (!CanSpectacularKillOn(pTarget))
		return false;

	// Can't start if they are taking part on other cooperative animation
	ICooperativeAnimationManager* pCooperativeAnimationManager = gEnv->pGame->GetIGameFramework()->GetICooperativeAnimationManager();
	if (pCooperativeAnimationManager->IsActorBusy(m_pOwner->GetEntityId()) ||	pCooperativeAnimationManager->IsActorBusy(m_targetId))
	{
		SK_DEBUG_LOG("Can't start from %s to %s: some of them are taking part in a cooperative animation already", m_pOwner->GetEntity()->GetName(), pTarget->GetEntity()->GetName());

		return false;
	}

	const Vec3 vKillerPos = m_pOwner->GetEntity()->GetWorldPos();
	const Vec3 vTargetPos = pTarget->GetEntity()->GetWorldPos();

	// The height distance between killer and victim needs to be acceptably small (simple check for terrain flatness)
	//  [11/08/2010 davidr] ToDo: Use deferred primitive world intersection checks with asset-dependant dimensions for height 
	// and obstacles detection
	if (fabs_tpl(vKillerPos.z - vTargetPos.z) > g_pGameCVars->g_spectacularKill.maxHeightBetweenActors)
	{
		SK_DEBUG_LOG("Can't start from %s to %s: Ground between killer and target is not flat (height distance is %f)", 
			m_pOwner->GetEntity()->GetName(), pTarget->GetEntity()->GetName(), fabs_tpl(vKillerPos.z - vTargetPos.z));

		return false;
	}

	// Obstacle check
	if (ObstacleCheck(vKillerPos, vTargetPos, anim))
	{
		SK_DEBUG_LOG("Can't start from %s to %s: Obstacles have been found between the actors", 
			m_pOwner->GetEntity()->GetName(), pTarget->GetEntity()->GetName());

		return false;
	}

	return true;
}
Пример #2
0
//------------------------------------------------------------------------
void CGameRules::KnockActorDown( EntityId actorEntityId )
{
		// Forbid fall and play if the actor is playing a hit/death reaction
		CActor* pHitActor = static_cast<CActor*>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor( actorEntityId ));
		if (pHitActor)
		{
				if (pHitActor->GetActorClass() == CPlayer::GetActorClassType())
				{
						// Don't trigger Fall and Play if the actor is playing a hit reaction
						CPlayer* pHitPlayer = static_cast<CPlayer*>(pHitActor);
						CHitDeathReactionsConstPtr pHitDeathReactions = pHitPlayer->GetHitDeathReactions();
						if (!pHitDeathReactions || !pHitDeathReactions->IsInReaction())
								pHitActor->Fall();
				}
				else
						pHitActor->Fall();
		}
}