//------------------------------------------------------------------------
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();
}
//------------------------------------------------------------------------
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();
		}
}
Exemple #3
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;
}
//------------------------------------------------------------------------
void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo)
{
	if (my->CallHook(
		"OnEntityDamage", 
		oohh::GetEntityFromId(simpleHitInfo.targetId), 
		oohh::GetEntityFromId(simpleHitInfo.weaponId), 
		oohh::GetEntityFromId(simpleHitInfo.shooterId), 
		simpleHitInfo.value, 
		Vec3(0,0,0), 
		Vec3(0,0,0)
	))
	{
		if (true)
			return;
	}

	switch (simpleHitInfo.type)
	{
	case 0: // tag
		{
			if (!simpleHitInfo.targetId)
				return;

			// tagged entities are temporary in MP, not in SP.
			bool temp = gEnv->bMultiplayer;

			AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp);
		}
		break;
	case 1: // tac
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId);

			if (pActor && pActor->CanSleep())
				pActor->Fall(Vec3(0.0f,0.0f,0.0f),simpleHitInfo.value);
		}
		break;
	case 0xe: // freeze
		{
			if (!simpleHitInfo.targetId)
				return;
			
			// call OnFreeze
			bool allow=true;
			if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction)
			{
				HSCRIPTFUNCTION func=0;
				m_serverStateScript->GetValue("OnFreeze", func);
				Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow);
				gEnv->pScriptSystem->ReleaseFunc(func);
			}

			if (!allow)
				return;

			if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId))
			{
				IScriptTable *pScriptTable=pEntity->GetScriptTable();

				// call OnFrost
				if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction)
				{
					HSCRIPTFUNCTION func=0;
					pScriptTable->GetValue("OnFrost", func);
					Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value);
					gEnv->pScriptSystem->ReleaseFunc(func);
				}

				FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f);
			}
		}
		break;
	default:
		assert(!"Unknown Simple Hit type!");
	}
}
void CCustomReactionFunctions::FallAndPlay_Reaction(CActor& actor, const SReactionParams& reactionParams, const HitInfo& hitInfo)
{
	actor.Fall();
	DeathImpulse_Reaction(actor, reactionParams, hitInfo);
}
//------------------------------------------------------------------------
void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo)
{
	switch (simpleHitInfo.type)
	{
	case 0: // tag
		{
			if (!simpleHitInfo.targetId)
				return;

			// tagged entities are temporary in MP, not in SP.
//			bool temp = gEnv->bMultiplayer;
			//kirill: - not anymore - design says must stay on
			bool temp = false;

			AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp);
		}
		break;
	case 1: // tac
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId);

			if (pActor && pActor->CanSleep())
			{
				pActor->Fall(Vec3(0.0f,0.0f,0.0f),false,simpleHitInfo.value);
				//This is only used in SP by the player, so don't need further checks
				CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
				if(pPlayer)
					pPlayer->PlaySound(CPlayer::ESound_TacBulletFeedBack,true);
			}
		}
		break;
	case 0xe: // freeze
		{
			if (!simpleHitInfo.targetId)
				return;

			CActor *pActor=GetActorByEntityId(simpleHitInfo.targetId);

			if (pActor && pActor->IsPlayer() && pActor->GetActorClass()==CPlayer::GetActorClassType())
			{
				CPlayer *pPlayer=static_cast<CPlayer *>(pActor);
				if (CNanoSuit *pSuit=pPlayer->GetNanoSuit())
					if (pSuit->IsInvulnerable())
						return;
			}

			// call OnFreeze
			bool allow=true;
			if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction)
			{
				HSCRIPTFUNCTION func=0;
				m_serverStateScript->GetValue("OnFreeze", func);
				Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow);
				gEnv->pScriptSystem->ReleaseFunc(func);
			}

			if (!allow)
				return;

			if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId))
			{
				IScriptTable *pScriptTable=pEntity->GetScriptTable();

				// call OnFrost
				if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction)
				{
					HSCRIPTFUNCTION func=0;
					pScriptTable->GetValue("OnFrost", func);
					Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value);
					gEnv->pScriptSystem->ReleaseFunc(func);
				}

				FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f);
			}
		}
		break;
	default:
		assert(!"Unknown Simple Hit type!");
	}
}