Пример #1
0
//------------------------------------------------------------------
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);
    }

}
Пример #2
0
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;
			}
		}
	}
}