virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo ) { if (event != eFE_Activate) return; if (!InputEntityIsLocalPlayer( pActInfo )) return; const bool bTriggered = IsPortActive(pActInfo, EIP_Trigger); const bool bFreqTriggered = IsPortActive(pActInfo, EIP_Frequency); if (bTriggered == false && bFreqTriggered == false) return; IGameFramework* pGF = gEnv->pGame->GetIGameFramework(); IView* pView = 0; IView* pActiveView = pGF->GetIViewSystem()->GetActiveView(); int viewType = GetPortInt(pActInfo, EIP_ViewType); if (viewType == VT_FirstPerson) // use player's view { IActor* pActor = pGF->GetClientActor(); if (pActor == 0) return; const int restriction = GetPortInt(pActInfo, EIP_Restriction); if (restriction != ER_None) { IVehicle* pVehicle = pActor->GetLinkedVehicle(); if (restriction == ER_InVehicle && pVehicle == 0) return; if (restriction == ER_NoVehicle && pVehicle != 0 /* && pVehicle->GetSeatForPassenger(entityId) != 0 */) return; } EntityId entityId = pActor->GetEntityId(); pView = pGF->GetIViewSystem()->GetViewByEntityId(entityId); } else // active view { pView = pActiveView; } if (pView == 0 || pView != pActiveView) return; const bool bGroundOnly = GetPortBool(pActInfo, EIP_GroundOnly); Ang3 angles = Ang3(DEG2RAD(GetPortVec3(pActInfo, EIP_Angle))); Vec3 shift = GetPortVec3(pActInfo, EIP_Shift); const float duration = GetPortFloat(pActInfo, EIP_Duration); float freq = GetPortFloat(pActInfo, EIP_Frequency); if (iszero(freq) == false) freq = 1.0f / freq; const float randomness = GetPortFloat(pActInfo, EIP_Randomness); static const bool bFlip = true; // GetPortBool(pActInfo, EIP_Flip); const bool bUpdateOnly = !bTriggered && bFreqTriggered; // it's an update if and only if Frequency has been changed const float distance = GetPortFloat(pActInfo, EIP_Distance); const float rangeMin = GetPortFloat(pActInfo, EIP_RangeMin); const float rangeMax = GetPortFloat(pActInfo, EIP_RangeMax); float amount = min(1.f, max(0.f, (rangeMax-distance) / (rangeMax-rangeMin) )); angles *= amount; shift *= amount; pView->SetViewShake(angles, shift, duration, freq, randomness, FLOWGRAPH_SHAKE_ID, bFlip, bUpdateOnly, bGroundOnly); }
//------------------------------------------- void CGameRules::ProcessClientExplosionScreenFX(const ExplosionInfo &explosionInfo) { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if (pClientActor) { //Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); //Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) CActor *pActor = (CActor *)pClientActor; SMovementState state; if (IMovementController *pMV = pActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; eyeToExplosion.Normalize(); bool inFOV = (state.eyeDirection.Dot(eyeToExplosion) > 0.68f); // if in a vehicle eyeDirection is wrong if(pActor && pActor->GetLinkedVehicle()) { Vec3 eyeDir = static_cast<CPlayer*>(pActor)->GetVehicleViewDir(); inFOV = (eyeDir.Dot(eyeToExplosion) > 0.68f); } //All explosions have radial blur (default 30m radius, to make Sean happy =)) float maxBlurDistance = (explosionInfo.maxblurdistance>0.0f)?explosionInfo.maxblurdistance:30.0f; if (maxBlurDistance>0.0f && g_pGameCVars->g_radialBlur>0.0f && m_explosionScreenFX && explosionInfo.radius>0.5f) { if (inFOV && dist < maxBlurDistance) { ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1); //If there was no obstacle between flashbang grenade and player if(!col) { if (CScreenEffects* pSE = pActor->GetScreenEffects()) { float blurRadius = (-1.0f/maxBlurDistance)*dist + 1.0f; gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Radius", blurRadius); gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Amount", 1.0f); IBlendedEffect *pBlur = CBlendedEffect<CPostProcessEffect>::Create(CPostProcessEffect(pClientActor->GetEntityId(),"FilterRadialBlurring_Amount", 0.0f)); IBlendType *pLinear = CBlendType<CLinearBlend>::Create(CLinearBlend(1.0f)); pSE->StartBlend(pBlur, pLinear, 1.0f, CScreenEffects::eSFX_GID_RBlur); pSE->SetUpdateCoords("FilterRadialBlurring_ScreenPosX","FilterRadialBlurring_ScreenPosY", explosionInfo.pos); } float distAmp = 1.0f - (dist / maxBlurDistance); if (gEnv->pInput) gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f, distAmp*3.0f, 0.0f)); } } } //Flashbang effect if(dist<explosionInfo.radius && inFOV && (!strcmp(explosionInfo.effect_class,"flashbang") || !strcmp(explosionInfo.effect_class,"FlashbangAI"))) { ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1); //If there was no obstacle between flashbang grenade and player if(!col) { float power = explosionInfo.flashbangScale; power *= max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = (eyeToExplosion.Dot(state.eyeDirection.normalize()) + 1)*0.5f; power *= lookingAt; SAFE_GAMEAUDIO_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION,MIN(power*40.0f,100.0f))); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", 1.0f + (power * 4)); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount",explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", (power * 2)); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1); } } else if(inFOV && (dist < explosionInfo.radius)) { if (explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { //Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; pActor->AddAngularImpulse(Ang3(Random(-angleX*0.5f,angleX),0.0f,Random(-angleZ,angleZ)),0.0f,dt*2.0f); } } float fDist2=(pClientActor->GetEntity()->GetWorldPos()-explosionInfo.pos).len2(); if (fDist2<250.0f*250.0f) { if (fDist2<sqr(SAFE_GAMEAUDIO_BATTLESTATUS_FUNC_RET(GetBattleRange()))) SAFE_GAMEAUDIO_BATTLESTATUS_FUNC(TickBattleStatus(1.0f)); } } }
//-------------------------------------------------------------------------- //--- ViewPreProcess //-------------------------------------------------------------------------- // Fetch all the data we need to work on. //-------------------------------------------------------------------------- void CPlayerView::ViewPreProcess(const CPlayer &rPlayer, SViewParams &viewParams, SViewStateIn &m_in) { // SViewStateIn --- the constants { m_in.lastPos = viewParams.position; m_in.lastQuat = viewParams.rotation; m_in.defaultFov = g_pGameCVars->cl_fov; m_in.frameTime = min(gEnv->pTimer->GetFrameTime(), 0.1f); m_in.pCharacter = rPlayer.GetEntity()->GetCharacter(0); m_in.pVehicle = rPlayer.GetLinkedVehicle(); m_in.bIsGrabbing = false; /*if (rPlayer.m_grabStats.grabId>0) { m_in.bIsGrabbing=true; // ***** viewParams.nearplane = 0.1f; // ***** }*/ m_in.stats_isRagDoll = rPlayer.m_stats.isRagDoll; m_in.stats_isStandingUp = rPlayer.m_stats.isStandingUp; m_in.stats_isFrozen = rPlayer.m_stats.isFrozen.Value(); m_in.stats_isShattered = rPlayer.m_stats.isShattered.Value(); m_in.stats_followCharacterHead = rPlayer.m_stats.followCharacterHead.Value(); m_in.stats_flatSpeed = rPlayer.m_stats.speedFlat; m_in.stats_leanAmount = rPlayer.m_stats.leanAmount; m_in.stats_inAir = rPlayer.m_stats.inAir; m_in.stats_inWater = rPlayer.m_stats.inWaterTimer; m_in.stats_headUnderWater = (rPlayer.m_stats.headUnderWaterTimer > 0.0f); m_io.stats_jumped = rPlayer.m_stats.jumped; m_in.stats_firstPersonBody = rPlayer.m_stats.firstPersonBody.Value(); m_in.stats_onGround = rPlayer.m_stats.onGround; m_io.stats_landed = rPlayer.m_stats.landed; m_in.stats_velocity = rPlayer.m_stats.velocity; m_in.bSprinting = rPlayer.m_stats.bSprinting; m_io.stats_inFreefall = rPlayer.m_stats.inFreefall.Value(); m_in.stats_onLadder = rPlayer.m_stats.isOnLadder; m_in.bLookingAtFriendlyAI = rPlayer.m_stats.bLookingAtFriendlyAI; m_in.bIsGrabbed = rPlayer.m_stats.isGrabbed; m_in.params_viewFoVScale = rPlayer.m_params.viewFoVScale; m_in.params_viewPivot = rPlayer.m_params.viewPivot; m_in.params_viewDistance = rPlayer.m_params.viewDistance; m_in.params_weaponInertiaMultiplier = rPlayer.m_params.weaponInertiaMultiplier; m_in.params_hudAngleOffset = rPlayer.m_params.hudAngleOffset; m_in.params_hudOffset = rPlayer.m_params.hudOffset; m_in.params_viewHeightOffset = rPlayer.m_params.viewHeightOffset; m_in.params_weaponBobbingMultiplier = rPlayer.m_params.weaponBobbingMultiplier; m_io.bobMul = g_pGameCVars->cl_bob * m_in.params_weaponBobbingMultiplier; m_in.bIsThirdPerson = rPlayer.IsThirdPerson(); m_in.vEntityWorldPos = rPlayer.GetEntity()->GetWorldPos(); m_in.entityId = rPlayer.GetEntityId(); // use absolute entity matrix when frozen if (rPlayer.m_stats.isFrozen.Value()) { m_in.entityWorldMatrix = Matrix34(rPlayer.GetEntity()->GetWorldTM()); } else { m_in.entityWorldMatrix = Matrix34(rPlayer.GetEntity()->GetSlotWorldTM(0)); } m_in.localEyePos = rPlayer.GetLocalEyePos(); m_in.worldEyePos = m_in.entityWorldMatrix * m_in.localEyePos; m_in.headMtxLocal.SetIdentity(); if (m_in.stats_followCharacterHead) { int16 joint_id = rPlayer.GetBoneID(BONE_HEAD); if (joint_id >= 0) { m_in.headMtxLocal = Matrix33(m_in.pCharacter->GetISkeletonPose()->GetAbsJointByID(joint_id).q.GetNormalized()); } } m_in.thirdPersonDistance = g_pGameCVars->cl_tpvDist; m_in.thirdPersonYaw = g_pGameCVars->cl_tpvYaw; EStance refStance((rPlayer.m_stance == STANCE_PRONE) ? STANCE_PRONE : STANCE_STAND); m_in.stand_MaxSpeed = rPlayer.GetStanceInfo(refStance)->maxSpeed; m_in.standSpeed = rPlayer.GetStanceMaxSpeed(refStance); m_in.health = rPlayer.GetHealth(); m_in.stance = rPlayer.m_stance; m_in.shake = g_pGameCVars->cl_sprintShake; m_in.deathTime = rPlayer.GetDeathTime(); } // SViewStateInOut -- temporaries and output { //--- temporaries - FirstThird shared //m_io.bUsePivot //m_io.bobMul //m_io.viewQuatForWeapon //m_io.eyeOffsetGoal //--- temporaries - view shared m_io.wAngles = Ang3(0, 0, 0); //--- I/O //m_io.m_lastPos=rPlayer.m_lastPos; // Integ //if (m_io.m_lastPos.len2()>0.01f) //{ // m_io.blendViewOffset = m_io.m_lastPos - rPlayer.GetEntity()->GetWorldPos(); // m_io.m_lastPos.Set(0,0,0); //} } // ***** viewParams.fov = m_in.defaultFov * rPlayer.m_params.viewFoVScale * (gf_PI / 180.0f); viewParams.nearplane = 0.0f; // ***** m_io.eyeOffsetViewGoal = rPlayer.GetStanceViewOffset(rPlayer.m_stance); m_io.viewQuatFinal = rPlayer.m_viewQuatFinal; m_io.viewQuat = rPlayer.m_viewQuat; m_io.stats_FPWeaponAngles = rPlayer.m_stats.FPWeaponAngles; m_io.stats_FPWeaponPos = rPlayer.m_stats.FPWeaponPos; m_io.vFPWeaponOffset = rPlayer.m_FPWeaponOffset; m_io.stats_FPSecWeaponAngles = rPlayer.m_stats.FPSecWeaponAngles; m_io.stats_FPSecWeaponPos = rPlayer.m_stats.FPSecWeaponPos; //m_io.viewShake=rPlayer.m_viewShake; m_io.eyeOffsetView = rPlayer.m_eyeOffsetView; m_io.baseQuat = rPlayer.m_baseQuat; m_io.vFPWeaponAngleOffset = rPlayer.m_FPWeaponAngleOffset; m_io.stats_bobCycle = rPlayer.m_stats.bobCycle; m_io.vFPWeaponLastDirVec = rPlayer.m_FPWeaponLastDirVec; m_io.bobOffset = rPlayer.m_bobOffset; m_io.angleOffset = rPlayer.m_angleOffset; m_io.viewAngleOffset = rPlayer.m_viewAnglesOffset; m_in.stats_flyMode = rPlayer.m_stats.flyMode; m_in.stats_spectatorMode = rPlayer.m_stats.spectatorMode; m_in.stats_spectatorTarget = rPlayer.m_stats.spectatorTarget; m_io.stats_smoothViewZ = rPlayer.m_stats.smoothViewZ; m_io.stats_smoothZType = rPlayer.m_stats.smoothZType; //-- Any individual PreProcess handlers should be called here }
inputParams.rangeMin = GetPortFloat(pActInfo, EIP_RangeMin); inputParams.rangeMax = GetPortFloat(pActInfo, EIP_RangeMax); inputParams.sustainDuration = GetPortFloat(pActInfo, EIP_SustainDuration); inputParams.fadeInDuration = GetPortFloat(pActInfo, EIP_FadeInDuration); inputParams.fadeOutDuration = GetPortFloat(pActInfo, EIP_FadeOutDuration); } } static SInputParams m_Presets[NUM_PRESETS]; int m_lastShakeFrameID; }; CFlowNode_CameraViewShakeEx::SInputParams CFlowNode_CameraViewShakeEx::m_Presets[]= { // Ground Smooth angle shift fr rnd d rm rm sd fi fo { "DistantExplosion", ER_None, VT_FirstPerson, false, false, Ang3(0.6f, 0.6f, 0.6f), Vec3(0.001f, 0.001f, 0.001f), 10, 2, 0, 0, 30, 0, 0.2f, 1.2f }, { "CloseExplosion", ER_None, VT_FirstPerson, false, false, Ang3(0.5f, 0.5f, 0.5f), Vec3(0.003f, 0.003f, 0.003f), 30, 5, 0, 0, 30, 0, 0, 1.1f }, { "SmallTremor", ER_None, VT_FirstPerson, false, false, Ang3(0.2f, 0.2f, 0.2f), Vec3(0.0001f, 0.0001f, 0.0001f), 18, 1.3f, 0, 0, 30, 2, 1.2f, 3.f }, { "SmallTremor2", ER_None, VT_FirstPerson, false, false, Ang3(0.25f, 0.25f, 0.25f), Vec3(0.00045f, 0.00045f, 0.00045f), 13, 2, 0, 0, 30, 2, 1.2f, 3.f }, }; ////////////////////////////////////////////////////////////////////////// class CFlowNode_CameraView : public CFlowBaseNode<eNCT_Instanced> { private: IView* m_pView; IView* m_pLocalPlayerView; IViewSystem* m_pViewSystem; public: CFlowNode_CameraView( SActivationInfo * pActInfo ):
void CPlayerView::ViewThirdPerson(SViewParams &viewParams) { if (m_in.thirdPersonYaw > 0.001f) { viewParams.rotation *= Quat::CreateRotationXYZ(Ang3(0, 0, m_in.thirdPersonYaw * gf_PI / 180.0f)); m_io.viewQuatFinal = viewParams.rotation; } if (g_pGameCVars->goc_enable) { Vec3 target(g_pGameCVars->goc_targetx, g_pGameCVars->goc_targety, g_pGameCVars->goc_targetz); static Vec3 current(target); Interpolate(current, target, 5.0f, m_in.frameTime); // make sure we don't clip through stuff that much Vec3 offsetX(0, 0, 0); Vec3 offsetY(0, 0, 0); Vec3 offsetZ(0, 0, 0); offsetX = m_io.viewQuatFinal.GetColumn0() * current.x; offsetY = m_io.viewQuatFinal.GetColumn1() * (current.y - 0.25f); offsetZ = m_io.viewQuatFinal.GetColumn2() * current.z; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId); if (pActor) { static ray_hit hit; IPhysicalEntity *pSkipEntities[10]; int nSkip = 0; IItem *pItem = pActor->GetCurrentItem(); if (pItem) { CWeapon *pWeapon = (CWeapon *)pItem->GetIWeapon(); if (pWeapon) { nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } } float oldLen = offsetY.len(); Vec3 start = m_io.baseQuat * m_io.eyeOffsetView + viewParams.position + offsetX + offsetZ; if (gEnv->pPhysicalWorld->RayWorldIntersection(start, offsetY, ent_static | ent_terrain | ent_rigid, rwi_ignore_noncolliding | rwi_stop_at_pierceable, &hit, 1, pSkipEntities, nSkip)) { offsetY = hit.pt - start; current.y = current.y * (hit.dist / oldLen); } } //viewParams.position += m_io.viewQuatFinal.GetColumn0() * current.x; // right //viewParams.position += m_io.viewQuatFinal.GetColumn1() * current.y; // back //viewParams.position += m_io.viewQuatFinal.GetColumn2() * current.z; // up viewParams.position += offsetX + offsetY + offsetZ; } else { if (m_io.bUsePivot) { viewParams.position += m_io.viewQuatFinal.GetColumn1() * m_in.params_viewDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset); } else { viewParams.position += m_io.viewQuatFinal.GetColumn1() * -m_in.thirdPersonDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset); } } }
// // Extract the various modifiers out into their own function. // // Aim is to make the code easier to understand and modify, as // well as to ease the addition of new modifiers. // void CPlayerView::ViewFirstPerson(SViewParams &viewParams) { //headbob Ang3 angOffset(0, 0, 0); Vec3 weaponOffset(0, 0, 0); Ang3 weaponAngleOffset(0, 0, 0); // jump/land spring effect. Adjust the eye and weapon pos as required. FirstPersonJump(viewParams, weaponOffset, weaponAngleOffset); //float standSpeed(GetStanceMaxSpeed(STANCE_STAND)); Vec3 vSpeed(0, 0, 0); if (m_in.standSpeed > 0.001f) { vSpeed = (m_in.stats_velocity / m_in.standSpeed); } float vSpeedLen(vSpeed.len()); if (vSpeedLen > 1.5f) { vSpeed = vSpeed / vSpeedLen * 1.5f; } float speedMul(0); if (m_in.standSpeed > 0.001f) { speedMul = (m_in.stats_flatSpeed / m_in.standSpeed * 1.1f); } speedMul = min(1.5f, speedMul); bool crawling(m_in.stance == STANCE_PRONE /*&& m_in.stats_flatSpeed>0.1f*/ && m_in.stats_onGround > 0.1f); bool weaponZoomed = false; bool weaponZooming = false; //Not crawling while in zoom mode IActor *owner = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId); if(owner && owner->IsPlayer()) { IItem *pItem = owner->GetCurrentItem(); if(pItem) { CWeapon *pWeapon = static_cast<CWeapon *>(pItem->GetIWeapon()); if(pWeapon) { weaponZoomed = pWeapon->IsZoomed(); weaponZooming = pWeapon->IsZoomingInOrOut(); if(weaponZoomed || weaponZooming) { crawling = false; } } } } // On the ground. if (m_in.stats_inAir < 0.1f /*&& m_in.stats_inWater < 0.1f*/) { //--- Bobbing. // bobCycle is a speed varying time step running (looping) from 0 to 1 // this feeds into a sin eqn creating a double horizontal figure of 8. // ( a lissajous figure with the vertical freq twice the horz freq ). // To tweak the total speed of the curve: // To tweak the effect speed has on the curve: float kSpeedToBobFactor = 1.15f; //0.9f // To tweak the width of the bob: float kBobWidth = 0.1f; // To tweak the height of the bob: float kBobHeight = 0.05f; // To tweak the scale of strafing lag: (may need to manually adjust the strafing angle offsets as well.) const float kStrafeHorzScale = 0.05f; kBobWidth = 0.15f; kBobHeight = 0.06f; m_io.stats_bobCycle += m_in.frameTime * kSpeedToBobFactor * speedMul;// * (m_in.bSprinting?1.25f:1.0f); //if player is standing set the bob to rest. (bobCycle reaches 1.0f within 1 second) if (speedMul < 0.1f) { m_io.stats_bobCycle = min(m_io.stats_bobCycle + m_in.frameTime * 1.0f, 1.0f); } // bobCycle loops between 0 and 1 if (m_io.stats_bobCycle > 1.0f) { m_io.stats_bobCycle = m_io.stats_bobCycle - 1.0f; } if (crawling) { kBobWidth *= 2.0f * speedMul; } else if (m_in.bSprinting) { kBobWidth *= 1.25f * speedMul; } //set the bob offset Vec3 bobDir(cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f)*kBobWidth * speedMul, 0, cry_sinf(m_io.stats_bobCycle * gf_PI * 4.0f)*kBobHeight * speedMul); //not the bob offset for the weapon bobDir *= 0.25f; //if player is strafing shift a bit the weapon on left/right if (speedMul > 0.01f) { // right vector dot speed vector float dot(m_io.viewQuatFinal.GetColumn0() * vSpeed); bobDir.x -= dot * kStrafeHorzScale; // the faster we move right, the more the gun lags to the left and vice versa //tweak the right strafe for weapon laser if (dot > 0.0f) { weaponAngleOffset.z += dot * 1.5f; // kStrafeHorzScale } else { weaponAngleOffset.z -= dot * 2.0f; // kStrafeHorzScale } weaponAngleOffset.y += dot * 5.0f; // kStrafeHorzScale } //CryLogAlways("bobDir.z: %f", bobDir.z); if (bobDir.z < 0.0f) { bobDir.x *= 1.0f; bobDir.y *= 1.0f; bobDir.z *= 0.35f; speedMul *= 0.65f; } else { bobDir.z *= 1.85f; } //CryLogAlways("bobDir.z: %f after", bobDir.z); weaponOffset += m_io.viewQuatFinal * bobDir; weaponOffset -= m_io.baseQuat.GetColumn2() * 0.035f * speedMul; weaponAngleOffset.y += cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * speedMul * -1.5f; if (crawling) { weaponAngleOffset.y *= 3.0f; } weaponAngleOffset.x += speedMul * 1.5f; if (crawling) { weaponAngleOffset.z += cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * speedMul * 3.0f; } //FIXME: viewAngles must include all the view offsets, otherwise aiming wont be precise. angOffset.x += cry_sinf(m_io.stats_bobCycle * gf_PI * 4.0f) * 0.7f * speedMul; if (crawling) { angOffset.x *= 2.5f; angOffset.y += cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * 1.25f * speedMul; angOffset.z -= cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * 2.5f * speedMul; } else if (m_in.bSprinting) { angOffset.x *= 2.5f; angOffset.y += cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * 1.0f * speedMul; angOffset.z -= cry_sinf(m_io.stats_bobCycle * gf_PI * 2.0f) * 2.25f * speedMul; } else if(m_in.stance == STANCE_CROUCH && !weaponZoomed && !weaponZooming) { weaponOffset.z += 0.035f; weaponOffset.y -= m_io.viewQuatFinal.GetColumn1().y * 0.03f; } else if(m_in.stance == STANCE_CROUCH && weaponZooming) { weaponOffset.z -= 0.07f; weaponOffset.y += m_io.viewQuatFinal.GetColumn1().y * 0.06f; } else { //angOffset.x *= 2.25f; //angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*0.5f*speedMul; //angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.125f*speedMul; } } else { m_io.stats_bobCycle = 0; //while flying offset a bit the weapon model by the player speed if (m_in.stats_velocity.len2() > 0.001f) { float dotFwd(m_io.viewQuatFinal.GetColumn1() * vSpeed); float dotSide(m_io.viewQuatFinal.GetColumn0() * vSpeed); float dotUp(m_io.viewQuatFinal.GetColumn2() * vSpeed); weaponOffset += m_io.viewQuatFinal * Vec3(dotSide * -0.05f, dotFwd * -0.035f, dotUp * -0.05f); weaponAngleOffset.x += dotUp * 2.0f; weaponAngleOffset.y += dotSide * 5.0f; weaponAngleOffset.z -= dotSide * 2.0f; } } //add some inertia to weapon due view direction change. float deltaDotSide(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn0()); float deltaDotUp(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn2()); weaponOffset += m_io.viewQuatFinal * Vec3(deltaDotSide * 0.1f + m_in.stats_leanAmount * 0.05f, 0, deltaDotUp * 0.1f - fabs(m_in.stats_leanAmount) * 0.05f) * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.x -= deltaDotUp * 5.0f * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.z += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.y += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier; if(m_in.stats_leanAmount < 0.0f) { weaponAngleOffset.y += m_in.stats_leanAmount * 5.0f; } //the weapon model tries to stay parallel to the terrain when the player is freefalling/parachuting if (m_in.stats_inWater > 0.0f) { weaponOffset -= m_io.viewQuat.GetColumn2() * 0.15f; } if (m_in.stats_inWater > 0.1f && !m_in.stats_headUnderWater) { Ang3 offset(m_io.viewQuatFinal); offset.z = 0; if (offset.x < 0.0f) { offset.x = 0; } weaponAngleOffset -= offset * (180.0f / gf_PI) * 0.75f; } else if (m_io.stats_inFreefall) { Ang3 offset(m_io.viewQuatFinal); offset.z = 0; weaponAngleOffset -= offset * (180.0f / gf_PI) * 0.5f; } //same thing with crawling else if (crawling) { //FIXME:to optimize, looks like a bit too expensive Vec3 forward(m_io.viewQuatFinal.GetColumn1()); Vec3 up(m_io.baseQuat.GetColumn2()); Vec3 right(-(up % forward)); Matrix33 mat; mat.SetFromVectors(right, up % right, up); mat.OrthonormalizeFast(); Ang3 offset(m_io.viewQuatFinal.GetInverted() * Quat(mat)); weaponAngleOffset += offset * (180.0f / gf_PI) * 0.5f; float lookDown(m_io.viewQuatFinal.GetColumn1() * m_io.baseQuat.GetColumn2()); weaponOffset += m_io.baseQuat * Vec3(0, -0.5f * max(-lookDown, 0.0f), -0.05f); float scale = 0.5f;; if(weaponAngleOffset.x > 0.0f) { scale = min(0.5f, weaponAngleOffset.x / 15.0f); weaponAngleOffset.x *= scale; } else { scale = min(0.5f, -weaponAngleOffset.x / 20.0f); weaponAngleOffset *= (1.0f - scale); weaponOffset *= scale; } if(vSpeedLen > 0.1f) { weaponAngleOffset += Ang3(-8.0f, 0, -12.5f); } } else if (m_in.bSprinting && vSpeedLen > 0.5f) { weaponAngleOffset += Ang3(-20.0f, 0, 10.0f); weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .1f); } else if (m_in.bLookingAtFriendlyAI && !weaponZooming && !weaponZoomed) { weaponAngleOffset += Ang3(-15.0f, 0, 8.0f); weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .05f); } //apply some multipliers weaponOffset *= m_in.params_weaponBobbingMultiplier; angOffset *= m_io.bobMul * 0.25f; if (m_io.bobMul * m_io.bobMul != 1.0f) { weaponOffset *= m_io.bobMul; weaponAngleOffset *= m_io.bobMul; } float bobSpeedMult(1.0f); if(m_in.stats_inWater > 0.1) { bobSpeedMult = 0.75f; } // m_io.viewQuatForWeapon *= Quat::CreateRotationXYZ(Ang3(rx,ry,rz)); Interpolate(m_io.vFPWeaponOffset, weaponOffset, 3.95f * bobSpeedMult, m_in.frameTime); Interpolate(m_io.vFPWeaponAngleOffset, weaponAngleOffset, 10.0f * bobSpeedMult, m_in.frameTime); Interpolate(m_io.vFPWeaponLastDirVec, m_io.viewQuatFinal.GetColumn1(), 5.0f * bobSpeedMult, m_in.frameTime); Interpolate(m_io.angleOffset, angOffset, 10.0f, m_in.frameTime, 0.002f); if(weaponZooming) { m_io.vFPWeaponLastDirVec = m_io.viewQuatFinal.GetColumn1(); m_io.vFPWeaponOffset.Set(0.0f, 0.0f, 0.0f); m_io.vFPWeaponAngleOffset.Set(0.0f, 0.0f, 0.0f); m_io.bobOffset.Set(0.0f, 0.0f, 0.0f); } if (m_in.bSprinting) { float headBobScale = (m_in.stats_flatSpeed / m_in.standSpeed); headBobScale = min(1.0f, headBobScale); m_io.bobOffset = m_io.vFPWeaponOffset * 2.5f * g_pGameCVars->cl_headBob * headBobScale; float bobLenSq = m_io.bobOffset.GetLengthSquared(); float bobLenLimit = g_pGameCVars->cl_headBobLimit; if (bobLenSq > bobLenLimit * bobLenLimit) { float bobLen = sqrt_tpl(bobLenSq); m_io.bobOffset *= bobLenLimit / bobLen; } viewParams.position += m_io.bobOffset; } }
void CPlayerInput::PreUpdate() { CMovementRequest request; // get rotation into a manageable form float mouseSensitivity; if (m_pPlayer->InZeroG()) mouseSensitivity = 0.00333f*MAX(0.01f, g_pGameCVars->cl_sensitivityZeroG); else mouseSensitivity = 0.00333f*MAX(0.01f, g_pGameCVars->cl_sensitivity); mouseSensitivity *= gf_PI / 180.0f;//doesnt make much sense, but after all helps to keep reasonable values for the sensitivity cvars //these 2 could be moved to CPlayerRotation mouseSensitivity *= m_pPlayer->m_params.viewSensitivity; mouseSensitivity *= m_pPlayer->GetMassFactor(); COffHand * pOffHand=static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && (pOffHand->GetOffHandState()&eOHS_HOLDING_NPC)) mouseSensitivity *= pOffHand->GetObjectMassScale(); // When carrying object/enemy, adapt mouse sensitiviy to feel the weight // Designers requested we ignore single-handed objects (1 == m_iCarryingObject) if(2 == m_iCarryingObject) { mouseSensitivity /= 2.0f; } if(m_fCrouchPressedTime>0.0f) { float fNow = gEnv->pTimer->GetAsyncTime().GetMilliSeconds(); if((fNow - m_fCrouchPressedTime) > 300.0f) { if(m_actions & ACTION_CROUCH) { m_actions &= ~ACTION_CROUCH; m_actions |= ACTION_PRONE; } m_fCrouchPressedTime = -1.0f; } } Ang3 deltaRotation(m_deltaRotation * mouseSensitivity); if (m_pStats->isFrozen.Value() && m_pPlayer->IsPlayer() && m_pPlayer->GetHealth()>0) { float sMin = g_pGameCVars->cl_frozenSensMin; float sMax = g_pGameCVars->cl_frozenSensMax; float mult = sMin + (sMax-sMin)*(1.f-m_pPlayer->GetFrozenAmount(true)); deltaRotation *= mult; m_pPlayer->UpdateUnfreezeInput(m_deltaRotation, m_deltaMovement-m_deltaMovementPrev, mult); } // apply rotation from xinput controller if(!m_bDisabledXIRot) { // Controller framerate compensation needs frame time! // The constant is to counter for small frame time values. // adjust some too small values, should be handled differently later on Ang3 xiDeltaRot=m_xi_deltaRotation*gEnv->pTimer->GetFrameTime() * mouseSensitivity * 50.0f; SmoothControllerInput(xiDeltaRot); ControlCameraMode(); // Applying aspect modifiers if (g_pGameCVars->ctrl_aspectCorrection > 0) { int vx, vy, vw, vh; gEnv->pRenderer->GetViewport(&vx, &vy, &vw, &vh); float med=((float)vw+vh)/2.0f; float crW=((float)vw)/med; float crH=((float)vh)/med; xiDeltaRot.x*=g_pGameCVars->ctrl_aspectCorrection == 2 ? crW : crH; xiDeltaRot.z*=g_pGameCVars->ctrl_aspectCorrection == 2 ? crH : crW; } if(g_pGameCVars->cl_invertController) xiDeltaRot.x*=-1; deltaRotation+=xiDeltaRot; IVehicle *pVehicle = m_pPlayer->GetLinkedVehicle(); if (pVehicle) { if (m_pPlayer->m_pVehicleClient) { m_pPlayer->m_pVehicleClient->PreUpdate(pVehicle, m_pPlayer->GetEntityId(), gEnv->pTimer->GetFrameTime()); } //FIXME:not really good m_actions = 0; m_deltaMovement.Set(0,0,0); m_deltaRotation.Set(0,0,0); } } if(m_bUseXIInput) { m_deltaMovement.x = m_xi_deltaMovement.x; m_deltaMovement.y = m_xi_deltaMovement.y; m_deltaMovement.z = 0; if (m_xi_deltaMovement.len2()>0.0f) m_actions |= ACTION_MOVE; else m_actions &= ~ACTION_MOVE; } bool animControlled(m_pPlayer->m_stats.animationControlled); // If there was a recent serialization, ignore the delta rotation, since it's accumulated over several frames. if ((m_lastSerializeFrameID + 2) > gEnv->pRenderer->GetFrameID()) deltaRotation.Set(0,0,0); //if(m_pPlayer->m_stats.isOnLadder) //deltaRotation.z = 0.0f; const SCVars* pGameCVars = g_pGameCVars; if(pGameCVars->cl_cam_orbit != 0 && m_pPlayer->IsClient() && m_pPlayer->IsThirdPerson()) { static bool IsInit = false; if (!IsInit) { m_pPlayer->m_camViewMtxFinal = Matrix33(gEnv->pRenderer->GetCamera().GetViewMatrix()); IsInit = true; } float frameTime=gEnv->pTimer->GetFrameTime(); float frameTimeNormalised=(frameTime>1 ? 1 : frameTime<0.0001f ? 0.0001f : frameTime)*30; // 1/30th => 1 1/60th =>0.5 etc float frameTimeClamped=(frameTime>1 ? 1 : frameTime<0.0001f ? 0.0001f : frameTime); m_pCameraInputHelper->UpdateCameraInput(deltaRotation, frameTimeClamped,frameTimeNormalised); // also modifies deltaRotation. } if (!animControlled) request.AddDeltaRotation( deltaRotation ); // add some movement... if (!m_pStats->isFrozen.Value() && !animControlled) request.AddDeltaMovement( FilterMovement(m_deltaMovement) ); m_deltaMovementPrev = m_deltaMovement; // handle actions if (m_actions & ACTION_JUMP) { if (m_pPlayer->GetStance() != STANCE_PRONE) request.SetJump(); else m_actions &= ~ACTION_JUMP; //m_actions &= ~ACTION_PRONE; /*if (m_pPlayer->GetStance() != STANCE_PRONE) { if(m_pPlayer->GetStance() == STANCE_STAND || m_pPlayer->TrySetStance(STANCE_STAND)) request.SetJump(); } else if(!m_pPlayer->TrySetStance(STANCE_STAND)) m_actions &= ~ACTION_JUMP; else m_actions &= ~ACTION_PRONE;*/ } if (m_pPlayer->m_stats.isOnLadder) { m_actions &= ~ACTION_PRONE; m_actions &= ~ACTION_CROUCH; } request.SetStance(FigureOutStance()); float pseudoSpeed = 0.0f; if (m_deltaMovement.len2() > 0.0f) { pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_pPlayer->m_stats.bSprinting); } /* design changed: sprinting with controller is removed from full stick up to Left Bumper if(m_bUseXIInput && m_xi_deltaMovement.len2() > 0.999f) { m_actions |= ACTION_SPRINT; } else if(m_bUseXIInput) { m_actions &= ~ACTION_SPRINT; }*/ request.SetPseudoSpeed(pseudoSpeed); if (m_deltaMovement.GetLength() > 0.1f) { float moveAngle = (float)RAD2DEG(fabs_tpl(cry_atan2f(-m_deltaMovement.x, fabsf(m_deltaMovement.y)<0.01f?0.01f:m_deltaMovement.y))); request.SetAllowStrafing(moveAngle > 20.0f); } else { request.SetAllowStrafing(true); } // send the movement request to the appropriate spot! m_pPlayer->m_pMovementController->RequestMovement( request ); m_pPlayer->m_actions = m_actions; // reset things for next frame that need to be m_lastMouseRawInput = m_deltaRotation; m_deltaRotation = Ang3(0,0,0); //static float color[] = {1,1,1,1}; //gEnv->pRenderer->Draw2dLabel(100,50,1.5,color,false,"deltaMovement:%f,%f", m_deltaMovement.x,m_deltaMovement.y); // PLAYERPREDICTION m_pPlayer->GetGameObject()->ChangedNetworkState(INPUT_ASPECT); // ~PLAYERPREDICTION }
void CPlayerView::ViewFirstThirdSharedPost(SViewParams &viewParams) { //--- Update the eye offset and apply { // Blend towards the goal eye offset float stanceTransitionSpeed = g_pGameCVars->g_stanceTransitionSpeed; if (m_in.stance == STANCE_PRONE) { stanceTransitionSpeed = 8; } Interpolate(m_io.eyeOffsetView, m_io.eyeOffsetViewGoal, stanceTransitionSpeed, m_in.frameTime); //apply eye offset if (!m_io.bUsePivot) { //apply some more offset to the view viewParams.position += m_io.baseQuat * m_io.eyeOffsetView; if (m_in.stats_firstPersonBody == 2) { float lookDown(m_io.viewQuatFinal.GetColumn1() * m_io.baseQuat.GetColumn2()); float forwardOffset(0.0f); if (m_in.stance == STANCE_STAND) { forwardOffset = 0.15f; } viewParams.position += m_io.viewQuatFinal.GetColumn1() * max(-lookDown, 0.0f) * forwardOffset + m_io.viewQuatFinal.GetColumn2() * max(-lookDown, 0.0f) * 0.0f; //Grabbed by the Hunter if(m_in.bIsGrabbed && !m_in.bIsThirdPerson) { viewParams.position = m_in.entityWorldMatrix.TransformPoint(m_io.eyeOffsetView); } } } } if(g_pGameCVars->g_detachCamera != 0) { viewParams.position = m_in.lastPos; viewParams.rotation = m_in.lastQuat; } //--- Weapon orientation //FIXME: this should be done in the player update anyway. //And all the view position update. (because the game may need to know other players eyepos and such) //update first person weapon model position/angles { Quat wQuat(m_io.viewQuatForWeapon * Quat::CreateRotationXYZ(m_io.vFPWeaponAngleOffset * gf_PI / 180.0f)); //wQuat *= Quat::CreateSlerp(viewParams.shakeQuat,IDENTITY,0.5f); wQuat *= Quat::CreateSlerp(viewParams.currentShakeQuat, IDENTITY, 0.5f); wQuat.NormalizeSafe(); m_io.wAngles = Ang3(wQuat); } //smooth out the view elevation if (m_in.stats_inAir < 0.1f && !m_in.stats_flyMode && !m_in.stats_spectatorMode && !m_io.bUsePivot) { if (m_io.stats_smoothZType != 1) { m_io.stats_smoothViewZ = viewParams.position.z; m_io.stats_smoothZType = 1; } Interpolate(m_io.stats_smoothViewZ, viewParams.position.z, 15.0f, m_in.frameTime); viewParams.position.z = m_io.stats_smoothViewZ; } else { if (m_io.stats_smoothZType == 1) { m_io.stats_smoothViewZ = m_in.lastPos.z - m_io.stats_smoothViewZ; m_io.stats_smoothZType = 2; } Interpolate(m_io.stats_smoothViewZ, 0.0f, 15.0f, m_in.frameTime); viewParams.position.z += m_io.stats_smoothViewZ; } }
//------------------------------------------------------------------------ void CRapid::Update(float frameTime, uint32 frameId) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); CSingle::Update(frameTime, frameId); if (m_speed <= 0.0f && m_acceleration < 0.0001f) { if(m_decelerating) { FinishDeceleration(); } return; } m_pWeapon->RequireUpdate(eIUS_FireMode); m_speed = m_speed + m_acceleration * frameTime; if (m_speed > m_pShared->rapidparams.max_speed) { m_speed = m_pShared->rapidparams.max_speed; m_accelerating = false; } if ((m_speed >= m_pShared->rapidparams.min_speed) && (!m_decelerating)) { float dt = 1.0f; if (cry_fabsf(m_speed) > 0.001f && cry_fabsf(m_pShared->rapidparams.max_speed > 0.001f)) { dt = m_speed / m_pShared->rapidparams.max_speed; } m_next_shot_dt = 60.0f / (m_pShared->fireparams.rate * dt); bool canShoot = CanFire(false); if (canShoot) { if (!OutOfAmmo()) { if (m_netshooting) { Firing(true); } else { Firing(Shoot(true, false)); } if (m_firing && !(m_pShared->rapidparams.camshake_rotate.IsZero() && m_pShared->rapidparams.camshake_shift.IsZero())) { CActor *act = m_pWeapon->GetOwnerActor(); if (act && act->IsClient()) { IView *pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView(); if (pView) { pView->SetViewShake(Ang3(m_pShared->rapidparams.camshake_rotate), m_pShared->rapidparams.camshake_shift, m_next_shot_dt / m_pShared->rapidparams.camshake_perShot, m_next_shot_dt / m_pShared->rapidparams.camshake_perShot, 0, 1); } } } } else { Firing(false); Accelerate(m_pShared->rapidparams.deceleration); if (m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer()) { SmokeEffect(); m_pWeapon->Reload(); } } } } else if (m_firing) { Firing(false); if (OutOfAmmo() && m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer()) { SmokeEffect(); m_pWeapon->Reload(); } } if ((m_speed < m_pShared->rapidparams.min_speed) && (m_acceleration < 0.0f) && (!m_decelerating)) { Accelerate(m_pShared->rapidparams.deceleration); } UpdateRotation(frameTime); UpdateSound(frameTime); }
virtual void ProcessEvent( EFlowEvent event,SActivationInfo* pActInfo ) { switch (event) { case eFE_Activate: { m_lastTime = gEnv->pTimer->GetFrameStartTime(); m_bActive = !GetPortBool(pActInfo, 1); pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, m_bActive ); if (!m_bActive) { ResetVelocity(pActInfo); } } break; case eFE_Initialize: { if (pActInfo->pEntity) m_localRot = pActInfo->pEntity->GetRotation(); else m_localRot.SetIdentity(); m_worldRot.SetIdentity(); m_lastTime = gEnv->pTimer->GetFrameStartTime(); m_bActive = !GetPortBool(pActInfo, 1); pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, m_bActive ); break; } case eFE_Update: { if (m_bActive && pActInfo->pEntity) { CTimeValue time = gEnv->pTimer->GetFrameStartTime(); float timeDifference = (time - m_lastTime).GetSeconds(); m_lastTime = time; IEntity* pEntity = pActInfo->pEntity; const bool bUseWorld = GetPortInt(pActInfo, 2) == 0 ? true : false; Vec3 speed = GetPortVec3(pActInfo, 0); speed *= timeDifference; Quat deltaRot (Ang3(DEG2RAD(speed))); Quat finalRot; if (bUseWorld == false) { finalRot = pEntity->GetRotation(); finalRot *= deltaRot; } else { m_worldRot *= deltaRot; finalRot = m_worldRot; finalRot *= m_localRot; } finalRot.NormalizeSafe(); IPhysicalEntity* piPhysEnt = pEntity->GetPhysics(); if (piPhysEnt && piPhysEnt->GetType() != PE_STATIC) { if (timeDifference > 0.0001f) { pe_action_set_velocity asv; asv.w = Quat::log(deltaRot) * (2.f / timeDifference); asv.bRotationAroundPivot = 1; pEntity->GetPhysics()->Action(&asv); } } else { pEntity->SetRotation(finalRot); } Ang3 currentAng = Ang3(finalRot); ActivateOutput(pActInfo, 1, Vec3(currentAng)); currentAng = RAD2DEG(currentAng); ActivateOutput(pActInfo, 0, Vec3(currentAng)); } break; } } }
//-------------------------------------------------------------------------------------------------- // Name: SpawnScreenExplosionEffect // Desc: Spawns screen explosion effect //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer) { // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX() const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo; if(explosionInfo.pressure < 1.0f) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor != NULL && !pClientActor->IsDead()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f; // Flashbang friends and self?... if(hasFlashBangEffect) { bool flashBangSelf = true; bool flashBangFriends = false; #ifndef _RELEASE flashBangSelf = g_pGameCVars->g_flashBangSelf != 0; flashBangFriends = g_pGameCVars->g_flashBangFriends != 0; #endif bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId; if((!flashBangSelf && ownFlashBang) || // FlashBang self? ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends? { return; } } // Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) SMovementState state; if(IMovementController *pMV = pClientActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection; eyeToExplosion.Normalize(); float eyeDirectionDP = eyeDir.Dot(eyeToExplosion); bool inFOV = (eyeDirectionDP > 0.68f); // All explosions have radial blur (default 30m radius) const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f; if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f)) { if (inFOV && (dist < maxBlurDistance)) { const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0); } } // Flashbang effect if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) || (inFOV && (dist < explosionInfo.radius)))) { ray_hit hit; const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; const int intersectionMaxHits = 1; int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos, -eyeToExplosion*dist, intersectionObjTypes, intersectionFlags, &hit, intersectionMaxHits); // If there was no obstacle between flashbang grenade and player if(!collision) { bool enabled = true; if(enabled) { CCCPOINT (FlashBang_Explode_BlindLocalPlayer); float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f); float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player"); SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); NET_BATTLECHATTER(BC_Blinded, pPlayer); if(pClientActor->GetEntityId() == explosionInfo.shooterId) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf); } else { g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time); } pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f); CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount); } } } else { CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry); } } else if(inFOV && (dist < explosionInfo.radius)) { if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { // Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; if (pClientActor) { static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(Random(-angleX*0.5f,angleX),0.0f,Random(-angleZ,angleZ)),0.0f,dt*2.0f); } } } } }//-------------------------------------------------------------------------------------------------
virtual void ProcessEvent(EFlowEvent event, SActivationInfo *pActInfo) { switch (event) { case eFE_Initialize: { if (pActInfo->pGraph != nullptr) { const bool enabled = GetPortBool( pActInfo, EIP_Enabled ); pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, enabled ); } } break; case eFE_Activate: { if (IsPortActive(pActInfo, EIP_Enabled)) { const bool enabled = GetPortBool( pActInfo, EIP_Enabled ); pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, enabled ); } } break; case eFE_Update: { // Camera info IRenderer * pRenderer = gEnv->pRenderer; if (pRenderer) { const CCamera &rCam = pRenderer->GetCamera(); const Ang3 angles = RAD2DEG(rCam.GetAngles()); ActivateOutput(pActInfo, EOP_CamPos, rCam.GetPosition()); ActivateOutput(pActInfo, EOP_CamRot, Vec3(angles)); } ActivateOutput(pActInfo, EOP_CamDataValid, pRenderer != nullptr); // HMD info IHMDManager * pHmdManager = gEnv->pSystem->GetHMDManager(); bool bHmdOk = false; if (pHmdManager != nullptr) { const HMDTrackingState& sensorState = pHmdManager->GetHMDDevice()->GetWorldTrackingState(); if (sensorState.CheckStatusFlags(HS_IsUsable)) { bHmdOk = true; Ang3 hmdAngles(sensorState.pose.orientation); ActivateOutput(pActInfo, EOP_HmdRot, Vec3(RAD2DEG(hmdAngles))); ActivateOutput(pActInfo, EOP_HmdPos, sensorState.pose.position); } } ActivateOutput(pActInfo, EOP_HmdDataValid, bHmdOk); // Player Info CPlayer* pLocalPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor()); if (pLocalPlayer) { Vec3 entityRotationInDegrees(RAD2DEG(Ang3(pLocalPlayer->GetViewQuat()))); ActivateOutput(pActInfo, EOP_PlayerViewRot, entityRotationInDegrees); ActivateOutput(pActInfo, EOP_PlayerPos, pLocalPlayer->GetEntity()->GetWorldPos()); } ActivateOutput(pActInfo, EOP_PlayerDataValid, pLocalPlayer != nullptr); } break; } }
//------------------------------------------------------------------------ EntityId CScriptBind_GameRules::SpawnPlayer(int channelId, mono::string name, mono::string className, Vec3 pos, Vec3 angles) { return g_pGame->GetGameRules()->SpawnPlayer(channelId, *name, *className, pos, Ang3(angles))->GetEntityId(); }
virtual void OnEditorMovedTransformGizmo(const QuatT& gizmoLocation) { posOffset = gizmoLocation.t; rotOffset = Ang3(gizmoLocation.q); }
void CUIHUD3D::UpdateView(const SViewParams &viewParams) { CActor* pLocalPlayer = (CActor*)g_pGame->GetIGameFramework()->GetClientActor(); if (gEnv->IsEditor() && !gEnv->IsEditing() && !m_pHUDRootEntity) SpawnHudEntities(); // When you die we destroy the HUD, so this will make sure it re-spawns when you respawned if (!gEnv->IsEditor() && !m_pHUDRootEntity) SpawnHudEntities(); const CUICVars* pCVars = g_pGame->GetUI()->GetCVars(); if (m_pHUDRootEntity && pLocalPlayer) { if(pCVars->hud_detach) return; const QuatT& cameraTran = pLocalPlayer->GetCameraTran(); const QuatT& hudTran = pLocalPlayer->GetHUDTran(); const Quat& cameraRotation = cameraTran.q; const Quat& hudRotation = hudTran.q; Quat deltaHudRotation = cameraRotation.GetInverted() * hudRotation; if(pCVars->hud_bobHud > 0.0f && !pLocalPlayer->IsDead()) { deltaHudRotation.w *= (float)__fres(pCVars->hud_bobHud); // Avoid divide by 0 if (!(fabs(deltaHudRotation.w) < FLT_EPSILON)) // IsValid() doesn't catch it { deltaHudRotation.Normalize(); } } else { deltaHudRotation.SetIdentity(); } // In general use the player position + viewparams override Vec3 viewPosition = pLocalPlayer->GetEntity()->GetPos() + viewParams.position; Quat clientRotation = viewParams.rotation * deltaHudRotation; // Override special cases: Third person should use camera-oriented HUD instead of HUD-bone oriented // Sliding should use the Bone instead of the viewParams solution if(pLocalPlayer->IsThirdPerson() || pLocalPlayer->GetLinkedVehicle() != NULL) { viewPosition = viewParams.position; } else { CPlayer* player = (CPlayer*)pLocalPlayer; if(player && player->IsSliding()) { viewPosition = pLocalPlayer->GetEntity()->GetWorldTM().TransformPoint(hudTran.t); } } // const Vec3 forward(clientRotation.GetColumn1()); const Vec3 up(clientRotation.GetColumn2()); const Vec3 right(-(up % forward)); const float distance = pCVars->hud_cameraOverride ? pCVars->hud_cameraDistance : m_fHudDist; const float offset = pCVars->hud_cameraOverride ? pCVars->hud_cameraOffsetZ : m_fHudZOffset; float offsetScale = 1.0f; if(viewParams.fov > 0.0f) { offsetScale = (pCVars->hud_cgf_positionScaleFOV * __fres(viewParams.fov )) + distance; } // Allow overscanBorders to control safe zones Vec2 overscanBorders = ZERO; if(gEnv->pRenderer) { gEnv->pRenderer->EF_Query(EFQ_OverscanBorders, overscanBorders); } const float viewDepth = 1.0f + (pCVars->hud_overscanBorder_depthScale * overscanBorders.y); viewPosition += forward*viewDepth*offsetScale; viewPosition += (up * offset); viewPosition += (right * pCVars->hud_cgf_positionRightScale); const Vec3 posVec(viewPosition + (forward * 0.001f)); static const Quat rot90Deg = Quat::CreateRotationXYZ( Ang3(gf_PI * 0.5f, 0, 0) ); const Quat rotation = clientRotation * rot90Deg; // rotate 90 degrees around X-Axis m_pHUDRootEntity->SetPosRotScale(posVec, rotation, m_pHUDRootEntity->GetScale(), ENTITY_XFORM_NO_SEND_TO_ENTITY_SYSTEM); } if (gEnv->pRenderer && m_pHUDRootEntity && pCVars->hud_debug3dpos > 0) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(m_pHUDRootEntity->GetWorldPos(), 0.2f, ColorB(255,0,0)); const int children = m_pHUDRootEntity->GetChildCount(); for (int i = 0; i < children && pCVars->hud_debug3dpos > 1; ++i) { IEntity* pChild = m_pHUDRootEntity->GetChild(i); gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(pChild->GetWorldPos(), 0.1f, ColorB(255,255,0)); } } }