void CNetPlayerInput::UpdateMoveRequest() { CMovementRequest moveRequest; SMovementState moveState; m_pPlayer->GetMovementController()->GetMovementState(moveState); Quat worldRot = m_pPlayer->GetBaseQuat(); // m_pPlayer->GetEntity()->GetWorldRotation(); Vec3 deltaMovement = worldRot.GetInverted().GetNormalized() * m_curInput.deltaMovement; // absolutely ensure length is correct deltaMovement = deltaMovement.GetNormalizedSafe(ZERO) * m_curInput.deltaMovement.GetLength(); moveRequest.AddDeltaMovement( deltaMovement ); if( IsDemoPlayback() ) { Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection); Ang3 deltaAngles(asinf(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y)); moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime()); } //else { //--- Vector slerp actually produces QNans if the vectors are exactly opposite, in that case snap to the target if (m_lookDir.Dot(m_curInput.lookDirection) < (float)-0.99f) { m_lookDir = m_curInput.lookDirection; } else { m_lookDir.SetSlerp(m_lookDir, m_curInput.lookDirection, g_pGameCVars->pl_netAimLerpFactor); } Vec3 distantTarget = moveState.eyePosition + 1000.0f * m_lookDir; Vec3 lookTarget = distantTarget; if (m_curInput.usinglookik) moveRequest.SetLookTarget( lookTarget ); else moveRequest.ClearLookTarget(); if (m_curInput.aiming) moveRequest.SetAimTarget( lookTarget ); else moveRequest.ClearAimTarget(); if (m_curInput.deltaMovement.GetLengthSquared() > sqr(0.02f)) // 0.2f is almost stopped moveRequest.SetBodyTarget( distantTarget ); else moveRequest.ClearBodyTarget(); } moveRequest.SetAllowStrafing(m_curInput.allowStrafing); if(m_pPlayer->IsPlayer()) moveRequest.SetPseudoSpeed(CalculatePseudoSpeed()); else moveRequest.SetPseudoSpeed(m_curInput.pseudoSpeed); float lean=0.0f; if (m_curInput.leanl) lean-=1.0f; if (m_curInput.leanr) lean+=1.0f; if (fabsf(lean)>0.01f) moveRequest.SetLean(lean); else moveRequest.ClearLean(); moveRequest.SetStance( (EStance)m_curInput.stance ); m_pPlayer->GetMovementController()->RequestMovement(moveRequest); if (m_curInput.sprint) m_pPlayer->m_actions |= ACTION_SPRINT; else m_pPlayer->m_actions &= ~ACTION_SPRINT; if (m_curInput.leanl) m_pPlayer->m_actions |= ACTION_LEANLEFT; else m_pPlayer->m_actions &= ~ACTION_LEANLEFT; if (m_curInput.leanr) m_pPlayer->m_actions |= ACTION_LEANRIGHT; else m_pPlayer->m_actions &= ~ACTION_LEANRIGHT; #if !defined(_RELEASE) // debug.. if (g_pGameCVars->g_debugNetPlayerInput & 2) { IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug(); pPD->Begin( string("update_player_input_") + m_pPlayer->GetEntity()->GetName(), true ); Vec3 wp = m_pPlayer->GetEntity()->GetWorldPos(); wp.z += 2.0f; pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,0.3f), 1.0f ); // pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,0.3f), 1.0f ); pPD->AddDirection( m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2), 1, m_curInput.deltaMovement, ColorF(1,0,0,0.3f), 1.0f ); } #endif //m_curInput.deltaMovement.zero(); }
void CNetPlayerInput::PreUpdate() { IPhysicalEntity * pPhysEnt = m_pPlayer->GetEntity()->GetPhysics(); if (!pPhysEnt) return; CMovementRequest moveRequest; SMovementState moveState; m_pPlayer->GetMovementController()->GetMovementState(moveState); Quat worldRot = m_pPlayer->GetBaseQuat(); // m_pPlayer->GetEntity()->GetWorldRotation(); Vec3 deltaMovement = worldRot.GetInverted().GetNormalized() * m_curInput.deltaMovement; // absolutely ensure length is correct deltaMovement = deltaMovement.GetNormalizedSafe(ZERO) * m_curInput.deltaMovement.GetLength(); moveRequest.AddDeltaMovement( deltaMovement ); if( IsDemoPlayback() ) { Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection); Ang3 deltaAngles(asin(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y)); moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime()); } //else { Vec3 distantTarget = moveState.eyePosition + 1000.0f * m_curInput.lookDirection; Vec3 lookTarget = distantTarget; if (gEnv->bClient && m_pPlayer->GetGameObject()->IsProbablyVisible()) { // post-process aim direction ray_hit hit; static const int obj_types = ent_all; // ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_living; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; bool rayHitAny = 0 != gEnv->pPhysicalWorld->RayWorldIntersection( moveState.eyePosition, 150.0f * m_curInput.lookDirection, obj_types, flags, &hit, 1, pPhysEnt ); if (rayHitAny) { lookTarget = hit.pt; } static float proneDist = 1.0f; static float crouchDist = 0.6f; static float standDist = 0.3f; float dist = standDist; if(m_pPlayer->GetStance() == STANCE_CROUCH) dist = crouchDist; else if(m_pPlayer->GetStance() == STANCE_PRONE) dist = proneDist; if((lookTarget - moveState.eyePosition).GetLength2D() < dist) { Vec3 eyeToTarget2d = lookTarget - moveState.eyePosition; eyeToTarget2d.z = 0.0f; eyeToTarget2d.NormalizeSafe(); eyeToTarget2d *= dist; ray_hit newhit; bool rayHitAny = 0 != gEnv->pPhysicalWorld->RayWorldIntersection( moveState.eyePosition + eyeToTarget2d, 3 * Vec3(0,0,-1), obj_types, flags, &newhit, 1, pPhysEnt ); if (rayHitAny) { lookTarget = newhit.pt; } } // SNH: new approach. Make sure the aimTarget is at least 1.5m away, // if not, pick a point 1m down the vector instead. Vec3 dir = lookTarget - moveState.eyePosition; static float minDist = 1.5f; if(dir.GetLengthSquared() < minDist) { lookTarget = moveState.eyePosition + dir.GetNormalizedSafe(); } // draw eye pos for comparison //gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(moveState.eyePosition, 0.04f, ColorF(0.3f,0.2f,0.7f,1.0f)); } moveRequest.SetLookTarget( lookTarget ); moveRequest.SetAimTarget( lookTarget ); if (m_curInput.deltaMovement.GetLengthSquared() > sqr(0.2f)) // 0.2f is almost stopped moveRequest.SetBodyTarget( distantTarget ); else moveRequest.ClearBodyTarget(); } moveRequest.SetAllowStrafing(true); float pseudoSpeed = 0.0f; if (m_curInput.deltaMovement.len2() > 0.0f) { pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_curInput.sprint); } moveRequest.SetPseudoSpeed(pseudoSpeed); float lean=0.0f; if (m_curInput.leanl) lean-=1.0f; if (m_curInput.leanr) lean+=1.0f; if (fabsf(lean)>0.01f) moveRequest.SetLean(lean); else moveRequest.ClearLean(); m_pPlayer->GetMovementController()->RequestMovement(moveRequest); if (m_curInput.sprint) m_pPlayer->m_actions |= ACTION_SPRINT; else m_pPlayer->m_actions &= ~ACTION_SPRINT; if (m_curInput.leanl) m_pPlayer->m_actions |= ACTION_LEANLEFT; else m_pPlayer->m_actions &= ~ACTION_LEANLEFT; if (m_curInput.leanr) m_pPlayer->m_actions |= ACTION_LEANRIGHT; else m_pPlayer->m_actions &= ~ACTION_LEANRIGHT; // debug.. if (g_pGameCVars->g_debugNetPlayerInput & 2) { IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug(); pPD->Begin( string("update_player_input_") + m_pPlayer->GetEntity()->GetName(), true ); Vec3 wp = m_pPlayer->GetEntity()->GetWorldPos(); wp.z += 2.0f; pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,0.3f), 1.0f ); // pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,0.3f), 1.0f ); pPD->AddDirection( m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2), 1, m_curInput.deltaMovement, ColorF(1,0,0,0.3f), 1.0f ); } //m_curInput.deltaMovement.zero(); }