2087 lines
68 KiB
C++
2087 lines
68 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FILE : UIReticule.cpp
|
|
// PURPOSE : manages the new Scaleform-based HUD code for the reticule (code taken from NewHud)
|
|
// AUTHOR : James Chagaris
|
|
// STARTED : 1/23/2013
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Frontend/UIReticule.h"
|
|
|
|
#include "input/headtracking.h"
|
|
|
|
#include "Camera/Base/BaseCamera.h"
|
|
#include "Camera/CamInterface.h"
|
|
#include "Camera/Cinematic/CinematicDirector.h"
|
|
#include "Camera/replay/ReplayDirector.h"
|
|
#include "Camera/Gameplay/Aim/FirstPersonPedAimCamera.h"
|
|
#include "Camera/Gameplay/Aim/FirstPersonShooterCamera.h"
|
|
#include "Camera/Gameplay/GameplayDirector.h"
|
|
#include "camera/cinematic/camera/mounted/CinematicMountedCamera.h"
|
|
#include "Camera/Helpers/ControlHelper.h"
|
|
#include "Camera/Viewports/ViewportManager.h"
|
|
#include "control/replay/ReplayExtensions.h"
|
|
#include "Frontend/NewHud.h"
|
|
#include "Frontend/ui_channel.h"
|
|
#include "frontend/MobilePhone.h"
|
|
#include "modelinfo/VehicleModelInfoFlags.h"
|
|
#include "Network/Network.h"
|
|
#include "Peds/Ped.h"
|
|
#include "peds/PedHelmetComponent.h"
|
|
#include "Peds/PedIntelligence.h"
|
|
#include "peds/PlayerInfo.h"
|
|
#include "Peds/QueriableInterface.h"
|
|
#include "renderer/OcclusionQueries.h"
|
|
#include "scene/playerswitch/PlayerSwitchInterface.h"
|
|
#include "Scene/World/GameWorld.h"
|
|
#include "Script/Commands_graphics.h"
|
|
#include "Script/Script_hud.h"
|
|
#include "System/Control.h"
|
|
#include "System/ControlMgr.h"
|
|
#include "Task/General/Phone/TaskMobilePhone.h"
|
|
#include "Task/Vehicle/TaskVehicleWeapon.h"
|
|
#include "task/Weapons/Gun/TaskVehicleDriveBy.h"
|
|
#include "task/Vehicle/TaskMountAnimalWeapon.h"
|
|
#include "Weapons/Inventory/PedWeaponManager.h"
|
|
#include "Vehicles/VehicleGadgets.h"
|
|
#include "core/watermark.h"
|
|
|
|
//OPTIMISATIONS_OFF()
|
|
FRONTEND_OPTIMISATIONS()
|
|
|
|
#define FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE_MAX ATSTRINGHASH("SNIPER_MAX",0xd3db07a8)
|
|
#define FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE ATSTRINGHASH("SNIPER_LARGE",0xc399f251)
|
|
#define FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE ATSTRINGHASH("SIMPLE_RETICLE",0x5619404)
|
|
#define FAKED_WEAPON_HASH_FOR_SIMPLE_MP_RETICLE ATSTRINGHASH("SIMPLE_MP_RETICLE",0x89c1ec2)
|
|
|
|
#define INVALID_ZOOM_LEVEL (-1)
|
|
#define INVALID_RETICULE_QUERY (0)
|
|
|
|
bank_bool CUIReticule::sm_bHideReticleWithLaserSight = false;
|
|
bank_float CUIReticule::sm_fDistanceToNoTarget = 25.0f;
|
|
bank_float CUIReticule::sm_fAccuracyScaler = 100.0f;
|
|
bank_u16 CUIReticule::sm_uMaxInvAccuracy = 100;
|
|
bank_float CUIReticule::sm_fDrawSphereRadius = 1.7f;
|
|
bank_float CUIReticule::sm_fDrawSpherePixelLimit = 10.0f;
|
|
bank_float CUIReticule::sm_fVehicleReticuleDisplayTime = 3.0f;
|
|
bank_float CUIReticule::sm_fVehicleReticuleFadeOutTime = 1.0f;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
CUIReticule::sPreviousFrameHudValues::sPreviousFrameHudValues():
|
|
m_eDisplayReticle(DISPLAY_INVALID)
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
void CUIReticule::sPreviousFrameHudValues::Reset()
|
|
{
|
|
// Setting to an invalid location, to force the scaleform function to be called the next time it's checked.
|
|
m_target.Reset(NULL);
|
|
m_vReticlePosition = Vector2(-10.0f, -10.0f);
|
|
m_ReticleStyle = RETICLE_STYLE_INVALID;
|
|
m_ReticleLockOnStyle = LOCK_ON_NOT_LOCKED_ON;
|
|
m_iReticleMode = HUD_RETICLE_INVALID;
|
|
m_iWeaponHashForReticule = 0;
|
|
m_accuracyScaler = -1.0f;
|
|
m_iReticleZoom = INVALID_ZOOM_LEVEL;
|
|
m_iHeading = -1;
|
|
|
|
ResetDisplay();
|
|
}
|
|
|
|
void CUIReticule::sPreviousFrameHudValues::ResetDisplay()
|
|
{
|
|
if(m_eDisplayReticle == DISPLAY_VISIBLE)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_VISIBLE"))
|
|
{
|
|
CScaleformMgr::AddParamBool(false);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
m_eDisplayReticle = DISPLAY_INVALID;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CUIReticule::sZoomState::Reset()
|
|
{
|
|
m_iZoomLevel = INVALID_ZOOM_LEVEL;
|
|
m_bIsFirstPersonAimingThroughScope = false;
|
|
m_bIsZoomed = false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
CUIReticule::CUIReticule()
|
|
: m_queryId(INVALID_RETICULE_QUERY)
|
|
#if __BANK
|
|
, m_bForceHideReticle(false)
|
|
, m_debugOverrideHashIndex(0)
|
|
, m_fTimeDisplayed(0.0f)
|
|
, m_bOnFootReticuleLockedOn(false)
|
|
#endif
|
|
{
|
|
m_vOnFootLockOnReticulePosition = Vector2(0.5f, 0.5f);
|
|
Reset();
|
|
}
|
|
|
|
void CUIReticule::Reset()
|
|
{
|
|
m_vReticuleBlendOutPos = Vector2(0.0f, 0.0f);
|
|
m_bReticuleBlendOut = false;
|
|
m_overrideHashThisFrame = 0;
|
|
m_queryUsedThisFrame = false;
|
|
m_killTargetThisFrame = false;
|
|
m_incapacitatedTargetThisFrame = false;
|
|
m_bHitVehicleThisFrame = false;
|
|
|
|
if(m_queryId != INVALID_RETICULE_QUERY)
|
|
{
|
|
OcclusionQueries::OQFree(m_queryId);
|
|
m_queryId = INVALID_RETICULE_QUERY;
|
|
}
|
|
|
|
PreviousHudValue.Reset();
|
|
m_ValidVehicleHitHashes.Reset();
|
|
}
|
|
|
|
bool CUIReticule::ShouldHideReticule(const CPed* pPlayerPed)
|
|
{
|
|
bool bDisplayReticle = true;
|
|
|
|
if (CNewHud::IsFullHudHidden() && gVpMan.AreWidescreenBordersActive()) // don't show reticule if widescreen borders are active
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
else if(pPlayerPed)
|
|
{
|
|
const CQueriableInterface* pInterface = pPlayerPed->GetPedIntelligence() ? pPlayerPed->GetPedIntelligence()->GetQueriableInterface() : NULL;
|
|
|
|
// dont display retitcle if player is entering or exiting the vehicle (only when he is actually sitting in it)
|
|
if (pInterface &&
|
|
(pInterface->IsTaskCurrentlyRunning(CTaskTypes::TASK_ENTER_VEHICLE) ||
|
|
pInterface->IsTaskCurrentlyRunning(CTaskTypes::TASK_EXIT_VEHICLE) ||
|
|
pInterface->IsTaskCurrentlyRunning(CTaskTypes::TASK_MELEE)))
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
|
|
const CWeaponInfo* pWeaponInfo = pPlayerPed->GetEquippedWeaponInfo();
|
|
if(pWeaponInfo && pWeaponInfo->GetHideReticule())
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
|
|
return !bDisplayReticle;
|
|
}
|
|
|
|
bool CUIReticule::IsInGameplay()
|
|
{
|
|
const camBaseCamera* dominantRenderedCamera = camInterface::GetDominantRenderedCamera();
|
|
const camGameplayDirector& gameplayDirector = camInterface::GetGameplayDirector();
|
|
const camBaseCamera* renderedGameplayCamera = gameplayDirector.GetRenderedCamera();
|
|
const bool isActuallyRenderingGameplay = dominantRenderedCamera && renderedGameplayCamera &&
|
|
((dominantRenderedCamera == renderedGameplayCamera) ||
|
|
renderedGameplayCamera->IsInterpolating(dominantRenderedCamera));
|
|
bool firstPersonMountedCam = false;
|
|
const camBaseCamera* pDominantRenderedCamera = camInterface::GetDominantRenderedCamera();
|
|
if(pDominantRenderedCamera && camInterface::GetDominantRenderedCamera()->GetIsClassId(camCinematicMountedCamera::GetStaticClassId()))
|
|
{
|
|
// Return true for pov AND bonnet cameras. (train mounted cameras are blocked as gameplay camera is marked as invalid for reticle)
|
|
firstPersonMountedCam = true;
|
|
}
|
|
|
|
const bool shouldRenderReticuleForGameplay = (isActuallyRenderingGameplay || firstPersonMountedCam) && gameplayDirector.ShouldDisplayReticule();
|
|
|
|
return shouldRenderReticuleForGameplay;
|
|
}
|
|
|
|
bool CUIReticule::IsInMovie()
|
|
{
|
|
// don't display reticle if a cinematic camera is rendering and does not require one
|
|
const camCinematicDirector& cinematicDirector = camInterface::GetCinematicDirector();
|
|
const camBaseCamera* renderedCinematicCamera = cinematicDirector.GetRenderedCamera();
|
|
const bool isActuallyRenderingCinematicCamera = renderedCinematicCamera && camInterface::IsDominantRenderedCamera(*renderedCinematicCamera);
|
|
const bool shouldBlockReticuleForCinematicCamera = isActuallyRenderingCinematicCamera && !cinematicDirector.ShouldDisplayReticule();
|
|
|
|
return shouldBlockReticuleForCinematicCamera;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CUIReticule::Update(bool forceShow, bool isHudHidden)
|
|
{
|
|
if(CPauseMenu::IsActive() REPLAY_ONLY(&& !CReplayMgr::IsEditModeActive()))
|
|
{
|
|
m_killTargetThisFrame = false;
|
|
m_incapacitatedTargetThisFrame = false;
|
|
m_bHitVehicleThisFrame = false;
|
|
|
|
//
|
|
// deal with hiding the reticle during the SP->MP or MP->SP transitions: (fixes 1618455 without script changes)
|
|
//
|
|
eReticleDisplay eDisplayReticle = g_PlayerSwitch.IsActive() ? DISPLAY_HIDDEN : PreviousHudValue.m_eDisplayReticle;
|
|
|
|
if (eDisplayReticle != PreviousHudValue.m_eDisplayReticle)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_VISIBLE"))
|
|
{
|
|
CScaleformMgr::AddParamBool(eDisplayReticle == DISPLAY_VISIBLE);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_eDisplayReticle = eDisplayReticle;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#define LAZER_COCKPIT_ROCKETS (u32)-199376390
|
|
#define LAZER_COCKPIT_MACHINE 1931187857
|
|
#define ROCKET_BARRAGE_HASH 144449218
|
|
#define LAZER_ROCKET_HASH 3487949222
|
|
#define LAZER_MACHINE_GUN_HASH 4261553085
|
|
|
|
CPed *pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
|
|
if (!pPlayerPed)
|
|
return;
|
|
|
|
const CPedWeaponManager* pPlayerWeaponManager = pPlayerPed->GetWeaponManager();
|
|
if (!pPlayerWeaponManager)
|
|
return;
|
|
|
|
#if GTA_REPLAY
|
|
// if this is a replay, we want to skip out and do a fake update that just triggers stuff on demand
|
|
if(CReplayMgr::IsEditModeActive() && ReplayReticuleExtension::HasExtension(pPlayerPed))
|
|
{
|
|
bool isSniperScopeVisible = false;
|
|
bool justMadeVisible = false;
|
|
|
|
u32 iWeaponHash = ReplayReticuleExtension::GetWeaponHash(pPlayerPed);
|
|
if (iWeaponHash == FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE || iWeaponHash == FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE_MAX || iWeaponHash == FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE || iWeaponHash == FAKED_WEAPON_HASH_FOR_SIMPLE_MP_RETICLE )
|
|
{
|
|
bool bFirstPerson = ReplayReticuleExtension::GetIsFirstPerson(pPlayerPed);
|
|
if (bFirstPerson)
|
|
{
|
|
CNewHud::SetHudComponentToBeShown(NEW_HUD_RETICLE);
|
|
|
|
isSniperScopeVisible = true;
|
|
}
|
|
}
|
|
|
|
eReticleDisplay eDisplayReticle = (isSniperScopeVisible && CReplayMgr::IsUsingRecordedCamera()) ? DISPLAY_VISIBLE : DISPLAY_HIDDEN;
|
|
if(PreviousHudValue.m_eDisplayReticle != eDisplayReticle)
|
|
{
|
|
//Adding a check to delay the sniper scope ui activation/deactivation until the replay has finished streaming all the entities.
|
|
//Also avoid to do this if we are fine scrubbing because the IsReplayPlayBackSetupFinished is always return false in that case.
|
|
if( (camInterface::GetReplayDirector().IsReplayPlaybackSetupFinished() || CReplayMgr::IsFineScrubbing()) )
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_VISIBLE"))
|
|
{
|
|
CScaleformMgr::AddParamBool(isSniperScopeVisible);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
if (isSniperScopeVisible)
|
|
justMadeVisible = true;
|
|
}
|
|
else
|
|
{
|
|
eDisplayReticle = PreviousHudValue.m_eDisplayReticle;
|
|
}
|
|
}
|
|
|
|
if (PreviousHudValue.m_iWeaponHashForReticule != iWeaponHash)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_USING_REMOTE_PLAY"))
|
|
{
|
|
CScaleformMgr::AddParamBool(CControlMgr::GetPlayerMappingControl().IsUsingRemotePlay()); // for 1847201
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
// Always force the reticule type upon making reticule visible, otherwise we get visibility problems.
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_TYPE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(iWeaponHash);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
s32 zoomLevel = static_cast<s32>(ReplayReticuleExtension::GetZoomLevel(pPlayerPed));
|
|
if (zoomLevel != PreviousHudValue.m_iReticleZoom || justMadeVisible)
|
|
{
|
|
if(isSniperScopeVisible)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_ZOOM"))
|
|
{
|
|
CScaleformMgr::AddParamInt(zoomLevel);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
PreviousHudValue.m_iReticleZoom = zoomLevel;
|
|
}
|
|
|
|
#if SUPPORT_MULTI_MONITOR
|
|
DrawBlinders(isSniperScopeVisible && eDisplayReticle == DISPLAY_VISIBLE);
|
|
#endif // SUPPORT_MULTI_MONITOR
|
|
|
|
|
|
PreviousHudValue.m_iReticleMode = HUD_RETICLE_INVALID;
|
|
// PreviousHudValue.m_ReticleLockOnStyle = ReticleLockOnStyle;
|
|
PreviousHudValue.m_iWeaponHashForReticule = iWeaponHash;
|
|
PreviousHudValue.m_eDisplayReticle = eDisplayReticle;
|
|
|
|
// for now, just disable the reticule component when not in sniper
|
|
// it's all we need it for ...for now.
|
|
if (!isSniperScopeVisible)
|
|
{
|
|
CNewHud::SetHudComponentToBeHidden(NEW_HUD_RETICLE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif // GTA_REPLAY
|
|
|
|
const CWeapon* pPlayerEquippedWeapon = pPlayerWeaponManager->GetEquippedWeapon();
|
|
const camGameplayDirector& gameplayDirector = camInterface::GetGameplayDirector();
|
|
|
|
// find out if we need to display the reticle:
|
|
// NOTE: We support forcing/simulating aiming (ie via a script command)
|
|
bool bDisplayReticle = forceShow || IsInGameplay();
|
|
eReticleLockOnStyle ReticleLockOnStyle = LOCK_ON_INVALID;
|
|
|
|
//
|
|
// get the current weapon:
|
|
//
|
|
u32 iVehicleWeaponHash = 0;
|
|
u32 iCurrentWeaponHash = 0;
|
|
|
|
|
|
CVehicle *pVehicle = pPlayerPed->GetVehiclePedInside();
|
|
const CPed* pMount = pPlayerPed->GetMyMount();
|
|
const CVehicleWeapon* pEquippedVehicleWeapon = pPlayerWeaponManager->GetEquippedVehicleWeapon();
|
|
const CWeaponInfo *pWeaponInfo = NULL;
|
|
|
|
m_queryUsedThisFrame = false;
|
|
|
|
// B*2077359: Enable reticule in aircraft if in FPS mode and have the pilot helmet equipped and using the mobile phone
|
|
bool bUsingPhoneInAircraftInFPSMode = CTaskMobilePhone::IsRunningMobilePhoneTask(*pPlayerPed) && pPlayerPed->GetHelmetComponent() && pPlayerPed->GetHelmetComponent()->HasPilotHelmetEquippedInAircraftInFPS(true);
|
|
|
|
if (pEquippedVehicleWeapon)
|
|
{
|
|
pWeaponInfo = pEquippedVehicleWeapon->GetWeaponInfo();
|
|
iVehicleWeaponHash = pEquippedVehicleWeapon->GetHash();
|
|
bool bHasVehiclePOVIronSight = MI_PLANE_STARLING.IsValid() && pVehicle && pVehicle->GetModelIndex() == MI_PLANE_STARLING;
|
|
|
|
if(pWeaponInfo && pWeaponInfo->GetDamageType() != DAMAGE_TYPE_NONE) // Don't put up the reticule if it can't hurt anything.
|
|
{
|
|
bDisplayReticle = !IsInMovie() || (camInterface::GetCinematicDirector().IsRenderingCinematicMountedCamera() && !bHasVehiclePOVIronSight);
|
|
}
|
|
}
|
|
#if FPS_MODE_SUPPORTED
|
|
// B*2077359: Enable reticule in aircraft if in FPS mode and have the pilot helmet equipped and using the mobile phone
|
|
else if(bUsingPhoneInAircraftInFPSMode && !pEquippedVehicleWeapon && pVehicle->GetVehicleWeaponMgr())
|
|
{
|
|
// Use the reticule style of the previously equipped vehicle weapon (as the phone is the currently equipped weapon)
|
|
// This is cached in the phone task just before we equip the phone object.
|
|
CTaskMobilePhone *pTaskMobilePhone = static_cast<CTaskMobilePhone*>(pPlayerPed->GetPedIntelligence()->FindTaskSecondaryByType(CTaskTypes::TASK_MOBILE_PHONE));
|
|
if (pTaskMobilePhone && pTaskMobilePhone->GetPreviousVehicleWeaponIndex() != -1)
|
|
{
|
|
pEquippedVehicleWeapon = pVehicle->GetVehicleWeaponMgr()->GetVehicleWeapon(pTaskMobilePhone->GetPreviousVehicleWeaponIndex());
|
|
if (pEquippedVehicleWeapon)
|
|
{
|
|
pWeaponInfo = pEquippedVehicleWeapon->GetWeaponInfo();
|
|
iVehicleWeaponHash = pEquippedVehicleWeapon->GetHash();
|
|
if(pWeaponInfo && pWeaponInfo->GetDamageType() != DAMAGE_TYPE_NONE) // Don't put up the reticule if it can't hurt anything.
|
|
{
|
|
bDisplayReticle = !IsInMovie() || camInterface::GetCinematicDirector().IsRenderingCinematicPointOfViewCamera();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif //FPS_MODE_SUPPORTED
|
|
|
|
//B*1833484: Fade out crosshair after timer
|
|
// only doing this for spycar machinegun for now
|
|
bool bFadeOutVehicleWeaponReticuleAfterTimer = pVehicle && pVehicle->InheritsFromSubmarineCar() && pEquippedVehicleWeapon && iVehicleWeaponHash == ATSTRINGHASH("VEHICLE_WEAPON_SPYCARGUN", 0xa9ee94f7);
|
|
bool bFadeOutVehReticule = false;
|
|
int iDimValue = 100;
|
|
#if FPS_MODE_SUPPORTED
|
|
TUNE_GROUP_BOOL(AIMING_TUNE, FORCE_FPS_SCOPE_RETICLE, false);
|
|
#endif // FPS_MODE_SUPPORTED
|
|
|
|
bool isFirstPersonAiming = false;
|
|
bool bHideReticuleInFPSMode = false;
|
|
if ((!pEquippedVehicleWeapon) || iVehicleWeaponHash == 0)
|
|
{
|
|
// Use the weapon info provided by the camera system, as this should keep the reticle synchronized with any camera transitions
|
|
pWeaponInfo = camGameplayDirector::ComputeWeaponInfoForPed(*pPlayerPed);
|
|
if(pWeaponInfo)
|
|
{
|
|
iCurrentWeaponHash = pWeaponInfo->GetHash();
|
|
|
|
if(pPlayerPed->GetWeaponManager() && pPlayerPed->GetWeaponManager()->GetEquippedWeaponHasFirstPersonScope())
|
|
{
|
|
//If the gameplay director isn't rendering a first-person aim camera, fall-back to using a third-person reticule.
|
|
if(gameplayDirector.IsFirstPersonAiming())
|
|
{
|
|
isFirstPersonAiming = true;
|
|
}
|
|
else
|
|
{
|
|
iCurrentWeaponHash = WEAPONTYPE_ASSAULTRIFLE;
|
|
}
|
|
}
|
|
if (rage::ioHeadTracking::UseFPSCamera())
|
|
{
|
|
isFirstPersonAiming = true;
|
|
bDisplayReticle = true;
|
|
}
|
|
#if FPS_MODE_SUPPORTED
|
|
const camFirstPersonShooterCamera* fpsCamera = camInterface::GetGameplayDirector().GetFirstPersonShooterCamera();
|
|
if( fpsCamera &&
|
|
camInterface::GetDominantRenderedCamera() == (camBaseCamera*)fpsCamera &&
|
|
((pWeaponInfo->GetIsArmed() && !pWeaponInfo->GetIsMeleeFist()) || pPlayerPed->GetPedResetFlag(CPED_RESET_FLAG_ThrowingProjectile)) )
|
|
{
|
|
if ( fpsCamera->ShowReticle() || FORCE_FPS_SCOPE_RETICLE )
|
|
{
|
|
bDisplayReticle = true;
|
|
}
|
|
else
|
|
{
|
|
bDisplayReticle = false;
|
|
bHideReticuleInFPSMode = true;
|
|
}
|
|
}
|
|
#endif // FPS_MODE_SUPPORTED
|
|
|
|
if(pWeaponInfo->GetReticuleStyleHash())
|
|
{
|
|
iCurrentWeaponHash = pWeaponInfo->GetReticuleStyleHash();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iCurrentWeaponHash = pPlayerPed->GetDefaultUnarmedWeaponHash();
|
|
}
|
|
|
|
// The unarmed weapon shouldn't have a reticule when in a vehicle, B* 988479
|
|
if((pVehicle || pMount) && iCurrentWeaponHash == pPlayerPed->GetDefaultUnarmedWeaponHash())
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
|
|
if(sm_bHideReticleWithLaserSight)
|
|
{
|
|
const CPedWeaponManager *pWeaponManager = pPlayerPed->GetWeaponManager();
|
|
if(pWeaponManager)
|
|
{
|
|
const CWeapon *pPlayersWeapon = pWeaponManager->GetEquippedWeapon();
|
|
if(pPlayersWeapon)
|
|
{
|
|
if (pPlayersWeapon->GetLaserSightComponent())
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(pEquippedVehicleWeapon && pEquippedVehicleWeapon->GetWeaponInfo() && pEquippedVehicleWeapon->GetWeaponInfo()->GetReticuleStyleHash())
|
|
{
|
|
iCurrentWeaponHash = pEquippedVehicleWeapon->GetWeaponInfo()->GetReticuleStyleHash();
|
|
|
|
#if FPS_MODE_SUPPORTED
|
|
if(!FORCE_FPS_SCOPE_RETICLE && camInterface::GetDominantRenderedCamera())
|
|
{
|
|
if( camInterface::GetDominantRenderedCamera()->GetIsClassId(camCinematicMountedCamera::GetStaticClassId()) )
|
|
{
|
|
const camCinematicMountedCamera* pMountedCamera = (const camCinematicMountedCamera*)camInterface::GetDominantRenderedCamera();
|
|
if(pMountedCamera->IsVehicleTurretCamera())
|
|
{
|
|
bDisplayReticle = pMountedCamera->ShouldDisplayReticule();
|
|
}
|
|
}
|
|
else if( camInterface::GetDominantRenderedCamera()->GetIsClassId(camFirstPersonShooterCamera::GetStaticClassId()) )
|
|
{
|
|
const camFirstPersonShooterCamera* pFpsCamera = (const camFirstPersonShooterCamera*)camInterface::GetDominantRenderedCamera();
|
|
if(pFpsCamera->IsEnteringTurretSeat())
|
|
{
|
|
bDisplayReticle = pFpsCamera->ShowReticle();
|
|
}
|
|
}
|
|
}
|
|
#endif // FPS_MODE_SUPPORTED
|
|
}
|
|
else
|
|
{
|
|
iCurrentWeaponHash = iVehicleWeaponHash;
|
|
}
|
|
|
|
Vector2 vReticlePosition(0.5f, 0.5f);
|
|
s32 iHeading = 0;
|
|
atHashWithStringNotFinal humanNameHash;
|
|
atHashWithStringNotFinal humanNameSuffixHash;
|
|
|
|
// B*2148150: On-foot homing weapons: process lock-on reticule style and lerp to/from lock-on position.
|
|
if(pWeaponInfo && pWeaponInfo->GetIsOnFootHoming() && !pPlayerPed->GetIsInVehicle())
|
|
{
|
|
CPlayerPedTargeting& rTargeting = pPlayerPed->GetPlayerInfo()->GetTargeting();
|
|
Vector3 vReticlePositionWorld;
|
|
bool bVisible = false;
|
|
bool bShiftReticulePosition = false;
|
|
|
|
// B*2153703: Only show reticule when aiming and locked on in FPS mode
|
|
bool bInFPSMode = pPlayerPed->IsFirstPersonShooterModeEnabledForPlayer(false);
|
|
|
|
if (rTargeting.GetLockOnTarget())
|
|
{
|
|
CPlayerPedTargeting::OnFootHomingLockOnState lockOnState = rTargeting.GetOnFootHomingLockOnState(pPlayerPed);
|
|
|
|
switch(lockOnState)
|
|
{
|
|
case(CPlayerPedTargeting::OFH_NOT_LOCKED):
|
|
ReticleLockOnStyle = LOCK_ON_NOT_LOCKED_ON;
|
|
break;
|
|
case(CPlayerPedTargeting::OFH_ACQUIRING_LOCK_ON):
|
|
ReticleLockOnStyle = LOCK_ON_ACQUIRING_LOCK_ON;
|
|
break;
|
|
case(CPlayerPedTargeting::OFH_LOCKED_ON):
|
|
ReticleLockOnStyle = LOCK_ON_LOCKED_ON;
|
|
break;
|
|
default:
|
|
ReticleLockOnStyle = LOCK_ON_NOT_LOCKED_ON;
|
|
break;
|
|
}
|
|
|
|
// Set the reticle position to the position of the current target entity
|
|
vReticlePositionWorld = rTargeting.GetLockonTargetPos();
|
|
bVisible = true;
|
|
bShiftReticulePosition = true;
|
|
|
|
// We usually hide the reticule in iron sights camera, but in this case we still want to show it so we know what we're locked on to.
|
|
if (bHideReticuleInFPSMode && !bDisplayReticle)
|
|
{
|
|
bDisplayReticle = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Lerp back to the normal reticule position if aren't back already.
|
|
if (!bInFPSMode && (m_vOnFootLockOnReticulePosition - vReticlePosition).Mag() > 0.01f)
|
|
{
|
|
static dev_float s_fReticuleApproachRateNotLocked = 0.33f;
|
|
float fLerpSpeed = s_fReticuleApproachRateNotLocked;
|
|
fLerpSpeed *= fwTimer::GetTimeStep() / (1.0f / 30.0f);
|
|
|
|
m_vOnFootLockOnReticulePosition = Lerp(fLerpSpeed, m_vOnFootLockOnReticulePosition, vReticlePosition);
|
|
vReticlePosition = m_vOnFootLockOnReticulePosition;
|
|
}
|
|
else
|
|
{
|
|
m_vOnFootLockOnReticulePosition = vReticlePosition;
|
|
}
|
|
m_bOnFootReticuleLockedOn = false;
|
|
ReticleLockOnStyle = LOCK_ON_NO_TARGET;
|
|
bVisible = true;
|
|
}
|
|
|
|
if (bVisible)
|
|
{
|
|
if( pWeaponInfo && pWeaponInfo->GetIsStaticReticulePosition())
|
|
{
|
|
bDisplayReticle = true;
|
|
vReticlePosition = pWeaponInfo->GetReticuleHudPosition();
|
|
}
|
|
else if (bShiftReticulePosition)
|
|
{
|
|
TransformReticulePosition(vReticlePositionWorld, vReticlePosition, bDisplayReticle);
|
|
|
|
static dev_float fReticuleAccuracyThreshold = 0.01f;
|
|
if((m_vOnFootLockOnReticulePosition - vReticlePosition).Mag() < fReticuleAccuracyThreshold)
|
|
{
|
|
m_bOnFootReticuleLockedOn = true;
|
|
}
|
|
|
|
// If we aren't fully locked on, lerp the reticule towards the target position
|
|
if (!bInFPSMode && ReticleLockOnStyle != LOCK_ON_LOCKED_ON && !m_bOnFootReticuleLockedOn)
|
|
{
|
|
static dev_float s_fReticuleApproachRateLocked = 0.33f;
|
|
float fLerpSpeed = s_fReticuleApproachRateLocked;
|
|
fLerpSpeed *= fwTimer::GetTimeStep() / (1.0f / 30.0f);
|
|
|
|
m_vOnFootLockOnReticulePosition = Lerp(fLerpSpeed, m_vOnFootLockOnReticulePosition, vReticlePosition);
|
|
vReticlePosition = m_vOnFootLockOnReticulePosition;
|
|
}
|
|
else
|
|
{
|
|
m_vOnFootLockOnReticulePosition = vReticlePosition;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
|
|
|
|
// B*1997859 - For vehicles with mounted turrets and static reticules we don't really want to check distances
|
|
const bool bAvoidDistanceChecks = (pWeaponInfo && pWeaponInfo->GetIsTurret() && pWeaponInfo->GetIsStaticReticulePosition()) || (pVehicle && MI_CAR_APC.IsValid() && pVehicle->GetModelIndex() == MI_CAR_APC);
|
|
if (!bAvoidDistanceChecks && pEquippedVehicleWeapon && iVehicleWeaponHash != 0 && bDisplayReticle && pVehicle && (!pVehicle->GetIsLandVehicle() || pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_USE_AIRCRAFT_STYLE_WEAPON_TARGETING)))
|
|
{
|
|
bool bVisible = false;
|
|
Vector3 vReticlePositionWorld;
|
|
|
|
bool bIsVehicleGadget = false;
|
|
|
|
bool bHoverMode = pVehicle->GetHoverMode();
|
|
for(int i = 0; i < pVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget *pVehicleGadget = pVehicle->GetVehicleGadget(i);
|
|
|
|
if(pVehicleGadget && pVehicleGadget->GetType() == VGT_VEHICLE_WEAPON_BATTERY)
|
|
{
|
|
CVehicleWeaponMgr* pVehWeaponMgr = pVehicle->GetVehicleWeaponMgr();
|
|
|
|
if (pVehWeaponMgr)
|
|
{
|
|
const CVehicleWeapon* pVehicleWeapon = pVehWeaponMgr->GetVehicleWeapon(iVehicleWeaponHash);
|
|
if(pVehicleWeapon)
|
|
{
|
|
pVehicleWeapon->GetReticlePosition(vReticlePositionWorld);
|
|
bVisible = IsSphereVisible(vReticlePositionWorld);
|
|
bIsVehicleGadget = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bIsVehicleGadget)
|
|
{
|
|
if(pEquippedVehicleWeapon->GetType() == VGT_VEHICLE_WEAPON_BATTERY)
|
|
{
|
|
const CVehicleWeaponBattery* pWeaponBattery = static_cast<const CVehicleWeaponBattery*>(pEquippedVehicleWeapon);
|
|
|
|
Vector3 vPositionTotal( Vector3::ZeroType );
|
|
int nWeaponCount = 0;
|
|
for(int i = 0; i < pWeaponBattery->GetNumWeaponsInBattery(); i++)
|
|
{
|
|
const CVehicleWeapon* pWeapon = pWeaponBattery->GetVehicleWeapon(i);
|
|
|
|
if(uiVerify(pWeapon) && pWeapon->GetHash() == iVehicleWeaponHash)
|
|
{
|
|
if( pWeapon->GetReticlePosition( vReticlePositionWorld ) )
|
|
{
|
|
vPositionTotal += vReticlePositionWorld;
|
|
nWeaponCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( nWeaponCount )
|
|
vReticlePositionWorld = vPositionTotal / (f32)nWeaponCount;
|
|
}
|
|
else
|
|
{
|
|
pEquippedVehicleWeapon->GetReticlePosition(vReticlePositionWorld);
|
|
}
|
|
|
|
bVisible = IsSphereVisible(vReticlePositionWorld);
|
|
}
|
|
|
|
if(pWeaponInfo && pWeaponInfo->GetIsHoming())
|
|
{ // The vehicle weapon is a homing weapon
|
|
CPlayerPedTargeting& rTargeting = pPlayerPed->GetPlayerInfo()->GetTargeting();
|
|
|
|
if (rTargeting.GetLockOnTarget() && rTargeting.GetVehicleHomingEnabled())
|
|
{
|
|
// Time needed before the target is considered locked on
|
|
float fTimeBeforeHoming = 0.0f;
|
|
const CAmmoInfo* pAmmoInfo = pWeaponInfo->GetAmmoInfo();
|
|
if(pAmmoInfo && (pAmmoInfo->GetClassId() == CAmmoRocketInfo::GetStaticClassId()) )
|
|
{
|
|
fTimeBeforeHoming = static_cast<const CAmmoRocketInfo*>(pAmmoInfo)->GetTimeBeforeHoming();
|
|
}
|
|
|
|
float fTotalLockOnTime = rTargeting.GetTimeAimingAtTarget();
|
|
if (fTotalLockOnTime < (fTimeBeforeHoming/2))
|
|
{ // Display the green reticle
|
|
ReticleLockOnStyle = LOCK_ON_NOT_LOCKED_ON;
|
|
}
|
|
else if (fTotalLockOnTime < fTimeBeforeHoming)
|
|
{ // Display the flashing orange reticle
|
|
ReticleLockOnStyle = LOCK_ON_ACQUIRING_LOCK_ON;
|
|
}
|
|
else
|
|
{ // Display the red reticle
|
|
ReticleLockOnStyle = LOCK_ON_LOCKED_ON;
|
|
}
|
|
// Set the reticle position to the position of the current target entity
|
|
vReticlePositionWorld = rTargeting.GetLockonTargetPos();
|
|
bVisible = IsSphereVisible(vReticlePositionWorld, 1.0f);
|
|
|
|
CEntity *pTargetEntity = rTargeting.GetLockOnTarget();
|
|
|
|
// B*1817732: If sphere isn't visible, do a probe test from the vehicle to the lock on position.
|
|
// Fixes issues on certain entities where the sphere is too small to be seen (ie inside of the Mule or the Titan).
|
|
if (!bVisible && pTargetEntity && pVehicle)
|
|
{
|
|
u32 includeFlags = 0;
|
|
if (pTargetEntity->GetIsTypeVehicle())
|
|
{
|
|
includeFlags = ArchetypeFlags::GTA_VEHICLE_TYPE;
|
|
}
|
|
else if (pTargetEntity->GetIsTypeObject())
|
|
{
|
|
includeFlags = ArchetypeFlags::GTA_OBJECT_TYPE;
|
|
}
|
|
|
|
WorldProbe::CShapeTestHitPoint probeIsect;
|
|
WorldProbe::CShapeTestResults probeResult(probeIsect);
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
Vector3 vVehiclePosition = VEC3V_TO_VECTOR3(pVehicle->GetTransform().GetPosition());
|
|
probeDesc.SetStartAndEnd(vVehiclePosition, vReticlePositionWorld);
|
|
probeDesc.SetResultsStructure(&probeResult);
|
|
probeDesc.SetExcludeEntity(pVehicle);
|
|
probeDesc.SetIncludeFlags(includeFlags);
|
|
probeDesc.SetContext(WorldProbe::LOS_GeneralAI);
|
|
|
|
if(WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc, WorldProbe::PERFORM_SYNCHRONOUS_TEST))
|
|
{
|
|
for (int i = 0; i < probeResult.GetNumHits(); i++)
|
|
{
|
|
if (pTargetEntity == probeResult[i].GetHitEntity())
|
|
{
|
|
bVisible = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set target lock-on state
|
|
if( bVisible && pVehicle && pTargetEntity && pTargetEntity->GetIsPhysical())
|
|
{
|
|
CEntity::eHomingLockOnState lockOnState = CEntity::HLOnS_NONE;
|
|
if( ReticleLockOnStyle == LOCK_ON_ACQUIRING_LOCK_ON )
|
|
lockOnState = CEntity::HLOnS_ACQUIRING;
|
|
else if( ReticleLockOnStyle == LOCK_ON_LOCKED_ON )
|
|
lockOnState = CEntity::HLOnS_ACQUIRED;
|
|
|
|
pVehicle->SetHomingLockOnState( lockOnState );
|
|
pVehicle->SetLockOnTarget(static_cast<CPhysical *>(pTargetEntity));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!rTargeting.GetVehicleHomingEnabled())
|
|
{
|
|
humanNameSuffixHash = "WT_HOMING_DISABLED";
|
|
}
|
|
|
|
ReticleLockOnStyle = LOCK_ON_NO_TARGET;
|
|
bVisible = true;
|
|
}
|
|
}
|
|
else if (pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_USE_AIRCRAFT_STYLE_WEAPON_TARGETING))
|
|
{
|
|
// We're a non-homing vehicle weapon (not just 'homing but disabled') that's not a static reticule turret.. let's just render the reticule?
|
|
// We don't care about the distance check, but skipping the 'IsHoming' chunk above only renders a static reticule, because we never hit TransformReticulePosition below.
|
|
bVisible = true;
|
|
}
|
|
|
|
if(pWeaponInfo && camInterface::GetCinematicDirector().IsRenderingCinematicMountedCamera())
|
|
{
|
|
// If we're locked on, the text should read "Lock"
|
|
if(ReticleLockOnStyle == LOCK_ON_LOCKED_ON)
|
|
{
|
|
humanNameHash = "WT_LOCK";
|
|
}
|
|
else
|
|
{
|
|
humanNameHash = pWeaponInfo->GetHumanNameHash();
|
|
}
|
|
|
|
isFirstPersonAiming = true;
|
|
iCurrentWeaponHash = pWeaponInfo->GetFirstPersonReticuleStyleHash();
|
|
iHeading = (s32)(camInterface::GetHeading() * RtoD);
|
|
while(iHeading < 0) {iHeading += 360;}
|
|
while(360 <= iHeading) {iHeading -= 360;}
|
|
}
|
|
|
|
|
|
if (bFadeOutVehicleWeaponReticuleAfterTimer)
|
|
{
|
|
m_fTimeDisplayed += fwTimer::GetTimeStep();
|
|
if (m_fTimeDisplayed > sm_fVehicleReticuleDisplayTime)
|
|
{
|
|
bFadeOutVehReticule = true;
|
|
|
|
// Calculate reticule dimness value
|
|
float fTimeLeft = (sm_fVehicleReticuleDisplayTime + sm_fVehicleReticuleFadeOutTime) - m_fTimeDisplayed;
|
|
iDimValue = (int)((fTimeLeft / sm_fVehicleReticuleFadeOutTime) * 100.0f);
|
|
if (iDimValue < 0)
|
|
{
|
|
bFadeOutVehReticule = false;
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bVisible)
|
|
{
|
|
if( pWeaponInfo && ( bHoverMode || pWeaponInfo->GetIsStaticReticulePosition() ) )
|
|
{
|
|
bDisplayReticle = true;
|
|
vReticlePosition = pWeaponInfo->GetReticuleHudPosition();
|
|
}
|
|
else
|
|
{
|
|
TransformReticulePosition(vReticlePositionWorld, vReticlePosition, bDisplayReticle);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
|
|
bool isPassenger = false;
|
|
bool isTank = false;
|
|
|
|
if (pVehicle)
|
|
{
|
|
bool bReticuleLockedOn = false;
|
|
|
|
isPassenger = !pPlayerPed->GetIsDrivingVehicle();
|
|
isTank = pVehicle->IsTank();
|
|
|
|
//! Don't test this flag. It's better to have the reticule lock on, even when smashing window etc (as you get a pop to centre and back if not).
|
|
//if(pPlayerPed->GetPlayerResetFlag(CPlayerResetFlags::PRF_ASSISTED_AIMING_ON))
|
|
//{
|
|
CPlayerPedTargeting& rTargeting = pPlayerPed->GetPlayerInfo()->GetTargeting();
|
|
CEntity* pLockOnEntity = rTargeting.GetLockOnTarget();
|
|
if (pLockOnEntity && pPlayerPed->GetIsDrivingVehicle())
|
|
{
|
|
//! DMKH. Get lock on position directly. The targeting one contains some lag, which isn't appropriate for reticule here.
|
|
Vector3 vLockOnPos;
|
|
pLockOnEntity->GetLockOnTargetAimAtPos(vLockOnPos);
|
|
TransformReticulePosition(vLockOnPos, vReticlePosition, bDisplayReticle);
|
|
|
|
//! DMKH. Start a blend out back to idle reticule pos (0.5, 0.5). Bug* 1007203.
|
|
m_bReticuleBlendOut = true;
|
|
m_vReticuleBlendOutPos = vReticlePosition;
|
|
|
|
bReticuleLockedOn = true;
|
|
}
|
|
//}
|
|
|
|
//! Blend reticule back to centre if we have indicated we would like to do so.
|
|
if(!bReticuleLockedOn && m_bReticuleBlendOut)
|
|
{
|
|
static dev_float s_fReticuleApproachRate = 0.25f;
|
|
float fLerpSpeed = s_fReticuleApproachRate;
|
|
fLerpSpeed *= fwTimer::GetTimeStep() / (1.0f / 30.0f);
|
|
|
|
Vector2 vReticuleBlendPos = Lerp(fLerpSpeed, m_vReticuleBlendOutPos, vReticlePosition);
|
|
m_vReticuleBlendOutPos = vReticuleBlendPos;
|
|
|
|
static dev_float s_fEpsilon = 0.00001f;
|
|
if(vReticuleBlendPos.IsClose(vReticlePosition, s_fEpsilon))
|
|
{
|
|
m_bReticuleBlendOut = false;
|
|
}
|
|
|
|
vReticlePosition = vReticuleBlendPos;
|
|
}
|
|
|
|
if(bDisplayReticle)
|
|
{
|
|
if(pVehicle->GetIsAircraft())
|
|
{
|
|
if(CControlMgr::GetMainPlayerControl().IsInputDisabled(INPUT_VEH_FLY_ATTACK) && !bUsingPhoneInAircraftInFPSMode)
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
else if(pVehicle->GetIsLandVehicle())
|
|
{
|
|
if(CControlMgr::GetMainPlayerControl().IsInputDisabled(INPUT_VEH_ATTACK) && CControlMgr::GetMainPlayerControl().IsInputDisabled(INPUT_VEH_ATTACK2))
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
|
|
if (pVehicle->GetIsAircraft() || pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_USE_AIRCRAFT_STYLE_WEAPON_TARGETING))
|
|
{
|
|
if(pEquippedVehicleWeapon && iVehicleWeaponHash != 0)
|
|
{
|
|
bool bShouldDoAimDirectionTest = pWeaponInfo ? !pWeaponInfo->GetDisableAimAngleChecksForReticule() : true;
|
|
|
|
if (bShouldDoAimDirectionTest)
|
|
{
|
|
// Do not render the reticule if we're not facing in the correct direction
|
|
// Use the ped's forward vector, rather than the vehicles as they maybe facing sideways
|
|
Vec3V aimFrontV = pPlayerPed->GetTransform().GetB();
|
|
Vector3 aimFront(aimFrontV.GetXf(), aimFrontV.GetYf(), aimFrontV.GetZf());
|
|
Vector3 camFront = camInterface::GetFront();
|
|
|
|
aimFront /= aimFront.Mag();
|
|
camFront /= camFront.Mag();
|
|
|
|
if(aimFront.Dot(camFront) < 0.0f)
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_bReticuleBlendOut = false;
|
|
}
|
|
|
|
if(pMount &&
|
|
(CControlMgr::GetMainPlayerControl().IsInputDisabled(INPUT_VEH_ATTACK) && CControlMgr::GetMainPlayerControl().IsInputDisabled(INPUT_VEH_ATTACK2)))
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
|
|
if (isHudHidden BANK_ONLY(|| m_bForceHideReticle))
|
|
{
|
|
bDisplayReticle = false;
|
|
m_bReticuleBlendOut = false;
|
|
}
|
|
|
|
// If the weapon is using a purchased scope, then we need to fake the reticle
|
|
if (pPlayerEquippedWeapon && gameplayDirector.IsFirstPersonAiming())
|
|
{
|
|
// NEVER TRUE?
|
|
//if(pPlayerEquippedWeapon->GetHasFirstPersonScope() &&
|
|
// !pPlayerEquippedWeapon->GetWeaponInfo()->GetHasFirstPersonScope())
|
|
//{
|
|
// isFirstPersonAiming = true;
|
|
// iCurrentWeaponHash = FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE;
|
|
//}
|
|
|
|
const CWeaponComponentScope* pScope = pPlayerEquippedWeapon->GetScopeComponent();
|
|
if(pScope && pScope->GetInfo() && pPlayerEquippedWeapon->GetHasFirstPersonScope())
|
|
{
|
|
u32 iScopeReticule = pScope->GetInfo()->GetReticuleHash();
|
|
if(iScopeReticule != 0)
|
|
{
|
|
iCurrentWeaponHash = iScopeReticule;
|
|
}
|
|
}
|
|
}
|
|
else if (gameplayDirector.IsFirstPersonAiming())
|
|
{
|
|
const CWeapon* pWeapon = pPlayerPed->GetWeaponManager() ? pPlayerPed->GetWeaponManager()->GetEquippedWeapon() : NULL;
|
|
if (pWeapon && pWeapon->GetHasFirstPersonScope())
|
|
{
|
|
const CPedInventory* inventory = pPlayerPed->GetInventory();
|
|
const CWeaponItem* weaponItem = inventory ? inventory->GetWeapon(pWeapon->GetWeaponInfo()->GetHash()) : NULL;
|
|
if (weaponItem && weaponItem->GetComponents())
|
|
{
|
|
const CWeaponItem::Components& components = *weaponItem->GetComponents();
|
|
for(s32 i=0; i<components.GetCount(); i++)
|
|
{
|
|
const CWeaponComponentInfo* componentInfo = components[i].pComponentInfo;
|
|
if(componentInfo && (componentInfo->GetClassId() == WCT_Scope))
|
|
{
|
|
u32 iScopeReticule = static_cast<const CWeaponComponentScopeInfo*>(componentInfo)->GetReticuleHash();
|
|
if (iScopeReticule != 0)
|
|
iCurrentWeaponHash = iScopeReticule;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!isFirstPersonAiming && !isTank && (ReticleLockOnStyle == LOCK_ON_INVALID) &&
|
|
CPauseMenu::GetMenuPreference(PREF_RETICULE) == 0 && iCurrentWeaponHash != LAZER_ROCKET_HASH)
|
|
{
|
|
iCurrentWeaponHash = FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE;
|
|
}
|
|
|
|
if(CNetwork::IsNetworkOpen() && iCurrentWeaponHash == FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE)
|
|
{
|
|
iCurrentWeaponHash = FAKED_WEAPON_HASH_FOR_SIMPLE_MP_RETICLE;
|
|
|
|
#if RSG_PC
|
|
if(CHudTools::IsSuperWideScreen() || GRCDEVICE.GetMonitorConfig().isMultihead())
|
|
iCurrentWeaponHash = FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE;
|
|
#endif // RSG_PC
|
|
}
|
|
|
|
#if __BANK
|
|
if(m_debugOverrideHashIndex)
|
|
{
|
|
m_overrideHashThisFrame = m_weaponHashes[m_debugOverrideHashIndex];
|
|
}
|
|
#endif
|
|
|
|
if(m_overrideHashThisFrame)
|
|
{
|
|
iCurrentWeaponHash = m_overrideHashThisFrame;
|
|
m_overrideHashThisFrame = 0;
|
|
}
|
|
|
|
if((!isFirstPersonAiming || pPlayerPed->GetIsDrivingVehicle()) && CNewHud::IsShowingHUDMenu())
|
|
{
|
|
if(pVehicle && pVehicle->GetIsAircraft())
|
|
{
|
|
if(CNewHud::IsRadioWheelActive() || CNewHud::IsShowingCharacterSwitch())
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
}
|
|
|
|
if(ShouldHideReticule(pPlayerPed))
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
|
|
if (pEquippedVehicleWeapon && !pEquippedVehicleWeapon->GetIsEnabled())
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
|
|
// only update if has changed
|
|
bool bForceUpdatePosAndHeading = false;
|
|
|
|
const bool c_IsUsingFirstPersonLazerWeapons = (iCurrentWeaponHash == LAZER_COCKPIT_ROCKETS || iCurrentWeaponHash == LAZER_COCKPIT_MACHINE) &&
|
|
((pPlayerPed && pPlayerPed->IsInFirstPersonVehicleCamera()) || camInterface::GetCinematicDirector().IsRenderingCinematicMountedCamera());
|
|
if( c_IsUsingFirstPersonLazerWeapons )
|
|
{
|
|
if(pPlayerPed->GetHelmetComponent() && pPlayerPed->GetHelmetComponent()->HasPilotHelmetEquippedInAircraftInFPS(false))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
switch (iCurrentWeaponHash)
|
|
{
|
|
case LAZER_COCKPIT_ROCKETS:
|
|
iCurrentWeaponHash = LAZER_ROCKET_HASH; // VULCAN_ROCKET
|
|
break;
|
|
case LAZER_COCKPIT_MACHINE:
|
|
iCurrentWeaponHash = LAZER_MACHINE_GUN_HASH; // WEAPON_VULKAN_GUNS
|
|
break;
|
|
default:
|
|
iCurrentWeaponHash = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
eReticleDisplay eDisplayReticle = bDisplayReticle ? DISPLAY_VISIBLE : DISPLAY_HIDDEN;
|
|
if ( (eDisplayReticle != PreviousHudValue.m_eDisplayReticle)
|
|
|| (iCurrentWeaponHash != PreviousHudValue.m_iWeaponHashForReticule)
|
|
|| (ReticleLockOnStyle != PreviousHudValue.m_ReticleLockOnStyle)
|
|
|| (humanNameHash != PreviousHudValue.m_uPrevHumanNameHash)
|
|
|| (humanNameSuffixHash != PreviousHudValue.m_uPrevHumanNameSuffixHash))
|
|
{
|
|
// Only reset the display timer if the weapon has changed
|
|
if (m_fTimeDisplayed != 0.0f && iCurrentWeaponHash != PreviousHudValue.m_iWeaponHashForReticule)
|
|
{
|
|
m_fTimeDisplayed = 0.0f;
|
|
}
|
|
|
|
//! Invalidate style - it needs updated again, otherwise it becomes stale.
|
|
PreviousHudValue.m_ReticleStyle = RETICLE_STYLE_INVALID;
|
|
|
|
if (bDisplayReticle)
|
|
{
|
|
bForceUpdatePosAndHeading = true;
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_USING_REMOTE_PLAY")) // for 1847201
|
|
{
|
|
CScaleformMgr::AddParamBool(CControlMgr::GetPlayerMappingControl().IsUsingRemotePlay());
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
// Always force the reticule type upon making reticule visible, otherwise we get visibility problems.
|
|
if(c_IsUsingFirstPersonLazerWeapons && iCurrentWeaponHash == 0)
|
|
{
|
|
eDisplayReticle = DISPLAY_HIDDEN;
|
|
ReticleLockOnStyle = LOCK_ON_INVALID;
|
|
bDisplayReticle = false;
|
|
}
|
|
else
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_TYPE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(iCurrentWeaponHash);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_LOCKON_TYPE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(ReticleLockOnStyle);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
if(humanNameHash != 0)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_TEXT"))
|
|
{
|
|
atString weaponName(TheText.Get(humanNameHash, "WeaponName"));
|
|
|
|
if(humanNameSuffixHash != 0)
|
|
{
|
|
weaponName += " ";
|
|
weaponName += TheText.Get(humanNameSuffixHash, "WeaponNameSuffix");
|
|
}
|
|
|
|
CScaleformMgr::AddParamString(weaponName.c_str());
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(iCurrentWeaponHash == ATSTRINGHASH("WEAPON_HOMINGLAUNCHER", 0x63ab0442))
|
|
{
|
|
if(pPlayerPed && pPlayerPed->GetPlayerInfo())
|
|
{
|
|
TUNE_GROUP_FLOAT(ON_FOOT_HOMING_LAUNCHER, fReticuleHeightOffset, 1.4f, 0.0f, 10.0f, 0.01f);
|
|
TUNE_GROUP_FLOAT(ON_FOOT_HOMING_LAUNCHER, fReticuleWidthOffset, 1.4f, 0.0f, 10.0f, 0.01f);
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "OVERRIDE_HOMING_SCOPE"))
|
|
{
|
|
CScaleformMgr::AddParamFloat(fReticuleHeightOffset); // height
|
|
CScaleformMgr::AddParamFloat(fReticuleWidthOffset); // width
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(PreviousHudValue.m_eDisplayReticle != eDisplayReticle)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_VISIBLE"))
|
|
{
|
|
CScaleformMgr::AddParamBool(bDisplayReticle);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
PreviousHudValue.m_iReticleMode = HUD_RETICLE_INVALID;
|
|
PreviousHudValue.m_ReticleLockOnStyle = ReticleLockOnStyle;
|
|
PreviousHudValue.m_iWeaponHashForReticule = iCurrentWeaponHash;
|
|
PreviousHudValue.m_eDisplayReticle = eDisplayReticle;
|
|
PreviousHudValue.m_uPrevHumanNameHash = humanNameHash;
|
|
PreviousHudValue.m_uPrevHumanNameSuffixHash = humanNameSuffixHash;
|
|
}
|
|
|
|
if( (iHeading != PreviousHudValue.m_iHeading) || bForceUpdatePosAndHeading)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_CAM_HEADING"))
|
|
{
|
|
CScaleformMgr::AddParamInt(iHeading);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_iHeading = iHeading;
|
|
}
|
|
|
|
if ( (vReticlePosition != PreviousHudValue.m_vReticlePosition) || bForceUpdatePosAndHeading)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_POSITION"))
|
|
{
|
|
CScaleformMgr::AddParamFloat(vReticlePosition.x);
|
|
CScaleformMgr::AddParamFloat(vReticlePosition.y);
|
|
CScaleformMgr::AddParamFloat(CHudTools::GetAspectRatioMultiplier());
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_vReticlePosition = vReticlePosition;
|
|
}
|
|
|
|
sZoomState zoomState = CUIReticule::GetZoomState(pPlayerPed, pPlayerEquippedWeapon, gameplayDirector);
|
|
if (zoomState.m_iZoomLevel != PreviousHudValue.m_iReticleZoom)
|
|
{
|
|
if(zoomState.m_iZoomLevel != INVALID_ZOOM_LEVEL)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_ZOOM"))
|
|
{
|
|
CScaleformMgr::AddParamInt(zoomState.m_iZoomLevel);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
PreviousHudValue.m_iReticleZoom = zoomState.m_iZoomLevel;
|
|
}
|
|
|
|
//
|
|
// do some reticle effects:
|
|
//
|
|
bool bReloading = false;
|
|
bool bFiring = false;
|
|
bool bAiming = false;
|
|
bool bIsInCover = pPlayerPed->GetCoverPoint() != NULL;
|
|
|
|
const CTaskGun* gunTask = static_cast<CTaskGun*>(pPlayerPed->GetPedIntelligence()->FindTaskActiveByType(CTaskTypes::TASK_GUN));
|
|
if(gunTask)
|
|
{
|
|
bFiring = (gunTask->GetIsFiring());
|
|
bAiming = (gunTask->GetIsAiming()) && (!bFiring) && (!camInterface::GetGameplayDirector().IsCameraInterpolating());
|
|
bReloading = (gunTask->GetIsReloading()) && (!bAiming) && (!bFiring);
|
|
}
|
|
|
|
// Reset the visibility timer if we're firing the vehicle weapon
|
|
if (bFadeOutVehicleWeaponReticuleAfterTimer)
|
|
{
|
|
bool bFiringVehicleWeapon = false;
|
|
const CTaskVehicleMountedWeapon* pTask = static_cast<CTaskVehicleMountedWeapon*>(pPlayerPed->GetPedIntelligence()->FindTaskActiveByType(CTaskTypes::TASK_VEHICLE_MOUNTED_WEAPON));
|
|
if(pTask)
|
|
{
|
|
bFiringVehicleWeapon = pTask->IsFiring();
|
|
}
|
|
|
|
if (bFiringVehicleWeapon && m_fTimeDisplayed != 0.0f)
|
|
{
|
|
m_fTimeDisplayed = 0.0f;
|
|
}
|
|
}
|
|
|
|
//NOTE: We do not dim the overlay when reloading a scoped weapon.
|
|
bool shouldDimReticule = gameplayDirector.ShouldDimReticule() || bReloading || bFadeOutVehReticule;
|
|
if (pPlayerPed && pPlayerPed->GetPedIntelligence())
|
|
{
|
|
const CTaskVehicleMountedWeapon* pMountedWeaponTask = NULL;
|
|
if(!shouldDimReticule)
|
|
{
|
|
pMountedWeaponTask = static_cast<CTaskVehicleMountedWeapon*>(pPlayerPed->GetPedIntelligence()->FindTaskActiveByType(CTaskTypes::TASK_VEHICLE_MOUNTED_WEAPON));
|
|
if(pMountedWeaponTask)
|
|
{
|
|
shouldDimReticule = pMountedWeaponTask->ShouldDimReticule();
|
|
}
|
|
}
|
|
|
|
if(!shouldDimReticule && isPassenger && !pMountedWeaponTask)
|
|
{
|
|
const CTaskAimGunVehicleDriveBy* pTask = static_cast<CTaskAimGunVehicleDriveBy*>(pPlayerPed->GetPedIntelligence()->FindTaskActiveByType(CTaskTypes::TASK_AIM_GUN_VEHICLE_DRIVE_BY));
|
|
if(pTask)
|
|
{
|
|
bool bIsThrown = pTask->GetPedWeaponInfo() && pTask->GetPedWeaponInfo()->GetIsThrownWeapon();
|
|
shouldDimReticule = (!pTask->GetIsReadyToFire() && !bIsThrown);
|
|
}
|
|
else
|
|
{
|
|
const CTaskMountThrowProjectile* pMountThrowProjectileTask = static_cast<CTaskMountThrowProjectile*>(pPlayerPed->GetPedIntelligence()->FindTaskActiveByType(CTaskTypes::TASK_MOUNT_THROW_PROJECTILE));
|
|
shouldDimReticule = (pMountThrowProjectileTask == NULL) ? true : false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (shouldDimReticule && !zoomState.m_bIsFirstPersonAimingThroughScope) // dim the reticle if its impossible to fire at this point
|
|
{
|
|
// Fixes 337967, If we dim the reticle before it's visible, then it won't get dimmed.
|
|
if (bDisplayReticle && (HUD_RETICLE_CANNOT_FIRE != PreviousHudValue.m_iReticleMode || bFadeOutVehReticule))
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_STYLE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(RETICLE_STYLE_DEFAULT);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_ReticleStyle = RETICLE_STYLE_DEFAULT;
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "START_DIM_RETICLE"))
|
|
{
|
|
if (bFadeOutVehReticule)
|
|
{
|
|
CScaleformMgr::AddParamInt(iDimValue);
|
|
}
|
|
else
|
|
CScaleformMgr::AddParamInt(15);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
|
|
if(m_killTargetThisFrame)
|
|
{
|
|
ShowHitMarker(HITMARKER_KILLED_BY_LOCAL_PLAYER);
|
|
}
|
|
|
|
if (m_incapacitatedTargetThisFrame)
|
|
{
|
|
ShowHitMarkerNonLethal(HITMARKER_INCAPACITATED_BY_LOCAL_PLAYER);
|
|
}
|
|
|
|
PreviousHudValue.m_iReticleMode = HUD_RETICLE_CANNOT_FIRE;
|
|
}
|
|
}
|
|
else // check for any scripted reticle states:
|
|
if (CScriptHud::iScriptReticleMode != -1)
|
|
{
|
|
if (CScriptHud::iScriptReticleMode != PreviousHudValue.m_iReticleMode)
|
|
{
|
|
Color32 colour;
|
|
|
|
switch ((eHudReticleModes)CScriptHud::iScriptReticleMode)
|
|
{
|
|
case HUD_RETICLE_CAN_BE_STUNNED:
|
|
{
|
|
colour = CHudColour::GetRGBA(HUD_COLOUR_RED);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
colour = CHudColour::GetRGBA(HUD_COLOUR_PURE_WHITE);
|
|
Assertf(0, "CUIReticule:: Invalid hud reticle mode passed by script %d", CScriptHud::iScriptReticleMode);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "START_FLASHING_RETICLE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(colour.GetRed());
|
|
CScaleformMgr::AddParamInt(colour.GetGreen());
|
|
CScaleformMgr::AddParamInt(colour.GetBlue());
|
|
CScaleformMgr::AddParamFloat((float)colour.GetAlphaf() * 100.0f);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_iReticleMode = static_cast<CUIReticule::eHudReticleModes>(CScriptHud::iScriptReticleMode);
|
|
}
|
|
}
|
|
else // reset the reticle to standard state:
|
|
{
|
|
bool wasDim = (PreviousHudValue.m_iReticleMode == HUD_RETICLE_CANNOT_FIRE);
|
|
|
|
if (CScriptHud::iScriptReticleMode != PreviousHudValue.m_iReticleMode)
|
|
{
|
|
CHudTools::CallHudScaleformMethod(NEW_HUD_RETICLE, "RESET_RETICLE");
|
|
|
|
PreviousHudValue.m_iReticleMode = static_cast<CUIReticule::eHudReticleModes>(CScriptHud::iScriptReticleMode);
|
|
}
|
|
|
|
#if WATERMARKED_BUILD
|
|
Color32 overrideColour = GetWatermarkColour();
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "START_FLASHING_RETICLE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(overrideColour.GetRed());
|
|
CScaleformMgr::AddParamInt(overrideColour.GetGreen());
|
|
CScaleformMgr::AddParamInt(overrideColour.GetBlue());
|
|
CScaleformMgr::AddParamFloat((float)1.0f * 100.0f);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
#endif
|
|
|
|
#if SUPPORT_MULTI_MONITOR
|
|
DrawBlinders(CNewHud::IsSniperSightActive());
|
|
#endif // SUPPORT_MULTI_MONITOR
|
|
|
|
eRETICLE_STYLE retStyle;
|
|
if (CNewHud::GetDisplayMode() == CNewHud::DM_ARCADE_CNC)
|
|
{
|
|
retStyle = GetReticuleStyleForCNCDisplayMode(pPlayerPed, pWeaponInfo);
|
|
}
|
|
else
|
|
{
|
|
retStyle = zoomState.m_bIsZoomed ? RETICLE_STYLE_DEFAULT : GetReticuleStyle(pPlayerPed, pWeaponInfo);
|
|
}
|
|
|
|
// if we are currently firing we need to check to see if we are hitting at any specific target and change the reticle if we are:
|
|
if (pPlayerEquippedWeapon && (bAiming || bReloading || bFiring || bIsInCover))
|
|
{
|
|
bool hitPed = pPlayerPed->GetPedResetFlag(CPED_RESET_FLAG_HitPedWithWeapon) || m_bHitVehicleThisFrame;
|
|
bool isEnemyOrFriend = (PreviousHudValue.m_ReticleStyle == RETICLE_STYLE_ENEMY || PreviousHudValue.m_ReticleStyle == RETICLE_STYLE_FRIENDLY);
|
|
|
|
if(isFirstPersonAiming && hitPed)
|
|
{
|
|
if(CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SHOW_SNIPER_HIT"))
|
|
{
|
|
CScaleformMgr::AddParamBool(retStyle == RETICLE_STYLE_DEAD);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
|
|
const CEntity* pTarget = GetTargetEntity(pPlayerPed, CScriptHud::bUseVehicleTargetingReticule);
|
|
|
|
// Show the hit marker if you just shot your target ped, or if the target ped just died this frame.
|
|
if(m_killTargetThisFrame || (retStyle == RETICLE_STYLE_DEAD && isEnemyOrFriend && PreviousHudValue.m_target == pTarget))
|
|
{
|
|
if(!isFirstPersonAiming)
|
|
{
|
|
if(m_killTargetThisFrame)
|
|
{
|
|
ShowHitMarker(HITMARKER_KILLED_BY_LOCAL_PLAYER);
|
|
}
|
|
else if(retStyle == RETICLE_STYLE_DEAD)
|
|
{
|
|
ShowHitMarker(HITMARKER_DEAD);
|
|
}
|
|
else
|
|
{
|
|
ShowHitMarker(HITMARKER_HIT);
|
|
}
|
|
}
|
|
|
|
if(retStyle == RETICLE_STYLE_DEAD)
|
|
{
|
|
retStyle = RETICLE_STYLE_DEFAULT;
|
|
}
|
|
}
|
|
|
|
//Show non-lethal hit marker if incapacitated this frame
|
|
if (m_incapacitatedTargetThisFrame && !isFirstPersonAiming)
|
|
{
|
|
ShowHitMarkerNonLethal(HITMARKER_INCAPACITATED_BY_LOCAL_PLAYER);
|
|
}
|
|
|
|
PreviousHudValue.m_target.Reset(pTarget);
|
|
float accuracyScaler = GetInvAccuracy(pPlayerPed, pPlayerEquippedWeapon);
|
|
|
|
if (accuracyScaler != PreviousHudValue.m_accuracyScaler)
|
|
{
|
|
if(CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_ACCURACY"))
|
|
{
|
|
CScaleformMgr::AddParamFloat(accuracyScaler);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_accuracyScaler = accuracyScaler;
|
|
}
|
|
}
|
|
|
|
if(CScriptHud::bUseVehicleTargetingReticule)
|
|
{
|
|
if(m_bHitVehicleThisFrame)
|
|
{
|
|
ShowHitMarker(HITMARKER_DEAD);
|
|
}
|
|
}
|
|
|
|
if(ReticleLockOnStyle == LOCK_ON_INVALID && iCurrentWeaponHash != LAZER_COCKPIT_MACHINE)
|
|
{
|
|
if(wasDim || retStyle != PreviousHudValue.m_ReticleStyle)
|
|
{
|
|
// Otherwise affect the color
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICLE_STYLE"))
|
|
{
|
|
CScaleformMgr::AddParamInt(static_cast<int>(retStyle));
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
PreviousHudValue.m_ReticleStyle = retStyle;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PreviousHudValue.m_ReticleStyle = RETICLE_STYLE_INVALID;
|
|
}
|
|
}
|
|
|
|
if(!m_queryUsedThisFrame && m_queryId != INVALID_RETICULE_QUERY)
|
|
{
|
|
OcclusionQueries::OQFree(m_queryId);
|
|
m_queryId = INVALID_RETICULE_QUERY;
|
|
}
|
|
|
|
#if GTA_REPLAY
|
|
// store off reticule data for replays
|
|
if(CReplayMgr::ShouldRecord() && pPlayerPed && (pPlayerPed->GetReplayID() != ReplayIDInvalid))
|
|
{
|
|
if(!ReplayReticuleExtension::HasExtension(pPlayerPed))
|
|
{
|
|
ReplayReticuleExtension::Add(pPlayerPed);
|
|
}
|
|
|
|
if(ReplayReticuleExtension::HasExtension(pPlayerPed))
|
|
{
|
|
ReplayReticuleExtension::SetWeaponHash(pPlayerPed, bDisplayReticle ? iCurrentWeaponHash : 0);
|
|
if (bDisplayReticle)
|
|
{
|
|
ReplayReticuleExtension::SetReadyToFire(pPlayerPed, bReloading);
|
|
ReplayReticuleExtension::SetHit(pPlayerPed, m_killTargetThisFrame);
|
|
ReplayReticuleExtension::SetIsFirstPerson(pPlayerPed, isFirstPersonAiming);
|
|
|
|
// zoom is 0 - 100 ...don't really need an s16 for that.
|
|
// don't worry about invalid too
|
|
u8 zoomLevel = zoomState.m_iZoomLevel > 0 ? static_cast<u8>(zoomState.m_iZoomLevel) : 0;
|
|
ReplayReticuleExtension::SetZoomLevel(pPlayerPed, zoomLevel);
|
|
}
|
|
else
|
|
{
|
|
ReplayReticuleExtension::SetReadyToFire(pPlayerPed, false);
|
|
ReplayReticuleExtension::SetIsFirstPerson(pPlayerPed, false);
|
|
ReplayReticuleExtension::SetHit(pPlayerPed, false);
|
|
ReplayReticuleExtension::SetZoomLevel(pPlayerPed, 0);
|
|
}
|
|
}
|
|
}
|
|
#endif // GTA_REPLAY
|
|
|
|
m_killTargetThisFrame = false;
|
|
m_incapacitatedTargetThisFrame = false;
|
|
m_bHitVehicleThisFrame = false;
|
|
}
|
|
|
|
#if SUPPORT_MULTI_MONITOR
|
|
void CUIReticule::DrawBlinders(bool bSniperActive)
|
|
{
|
|
bool bInCutscene = (CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->IsRunning());
|
|
if(bSniperActive && !bInCutscene)
|
|
{
|
|
CNewHud::SetDrawBlinder(2);
|
|
}
|
|
|
|
if(!bSniperActive && CNewHud::ShouldDrawBlinders() && !CutSceneManager::GetManualBlinders())
|
|
{
|
|
CNewHud::SetDrawBlinder(0);
|
|
CutSceneManager::StartMultiheadFade(false, true);
|
|
}
|
|
}
|
|
#endif // SUPPORT_MULTI_MONITOR
|
|
|
|
CUIReticule::eRETICLE_STYLE CUIReticule::GetReticuleStyleForCNCDisplayMode(CPed * pPlayerPed, const CWeaponInfo *pWeaponInfo)
|
|
{
|
|
if (!uiVerify(pPlayerPed))
|
|
{
|
|
return RETICLE_STYLE_INVALID;
|
|
}
|
|
|
|
eRETICLE_STYLE retStyle = RETICLE_STYLE_DEFAULT;
|
|
const CEntity* pTargetEntity = GetTargetEntity(pPlayerPed, CScriptHud::bUseVehicleTargetingReticule);
|
|
|
|
if (pTargetEntity)
|
|
{
|
|
const CPed* pTargetPed = pTargetEntity->GetIsTypeVehicle() ? static_cast<const CVehicle*>(pTargetEntity)->GetDriver() : pTargetEntity->GetIsTypePed() ? static_cast<const CPed*>(pTargetEntity) : nullptr;
|
|
|
|
if (pTargetPed == nullptr || (!CScriptHud::bUseVehicleTargetingReticule && pTargetEntity->GetIsTypeVehicle()))
|
|
{
|
|
return retStyle;
|
|
}
|
|
|
|
CPedTargetting* pTargetPedTargetting = pTargetPed->GetPedIntelligence()->GetTargetting();
|
|
|
|
if (pTargetPed->IsDead())
|
|
{
|
|
retStyle = RETICLE_STYLE_DEAD;
|
|
}
|
|
else
|
|
{
|
|
bool canBeTargeted = !pTargetPed->GetPedConfigFlag(CPED_CONFIG_FLAG_NeverEverTargetThisPed);
|
|
|
|
if (NetworkInterface::AreBulletsImpactsDisabledInMP(*pPlayerPed, *pTargetPed))
|
|
{
|
|
canBeTargeted = false;
|
|
}
|
|
|
|
if (pTargetPed->IsVisible() && canBeTargeted)
|
|
{
|
|
bool isEnemy = false;
|
|
bool isBuddy = false;
|
|
|
|
|
|
if (pTargetPed->IsPlayer())
|
|
{
|
|
eArcadeTeam eLocalTeam = pPlayerPed->GetPlayerInfo()->GetArcadeInformation().GetTeam();
|
|
eArcadeTeam eTargetTeam = pTargetPed->GetPlayerInfo()->GetArcadeInformation().GetTeam();
|
|
|
|
if (eLocalTeam == eTargetTeam)
|
|
{
|
|
isBuddy = true;
|
|
}
|
|
// If a crook is wanted and we are a cop they are our enemy
|
|
else if (eLocalTeam == eArcadeTeam::AT_CNC_COP && eTargetTeam == eArcadeTeam::AT_CNC_CROOK)
|
|
{
|
|
if (!pTargetPed->GetPlayerWanted()->m_WantedLevel == WANTED_CLEAN)
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pTargetPed->GetPedConfigFlag(CPED_CONFIG_FLAG_PedIsEnemyToPlayer))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
else
|
|
{
|
|
if(pTargetPed->GetPedIntelligence()->GetQueriableInterface() && pTargetPed->GetPedIntelligence()->GetQueriableInterface()->IsTaskCurrentlyRunning(CTaskTypes::TASK_COMBAT))
|
|
{
|
|
CEntity* pTargetEntity = pTargetPed->GetPedIntelligence()->GetQueriableInterface()->GetTargetForTaskType(CTaskTypes::TASK_COMBAT);
|
|
if (pTargetEntity && pTargetEntity->GetIsTypePed() && static_cast<CPed*>(pTargetEntity)->IsLocalPlayer())
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
else
|
|
{
|
|
if(pTargetPedTargetting && pTargetPedTargetting->FindTarget(pPlayerPed))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isEnemy)
|
|
{
|
|
if(pTargetPed->GetPedIntelligence()->IsThreatenedBy(*pPlayerPed) || pPlayerPed->GetPedIntelligence()->IsThreatenedBy(*pTargetPed))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
if (pWeaponInfo && pWeaponInfo->GetFlag(CWeaponInfoFlags::NonLethal) && pTargetPed->GetPedConfigFlag(CPED_CONFIG_FLAG_CanBeIncapacitated))
|
|
{
|
|
if (pTargetPed->GetEndurance() > 0.0f)
|
|
{
|
|
retStyle = RETICLE_STYLE_NON_LETHAL;
|
|
}
|
|
else
|
|
{
|
|
retStyle = RETICLE_STYLE_DEAD;
|
|
}
|
|
}
|
|
else if (isBuddy)
|
|
{
|
|
retStyle = RETICLE_STYLE_BUDDY;
|
|
}
|
|
else if (isEnemy)
|
|
{
|
|
retStyle = RETICLE_STYLE_ENEMY;
|
|
}
|
|
else
|
|
{
|
|
retStyle = RETICLE_STYLE_DEAD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retStyle;
|
|
}
|
|
|
|
CUIReticule::eRETICLE_STYLE CUIReticule::GetReticuleStyle(CPed* pPlayerPed, const CWeaponInfo *pWeaponInfo)
|
|
{
|
|
eRETICLE_STYLE retStyle = RETICLE_STYLE_DEFAULT;
|
|
const CEntity* pTargetEntity = GetTargetEntity(pPlayerPed, CScriptHud::bUseVehicleTargetingReticule);
|
|
|
|
if(pTargetEntity)
|
|
{
|
|
const CPed* pTargetPed = pTargetEntity->GetIsTypeVehicle() ? static_cast<const CVehicle*>(pTargetEntity)->GetDriver() : pTargetEntity->GetIsTypePed() ? static_cast<const CPed*>(pTargetEntity) : nullptr;
|
|
|
|
if(pTargetPed == nullptr || (!CScriptHud::bUseVehicleTargetingReticule && pTargetEntity->GetIsTypeVehicle()))
|
|
{
|
|
return retStyle;
|
|
}
|
|
|
|
CPedTargetting* pTargetPedTargetting = pTargetPed->GetPedIntelligence()->GetTargetting();
|
|
|
|
if(pTargetPed->IsDead())
|
|
{
|
|
retStyle = RETICLE_STYLE_DEAD;
|
|
}
|
|
else
|
|
{
|
|
bool canBeTargeted = !pTargetPed->GetPedConfigFlag( CPED_CONFIG_FLAG_NeverEverTargetThisPed);
|
|
|
|
if (NetworkInterface::AreBulletsImpactsDisabledInMP(*pPlayerPed, *pTargetPed))
|
|
{
|
|
canBeTargeted = false;
|
|
}
|
|
|
|
if(pTargetPed->IsVisible() && canBeTargeted)
|
|
{
|
|
bool isEnemy = false;
|
|
bool isBuddy = false;
|
|
|
|
if(pTargetPed->IsPlayer())
|
|
{
|
|
CNetObjPed* pTargetPedObj = SafeCast(CNetObjPed, pTargetPed->GetNetworkObject());
|
|
if (pTargetPedObj)
|
|
{
|
|
isBuddy = !pTargetPedObj->GetIsTargettableByPlayer(pPlayerPed->GetPlayerInfo()->GetPhysicalPlayerIndex());
|
|
}
|
|
}
|
|
|
|
if(isBuddy)
|
|
{
|
|
retStyle = RETICLE_STYLE_BUDDY;
|
|
}
|
|
else
|
|
{
|
|
if(pTargetPed->IsPlayer() && pWeaponInfo)
|
|
{
|
|
isEnemy = pPlayerPed->IsAllowedToDamageEntity(pWeaponInfo, pTargetPed);
|
|
}
|
|
|
|
if(pTargetPed->GetPedConfigFlag(CPED_CONFIG_FLAG_PedIsEnemyToPlayer))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
else
|
|
{
|
|
if(pTargetPed->GetPedIntelligence()->GetQueriableInterface() && pTargetPed->GetPedIntelligence()->GetQueriableInterface()->IsTaskCurrentlyRunning(CTaskTypes::TASK_COMBAT))
|
|
{
|
|
CEntity* pTargetEntity = pTargetPed->GetPedIntelligence()->GetQueriableInterface()->GetTargetForTaskType(CTaskTypes::TASK_COMBAT);
|
|
if(pTargetEntity && pTargetEntity->GetIsTypePed() && static_cast<CPed*>(pTargetEntity)->IsLocalPlayer())
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
else
|
|
{
|
|
if(pTargetPedTargetting && pTargetPedTargetting->FindTarget(pPlayerPed))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!isEnemy)
|
|
{
|
|
if(pTargetPed->GetPedIntelligence()->IsThreatenedBy(*pPlayerPed) || pPlayerPed->GetPedIntelligence()->IsThreatenedBy(*pTargetPed))
|
|
{
|
|
isEnemy = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isEnemy)
|
|
{
|
|
retStyle = RETICLE_STYLE_ENEMY;
|
|
}
|
|
else
|
|
{
|
|
retStyle = RETICLE_STYLE_FRIENDLY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retStyle;
|
|
}
|
|
|
|
float CUIReticule::GetInvAccuracy(const CPed* pPlayerPed, const CWeapon* pPlayerEquippedWeapon)
|
|
{
|
|
if(!uiVerify(pPlayerEquippedWeapon))
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
const CEntity* pTarget = GetTargetEntity(pPlayerPed, CScriptHud::bUseVehicleTargetingReticule);
|
|
const float distToTarget = (pTarget && pPlayerPed) ? (pPlayerPed->GetPreviousPosition() - pTarget->GetPreviousPosition()).Mag() : sm_fDistanceToNoTarget;
|
|
|
|
sWeaponAccuracy weaponAccuracy;
|
|
pPlayerEquippedWeapon->GetAccuracy(pPlayerPed, distToTarget, weaponAccuracy);
|
|
float spread = pPlayerEquippedWeapon->GetWeaponInfo()->GetAccuracySpread();
|
|
|
|
return (1.0f - weaponAccuracy.fAccuracyMin) * spread;
|
|
}
|
|
|
|
CUIReticule::sZoomState CUIReticule::GetZoomState(const CPed *pPlayerPed, const CWeapon* pPlayerEquippedWeapon, const camGameplayDirector& gameplayDirector)
|
|
{
|
|
sZoomState zoomState;
|
|
|
|
if (pPlayerEquippedWeapon && pPlayerEquippedWeapon->GetHasFirstPersonScope())
|
|
{
|
|
const camFirstPersonPedAimCamera* pAimCamera = gameplayDirector.GetFirstPersonPedAimCamera(pPlayerPed);
|
|
if (pAimCamera)
|
|
{
|
|
zoomState.m_bIsFirstPersonAimingThroughScope = true;
|
|
|
|
const camControlHelper* pControlHelper = pAimCamera->GetControlHelper();
|
|
if (pControlHelper)
|
|
{
|
|
const Vector2& vZoomFactorLimits = pControlHelper->GetZoomFactorLimits();
|
|
|
|
if(vZoomFactorLimits.y > (vZoomFactorLimits.x + SMALL_FLOAT))
|
|
{
|
|
zoomState.m_bIsZoomed = true;
|
|
float fZoomFactor = pControlHelper->GetZoomFactor();
|
|
|
|
zoomState.m_iZoomLevel = (s32)Floorf(RampValueSafe(fZoomFactor, vZoomFactorLimits.x, vZoomFactorLimits.y, 0.0f, 100.0f));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return zoomState;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// NAME: CUIReticule::TransformReticulePosition()
|
|
// PURPOSE: transforms reticule postion from world space to screen space
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CUIReticule::TransformReticulePosition(const Vector3& vReticlePositionWorld, Vector2& vReticlePosition, bool& bDisplayReticle)
|
|
{
|
|
if(!uiVerify(gVpMan.GetCurrentViewport()))
|
|
{
|
|
return;
|
|
}
|
|
|
|
float fX = 1.0f;
|
|
float fY = 1.0f;
|
|
gVpMan.GetCurrentViewport()->GetGrcViewport().Transform((Vec3V&)vReticlePositionWorld, fX, fY);
|
|
|
|
float fWidth = (float)GRCDEVICE.GetWidth();
|
|
float fHeight = (float)GRCDEVICE.GetHeight();
|
|
|
|
#if SUPPORT_MULTI_MONITOR
|
|
if(GRCDEVICE.GetMonitorConfig().isMultihead())
|
|
{
|
|
const GridMonitor &mon = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor();
|
|
float fOffset = fWidth * mon.getArea().GetWidth();
|
|
fWidth = fOffset;
|
|
fX -= fWidth;
|
|
}
|
|
#endif // SUPPORT_MULTI_MONITOR
|
|
vReticlePosition.x = fX / fWidth;
|
|
vReticlePosition.y = fY / fHeight;
|
|
|
|
if (vReticlePosition.x > 1.0f ||
|
|
vReticlePosition.y > 1.0f ||
|
|
vReticlePosition.x < 0.0f ||
|
|
vReticlePosition.y < 0.0f)
|
|
{
|
|
bDisplayReticle = false;
|
|
}
|
|
else
|
|
{
|
|
// round off to 3dp so we dont get a very slightly different value every frame, even though the on-screen pos is the same in reality
|
|
vReticlePosition.x = ceilf(vReticlePosition.x * 1000.0f) / 1000.0f;
|
|
vReticlePosition.y = ceilf(vReticlePosition.y * 1000.0f) / 1000.0f;
|
|
}
|
|
}
|
|
|
|
const CEntity* CUIReticule::GetTargetEntity(const CPed* pPlayerPed, bool bCheckVehicles)
|
|
{
|
|
if(!uiVerify(pPlayerPed) || !uiVerify(pPlayerPed->GetPlayerInfo()))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return bCheckVehicles ? pPlayerPed->GetPlayerInfo()->GetTargeting().GetFreeAimTarget() : pPlayerPed->GetPlayerInfo()->GetTargeting().GetFreeAimTargetRagdoll();
|
|
}
|
|
|
|
bool CUIReticule::IsSphereVisible(const Vector3& vReticlePositionWorld, float fPixelThresholdOverride)
|
|
{
|
|
bool isOnScreen = uiVerify(gVpMan.GetCurrentViewport()) ? (gVpMan.GetCurrentViewport()->GetGrcViewport().IsSphereVisible(vReticlePositionWorld.x, vReticlePositionWorld.y, vReticlePositionWorld.z, 0.01f) != cullOutside) : false;
|
|
|
|
if(isOnScreen && !camInterface::GetCinematicDirector().IsRenderingCinematicMountedCamera())
|
|
{
|
|
m_queryUsedThisFrame = true;
|
|
|
|
if(m_queryId == INVALID_RETICULE_QUERY)
|
|
{
|
|
m_queryId =OcclusionQueries::OQAllocate();
|
|
Assertf(m_queryId != 0, "Out of Occlusion Query Ids %s",CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
|
|
if(m_queryId != INVALID_RETICULE_QUERY)
|
|
{
|
|
int pixelCount = OcclusionQueries::OQGetQueryResult(m_queryId);
|
|
|
|
if(0 <= pixelCount)
|
|
{
|
|
float fThreshold = fPixelThresholdOverride > 0.0f ? fPixelThresholdOverride : sm_fDrawSpherePixelLimit;
|
|
isOnScreen = fThreshold < pixelCount;
|
|
}
|
|
|
|
const Vec3V minV(ScalarV(-sm_fDrawSphereRadius * 0.5f));
|
|
const Vec3V maxV(ScalarV(sm_fDrawSphereRadius * 0.5f));
|
|
Mat34V matrix(V_IDENTITY);
|
|
matrix.Setd(RCC_VEC3V(vReticlePositionWorld));
|
|
|
|
OcclusionQueries::OQSetBoundingBox(m_queryId, minV, maxV, matrix);
|
|
}
|
|
}
|
|
|
|
return isOnScreen;
|
|
}
|
|
|
|
void CUIReticule::ShowHitMarker(eReticleHitMarkerStyle markerStyle)
|
|
{
|
|
if(CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SHOW_HITMARKER"))
|
|
{
|
|
CScaleformMgr::AddParamInt((int)markerStyle);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
|
|
}
|
|
|
|
void CUIReticule::ShowHitMarkerNonLethal(eReticleHitMarkerNonLethalStyle markerStyle)
|
|
{
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SHOW_HITMARKER_NON_LETHAL"))
|
|
{
|
|
CScaleformMgr::AddParamInt((int)markerStyle);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
void CUIReticule::RegisterPedKill(const CPed& inflictor, const CPed& victim, u32 weaponHash)
|
|
{
|
|
if(inflictor.IsLocalPlayer())
|
|
{
|
|
const CEntity* pTarget = GetPreviousValues().m_target.Get();
|
|
u32 equipedWeaponHash = inflictor.GetEquippedWeaponInfo() ? inflictor.GetEquippedWeaponInfo()->GetHash() : 0;
|
|
|
|
// If you kill the ped your aiming at, or if you don't have a target but kill someone (i.e. using shotgun and their outside your aiming probe range, or kill the target before the aiming probe finishes)
|
|
if(pTarget == &victim ||
|
|
(pTarget == NULL && weaponHash == equipedWeaponHash))
|
|
{
|
|
m_killTargetThisFrame = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CUIReticule::RegisterPedIncapacitated(const CPed& inflictor, const CPed& victim, u32 weaponHash)
|
|
{
|
|
if (inflictor.IsLocalPlayer())
|
|
{
|
|
const CEntity* pTarget = GetPreviousValues().m_target.Get();
|
|
u32 equipedWeaponHash = inflictor.GetEquippedWeaponInfo() ? inflictor.GetEquippedWeaponInfo()->GetHash() : 0;
|
|
|
|
// If you incapacitate the ped your aiming at, or if you don't have a target but incapacitate someone (i.e. using shotgun and their outside your aiming probe range, or incapacitate the target before the aiming probe finishes)
|
|
if (pTarget == &victim ||
|
|
(pTarget == NULL && weaponHash == equipedWeaponHash))
|
|
{
|
|
m_incapacitatedTargetThisFrame = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CUIReticule::RegisterVehicleHit(const CPed& inflictor, u32 uVehicleHash, float iHealthLost)
|
|
{
|
|
if(inflictor.IsLocalPlayer())
|
|
{
|
|
// NOTE: As of now we're only going to allow this for the Bombushka DLC vehicle...
|
|
// ... and some others because 'this is a one off' was a lie.
|
|
#define BOMBUSHKA_HASH 4262088844
|
|
#define MIN_HP_LOSS_REQUIRED_FOR_HIT 13
|
|
|
|
bool bValidVehicleHit = false;
|
|
for(int i = 0; i < m_ValidVehicleHitHashes.GetCount(); ++i)
|
|
{
|
|
if(uVehicleHash == m_ValidVehicleHitHashes[i])
|
|
{
|
|
bValidVehicleHit = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( uVehicleHash == BOMBUSHKA_HASH ||
|
|
bValidVehicleHit)
|
|
{
|
|
if(iHealthLost > MIN_HP_LOSS_REQUIRED_FOR_HIT)
|
|
{
|
|
m_bHitVehicleThisFrame = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CUIReticule::SetWeaponTimer(float fTimePercent)
|
|
{
|
|
Color32 colour;
|
|
fTimePercent = 100 - fTimePercent;
|
|
bool bWhite = (fTimePercent == 100) ||
|
|
(fTimePercent >= 98 && fTimePercent <= 99) ||
|
|
(fTimePercent >= 92 && fTimePercent <= 94) ||
|
|
(fTimePercent >= 85 && fTimePercent <= 88) ||
|
|
(fTimePercent >= 77 && fTimePercent <= 80) ||
|
|
(fTimePercent >= 67 && fTimePercent <= 71) ||
|
|
(fTimePercent >= 56 && fTimePercent <= 61) ||
|
|
(fTimePercent >= 43 && fTimePercent <= 49) ||
|
|
(fTimePercent >= 27 && fTimePercent <= 35) ||
|
|
(fTimePercent >= 8 && fTimePercent <= 18);
|
|
|
|
if(bWhite)
|
|
{
|
|
colour = CHudColour::GetRGBA(HUD_COLOUR_PURE_WHITE);
|
|
}
|
|
else
|
|
{
|
|
colour = CHudColour::GetRGBA(HUD_COLOUR_GREYDARK);
|
|
}
|
|
|
|
if (CHudTools::BeginHudScaleformMethod(NEW_HUD_RETICLE, "SET_RETICULE_COLOR"))
|
|
{
|
|
CScaleformMgr::AddParamInt(colour.GetRed());
|
|
CScaleformMgr::AddParamInt(colour.GetGreen());
|
|
CScaleformMgr::AddParamInt(colour.GetBlue());
|
|
CScaleformMgr::AddParamFloat((float)colour.GetAlphaf() * 100.0f);
|
|
CScaleformMgr::EndMethod();
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
void CUIReticule::CreateBankWidgets(bkBank *pBank)
|
|
{
|
|
if(uiVerify(pBank))
|
|
{
|
|
pBank->AddToggle("Hide reticle", &m_bForceHideReticle);
|
|
pBank->AddToggle("Hide reticle when using laser sight", &sm_bHideReticleWithLaserSight);
|
|
pBank->AddSlider("Assumed non-target distance", &sm_fDistanceToNoTarget, 0.0f, 1000.0f, 0.1f);
|
|
pBank->AddSlider("Reticule Accuracy Scaler", &sm_fAccuracyScaler, 0.0f, 1000.0f, 1.0f);
|
|
pBank->AddSlider("Max Inv Reticule Accuracy", &sm_uMaxInvAccuracy, 0, 1000, 1);
|
|
pBank->AddSlider("Draw Sphere Radius", &sm_fDrawSphereRadius, 0.0f, 100.0f, 0.1f);
|
|
|
|
{
|
|
const int pWeaponNameSize = 50;
|
|
char* pWeaponName;
|
|
u32 nameHash = 0;
|
|
|
|
pWeaponName = rage_new char[pWeaponNameSize];
|
|
formatf(pWeaponName, pWeaponNameSize, "%s (%d)", "NONE", nameHash);
|
|
m_weaponNames.PushAndGrow(pWeaponName);
|
|
m_weaponHashes.PushAndGrow(0);
|
|
|
|
pWeaponName = rage_new char[pWeaponNameSize];
|
|
formatf(pWeaponName, pWeaponNameSize, "%s (%d)", "FAKED_SCOPED_RETICLE", FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE);
|
|
m_weaponNames.PushAndGrow(pWeaponName);
|
|
m_weaponHashes.PushAndGrow(FAKED_WEAPON_HASH_FOR_SCOPED_RETICLE);
|
|
|
|
pWeaponName = rage_new char[pWeaponNameSize];
|
|
formatf(pWeaponName, pWeaponNameSize, "%s (%d)", "FAKED_SIMPLE_RETICLE", FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE);
|
|
m_weaponNames.PushAndGrow(pWeaponName);
|
|
m_weaponHashes.PushAndGrow(FAKED_WEAPON_HASH_FOR_SIMPLE_RETICLE);
|
|
|
|
CWeaponInfoManager::StringList& weaponNames = CWeaponInfoManager::GetNames(CWeaponInfoBlob::IT_Weapon);
|
|
for(int i=0; i<weaponNames.GetCount(); ++i)
|
|
{
|
|
nameHash = atStringHash(weaponNames[i]);
|
|
|
|
pWeaponName = rage_new char[pWeaponNameSize];
|
|
formatf(pWeaponName, pWeaponNameSize, "%s (%d)", weaponNames[i], nameHash);
|
|
m_weaponNames.PushAndGrow(pWeaponName);
|
|
m_weaponHashes.PushAndGrow(nameHash);
|
|
}
|
|
|
|
pBank->AddCombo("Reticule Override", &m_debugOverrideHashIndex, m_weaponNames.GetCount(), &m_weaponNames[0], NullCallback);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// eof
|
|
|