//------------------------------------------------------------------ void CLam::UpdateFPLaser(float frameTime, CItem* parent) { Vec3 lamPos, dir; if (m_laserActivated) AdjustLaserFPDirection(parent,dir,lamPos); else { // Lam Light lamPos = parent->GetSlotHelperPos(eIGS_FirstPerson,m_laserHelperFP.c_str(),true); Quat lamRot = Quat(parent->GetSlotHelperRotation(eIGS_FirstPerson,m_laserHelperFP.c_str(),true)); dir = lamRot.GetColumn1(); } // float len = m_lamparams.laser_range[eIGS_FirstPerson]; dir.Normalize(); const float nearClipPlaneLimit = 10.0f; Vec3 hitPos(0,0,0); float laserLength = 0.0f; float dotScale = 1.0f; { IPhysicalEntity* pSkipEntity = NULL; if(parent->GetOwner()) pSkipEntity = parent->GetOwner()->GetPhysics(); const int objects = ent_all; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*m_lamparams.laser_range[eIGS_FirstPerson], objects, flags, &hit, 1, &pSkipEntity, pSkipEntity?1:0)) { //Clamp distance below near clip plane limits, if not dot will be overdrawn during rasterization if(hit.dist>nearClipPlaneLimit) { laserLength = nearClipPlaneLimit; m_lastLaserHitPt = lamPos + (nearClipPlaneLimit*dir); } else { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; } m_lastLaserHitSolid = true; if(parent->GetOwnerActor() && parent->GetOwnerActor()->GetActorParams()) dotScale *= max(0.3f,parent->GetOwnerActor()->GetActorParams()->viewFoVScale); } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = lamPos - (dir*3.0f); laserLength = 3.0f; } hitPos = m_lastLaserHitPt; if(g_pGameCVars->i_debug_projectiles!=0) gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(hitPos, 0.2f, ColorB(255,0,0)); } if (m_laserActivated && m_dotEffectSlot >= 0) { Matrix34 worldMatrix = GetEntity()->GetWorldTM(); if(laserLength<=0.7f) hitPos = lamPos+(0.7f*dir); CWeapon* pWep = static_cast<CWeapon*>(parent->GetIWeapon()); if(pWep && pWep->IsWeaponLowered()) { hitPos = lamPos+(2.0f*dir); laserLength = 2.0f; } if(laserLength<=2.0f) dotScale *= min(1.0f,(0.35f + ((laserLength-0.7f)*0.5f))); IEntity* pDotEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId); if(pDotEntity) { Matrix34 finalMatrix = Matrix34::CreateTranslationMat(hitPos-(0.2f*dir)); pDotEntity->SetWorldTM(finalMatrix); Matrix34 localScale = Matrix34::CreateIdentity(); localScale.SetScale(Vec3(dotScale,dotScale,dotScale)); pDotEntity->SetSlotLocalTM(m_dotEffectSlot,localScale); } } if (m_laserActivated || m_lightActivated) { float laserAIRange = m_laserActivated ? laserLength : 0.0f; float lightAIRange = m_lightActivated ? min(laserLength, m_lamparams.light_range[eIGS_FirstPerson] * 1.5f) : 0.0f; UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_FirstPerson], laserAIRange); } }
void CHUDCrosshair::UpdateCrosshair() { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(!pClientActor) return; int iNewFriendly = 0; if(pClientActor->GetLinkedVehicle()) { // JanM/MichaelR: // Get status from the VehicleWeapon, which raycasts considering the necessary SkipEntities (in contrast to WorldQuery) // Julien: this is now done in MP as well iNewFriendly = g_pHUD->GetVehicleInterface()->GetFriendlyFire(); } else { if(!gEnv->bMultiplayer) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { iNewFriendly = pWeapon->IsWeaponLowered() && pWeapon->IsPendingFireRequest(); if(iNewFriendly && pWeapon->GetEntity()->GetClass() == CItem::sTACGunFleetClass) iNewFriendly = 0; } else{ //Two handed pickups need the red X as well CPlayer *pPlayer= static_cast<CPlayer*>(pClientActor); if(CWeapon *pOffHand = static_cast<CWeapon*>(pPlayer->GetItemByClass(CItem::sOffHandClass))) iNewFriendly = pOffHand->IsWeaponLowered(); } } else { EntityId uiCenterId = pClientActor->GetGameObject()->GetWorldQuery()->GetLookAtEntityId(); if(uiCenterId) { iNewFriendly = IsFriendlyEntity(gEnv->pEntitySystem->GetEntity(uiCenterId)); } } } // SNH: if player is carrying a claymore or mine, ask the weapon whether it is possible to place it currently // (takes into account player speed / stance / aim direction). // So 'friendly' is a bit of a misnomer here, but we want the "don't/can't fire" crosshair... if(iNewFriendly != 1 && g_pHUD) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { static IEntityClass* pClaymoreClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Claymore"); static IEntityClass* pAVMineClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("AVMine"); IEntityClass* pClass = pWeapon->GetEntity()->GetClass(); if(pClass == pClaymoreClass || pClass == pAVMineClass) { if(IFireMode* pfm = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode())) { if(!pfm->IsFiring()) iNewFriendly = pWeapon->CanFire() ? 0 : 1; } } } } if(iNewFriendly != m_iFriendlyTarget) { m_iFriendlyTarget = iNewFriendly; //m_animCrossHair.Invoke("setFriendly", m_iFriendlyTarget); if(iNewFriendly) m_animFriendCross.SetVisible(true); else m_animFriendCross.SetVisible(false); } if(m_animInterActiveIcons.GetVisible()) { m_bHideUseIconTemp = false; CItem *pItem = static_cast<CItem*>(pClientActor->GetCurrentItem()); if(pItem) { IWeapon *pWeapon = pItem->GetIWeapon(); if(pWeapon) { CItem::SStats stats = pItem->GetStats(); if(stats.mounted && stats.used) m_bHideUseIconTemp = true; } } if(!m_bHideUseIconTemp) { EntityId offHandId = pClientActor->GetInventory()->GetItemByClass(CItem::sOffHandClass); IItem *pOffHandItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(offHandId); if(pOffHandItem) { COffHand *pOffHand = static_cast<COffHand*>(pOffHandItem); uint32 offHandState = pOffHand->GetOffHandState(); if(offHandState == eOHS_HOLDING_OBJECT || offHandState == eOHS_THROWING_OBJECT || offHandState == eOHS_HOLDING_NPC || offHandState == eOHS_THROWING_NPC) m_bHideUseIconTemp = true; } } } }