//------------------------------------------------------------------------ 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(); } }
//----------------------------------------------------------------------- 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!"); } }