//! this is main camera class class DayZPlayerCameraIronsights extends DayZPlayerCameraBase { static const float CONST_UD_MIN = -85.0; //!< down limit static const float CONST_UD_MAX = 85.0; //!< up limit static const float CONST_UD_MIN_BACK = -25.0; //!< down limit on back static const float CONST_LR_MIN = -160.0; //!< down limit static const float CONST_LR_MAX = 160.0; //!< up limit protected bool m_isEntering = false; protected bool m_opticsHasWeaponOverride = false; protected ref array temp_array; //DOF only protected PPERequester_CameraADS m_RequesterADS; //! camera dynamics float m_velocityYaw[1]; float m_velocityPitch[1]; float m_dynamicsStrength; float m_dynamicsSmoothTime; vector m_SightMisalignmentModifier; float m_movementTimeAcc; float m_movementAmplitudeX; float m_movementAmplitudeY; float m_movementFrequencyX; float m_movementFrequencyY; void DayZPlayerCameraIronsights(DayZPlayer pPlayer, HumanInputController pInput) { if (!temp_array) temp_array = new array; m_iBoneIndex = pPlayer.GetBoneIndexByName("RightHand_Dummy"); if (m_iBoneIndex == -1) { Print("DayZPlayerCamera1stPerson: main bone not found"); } m_dynamicsStrength = 2; m_dynamicsSmoothTime = 0.3; SetupSightEntities(); GetCurrentSightInfo(m_OpticsCamPos, m_OpticsCamDir); m_isEntering = true; m_WeaponSwayModifier = 0.5; m_movementTimeAcc = 0; m_movementAmplitudeX = 1; m_movementAmplitudeY = 1; m_movementFrequencyX = 1; m_movementFrequencyY = 2; Class.CastTo(m_RequesterADS,PPERequester_CameraADS.Cast(PPERequesterBank.GetRequester(PPERequester_CameraADS))); Init(); } void SetupSightEntities() { EntityAI inHands = m_pPlayer.GetHumanInventory().GetEntityInHands(); if (inHands) { m_weaponUsed = Weapon_Base.Cast(inHands); if( m_weaponUsed ) { m_SightMisalignmentModifier = m_weaponUsed.GetPropertyModifierObject().m_SightMisalignment; m_dynamicsStrength = m_dynamicsStrength * m_SightMisalignmentModifier[0]; m_dynamicsSmoothTime = m_dynamicsSmoothTime * m_SightMisalignmentModifier[1]; m_opticsUsed = m_weaponUsed.GetAttachedOptics(); if( m_opticsUsed ) { m_opticsHasWeaponOverride = m_opticsUsed.HasWeaponIronsightsOverride(); } } else { m_opticsUsed = ItemOptics.Cast(inHands); } } } // override void OnActivate (DayZPlayerCamera pPrevCamera, DayZPlayerCameraResult pPrevCameraResult) { super.OnActivate(pPrevCamera, pPrevCameraResult); if (pPrevCamera) { vector baseAngles = pPrevCamera.GetBaseAngles(); m_fUpDownAngle = baseAngles[0]; m_fLeftRightAngle = baseAngles[1]; vector addAngles = pPrevCamera.GetAdditiveAngles(); m_fUpDownAngleAdd = addAngles[0]; m_fLeftRightAngleAdd = addAngles[1]; } } EntityAI GetCurrentSightEntity () { if (m_opticsHasWeaponOverride) return m_opticsUsed; return m_weaponUsed; } bool GetCurrentSightInfo (out vector camPos, out vector camDir) { EntityAI e = GetCurrentSightEntity(); if (e) { if (e == m_weaponUsed) { m_weaponUsed.GetCameraPoint(m_weaponUsed.GetCurrentMuzzle(), camPos, camDir); return true; } else if (e == m_opticsUsed) { m_opticsUsed.UseWeaponIronsightsOverride(m_opticsHasWeaponOverride); m_opticsUsed.GetCameraPoint(camPos, camDir); return true; } } else { ErrorEx("No sight entity found in " + this,ErrorExSeverity.INFO); } return false; } // override void OnUpdate(float pDt, out DayZPlayerCameraResult pOutResult) { //! update angles from input float min; DayZPlayerImplement player = DayZPlayerImplement.Cast(GetGame().GetPlayer()); if (player && player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_RAISEDPRONE)) min = CONST_UD_MIN_BACK; else min = CONST_UD_MIN; m_CurrentCameraYaw = UpdateLRAngleUnlocked(m_fLeftRightAngle, m_fLeftRightAngleAdd, CONST_LR_MIN, CONST_LR_MAX, pDt); m_CurrentCameraPitch = UpdateUDAngleUnlocked(m_fUpDownAngle, m_fUpDownAngleAdd, min, CONST_UD_MAX, pDt); // get model space transform matrix of the gun's eye vector vector matTM[4]; HumanItemAccessor hia = m_pPlayer.GetItemAccessor(); if(GetCurrentSightEntity()) hia.WeaponGetCameraPointBoneRelative(GetCurrentSightEntity(), m_OpticsCamPos, m_OpticsCamDir, m_iBoneIndex, matTM); // aim change based on character movement vector aimChangeYPR; float aimChangeX = m_pInput.GetAimDelta(pDt)[0] * Math.RAD2DEG; float aimChangeY = m_pInput.GetAimDelta(pDt)[1] * Math.RAD2DEG; HumanCommandMove hcm = m_pPlayer.GetCommand_Move(); if (hcm) { float speed = hcm.GetCurrentMovementSpeed(); if( speed > 0 ) m_movementTimeAcc += pDt; else m_movementTimeAcc = 0; aimChangeX += m_movementAmplitudeX * speed * Math.Sin(Math.PI2 * m_movementFrequencyX * m_movementTimeAcc); aimChangeY += m_movementAmplitudeY * speed * Math.Sin(Math.PI2 * m_movementFrequencyY * m_movementTimeAcc); } aimChangeYPR[0] = Math.SmoothCD(aimChangeYPR[0], -(m_dynamicsStrength * aimChangeY), m_velocityYaw, m_dynamicsSmoothTime, 1000, pDt); aimChangeYPR[1] = Math.SmoothCD(aimChangeYPR[1], -(m_dynamicsStrength * aimChangeX), m_velocityPitch, m_dynamicsSmoothTime, 1000, pDt); aimChangeYPR[2] = 0; vector dynamics[4]; Math3D.YawPitchRollMatrix(aimChangeYPR, dynamics); dynamics[3] = vector.Zero; // aiming model offsets vector aimingMatTM[4]; hia.WeaponGetAimingModelDirTm(aimingMatTM); // final offset matrix Math3D.MatrixMultiply4(dynamics, aimingMatTM, dynamics); Math3D.MatrixMultiply4(dynamics, matTM, pOutResult.m_CameraTM); AdjustCameraParameters(pDt, pOutResult); UpdateBatteryOptics(GetCurrentSightEntity()); UpdateCameraNV(PlayerBase.Cast(m_pPlayer)); if(m_CameraShake) { float x,y; m_CameraShake.Update(pDt, x, y); DayZPlayerImplement.Cast(m_pPlayer).GetAimingModel().SetCamShakeValues(x, y); } } override vector GetBaseAngles() { vector a; a[0] = m_fUpDownAngle; a[1] = m_fLeftRightAngle; a[2] = 0; return a; } override vector GetAdditiveAngles() { vector a; a[0] = m_fUpDownAngleAdd; a[1] = m_fLeftRightAngleAdd; a[2] = 0; return a; } void AdjustCameraParameters(float pDt, inout DayZPlayerCameraResult pOutResult) { pOutResult.m_iDirectBone = m_iBoneIndex; pOutResult.m_iDirectBoneMode = 4; pOutResult.m_fFovAbsolute = HoldBreathFOVEffect(pDt); pOutResult.m_bUpdateWhenBlendOut = false; pOutResult.m_fDistance = 0; pOutResult.m_fUseHeading = 0; pOutResult.m_fInsideCamera = 1.0; pOutResult.m_fShootFromCamera = m_fShootFromCamera; pOutResult.m_fNearPlane = 0.04; //0.07 default } float HoldBreathFOVEffect(float pDt) { if (m_pPlayer.IsHoldingBreath()) { m_fFovAbsolute = Math.SmoothCD(m_fFovAbsolute, GameConstants.DZPLAYER_CAMERA_FOV_EYEZOOM, m_fFovAbsVel, 0.1, 1000, pDt); } else if (m_isEntering) //sets FOV immediatelly to avoid "floating camera" effect { m_fFovAbsolute = GameConstants.DZPLAYER_CAMERA_FOV_IRONSIGHTS; m_isEntering = false; } else { m_fFovAbsolute = Math.SmoothCD(m_fFovAbsolute, GameConstants.DZPLAYER_CAMERA_FOV_IRONSIGHTS, m_fFovAbsVel, 0.1, 1000, pDt); } return m_fFovAbsolute; } // sets PP for ironsights and optics (override) cameras override void SetCameraPP(bool state, DayZPlayerCamera launchedFrom) { //Print("SetCameraPP - ADS"); if (PlayerBase.Cast(m_pPlayer) && launchedFrom.Type() != PlayerBase.Cast(m_pPlayer).GetCurrentPlayerCamera().Type()) { //Print("DayZPlayerCameraIronsights | SetCameraPP | skipping, wrong camera type active!"); return; } //if (!state || !m_weaponUsed || (PlayerBase.Cast(m_pPlayer) && launchedFrom != PlayerBase.Cast(m_pPlayer).GetCurrentPlayerCamera())) if (!state || !m_weaponUsed) { m_RequesterADS.Stop(); if (IsCameraNV()) { SetNVPostprocess(GetCameraNVType()); } else { SetNVPostprocess(NVTypes.NONE); } } else { temp_array = {false, 0.0, 0.0, 0.0, 0.0, 1.0}; if (m_weaponUsed.GetWeaponDOF() || (m_opticsUsed && m_opticsUsed.GetOpticsDOF())) { if (m_opticsUsed && m_opticsUsed.GetOpticsDOF().Count() == 6) { temp_array = m_opticsUsed.GetOpticsDOF(); } else { temp_array = m_weaponUsed.GetWeaponDOF(); } if (temp_array.Count() != 6) temp_array = {false, 0.0, 0.0, 0.0, 0.0, 1.0}; } m_RequesterADS.SetValuesIronsights(temp_array); //DOF only if (IsCameraNV()) { SetNVPostprocess(GetCameraNVType()); } else { SetNVPostprocess(NVTypes.NONE); } } if (m_weaponUsed) { m_weaponUsed.HideWeaponBarrel(false); } } override string GetCameraName() { return "DayZPlayerCameraIronsights"; } override void SetCameraPPDelay(DayZPlayerCamera pPrevCamera) { if (pPrevCamera.GetCameraName() == "DayZPlayerCamera1stPerson") { //Print("---ironsights---DayZPlayerCamera1stPerson"); m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_01; } else if (pPrevCamera.GetCameraName() == "DayZPlayerCameraOptics") { m_CameraPPDelay = 0; } else { //Print("---ironsights---else"); m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_02; } } void UpdateBatteryOptics(EntityAI entity) { ItemOptics optics = ItemOptics.Cast(entity); if (optics) optics.UpdateOpticsReddotVisibility(); } //! settings protected float m_fShootFromCamera = 0.0; //! runtime values protected int m_iBoneIndex; //!< right hand dummy bone index protected vector m_OpticsCamPos; protected vector m_OpticsCamDir; protected float m_fUpDownAngle; //!< up down angle in rad protected float m_fUpDownAngleAdd; //!< up down angle in rad protected float m_fLeftRightAngle; //!< left right angle in rad (in freelook only) protected float m_fLeftRightAngleAdd; //!< left right angle in rad (in freelook only) } class DayZPlayerCameraOptics : DayZPlayerCameraIronsights { static const float CONST_NEARPLANE_OPTICS = 0.06; //Default near plane value for this camera protected float m_RecoilOffsetZ = 0.0; void DayZPlayerCameraOptics(DayZPlayer pPlayer, HumanInputController pInput) { if (!temp_array) temp_array = new array; m_fShootFromCamera = 0; } override void Init() { if (m_opticsUsed && m_opticsUsed.IsNVOptic() && m_opticsUsed.IsWorking()) { SetCameraNV(true); } else { SetCameraNV(false); } } override EntityAI GetCurrentSightEntity () { return m_opticsUsed; } override bool GetCurrentSightInfo (out vector camPos, out vector camDir) { if (m_opticsUsed) { m_opticsUsed.UseWeaponIronsightsOverride(false); m_opticsUsed.GetCameraPoint(camPos, camDir); return true; } return false; } override void OnActivate (DayZPlayerCamera pPrevCamera, DayZPlayerCameraResult pPrevCameraResult) { super.OnActivate(pPrevCamera,pPrevCameraResult); PlayerBase player = PlayerBase.Cast(m_pPlayer); if (player && m_opticsUsed) { GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(player.HideClothing,m_CameraPPDelay*1000,false,m_opticsUsed,true); } } override void AdjustCameraParameters(float pDt, inout DayZPlayerCameraResult pOutResult) { pOutResult.m_iDirectBone = m_iBoneIndex; pOutResult.m_iDirectBoneMode = 4; pOutResult.m_fFovAbsolute = HoldBreathFOVEffect(pDt); pOutResult.m_bUpdateWhenBlendOut = false; pOutResult.m_fDistance = 0; pOutResult.m_fUseHeading = 0; pOutResult.m_fInsideCamera = 1.0; pOutResult.m_fShootFromCamera = m_fShootFromCamera; if (!m_opticsUsed) pOutResult.m_fNearPlane = Math.Clamp(CONST_NEARPLANE_OPTICS - m_RecoilOffsetZ, CONST_NEARPLANE_OPTICS, 10.0); else pOutResult.m_fNearPlane = Math.Clamp(m_opticsUsed.GetNearPlaneValue() - m_RecoilOffsetZ, CONST_NEARPLANE_OPTICS, 10.0); //some sufficiently nonsensical max } override float HoldBreathFOVEffect(float pDt) { //hotfix; two cameras exist and update simultaneously during transition, even if optics/weapons is no longer present! /*PlayerBase player = PlayerBase.Cast(m_pPlayer); if (player && player.GetCurrentCamera() != this) return 0.6;*/ ItemOptics optics = ItemOptics.Cast( GetCurrentSightEntity() ); if (optics) { if (optics.GetCurrentStepFOV() >= GameConstants.DZPLAYER_CAMERA_FOV_EYEZOOM && (m_pPlayer.IsHoldingBreath() || m_pPlayer.GetEyeZoomLevel())) { m_fFovAbsolute = Math.SmoothCD(m_fFovAbsolute, GameConstants.DZPLAYER_CAMERA_FOV_EYEZOOM, m_fFovAbsVel, 0.1, 1000, pDt); } else if (m_isEntering) //sets FOV immediatelly to avoid "floating camera" effect { m_fFovAbsolute = optics.GetCurrentStepFOV(); m_isEntering = false; } else { m_fFovAbsolute = Math.SmoothCD(m_fFovAbsolute, optics.GetCurrentStepFOV(), m_fFovAbsVel, 0.1, 1000, pDt); //m_fFovAbsolute = optics.GetCurrentStepFOV(); } return m_fFovAbsolute; } else { //Error("optic camera, but there is no optic item or optic on weapon"); //camera update ticks on transitions as well, caused problems return 0.6; //TODO figure some other way to get original FOV here! } } override void SetCameraPP(bool state,DayZPlayerCamera launchedFrom) { //Print("SetCameraPP - optics"); if (PlayerBase.Cast(m_pPlayer) && launchedFrom.Type() != PlayerBase.Cast(m_pPlayer).GetCurrentPlayerCamera().Type()) { //Print("DayZPlayerCameraOptics | SetCameraPP | skipping, wrong camera type active!"); return; } if (!state || !m_opticsUsed) { m_RequesterADS.Stop(); if (IsCameraNV()) { SetNVPostprocess(GetCameraNVType()); } else { SetNVPostprocess(NVTypes.NONE); } if (m_weaponUsed) { m_weaponUsed.HideWeaponBarrel(false); } } else { array lens_values = new array; array mask_values = new array; float gauss = 0.0; temp_array = {false, 0.0, 0.0, 0.0, 0.0, 1.0}; // 1x scopes only if (m_opticsUsed.AllowsDOF() && !NVGoggles.Cast(m_opticsUsed)) { if (m_weaponUsed) { if (m_opticsUsed.GetOpticsDOF().Count() == 6) { temp_array = m_opticsUsed.GetOpticsDOF(); } else { temp_array = m_weaponUsed.GetWeaponDOF(); //TODO should some optics have own DOF settings (different eye point)? } if (temp_array.Count() != 6) temp_array = {false, 0.0, 0.0, 0.0, 0.0, 1.0}; } m_RequesterADS.SetValuesIronsights(temp_array); //DOF only // optics NV mode if (m_opticsUsed.IsNVOptic()) { SetCameraNV(true); SetNVPostprocess(m_opticsUsed.GetCurrentNVType()); } else { if (IsCameraNV()) { SetNVPostprocess(GetCameraNVType()); } else { SetNVPostprocess(NVTypes.NONE); } } } else //magnifying scopes { // optics mask if (m_opticsUsed.GetOpticsPPMask() && m_opticsUsed.GetOpticsPPMask().Count() == 4) { mask_values = m_opticsUsed.GetOpticsPPMask(); } //optics lens if (m_opticsUsed.GetOpticsPPLens() && m_opticsUsed.GetOpticsPPLens().Count() == 4) { lens_values = m_opticsUsed.GetOpticsPPLens(); } //optics blur if (m_opticsUsed.GetOpticsPPBlur() != 0) { gauss = m_opticsUsed.GetOpticsPPBlur(); } m_RequesterADS.SetValuesOptics(mask_values,lens_values,gauss); // optics NV mode if (m_opticsUsed.IsNVOptic()) { SetCameraNV(true); SetNVPostprocess(m_opticsUsed.GetCurrentNVType()); } else { SetNVPostprocess(NVTypes.NONE); //magnifying optics do not combine with other NV sources (would render NV optics obsolete) } } if (m_weaponUsed) { m_weaponUsed.HideWeaponBarrel(true); } } } override string GetCameraName() { return "DayZPlayerCameraOptics"; } override void SetCameraPPDelay(DayZPlayerCamera pPrevCamera) { if (pPrevCamera.GetCameraName() == "DayZPlayerCameraIronsights") { m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_02 - 0.05; } else if (pPrevCamera.GetCameraName() == "DayZPlayerCamera1stPerson") { m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_02 - 0.05; //changed to accomodate handheld optics, had to be changed here also } else if (!pPrevCamera.IsCamera3rdRaised()) { m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_03 - 0.05; } else { m_CameraPPDelay = DayZPlayerCameras.TIME_CAMERACHANGE_02 - 0.05; } } override void SendRecoilOffsetZ(float offset) { m_RecoilOffsetZ = offset; } };