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