bool CLaser::GetFiringDir(EntityId weaponId, const IFireMode* pFireMode, Vec3& dir, const Vec3& probableHit, const Vec3& firingPos) { CWeapon* pParentWeapon = GetWeapon(); if (!m_laserBeam.IsLaserActivated()) return false; if(gEnv->bMultiplayer && pParentWeapon && pParentWeapon->IsZoomed()) { return false; } if(!probableHit.IsZero() && !firingPos.IsZero()) { dir = (probableHit - firingPos).GetNormalized(); return true; } if (pParentWeapon) { int slot = pParentWeapon->IsOwnerFP() ? eIGS_FirstPerson : eIGS_ThirdPerson; Matrix33 rotation = pParentWeapon->GetSlotHelperRotation(slot, "weapon_term", true); dir = rotation.GetColumn1(); return true; } return false; }
bool CLaser::GetProbableHit(EntityId weaponId, const IFireMode* pFireMode, Vec3& hit) { if (!m_laserBeam.IsLaserActivated()) return false; if(gEnv->bMultiplayer) { CWeapon* pParentWeapon = GetWeapon(); if (pParentWeapon && pParentWeapon->IsZoomed()) { return false; } } CWeapon* pWeapon = GetWeapon(); int slot = pWeapon->IsOwnerFP() ? eIGS_FirstPerson : eIGS_ThirdPerson; Vec3 lastBeamHit = m_laserBeam.GetLastHit(); Vec3 currentBeamPosition = pWeapon->GetSlotHelperPos(slot, "weapon_term", true); Matrix33 rotation = pWeapon->GetSlotHelperRotation(slot, "weapon_term", true); Vec3 currentBeamDirection = rotation.GetColumn1(); const CFireMode* pCFireMode = static_cast<const CFireMode*>(pFireMode); const CSingle* pSingle = crygti_cast<const CSingle*>(pCFireMode); if (pSingle && pSingle->GetShared()->fireparams.laser_beam_uses_spread) { currentBeamDirection = pSingle->ApplySpread(currentBeamDirection, pSingle->GetSpread()); } float distanceToLastHit = lastBeamHit.GetDistance(currentBeamPosition); hit = currentBeamPosition + currentBeamDirection * distanceToLastHit; return true; }
//------------------------------------------------------------------ void CLam::AdjustLaserFPDirection(CItem* parent, Vec3 &dir, Vec3 &pos) { pos = parent->GetSlotHelperPos(eIGS_FirstPerson,m_laserHelperFP.c_str(),true); Quat lamRot = Quat(parent->GetSlotHelperRotation(eIGS_FirstPerson,m_laserHelperFP.c_str(),true)); dir = -lamRot.GetColumn0(); if(!m_lamparams.isLamRifle) dir = lamRot.GetColumn1(); CActor *pActor = parent->GetOwnerActor(); IMovementController * pMC = pActor ? pActor->GetMovementController() : NULL; if (pMC) { SMovementState info; pMC->GetMovementState(info); CWeapon* pWep = static_cast<CWeapon*>(parent->GetIWeapon()); if(pWep && (pWep->IsReloading() || (!pActor->CanFire() && !pWep->IsZoomed()))) return; if(dir.Dot(info.fireDirection)<0.985f) return; CCamera& camera = gEnv->pSystem->GetViewCamera(); pos = camera.GetPosition(); dir = camera.GetMatrix().GetColumn1(); dir.Normalize(); } }
float CActor::currentFOV() { CWeapon* pWeapon = smart_cast<CWeapon*>(inventory().ActiveItem()); if (eacFirstEye == cam_active && pWeapon && pWeapon->IsZoomed() && (!pWeapon->ZoomTexture() || (!pWeapon->IsRotatingToZoom() && pWeapon->ZoomTexture()))) return pWeapon->GetZoomFactor(); else return DEFAULT_FOV; }
void CCustomDetector::UpdateVisibility() { //check visibility attachable_hud_item* i0 = g_player_hud->attached_item(0); if(i0 && HudItemData()) { CWeapon* wpn = smart_cast<CWeapon*>(i0->m_parent_hud_item); if(wpn) { u32 state = wpn->GetState(); bool bClimb = ( (Actor()->MovingState()&mcClimb) != 0 ); if(bClimb || wpn->IsZoomed() || state==CWeapon::eReload || state==CWeapon::eSwitch) { HideDetector (true); m_bNeedActivation = true; } } }else if(m_bNeedActivation) { attachable_hud_item* i0 = g_player_hud->attached_item(0); bool bClimb = ( (Actor()->MovingState()&mcClimb) != 0 ); if(!bClimb) { CWeapon* wpn = (i0)?smart_cast<CWeapon*>(i0->m_parent_hud_item) : NULL; if( !wpn || ( !wpn->IsZoomed() && wpn->GetState()!=CWeapon::eReload && wpn->GetState()!=CWeapon::eSwitch ) ) { ShowDetector (true); } } } }
bool CLaser::GetFiringPos(EntityId weaponId, const IFireMode* pFireMode, Vec3& pos) { CWeapon* pParentWeapon = GetWeapon(); if (!m_laserBeam.IsLaserActivated()) return false; if (pParentWeapon && (!gEnv->bMultiplayer ||!pParentWeapon->IsZoomed())) { int slot = pParentWeapon->IsOwnerFP() ? eIGS_FirstPerson : eIGS_ThirdPerson; pos = pParentWeapon->GetSlotHelperPos(slot, "weapon_term", true); return true; } return false; }
IAction::EStatus CActionItemIdle::Update(float timePassed) { UpdateFragmentTags(); CWeapon *weapon = m_ownerPlayer.GetWeapon(m_ownerPlayer.GetCurrentItemId()); bool canPlayIdleBreak = !weapon || !(weapon->IsZoomed() || weapon->IsZoomingInOrOut()); if (m_playingIdleBreak) { if (!canPlayIdleBreak) { m_playingIdleBreak = false; } } else if (canPlayIdleBreak) { const float currentTime = gEnv->pTimer->GetAsyncCurTime(); IPlayerInput* pClientInput = m_ownerPlayer.GetPlayerInput(); if (pClientInput) { const float idleBreakDelay = g_pGameCVars->cl_idleBreaksDelayTime; const float lastInputTime = pClientInput->GetLastRegisteredInputTime(); const float referenceTime = (float)__fsel((lastInputTime - m_lastIdleBreakTime), lastInputTime, m_lastIdleBreakTime); if ((currentTime - referenceTime) > idleBreakDelay) { m_playingIdleBreak = true; SetFragment(m_fragmentIdleBreak, m_fragTags); m_lastIdleBreakTime = currentTime; } } } if (!m_playingIdleBreak) { if (GetRootScope().IsDifferent(m_fragmentIdle, m_fragTags)) { SetFragment(m_fragmentIdle, m_fragTags); } } return BaseClass::Update(timePassed); }
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { if(eFE_Activate == event && IsPortActive(pActInfo,0)) { IActor* pActor = GetActor(pActInfo); if (pActor == 0) return; CWeapon* pWeapon = static_cast<CWeapon*> (GetWeapon(pActor)); bool bZoomed = false; if (pWeapon != 0) { const string& weaponClass = GetPortString(pActInfo, 1); if (weaponClass.empty() == true || weaponClass == pWeapon->GetEntity()->GetClass()->GetName()) { bZoomed = pWeapon->IsZoomed(); } } ActivateOutput(pActInfo, bZoomed ? 1 : 0, true); } }
bool CCustomDetector::CheckCompatibilityInt(CHudItem* itm) { if(itm==NULL) return true; CInventoryItem iitm = itm->item(); u32 slot = iitm.GetSlot(); bool bres = (slot==PISTOL_SLOT || slot==KNIFE_SLOT || slot==BOLT_SLOT); if(itm->GetState()!=CHUDState::eShowing) bres = bres && !itm->IsPending(); if(bres) { CWeapon* W = smart_cast<CWeapon*>(itm); if(W) bres = bres && (W->GetState() != CHUDState::eBore) && (W->GetState() != CWeapon::eReload) && (W->GetState() != CWeapon::eSwitch) && !W->IsZoomed();//+ } return bres; }
bool CPlayerStateUtil::ShouldSprint( const CPlayer& player, const SActorFrameMovementParams& movement, IItem* pCurrentPlayerItem ) { bool shouldSprint = false; const SPlayerStats& stats = player.m_stats; const bool movingForward = IsMovingForward( player, movement ); bool restrictSprint = player.IsJumping() || stats.bIgnoreSprinting || player.IsSliding() || player.IsCinematicFlagActive(SPlayerStats::eCinematicFlag_RestrictMovement); CWeapon* pWeapon = pCurrentPlayerItem ? static_cast<CWeapon*>(pCurrentPlayerItem->GetIWeapon()) : NULL; bool isZooming = pWeapon ? pWeapon->IsZoomed() && !pWeapon->IsZoomingInOrOut() : false; if (pWeapon && !pWeapon->CanSprint()) restrictSprint = true; restrictSprint = restrictSprint || (player.GetSprintStaminaLevel() <= 0.f); //CryLogAlways(" restrictSprint = %d", restrictSprint); if (player.IsSprinting() == false) { shouldSprint = movingForward && !restrictSprint && !isZooming; CCCPOINT_IF(shouldSprint, PlayerMovement_SprintOn); } else { shouldSprint = movingForward && !restrictSprint && !isZooming; //CryLogAlways(" shouldSprint = %d", shouldSprint); shouldSprint = shouldSprint && (!(player.m_actions & ACTION_CROUCH)); if(!shouldSprint && pWeapon) { pWeapon->ForcePendingActions(); } } CCCPOINT_IF(!player.IsSprinting() && !shouldSprint && (player.m_actions & ACTION_SPRINT), PlayerMovement_SprintRequestIgnored); CCCPOINT_IF(player.IsSprinting() && !shouldSprint, PlayerMovement_SprintOff); //CryLogAlways(" returning (for \"%s\") shouldSprint = %d", m_player.GetEntity()->GetName(), shouldSprint); return shouldSprint; }
//------------------------------------------- void CLaser::Update(SEntityUpdateContext& ctx, int slot) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if((slot == eIUS_General) && m_laserBeam.IsLaserActivated()) { RequireUpdate(eIUS_General); CWeapon* pParentWeapon = GetWeapon(); if (pParentWeapon) { CActor* pOwnerActor = pParentWeapon->GetOwnerActor(); Vec3 laserPos, laserDir; GetLaserPositionAndDirection(pParentWeapon, laserPos, laserDir); CLaserBeam::SLaserUpdateDesc laserUpdateDesc(laserPos, laserDir, ctx.fFrameTime, pParentWeapon->GetEntity()->IsHidden()); laserUpdateDesc.m_weaponZoomed = pParentWeapon->IsZoomed() || pParentWeapon->IsZoomingInOrOut(); m_laserBeam.UpdateLaser(laserUpdateDesc); } } }
// (jh) this function is called on any input dispatching it to a relevant method and eventually to Lua onAction method void CPlayerInput::OnAction( const ActionId& actionId, int activationMode, float value ) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if (g_pGame->GetHostMigrationState() != CGame::eHMS_NotMigrating) { Reset(); return; } m_pPlayer->GetGameObject()->ChangedNetworkState( INPUT_ASPECT ); m_lastActions=m_actions; //this tell if OnAction have to be forwarded to scripts, now its true by default, only high framerate actions are ignored bool filterOut = true; m_checkZoom = false; const CGameActions& actions = g_pGame->Actions(); IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle(); bool canMove = CanMove(); // disable movement while standing up if (!canMove) m_deltaMovement.zero(); // try to dispatch action to OnActionHandlers bool handled; { FRAME_PROFILER("New Action Processing", GetISystem(), PROFILE_GAME); handled = s_actionHandler.Dispatch(this, m_pPlayer->GetEntityId(), actionId, activationMode, value, filterOut); } { FRAME_PROFILER("Regular Action Processing", GetISystem(), PROFILE_GAME); if (!handled) { filterOut = true; if (!m_pPlayer->m_stats.spectatorMode) { if (actions.ulammo==actionId && m_pPlayer->m_pGameFramework->CanCheat() && gEnv->pSystem->IsDevMode()) { g_pGameCVars->i_unlimitedammo = 1; } else if (actions.debug_ag_step == actionId) { gEnv->pConsole->ExecuteString("ag_step"); } else if(actions.voice_chat_talk == actionId) { if(gEnv->bMultiplayer) { if(activationMode == eAAM_OnPress) g_pGame->GetIGameFramework()->EnableVoiceRecording(true); else if(activationMode == eAAM_OnRelease) g_pGame->GetIGameFramework()->EnableVoiceRecording(false); } } } } if (!m_pPlayer->m_stats.spectatorMode) { IInventory* pInventory = m_pPlayer->GetInventory(); if (!pInventory) return; bool scope = false; EntityId itemId = pInventory->GetCurrentItem(); CWeapon *pWeapon = 0; if (itemId) { pWeapon = m_pPlayer->GetWeapon(itemId); if (pWeapon) { scope = (pWeapon->IsZoomed() && pWeapon->GetMaxZoomSteps()>1); } } if (pVehicle) { if (m_pPlayer->m_pVehicleClient && !m_pPlayer->IsFrozen()) m_pPlayer->m_pVehicleClient->OnAction(pVehicle, m_pPlayer->GetEntityId(), actionId, activationMode, value); //FIXME:not really good m_actions = 0; m_deltaMovement.Set(0,0,0); } else if (m_pPlayer->GetHealth() > 0 && !m_pPlayer->m_stats.isFrozen.Value() && !m_pPlayer->m_stats.inFreefall.Value() && !m_pPlayer->m_stats.isOnLadder && !m_pPlayer->m_stats.isStandingUp && m_pPlayer->GetGameObject()->GetAspectProfile(eEA_Physics)!=eAP_Sleep) { m_pPlayer->CActor::OnAction(actionId, activationMode, value); if ((!scope || actionId == actions.use)) { COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if (pOffHand) { pOffHand->OnAction(m_pPlayer->GetEntityId(), actionId, activationMode, value); } if ((!pWeapon || !pWeapon->IsMounted())) { if ((actions.drop==actionId) && itemId) { float impulseScale=1.0f; if (activationMode==eAAM_OnPress) m_buttonPressure=2.5f; if (activationMode==eAAM_OnRelease) { m_buttonPressure=CLAMP(m_buttonPressure, 0.0f, 2.5f); impulseScale=1.0f+(1.0f-m_buttonPressure/2.5f)*15.0f; if (m_pPlayer->DropItem(itemId, impulseScale, true) && pOffHand && pOffHand->IsSelected()) { if (EntityId fistsId = pInventory->GetItemByClass(CItem::sFistsClass)) { m_pPlayer->SelectItem(fistsId, false); } pOffHand->PreExecuteAction(eOHA_REINIT_WEAPON, eAAM_OnPress); CItem* pItem = static_cast<CItem*>(m_pPlayer->GetCurrentItem()); if (pItem) { pItem->SetActionSuffix("akimbo_"); pItem->PlayAction(g_pItemStrings->idle); } } } } else if (actions.nextitem==actionId) m_pPlayer->SelectNextItem(1, true, 0); else if (actions.previtem==actionId) m_pPlayer->SelectNextItem(-1, true, 0); else if (actions.handgrenade==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.explosive==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.utility==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.small==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.medium==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.heavy==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.debug==actionId) { if (g_pGame) { if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sDebugGunClass)) g_pGame->GetWeaponSystem()->DebugGun(0); if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sRefWeaponClass)) g_pGame->GetWeaponSystem()->RefGun(0); } m_pPlayer->SelectNextItem(1, true, actionId.c_str()); } } } else { if (actions.handgrenade==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.explosive==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.utility==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.small==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.medium==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.heavy==actionId) m_pPlayer->SelectNextItem(1, true, actionId.c_str()); else if (actions.drop==actionId && activationMode == eAAM_OnRelease && itemId) m_pPlayer->DropItem(itemId, 1.0f, true); } } if (m_checkZoom) { if (pWeapon) { IZoomMode *zm = pWeapon->GetZoomMode(pWeapon->GetCurrentZoomMode()); CScreenEffects* pScreenEffects = m_pPlayer->GetScreenEffects(); if (zm && !zm->IsZoomingInOrOut() && !zm->IsZoomed() && pScreenEffects != 0) { if (!m_moveButtonState && m_pPlayer->IsClient()) { IBlendedEffect *fovEffect = CBlendedEffect<CFOVEffect>::Create(CFOVEffect(m_pPlayer->GetEntityId(),1.0f)); IBlendType *blend = CBlendType<CLinearBlend>::Create(CLinearBlend(1.0f)); pScreenEffects->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomIn, false); pScreenEffects->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomOut, false); pScreenEffects->StartBlend(fovEffect, blend, 1.0f/.25f, CScreenEffects::eSFX_GID_ZoomIn); } else { pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomIn); pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomOut); pScreenEffects->EnableBlends(true, CScreenEffects::eSFX_GID_HitReaction); } } } } } } bool hudFilterOut = true; // FIXME: temporary method to dispatch Actions to HUD (it's not yet possible to register) hudFilterOut = true; //Filter must take into account offHand too COffHand* pOffHand = static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && pOffHand->IsSelected()) filterOut = false; //send the onAction to scripts, after filter the range of actions. for now just use and hold if (filterOut && hudFilterOut) { FRAME_PROFILER("Script Processing", GetISystem(), PROFILE_GAME); HSCRIPTFUNCTION scriptOnAction(NULL); IScriptTable *scriptTbl = m_pPlayer->GetEntity()->GetScriptTable(); if (scriptTbl) { scriptTbl->GetValue("OnAction", scriptOnAction); if (scriptOnAction) { char *activation = 0; switch(activationMode) { case eAAM_OnHold: activation = "hold"; break; case eAAM_OnPress: activation = "press"; break; case eAAM_OnRelease: activation = "release"; break; default: activation = ""; break; } Script::Call(gEnv->pScriptSystem,scriptOnAction,scriptTbl,actionId.c_str(),activation, value); } } gEnv->pScriptSystem->ReleaseFunc(scriptOnAction); } }
void CActor::g_SetAnimation( u32 mstate_rl ) { if (!g_Alive()) { if (m_current_legs||m_current_torso){ SActorState* ST = 0; if (mstate_rl&mcCrouch) ST = &m_anims->m_crouch; else ST = &m_anims->m_normal; mstate_real = 0; m_current_legs.invalidate (); m_current_torso.invalidate (); smart_cast<CKinematicsAnimated*>(Visual())->PlayCycle(m_anims->m_dead_stop); } return; } STorsoWpn::eMovingState moving_idx = STorsoWpn::eIdle; SActorState* ST = 0; SAnimState* AS = 0; if (mstate_rl&mcCrouch) ST = &m_anims->m_crouch; else if (mstate_rl&mcClimb) ST = &m_anims->m_climb; else ST = &m_anims->m_normal; bool bAccelerated = isActorAccelerated(mstate_rl, IsZoomAimingMode()); if ( bAccelerated ){ AS = &ST->m_run; }else{ AS = &ST->m_walk; } if(mstate_rl&mcAnyMove){ if( bAccelerated ) moving_idx = STorsoWpn::eRun; else moving_idx = STorsoWpn::eWalk; } // анимации MotionID M_legs; MotionID M_torso; MotionID M_head; //если мы просто стоим на месте bool is_standing = false; // Legs if (mstate_rl&mcLanding) M_legs = ST->landing[0]; else if (mstate_rl&mcLanding2) M_legs = ST->landing[1]; else if ((mstate_rl&mcTurn)&& !(mstate_rl&mcClimb)) M_legs = ST->legs_turn; else if (mstate_rl&mcFall) M_legs = ST->jump_idle; else if (mstate_rl&mcJump) M_legs = ST->jump_begin; else if (mstate_rl&mcFwd) M_legs = AS->legs_fwd; else if (mstate_rl&mcBack) M_legs = AS->legs_back; else if (mstate_rl&mcLStrafe) M_legs = AS->legs_ls; else if (mstate_rl&mcRStrafe) M_legs = AS->legs_rs; else is_standing = true; if(mstate_rl&mcSprint){ g_SetSprintAnimation (mstate_rl,M_head,M_torso,M_legs); moving_idx = STorsoWpn::eSprint; } //--------------------------------------------------------------- if (this == Level().CurrentViewEntity()) { if ((mstate_rl&mcSprint) != (mstate_old&mcSprint)) { CHudItem* pHudItem = smart_cast<CHudItem*>(inventory().ActiveItem()); if (pHudItem) pHudItem->onMovementChanged(mcSprint); }; }; //----------------------------------------------------------------------- // Torso if(mstate_rl&mcClimb) { if (mstate_rl&mcFwd) M_torso = AS->legs_fwd; else if (mstate_rl&mcBack) M_torso = AS->legs_back; else if (mstate_rl&mcLStrafe) M_torso = AS->legs_ls; else if (mstate_rl&mcRStrafe) M_torso = AS->legs_rs; } if(!M_torso) { CInventoryItem* _i = inventory().ActiveItem(); CHudItem *H = smart_cast<CHudItem*>(_i); CWeapon *W = smart_cast<CWeapon*>(_i); CMissile *M = smart_cast<CMissile*>(_i); CArtefact *A = smart_cast<CArtefact*>(_i); if (H) { VERIFY(H->animation_slot() <= _total_anim_slots_); STorsoWpn* TW = &ST->m_torso[H->animation_slot() - 1]; if (!b_DropActivated&&!fis_zero(f_DropPower)){ M_torso = TW->drop; if (!M_torso) { Msg("! drop animation for %s", *(H->object().cName())); M_torso = ST->m_torso_idle; }; m_bAnimTorsoPlayed = TRUE; }else{ if (!m_bAnimTorsoPlayed) { if (W) { bool K =inventory().GetActiveSlot() == KNIFE_SLOT; bool R3 = W->IsTriStateReload(); if(K) { switch (W->GetState()){ case CWeapon::eIdle: M_torso = TW->moving[moving_idx]; break; case CWeapon::eFire: if(is_standing) M_torso = M_legs = M_head = TW->all_attack_0; else M_torso = TW->attack_zoom; break; case CWeapon::eFire2: if(is_standing) M_torso = M_legs = M_head = TW->all_attack_1; else M_torso = TW->fire_idle; break; case CWeapon::eJammed: case CWeapon::eReload: M_torso = TW->reload; break; case CWeapon::eShowing: M_torso = TW->draw; break; case CWeapon::eHiding: M_torso = TW->holster; break; default : M_torso = TW->moving[moving_idx]; break; } } else { switch (W->GetState()){ case CWeapon::eIdle: M_torso = W->IsZoomed()?TW->zoom:TW->moving[moving_idx]; break; case CWeapon::eFire: M_torso = W->IsZoomed()?TW->attack_zoom:TW->attack; break; case CWeapon::eFire2: M_torso = W->IsZoomed()?TW->attack_zoom:TW->attack; break; case CWeapon::eJammed: case CWeapon::eReload: if(!R3) M_torso = TW->reload; else{ CWeapon::EWeaponSubStates sub_st = W->GetReloadState(); switch (sub_st){ case CWeapon::eSubstateReloadBegin: M_torso = TW->reload; break; case CWeapon::eSubstateReloadInProcess: M_torso = TW->reload_1; break; case CWeapon::eSubstateReloadEnd: M_torso = TW->reload_2; break; default: M_torso = TW->reload; break; } }break; case CWeapon::eShowing: M_torso = TW->draw; break; case CWeapon::eHiding: M_torso = TW->holster; break; default : M_torso = TW->moving[moving_idx]; break; } } } else if (M) { if(is_standing) { switch (M->GetState()){ case MS_SHOWING : M_torso = TW->draw; break; case MS_HIDING : M_torso = TW->holster; break; case MS_IDLE_SPRINT: ; case MS_IDLE : M_torso = TW->moving[moving_idx]; break; case MS_EMPTY : M_torso = TW->zoom; break; case MS_THREATEN : M_torso = M_legs = M_head = TW->all_attack_0; break; case MS_READY : M_torso = M_legs = M_head = TW->all_attack_1; break; case MS_THROW : M_torso = M_legs = M_head = TW->all_attack_2; break; case MS_END : M_torso = M_legs = M_head = TW->all_attack_2; break; default : M_torso = TW->draw; break; } } else { switch (M->GetState()){ case MS_SHOWING : M_torso = TW->draw; break; case MS_HIDING : M_torso = TW->holster; break; case MS_IDLE_SPRINT: ; case MS_IDLE : M_torso = TW->moving[moving_idx]; break; case MS_EMPTY : M_torso = TW->moving[moving_idx]; break; case MS_THREATEN : M_torso = TW->attack_zoom; break; case MS_READY : M_torso = TW->fire_idle; break; case MS_THROW : M_torso = TW->fire_end; break; case MS_END : M_torso = TW->fire_end; break; default : M_torso = TW->draw; break; } } } else if (A){ switch(A->GetState()){ case CArtefact::eIdle : M_torso = TW->moving[moving_idx]; break; case CArtefact::eShowing : M_torso = TW->draw; break; case CArtefact::eHiding : M_torso = TW->holster; break; case CArtefact::eActivating : M_torso = TW->zoom; break; default : M_torso = TW->moving[moving_idx]; } } } } } } if (!M_legs) { if((mstate_rl&mcCrouch)&&!isActorAccelerated(mstate_rl, IsZoomAimingMode()))//!(mstate_rl&mcAccel)) { M_legs=smart_cast<CKinematicsAnimated*>(Visual())->ID_Cycle("cr_idle_1"); } else M_legs = ST->legs_idle; } if (!M_head) M_head = ST->m_head_idle; if (!M_torso){ if (m_bAnimTorsoPlayed) M_torso = m_current_torso; else M_torso = ST->m_torso_idle; } // есть анимация для всего - запустим / иначе запустим анимацию по частям if (m_current_torso!=M_torso){ if (m_bAnimTorsoPlayed) m_current_torso_blend = smart_cast<CKinematicsAnimated*> (Visual())->PlayCycle(M_torso,TRUE,AnimTorsoPlayCallBack,this); else /**/m_current_torso_blend = /**/smart_cast<CKinematicsAnimated*> (Visual())->PlayCycle(M_torso); m_current_torso=M_torso; } if(m_current_head!=M_head) { if(M_head)smart_cast<CKinematicsAnimated*>(Visual())->PlayCycle(M_head); m_current_head=M_head; } if (m_current_legs!=M_legs){ float pos = 0.f; VERIFY (!m_current_legs_blend || !fis_zero(m_current_legs_blend->timeTotal)); if ((mstate_real&mcAnyMove)&&(mstate_old&mcAnyMove)&&m_current_legs_blend) pos = fmod(m_current_legs_blend->timeCurrent,m_current_legs_blend->timeTotal)/m_current_legs_blend->timeTotal; m_current_legs_blend = smart_cast<CKinematicsAnimated*>(Visual())->PlayCycle(M_legs,TRUE,legs_play_callback,this); if ((!(mstate_old&mcAnyMove))&&(mstate_real&mcAnyMove)) pos = 0.5f*Random.randI(2); if (m_current_legs_blend) m_current_legs_blend->timeCurrent = m_current_legs_blend->timeTotal*pos; m_current_legs = M_legs; CStepManager::on_animation_start(M_legs, m_current_legs_blend); } #ifdef _DEBUG if(bDebug){ HUD().Font().pFontStat->OutSetI (0,0); HUD().Font().pFontStat->OutNext("[%s]",mov_state[moving_idx]); } #endif #ifdef _DEBUG if ((Level().CurrentControlEntity() == this) && g_ShowAnimationInfo) { string128 buf; strcpy(buf,""); if (isActorAccelerated(mstate_rl, IsZoomAimingMode())) strcat(buf,"Accel "); if (mstate_rl&mcCrouch) strcat(buf,"Crouch "); if (mstate_rl&mcFwd) strcat(buf,"Fwd "); if (mstate_rl&mcBack) strcat(buf,"Back "); if (mstate_rl&mcLStrafe) strcat(buf,"LStrafe "); if (mstate_rl&mcRStrafe) strcat(buf,"RStrafe "); if (mstate_rl&mcJump) strcat(buf,"Jump "); if (mstate_rl&mcFall) strcat(buf,"Fall "); if (mstate_rl&mcTurn) strcat(buf,"Turn "); if (mstate_rl&mcLanding) strcat(buf,"Landing "); if (mstate_rl&mcLLookout) strcat(buf,"LLookout "); if (mstate_rl&mcRLookout) strcat(buf,"RLookout "); if (m_bJumpKeyPressed) strcat(buf,"+Jumping "); HUD().Font().pFontStat->OutNext ("MSTATE: [%s]",buf); /* switch (m_PhysicMovementControl->Environment()) { case CPHMovementControl::peOnGround: strcpy(buf,"ground"); break; case CPHMovementControl::peInAir: strcpy(buf,"air"); break; case CPHMovementControl::peAtWall: strcpy(buf,"wall"); break; } HUD().Font().pFontStat->OutNext (buf); HUD().Font().pFontStat->OutNext ("Accel [%3.2f, %3.2f, %3.2f]",VPUSH(NET_SavedAccel)); HUD().Font().pFontStat->OutNext ("V [%3.2f, %3.2f, %3.2f]",VPUSH(m_PhysicMovementControl->GetVelocity())); HUD().Font().pFontStat->OutNext ("vertex ID %d",ai_location().level_vertex_id()); Game().m_WeaponUsageStatistic->Draw(); */ }; #endif if (!m_current_torso_blend) return; CKinematicsAnimated *skeleton_animated = PKinematicsAnimated(Visual()); CMotionDef *motion0 = skeleton_animated->LL_GetMotionDef(m_current_torso); VERIFY (motion0); if (!(motion0->flags & esmSyncPart)) return; if (!m_current_legs_blend) return; CMotionDef *motion1 = skeleton_animated->LL_GetMotionDef(m_current_legs); VERIFY (motion1); if (!(motion1->flags & esmSyncPart)) return; m_current_torso_blend->timeCurrent = m_current_legs_blend->timeCurrent/m_current_legs_blend->timeTotal*m_current_torso_blend->timeTotal; }
void CActor::UpdateCL () { if(m_feel_touch_characters>0) { for(xr_vector<CObject*>::iterator it = feel_touch.begin(); it != feel_touch.end(); it++) { CPhysicsShellHolder *sh = smart_cast<CPhysicsShellHolder*>(*it); if(sh&&sh->character_physics_support()) { sh->character_physics_support()->movement()->UpdateObjectBox(character_physics_support()->movement()->PHCharacter()); } } } if(m_holder) m_holder->UpdateEx( currentFOV() ); m_snd_noise -= 0.3f*Device.fTimeDelta; VERIFY2 (_valid(renderable.xform),*cName()); inherited::UpdateCL(); VERIFY2 (_valid(renderable.xform),*cName()); m_pPhysics_support->in_UpdateCL (); VERIFY2 (_valid(renderable.xform),*cName()); if (g_Alive()) PickupModeUpdate (); PickupModeUpdate_COD(); m_bZoomAimingMode = false; CWeapon* pWeapon = smart_cast<CWeapon*>(inventory().ActiveItem()); Device.Statistic->TEST1.Begin (); cam_Update(float(Device.dwTimeDelta)/1000.0f, currentFOV()); Device.Statistic->TEST1.End (); if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { psHUD_Flags.set( HUD_CROSSHAIR_RT2, true ); psHUD_Flags.set( HUD_DRAW_RT, true ); } if(pWeapon ) { if(pWeapon->IsZoomed()) { float full_fire_disp = pWeapon->GetFireDispersion(true); CEffectorZoomInertion* S = smart_cast<CEffectorZoomInertion*> (Cameras().GetCamEffector(eCEZoom)); if(S) S->SetParams(full_fire_disp); m_bZoomAimingMode = true; } if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { float fire_disp_full = pWeapon->GetFireDispersion(true); HUD().SetCrosshairDisp(fire_disp_full, 0.02f); HUD().ShowCrosshair(pWeapon->use_crosshair()); psHUD_Flags.set( HUD_CROSSHAIR_RT2, pWeapon->show_crosshair() ); psHUD_Flags.set( HUD_DRAW_RT, pWeapon->show_indicators() ); } } else { if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { HUD().SetCrosshairDisp(0.f); HUD().ShowCrosshair(false); } } UpdateDefferedMessages(); if (g_Alive()) CStepManager::update(); spatial.type |=STYPE_REACTTOSOUND; if(m_sndShockEffector) { if (this == Level().CurrentViewEntity()) { m_sndShockEffector->Update(); if(!m_sndShockEffector->InWork()) xr_delete(m_sndShockEffector); } else xr_delete(m_sndShockEffector); } }
void CPlayerStateJump::Landed(CPlayer& player, const bool isHeavyWeapon, float fallSpeed) { #ifdef STATE_DEBUG bool remoteControlled = false; IVehicle* pVehicle = player.GetLinkedVehicle(); if(pVehicle) { IVehicleSeat* pVehicleSeat = pVehicle->GetSeatForPassenger(player.GetEntityId()); if(pVehicleSeat && pVehicleSeat->IsRemoteControlled()) { remoteControlled = true; } } CRY_ASSERT_MESSAGE( player.GetLinkedEntity()==NULL || remoteControlled, "Cannot 'land' when you're linked to another entity!" ); #endif const SPlayerStats& stats = player.m_stats; Vec3 playerPosition = player.GetEntity()->GetWorldPos(); IPhysicalEntity *phys = player.GetEntity()->GetPhysics(); IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); const SActorPhysics& actorPhysics = player.GetActorPhysics(); int matID = actorPhysics.groundMaterialIdx != -1 ? actorPhysics.groundMaterialIdx : mfx->GetDefaultSurfaceIndex(); const float fHeightofEntity = playerPosition.z; const float worldWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel(); TMFXEffectId effectId = mfx->GetEffectId("bodyfall", matID); if (effectId != InvalidEffectId) { SMFXRunTimeEffectParams params; Vec3 direction = Vec3(0,0,0); if (IMovementController *pMV = player.GetMovementController()) { SMovementState state; pMV->GetMovementState(state); direction = state.aimDirection; } params.pos = playerPosition + direction; //params.soundSemantic = eSoundSemantic_Player_Foley; float landFallParamVal = (float)__fsel( -(fallSpeed - 7.5f), 0.25f, 0.75f); params.AddAudioRtpc("landfall", landFallParamVal); const float speedParamVal = min(fabsf((actorPhysics.velocity.z * 0.1f)), 1.0f); params.AddAudioRtpc("speed", speedParamVal); mfx->ExecuteEffect(effectId, params); } bool heavyLanded = false; IItem* pCurrentItem = player.GetCurrentItem(); CWeapon* pCurrentWeapon = pCurrentItem ? static_cast<CWeapon*>(pCurrentItem->GetIWeapon()) : NULL; if (fallSpeed > 0.0f && player.IsPlayer()) { if(!gEnv->bMultiplayer) { const float verticalSpeed = fabs(fallSpeed); const float speedForHeavyLand = g_pGameCVars->pl_health.fallSpeed_HeavyLand; if ((verticalSpeed >= speedForHeavyLand) && (player.GetPickAndThrowEntity() == 0) && !player.IsDead()) { if ( !isHeavyWeapon ) { if (pCurrentWeapon) { pCurrentWeapon->FumbleGrenade(); pCurrentWeapon->CancelCharge(); } player.StartInteractiveActionByName("HeavyLand", false); } heavyLanded = true; } } } if(player.m_isClient) { if (fallSpeed > 0.0f) { const float fallIntensityMultiplier = stats.wasHit ? g_pGameCVars->pl_fall_intensity_hit_multiplier : g_pGameCVars->pl_fall_intensity_multiplier; const float fallIntensityMax = g_pGameCVars->pl_fall_intensity_max; const float fallTimeMultiplier = g_pGameCVars->pl_fall_time_multiplier; const float fallTimeMax = g_pGameCVars->pl_fall_time_max; const float zoomMultiplayer = (pCurrentWeapon && pCurrentWeapon->IsZoomed()) ? 0.2f : 1.0f; const float direction = ((cry_rand()%2)==0) ? -1.0f : 1.0f; const float intensity = clamp_tpl(fallIntensityMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallIntensityMax); const float shakeTime = clamp_tpl(fallTimeMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallTimeMax); const Vec3 rotation = Vec3(-0.5f, 0.15f*direction, 0.05f*direction); if (CScreenEffects* pGameScreenEffects = g_pGame->GetScreenEffects()) { pGameScreenEffects->CamShake(rotation*intensity, Vec3(0, 0, 0), shakeTime, shakeTime, 0.05f, CScreenEffects::eCS_GID_Player); } IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem(); assert(pForceFeedback); ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName("landFF"); pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(intensity, 0.0f)); if(fallSpeed > 7.0f) { player.PlaySound(CPlayer::ESound_Fall_Drop); } CPlayer::EPlayerSounds playerSound = heavyLanded ? CPlayer::ESound_Gear_HeavyLand : CPlayer::ESound_Gear_Land; player.PlaySound(playerSound, true); } CCCPOINT(PlayerMovement_LocalPlayerLanded); } if( gEnv->pAISystem ) { // Notify AI //If silent feet active, ignore here const float noiseSupression = 0.0f; const float fAISoundRadius = (g_pGameCVars->ai_perception.landed_baseRadius + (g_pGameCVars->ai_perception.landed_speedMultiplier * fallSpeed)) * (1.0f - noiseSupression); SAIStimulus stim(AISTIM_SOUND, AISOUND_MOVEMENT_LOUD, player.GetEntityId(), 0, player.GetEntity()->GetWorldPos() + player.GetEyeOffset(), ZERO, fAISoundRadius); gEnv->pAISystem->RegisterStimulus(stim); } // Record 'Land' telemetry stats. CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Land, fallSpeed); if (fallSpeed > 0.0f) { player.CreateScriptEvent( heavyLanded ? "heavylanded" : "landed",stats.fallSpeed); } }
// // 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 weaponZomming = 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(); weaponZomming = pWeapon->IsZooming(); if(weaponZoomed||weaponZomming||pWeapon->IsModifying()) 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 && !weaponZomming) { weaponOffset.z += 0.035f; weaponOffset.y -= m_io.viewQuatFinal.GetColumn1().y * 0.03f; } else if(m_in.stance==STANCE_CROUCH && weaponZomming) { 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 && !weaponZomming && !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(weaponZomming) { 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; } }