//------------------------------------------------------------------------
int CScriptBind_Actor::Fall(IFunctionHandler *pH, Vec3 hitPos)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();

	// [Mikko] 11.10.2007 - Moved the check here, since it was causing too much trouble in CActor.Fall().
	// The point of this filtering is to mostly mask out self-induced collision damage on friendly NPCs
	// which are playing special animations.
	if(!g_pGameCVars->g_enableFriendlyFallAndPlay)
	{
		if (IAnimatedCharacter* pAC = pActor->GetAnimatedCharacter())
		{
			if ((pAC->GetPhysicalColliderMode() == eColliderMode_NonPushable) ||
				(pAC->GetPhysicalColliderMode() == eColliderMode_PushesPlayersOnly))
			{
				// Only mask for player friendly NPCs.
				if (pActor->GetEntity() && pActor->GetEntity()->GetAI())
				{
					IAIObject* pAI = pActor->GetEntity()->GetAI();
					IAIActor* pAIActor = pAI->CastToIAIActor();
					if (pAIActor && pAIActor->GetParameters().m_nSpecies == 0)
					{
						return pH->EndFunction();
					}
				}
			}
		}
	}

	pActor->Fall(hitPos);

	return pH->EndFunction();
}
Exemple #2
0
/**
 * Turn the grabbed AnimatedCharacter on/off if necessary.  If the grabbed thing
 * has an AC, it's necessary to turn it off during the grab to prevent it from
 * interfering and messing with its Entity's transformation.
 */
void CBaseGrabHandler::DisableGrabbedAnimatedCharacter (bool enable) const
{
	CActor *pGrabbedActor = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_grabStats.grabId);
	if ( ! pGrabbedActor) return;

	IAnimatedCharacter * pGrabbedAC = pGrabbedActor->GetAnimatedCharacter();
	if (pGrabbedAC)
		pGrabbedAC->SetNoMovementOverride (enable);

//	SActorStats *stats = static_cast<SActorStats*>(pGrabbedActor->GetActorStats());
//	stats->isGrabbed = enable;

	if(pGrabbedActor->IsClient())
	{
		if(SActorStats *stats = static_cast<SActorStats*>(pGrabbedActor->GetActorStats()))
			stats->isGrabbed = enable;
	}
}
int CScriptBind_Actor::SetMovementControlledByAnimation(IFunctionHandler *pH, bool enable)
{
		CActor *pActor = GetActor(pH);
		if (!pActor)
				return pH->EndFunction();

		IAnimatedCharacter* pAnimChar = pActor->GetAnimatedCharacter();
		if (!pAnimChar)
				return pH->EndFunction();

		if(enable)
		{
				pAnimChar->SetMovementControlMethods(eMCM_AnimationHCollision, eMCM_Animation);
				pAnimChar->UseAnimationMovementForEntity( true, true, true );
		}
		else
		{
				pAnimChar->SetMovementControlMethods( eMCM_Entity, eMCM_Entity );
				pAnimChar->UseAnimationMovementForEntity( false, false, false );
		}
		
		return pH->EndFunction();
}
void CHeavyMountedWeapon::FinishRipOff()
{
	m_rippingOff = false;
	m_rippedOff = true;
	
	RemoveViewLimits();

	if(IsClient() && gEnv->pGame->GetIGameFramework()->GetClientActorId()==GetOwnerId())
	{
		if(IEntity* pEntity = GetEntity())
		{
			const char* collectibleId = pEntity->GetClass()->GetName();
			CPersistantStats* pStats = g_pGame->GetPersistantStats();
			if(pStats && pStats->GetStat(collectibleId, EMPS_SPWeaponByName) == 0)
			{
				pStats->SetMapStat(EMPS_SPWeaponByName, collectibleId, eDatabaseStatValueFlag_Available);

				if(!gEnv->bMultiplayer)
				{
					// Show hud unlock msg
					SHUDEventWrapper::DisplayWeaponUnlockMsg(collectibleId);
				}
			}
		}
	}

	CActor* pOwner = GetOwnerActor();
	IActionController* pController = pOwner ? pOwner->GetAnimatedCharacter()->GetActionController() : NULL;
	if(pController)
	{
		CMannequinUserParamsManager& mannequinUserParams = g_pGame->GetIGameFramework()->GetMannequinInterface().GetMannequinUserParamsManager();
		const SMannequinItemParams* pParams = mannequinUserParams.FindOrCreateParams<SMannequinItemParams>(pController);

		UpdateMountedTags(pParams, pController->GetContext().state, true);
	}
}
Exemple #5
0
//-----------------------------------------------------------------------
void CSpectacularKill::End(bool bKillerDied/* = false*/)
{
	CRY_ASSERT_MESSAGE(IsBusy(), "spectacular kill cannot be stopped if it is not in progress");
	if (!IsBusy())
		return;

	ICooperativeAnimationManager* pCooperativeAnimationManager = gEnv->pGame->GetIGameFramework()->GetICooperativeAnimationManager();

	CActor* pTarget = GetTarget();
	CRY_ASSERT(pTarget);
	if(pTarget)
	{
		pCooperativeAnimationManager->StopCooperativeAnimationOnActor(m_pOwner->GetAnimatedCharacter(), pTarget->GetAnimatedCharacter());

		// Enable AI again (for what it's worth - this helps editor)
		if (!pTarget->IsPlayer() && pTarget->GetEntity()->GetAI())
			pTarget->GetEntity()->GetAI()->Event(AIEVENT_ENABLE, 0);

		if (bKillerDied && (m_deathBlowState == eDBS_None) && static_cast<CPlayer*> (pTarget)->CanFall())
		{
			// Enable Fall n Play on target if killer dies before death blowing it
			pTarget->Fall();
		}
		else if (m_deathBlowState != eDBS_Done)
		{
			DeathBlow(*pTarget); // Call this in case the notification from the animation system got skipped or missed for some reason
		}

		SActorStats* pTargetStats = pTarget->GetActorStats();
		pTargetStats->spectacularKillPartner = 0;
	}
	else
	{
		pCooperativeAnimationManager->StopCooperativeAnimationOnActor(m_pOwner->GetAnimatedCharacter());
	}

	// Enable AI again (for what it's worth - this helps editor)
	if (m_pOwner && m_pOwner->GetEntity()->GetAI())
		m_pOwner->GetEntity()->GetAI()->Event(AIEVENT_ENABLE, 0);

	ClearState();

  assert(m_pOwner);
	SActorStats* pStats = m_pOwner->GetActorStats();
	if(pStats)
		pStats->spectacularKillPartner = 0;
}
//------------------------------------------------------------------------
int CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, EntityId collidedEntityId, int partId, int ipart, int surfaceIdx, bool remote)
{
	MeleeDebugLog ("CMelee<%p> HitPointDirNormal(remote=%s)", this, remote ? "true" : "false");
	int hitTypeID = 0;

	CActor *pOwnerActor = m_pWeapon->GetOwnerActor();

	if (pOwnerActor)
	{	
		IActor* pTargetActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(collidedEntityId);
		IEntity* pTarget = pTargetActor ? pTargetActor->GetEntity() : gEnv->pEntitySystem->GetEntity(collidedEntityId);
		IEntity* pOwnerEntity = pOwnerActor->GetEntity();
		IAIObject* pOwnerAI = pOwnerEntity->GetAI();
		
		float damageScale = 1.0f;
		bool silentHit = false;

		if(pTargetActor)
		{
			IAnimatedCharacter* pTargetAC = pTargetActor->GetAnimatedCharacter();
			IAnimatedCharacter* pOwnerAC = pOwnerActor->GetAnimatedCharacter();

			if(pTargetAC && pOwnerAC)
			{
				Vec3 targetFacing(pTargetAC->GetAnimLocation().GetColumn1());
				Vec3 ownerFacing(pOwnerAC->GetAnimLocation().GetColumn1());
				float ownerFacingDot = ownerFacing.Dot(targetFacing);
				float fromBehindDot = cos_tpl(DEG2RAD(g_pGameCVars->pl_melee.angle_limit_from_behind));

				if(ownerFacingDot > fromBehindDot)
				{
#ifndef _RELEASE
					if (g_pGameCVars->g_LogDamage)
					{
						CryLog ("[DAMAGE] %s '%s' is%s meleeing %s '%s' from behind (because %f > %f)",
							pOwnerActor->GetEntity()->GetClass()->GetName(), pOwnerActor->GetEntity()->GetName(), silentHit ? " silently" : "",
							pTargetActor->GetEntity()->GetClass()->GetName(), pTargetActor->GetEntity()->GetName(),
							ownerFacingDot, fromBehindDot);
					}
#endif

					damageScale *= g_pGameCVars->pl_melee.damage_multiplier_from_behind;
				}
			}
		}


		// Send target stimuli
		if (!gEnv->bMultiplayer)
		{
			IAISystem *pAISystem = gEnv->pAISystem;
			ITargetTrackManager *pTargetTrackManager = pAISystem ? pAISystem->GetTargetTrackManager() : NULL;
			if (pTargetTrackManager && pOwnerAI)
			{
				IAIObject *pTargetAI = pTarget ? pTarget->GetAI() : NULL;
				if (pTargetAI)
				{
					const tAIObjectID aiOwnerId = pOwnerAI->GetAIObjectID();
					const tAIObjectID aiTargetId = pTargetAI->GetAIObjectID();

					TargetTrackHelpers::SStimulusEvent eventInfo;
					eventInfo.vPos = pt;
					eventInfo.eStimulusType = TargetTrackHelpers::eEST_Generic;
					eventInfo.eTargetThreat = AITHREAT_AGGRESSIVE;
					pTargetTrackManager->HandleStimulusEventForAgent(aiTargetId, aiOwnerId, "MeleeHit",eventInfo);
					pTargetTrackManager->HandleStimulusEventInRange(aiOwnerId, "MeleeHitNear", eventInfo, 5.0f);
				}
			}
		}

		//Check if is a friendly hit, in that case FX and Hit will be skipped
		bool isFriendlyHit = (pOwnerEntity && pTarget) ? IsFriendlyHit(pOwnerEntity, pTarget) : false;

		if(!isFriendlyHit)
		{
			CPlayer * pAttackerPlayer = pOwnerActor->IsPlayer() ? static_cast<CPlayer*>(pOwnerActor) : NULL;
			float damage = m_pMeleeParams->meleeparams.damage_ai;

			if(pOwnerActor->IsPlayer())
			{
				damage = m_slideKick ? m_pMeleeParams->meleeparams.slide_damage : GetMeleeDamage();
			}

#ifndef _RELEASE
			if (pTargetActor && g_pGameCVars->g_LogDamage)
			{
				CryLog ("[DAMAGE] %s '%s' is%s meleeing %s '%s' applying damage = %.3f x %.3f = %.3f",
					pOwnerActor->GetEntity()->GetClass()->GetName(), pOwnerActor->GetEntity()->GetName(), silentHit ? " silently" : "",
					pTargetActor->GetEntity()->GetClass()->GetName(), pTargetActor->GetEntity()->GetName(),
					damage, damageScale, damage * damageScale);
			}
#endif

			//Generate Hit
			if(pTarget)
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();
				CRY_ASSERT_MESSAGE(pGameRules, "No game rules! Melee can not apply hit damage");

				if (pGameRules)
				{
					hitTypeID = silentHit ? CGameRules::EHitType::SilentMelee : m_hitTypeID;
					HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(),
						damage * damageScale, 0.0f, surfaceIdx, partId, hitTypeID, pt, dir, normal);

					if (m_pMeleeParams->meleeparams.knockdown_chance>0 && Random(100) < m_pMeleeParams->meleeparams.knockdown_chance)
						info.knocksDown = true;

					info.remote = remote;

					pGameRules->ClientHit(info);
				}

				if (pAttackerPlayer && pAttackerPlayer->IsClient())
				{
					const Vec3 posOffset = (pt - pTarget->GetWorldPos());
					SMeleeHitParams params;

					params.m_boostedMelee = false;
					params.m_hitNormal = normal;
					params.m_hitOffset = posOffset;
					params.m_surfaceIdx = surfaceIdx;
					params.m_targetId = pTarget->GetId();

					pAttackerPlayer->OnMeleeHit(params);
				}
			}
			else
			{
				//Play Material FX
				PlayHitMaterialEffect(pt, normal, false, surfaceIdx);
			}
		}

		if (pTarget)
		{
			CActor *pCTargetActor = static_cast<CActor*>(pTargetActor);
			CPlayer* pTargetPlayer = (pTargetActor && pTargetActor->IsPlayer()) ? static_cast<CPlayer*>(pTargetActor) : NULL;

			if(pTargetPlayer && pTargetPlayer->IsClient())
			{
				if(m_pMeleeParams->meleeparams.trigger_client_reaction)
				{
					pTargetPlayer->TriggerMeleeReaction();
				}
			}
		}
	}

	return hitTypeID;
}