From 6eff4f2e01d1095dea633180b93a3c6f727a2d17 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 28 Oct 2017 20:21:52 -1000 Subject: [PATCH] Implement most of CTargetingManager --- DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp | 1 + DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp | 29 +- DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp | 3 +- DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp | 76 ++- Runtime/AutoMapper/CAutoMapper.cpp | 2 +- Runtime/GuiSys/CCompoundTargetReticle.cpp | 617 +++++++++++++++++- Runtime/GuiSys/CCompoundTargetReticle.hpp | 156 +++-- Runtime/GuiSys/COrbitPointMarker.cpp | 112 ++++ Runtime/GuiSys/COrbitPointMarker.hpp | 21 +- Runtime/GuiSys/CTargetingManager.cpp | 35 +- Runtime/GuiSys/CTargetingManager.hpp | 7 +- Runtime/MP1/CSamusHud.cpp | 4 +- specter | 2 +- 13 files changed, 943 insertions(+), 122 deletions(-) diff --git a/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp b/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp index 69ae3b8ad..89771d363 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp @@ -91,6 +91,7 @@ struct ITweakGuiColors : BigYAML virtual const zeus::CColor& GetScanIconCriticalDimColor() const=0; virtual const zeus::CColor& GetScanIconNoncriticalColor() const=0; virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const=0; + virtual const zeus::CColor& GetScanReticuleColor() const=0; virtual const zeus::CColor& GetThreatDigitsFont() const=0; virtual const zeus::CColor& GetThreatDigitsOutline() const=0; virtual const zeus::CColor& GetMissileDigitsFont() const=0; diff --git a/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp b/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp index d18b343db..9500f17cc 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp @@ -6,8 +6,33 @@ namespace DataSpec { struct ITweakTargeting : public ITweak { - virtual float GetOvershootOffset() const =0; - virtual float GetXD0() const = 0; + virtual atUint32 GetTargetRadiusMode() const=0; + virtual float GetSeekerScale() const=0; + virtual float GetSeekerAngleSpeed() const=0; + virtual float GetXRayRetAngleSpeed() const=0; + virtual float GetOrbitPointZOffset() const=0; + virtual float GetOrbitPointInTime() const=0; + virtual float GetOrbitPointOutTime() const=0; + virtual const zeus::CColor& GetThermalReticuleColor() const=0; + virtual float GetOvershootOffset() const=0; + virtual float GetXD0() const=0; + virtual const zeus::CColor& GetSeekerColor() const=0; + virtual float GetSeekerClampMin() const=0; + virtual float GetSeekerClampMax() const=0; + virtual float GetGrappleSelectScale() const=0; + virtual float GetGrappleScale() const=0; + virtual float GetGrappleClampMin() const=0; + virtual float GetGrappleClampMax() const=0; + virtual const zeus::CColor& GetGrapplePointSelectColor() const=0; + virtual const zeus::CColor& GetGrapplePointColor() const=0; + virtual const zeus::CColor& GetLockedGrapplePointSelectColor() const=0; + virtual const zeus::CColor& GetOrbitPointColor() const=0; + virtual const zeus::CColor& GetCrosshairsColor() const=0; + virtual bool DrawOrbitPoint() const=0; + virtual float GetReticuleClampMin() const=0; + virtual float GetReticuleClampMax() const=0; + virtual const zeus::CColor& GetXRayRetRingColor() const=0; + virtual float GetReticuleScale() const=0; virtual float GetScanTargetClampMin() const=0; virtual float GetScanTargetClampMax() const=0; }; diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp index 9cb59204a..eef2f082c 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp @@ -111,7 +111,7 @@ struct CTweakGuiColors final : public ITweakGuiColors DNAColor x18c_scanIconCriticalDimColor; DNAColor x190_scanIconNoncriticalColor; DNAColor x194_scanIconNoncriticalDimColor; - DNAColor x198_; + DNAColor x198_scanReticuleColor; DNAColor x19c_threatDigitsFont; DNAColor x1a0_threatDigitsOutline; DNAColor x1a4_missileDigitsFont; @@ -209,6 +209,7 @@ struct CTweakGuiColors final : public ITweakGuiColors const zeus::CColor& GetScanIconCriticalDimColor() const { return x18c_scanIconCriticalDimColor; } const zeus::CColor& GetScanIconNoncriticalColor() const { return x190_scanIconNoncriticalColor; } const zeus::CColor& GetScanIconNoncriticalDimColor() const { return x194_scanIconNoncriticalDimColor; } + const zeus::CColor& GetScanReticuleColor() const { return x198_scanReticuleColor; } const zeus::CColor& GetThreatDigitsFont() const { return x19c_threatDigitsFont; } const zeus::CColor& GetThreatDigitsOutline() const { return x1a0_threatDigitsOutline; } const zeus::CColor& GetMissileDigitsFont() const { return x1a4_missileDigitsFont; } diff --git a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp b/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp index 1a06aedf6..ba58f306e 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp @@ -10,7 +10,8 @@ namespace DNAMP1 struct CTweakTargeting final : public ITweakTargeting { DECL_YAML - Value x4_; + Value x0_; + Value x4_targetRadiusMode; Value x8_; Value xc_; Value x10_; @@ -18,16 +19,16 @@ struct CTweakTargeting final : public ITweakTargeting Value x18_; Value x1c_; Value x20_; - Value x24_; - Value x28_; - Value x2c_; + Value x24_seekerScale; + Value x28_seekerAngleSpeed; + Value x2c_xrayRetAngleSpeed; Value x30_; Value x3c_; Value x48_; Value x4c_; - Value x50_; - Value x54_; - Value x58_; + Value x50_orbitPointZOffset; + Value x54_orbitPointInTime; + Value x58_orbitPointOutTime; Value x5c_; Value x60_; Value x6c_; @@ -41,7 +42,7 @@ struct CTweakTargeting final : public ITweakTargeting Value xa4_; Value xa8_; Value xac_; - Value xb0_; + DNAColor xb0_thermalReticuleColor; Value xb4_; Value xb8_; Value xbc_; @@ -83,13 +84,13 @@ struct CTweakTargeting final : public ITweakTargeting Value x144_; Value x148_; Value x14c_; - Value x150_; + DNAColor x150_seekerColor; Value x154_; Value x158_; Value x15c_; Value x160_; - Value x164_; - Value x168_; + Value x164_seekerClampMin; + Value x168_seekerClampMax; Value x16c_; Value x170_; Value x174_; @@ -100,20 +101,20 @@ struct CTweakTargeting final : public ITweakTargeting Value x188_; Value x18c_; Value x190_; - Value x194_; - Value x198_; - Value x19c_; - Value x1a0_; - Value x1a4_; - Value x1a8_; - Value x1ac_; + Value x194_grappleSelectScale; + Value x198_grappleScale; + Value x19c_grappleClampMin; + Value x1a0_grappleClampMax; + DNAColor x1a4_grapplePointSelectColor; + DNAColor x1a8_grapplePointColor; + DNAColor x1ac_lockedGrapplePointSelectColor; Value x1b0_; Value x1b4_; Value x1b8_; - Value x1bc_; - Value x1c0_; + DNAColor x1bc_orbitPointColor; + DNAColor x1c0_crosshairsColor; Value x1c4_; - Value x1c8_; + Value x1c8_drawOrbitPoint; Value x1cc_; Value x1d0_; Value x1d4_; @@ -130,10 +131,10 @@ struct CTweakTargeting final : public ITweakTargeting Value x200_; Value x204_; Value x208_; - Value x20c_; - Value x210_; - Value x214_; - Value x218_; + Value x20c_reticuleClampMin; + Value x210_reticuleClampMax; + DNAColor x214_xrayRetRingColor; + Value x218_reticuleScale; Value x21c_scanTargetClampMin; Value x220_scanTargetClampMax; Value x224_; @@ -148,8 +149,33 @@ struct CTweakTargeting final : public ITweakTargeting x208_ = (2.f * M_PIF) * (0.003f * x208_); } + atUint32 GetTargetRadiusMode() const { return x4_targetRadiusMode; } + float GetSeekerScale() const { return x24_seekerScale; } + float GetSeekerAngleSpeed() const { return x28_seekerAngleSpeed; } + float GetXRayRetAngleSpeed() const { return x2c_xrayRetAngleSpeed; } + float GetOrbitPointZOffset() const { return x50_orbitPointZOffset; } + float GetOrbitPointInTime() const { return x54_orbitPointInTime; } + float GetOrbitPointOutTime() const { return x58_orbitPointOutTime; } + const zeus::CColor& GetThermalReticuleColor() const { return xb0_thermalReticuleColor; } float GetOvershootOffset() const { return xe8_overshootOffset; } float GetXD0() const { return xd0_; } + const zeus::CColor& GetSeekerColor() const { return x150_seekerColor; } + float GetSeekerClampMin() const { return x164_seekerClampMin; } + float GetSeekerClampMax() const { return x168_seekerClampMax; } + float GetGrappleSelectScale() const { return x194_grappleSelectScale; } + float GetGrappleScale() const { return x198_grappleScale; } + float GetGrappleClampMin() const { return x19c_grappleClampMin; } + float GetGrappleClampMax() const { return x1a0_grappleClampMax; } + const zeus::CColor& GetGrapplePointSelectColor() const { return x1a4_grapplePointSelectColor; } + const zeus::CColor& GetGrapplePointColor() const { return x1a8_grapplePointColor; } + const zeus::CColor& GetLockedGrapplePointSelectColor() const { return x1ac_lockedGrapplePointSelectColor; } + const zeus::CColor& GetOrbitPointColor() const { return x1bc_orbitPointColor; } + const zeus::CColor& GetCrosshairsColor() const { return x1c0_crosshairsColor; } + bool DrawOrbitPoint() const { return x1c8_drawOrbitPoint; } + float GetReticuleClampMin() const { return x20c_reticuleClampMin; } + float GetReticuleClampMax() const { return x210_reticuleClampMax; } + const zeus::CColor& GetXRayRetRingColor() const { return x214_xrayRetRingColor; } + float GetReticuleScale() const { return x218_reticuleScale; } float GetScanTargetClampMin() const { return x21c_scanTargetClampMin; } float GetScanTargetClampMax() const { return x220_scanTargetClampMax; } }; diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index 75aef3eb1..febe24955 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -132,7 +132,7 @@ bool CAutoMapper::CheckLoadComplete() return false; x4_loadPhase = ELoadPhase::LoadUniverse; case ELoadPhase::LoadUniverse: - if (x8_mapu.IsLoaded()) + if (!x8_mapu.IsLoaded()) return false; x14_dummyWorlds.resize(x8_mapu->GetNumMapWorldDatas()); SetCurWorldAssetId(x24_world->IGetWorldAssetId()); diff --git a/Runtime/GuiSys/CCompoundTargetReticle.cpp b/Runtime/GuiSys/CCompoundTargetReticle.cpp index af5c4c2f1..64b01cf99 100644 --- a/Runtime/GuiSys/CCompoundTargetReticle.cpp +++ b/Runtime/GuiSys/CCompoundTargetReticle.cpp @@ -2,9 +2,11 @@ #include "GameGlobalObjects.hpp" #include "Camera/CGameCamera.hpp" #include "CSimplePool.hpp" -#include "Graphics/CModel.hpp" #include "CStateManager.hpp" -#include +#include "TCastTo.hpp" +#include "World/CScriptGrapplePoint.hpp" +#include "World/CPlayer.hpp" +#include "World/CWorld.hpp" namespace urde { @@ -15,17 +17,11 @@ static float offshoot_func(float f1, float f2, float f3) { return (f1 * 0.5f) + static float calculate_premultiplied_overshoot_offset(float f1) { return 2.f * (M_PIF - std::asin(1.f / f1)); } -CCompoundTargetReticle::SOuterItemInfo::SOuterItemInfo(const char* res) : x0_(g_SimplePool->GetObj(res)) {} - -CTargetReticleRenderState::CTargetReticleRenderState(TUniqueId target, float f1, const zeus::CVector3f& vec, float f2, - float f3, bool b1) -: x0_target(target), x4_(f1), x8_(vec), x14_(f2), x18_(f3), x1c_(b1) -{ -} +CCompoundTargetReticle::SOuterItemInfo::SOuterItemInfo(const char* res) : x0_model(g_SimplePool->GetObj(res)) {} CCompoundTargetReticle::CCompoundTargetReticle(const CStateManager& mgr) -: x0_(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f()) -, x10_(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f()) +: x0_leadingOrientation(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f()) +, x10_laggingOrientation(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f()) , x2c_overshootOffsetHalf(0.5f * g_tweakTargeting->GetOvershootOffset()) , x30_premultOvershootOffset(calculate_premultiplied_overshoot_offset(g_tweakTargeting->GetOvershootOffset())) , x34_crosshairs(g_SimplePool->GetObj(skCrosshairsReticleAssetName)) @@ -41,8 +37,8 @@ CCompoundTargetReticle::CCompoundTargetReticle(const CStateManager& mgr) , xac_xrayRetRing(g_SimplePool->GetObj(skXRayRingModelName)) , xb8_thermalReticle(g_SimplePool->GetObj(skThermalReticleAssetName)) , xc4_chargeGauge(skChargeGaugeAssetName) -, xf4_(CalculateOrbitZoneReticlePosition(mgr)) -, x100_(CalculateOrbitZoneReticlePosition(mgr)) +, xf4_targetPos(CalculateOrbitZoneReticlePosition(mgr, false)) +, x100_laggingTargetPos(CalculateOrbitZoneReticlePosition(mgr, true)) , x208_(g_tweakTargeting->GetXD0()) { xe0_outerBeamIconSquares.reserve(9); @@ -55,7 +51,567 @@ CCompoundTargetReticle::CCompoundTargetReticle(const CStateManager& mgr) x34_crosshairs.Lock(); } -zeus::CVector3f CCompoundTargetReticle::CalculateOrbitZoneReticlePosition(const CStateManager&) const { return {}; } +CCompoundTargetReticle::SScanReticuleRenderer::SScanReticuleRenderer() +{ + m_token = CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) + { + for (int i=0 ; i<2 ; ++i) + { + m_lineRenderers[i].emplace(ctx, CLineRenderer::EPrimitiveMode::Lines, 8, nullptr, true); + for (int j=0 ; j<4 ; ++j) + m_stripRenderers[i][j].emplace(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true); + } + return true; + }); +} + +CCompoundTargetReticle::EReticleState CCompoundTargetReticle::GetDesiredReticleState(const CStateManager& mgr) const +{ + switch (mgr.GetPlayerState()->GetCurrentVisor()) + { + case CPlayerState::EPlayerVisor::Scan: + return EReticleState::Scan; + case CPlayerState::EPlayerVisor::XRay: + return EReticleState::XRay; + case CPlayerState::EPlayerVisor::Combat: + default: + return EReticleState::Combat; + case CPlayerState::EPlayerVisor::Thermal: + return EReticleState::Thermal; + } +} + +void CCompoundTargetReticle::Update(float dt, const CStateManager& mgr) +{ + float angle = x10_laggingOrientation.angleFrom(x0_leadingOrientation).asDegrees(); + float t; + if (angle < 0.1f || angle > 45.f) + t = 1.f; + else + t = std::min(1.f, g_tweakTargeting->x224_ * dt / angle); + x10_laggingOrientation = t == 1.f ? x0_leadingOrientation : + zeus::CQuaternion::slerp(x10_laggingOrientation, x0_leadingOrientation, t); + xf4_targetPos = CalculateOrbitZoneReticlePosition(mgr, false); + x100_laggingTargetPos = CalculateOrbitZoneReticlePosition(mgr, true); + UpdateCurrLockOnGroup(dt, mgr); + UpdateNextLockOnGroup(dt, mgr); + UpdateOrbitZoneGroup(dt, mgr); + EReticleState desiredState = GetDesiredReticleState(mgr); + if (desiredState != x20_prevState && x20_prevState == x24_nextState) + { + x24_nextState = desiredState; + x28_noDrawTicks = 2; + } + if (x20_prevState != x24_nextState && x28_noDrawTicks <= 0) + { + x20_prevState = x24_nextState; + float combat = false; + float scan = false; + float xray = false; + float thermal = false; + switch (x24_nextState) + { + case EReticleState::Combat: + combat = true; + break; + case EReticleState::Scan: + scan = true; + break; + case EReticleState::XRay: + xray = true; + break; + case EReticleState::Thermal: + thermal = true; + break; + default: + break; + } + if (combat) + x40_seeker.Lock(); + else + x40_seeker.Unlock(); + if (combat) + x4c_lockConfirm.Lock(); + else + x4c_lockConfirm.Unlock(); + if (combat) + x58_targetFlower.Lock(); + else + x58_targetFlower.Unlock(); + if (combat) + x64_missileBracket.Lock(); + else + x64_missileBracket.Unlock(); + if (combat) + x70_innerBeamIcon.Lock(); + else + x70_innerBeamIcon.Unlock(); + if (combat) + x7c_lockFire.Lock(); + else + x7c_lockFire.Unlock(); + if (combat) + x88_lockDagger.Lock(); + else + x88_lockDagger.Unlock(); + if (combat) + xa0_chargeTickFirst.Lock(); + else + xa0_chargeTickFirst.Unlock(); + if (xray) + xac_xrayRetRing.Lock(); + else + xac_xrayRetRing.Unlock(); + if (thermal) + xb8_thermalReticle.Lock(); + else + xb8_thermalReticle.Unlock(); + if (combat) + xc4_chargeGauge.x0_model.Lock(); + else + xc4_chargeGauge.x0_model.Unlock(); + if (scan) + x94_grapple.Lock(); + else + x94_grapple.Unlock(); + for (SOuterItemInfo& info : xe0_outerBeamIconSquares) + { + if (combat) + info.x0_model.Lock(); + else + info.x0_model.Unlock(); + } + } + CPlayerGun* gun = mgr.GetPlayer().GetPlayerGun(); + bool fullyCharged = (gun->IsCharging() ? gun->GetChargeBeamFactor() : 0.f) >= 1.f; + if (fullyCharged != x21a_fullyCharged) + x21a_fullyCharged = fullyCharged; + if (x21a_fullyCharged) + x214_ = std::min(dt / g_tweakTargeting->x1b8_ + x214_, g_tweakTargeting->x0_); + else + x214_ = std::max(x214_ - dt / g_tweakTargeting->x1b8_, 0.f); + bool missileActive = gun->GetMissleMode() == CPlayerGun::EMissleMode::Active; + if (missileActive != x1f4_missileActive) + { + if (x1f8_ != 0.f) + x1f8_ = FLT_EPSILON - x1f8_; + else + x1f8_ = FLT_EPSILON; + x1f4_missileActive = missileActive; + } + CPlayerState::EBeamId beam = gun->GetCurrentBeam(); + if (beam != x200_beam) + { + x204_ = g_tweakTargeting->xec_; + for (int i=0 ; i<9 ; ++i) + { + zeus::CRelAngle f1 = g_tweakTargeting->xf8_[int(beam)].floats[i]; + SOuterItemInfo& icon = xe0_outerBeamIconSquares[i]; + zeus::CRelAngle f7 = f1.asRadians() - icon.x10_; + if ((i & 0x1) == 1) + f7 = (f1 > 0.f) ? zeus::CRelAngle(-2.f * M_PIF - f1) : zeus::CRelAngle(2.f * M_PIF + f1); + icon.xc_ = icon.x10_; + icon.x18_ = f7; + icon.x14_ = f1; + } + zeus::CRelAngle f30 = g_tweakTargeting->x108_[int(beam)]; + float f2 = f30.asRadians() - xc4_chargeGauge.x10_; + if ((rand() & 0x1) == 1) + f2 = (f2 > 0.f) ? -2.f * M_PIF - f2 : 2.f * M_PIF + f2; + xc4_chargeGauge.xc_ = xc4_chargeGauge.x10_; + xc4_chargeGauge.x18_ = f2; + xc4_chargeGauge.x14_ = f30; + x200_beam = beam; + x208_ = 0.f; + } + if (gun->GetLastFireButtonStates() & 0x1) + { + if (!x218_beamShot) + x210_ = g_tweakTargeting->x12c_; + x218_beamShot = true; + } + else + { + x218_beamShot = false; + } + if (gun->GetLastFireButtonStates() & 0x2) + { + if (!x219_missileShot) + x1fc_ = g_tweakTargeting->xc8_; + x219_missileShot = true; + } + else + { + x219_missileShot = false; + } + if (TCastToConstPtr point = mgr.GetObjectById(xf2_)) + { + if (point->GetUniqueId() != x1dc_grapplePoint0) + { + float tmp; + if (point->GetUniqueId() == x1de_grapplePoint1) + tmp = std::max(FLT_EPSILON, x1e4_grapplePoint1T); + else + tmp = FLT_EPSILON; + x1de_grapplePoint1 = x1dc_grapplePoint0; + x1e4_grapplePoint1T = x1e0_grapplePoint0T; + x1e0_grapplePoint0T = tmp; + x1dc_grapplePoint0 = point->GetUniqueId(); + } + } + else if (x1dc_grapplePoint0 != kInvalidUniqueId) + { + x1de_grapplePoint1 = x1dc_grapplePoint0; + x1e4_grapplePoint1T = x1e0_grapplePoint0T; + x1e0_grapplePoint0T = 0.f; + x1dc_grapplePoint0 = kInvalidUniqueId; + } + if (x1e0_grapplePoint0T > 0.f) + x1e0_grapplePoint0T = std::min(dt / 0.5f + x1e0_grapplePoint0T, 1.f); + if (x1e4_grapplePoint1T > 0.f) + { + x1e4_grapplePoint1T = std::max(0.f, x1e4_grapplePoint1T - dt / 0.5f); + if (x1e4_grapplePoint1T == 0.f) + x1de_grapplePoint1 = kInvalidUniqueId; + } + x1f0_xrayRetAngle = zeus::CRelAngle(zeus::degToRad(g_tweakTargeting->GetXRayRetAngleSpeed() * dt) + x1f0_xrayRetAngle); + x1ec_seekerAngle = zeus::CRelAngle(zeus::degToRad(g_tweakTargeting->GetSeekerAngleSpeed() * dt) + x1ec_seekerAngle); +} + +void CTargetReticleRenderState::InterpolateWithClamp(const CTargetReticleRenderState& a, + CTargetReticleRenderState& out, + const CTargetReticleRenderState& b, float t) +{ + t = zeus::clamp(0.f, t, 1.f); + float omt = 1.f - t; + out.x4_radiusWorld = omt * a.x4_radiusWorld + t * b.x4_radiusWorld; + out.x14_factor = omt * a.x14_factor + t * b.x14_factor; + out.x18_minVpClampScale = omt * a.x18_minVpClampScale + t * b.x18_minVpClampScale; + out.x8_positionWorld = zeus::CVector3f::lerp(a.x8_positionWorld, b.x8_positionWorld, t); + + if (t == 1.f) + out.x0_target = b.x0_target; + else if (t == 0.f) + out.x0_target = a.x0_target; + else + out.x0_target = kInvalidUniqueId; +} + +void CCompoundTargetReticle::UpdateCurrLockOnGroup(float dt, const CStateManager& mgr) +{ + // TODO: Finish +} + +void CCompoundTargetReticle::UpdateNextLockOnGroup(float dt, const CStateManager& mgr) +{ + // TODO: Finish +} + +void CCompoundTargetReticle::UpdateOrbitZoneGroup(float dt, const CStateManager& mgr) +{ + // TODO: Finish +} + +void CCompoundTargetReticle::Draw(const CStateManager& mgr, bool hideLockon) const +{ + if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed && + !mgr.GetCameraManager()->IsInCinematicCamera()) + { + zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); + CGraphics::SetViewPointMatrix(camXf); + if (!hideLockon) + { + DrawCurrLockOnGroup(camXf.basis, mgr); + DrawNextLockOnGroup(camXf.basis, mgr); + DrawOrbitZoneGroup(camXf.basis, mgr); + } + DrawGrappleGroup(camXf.basis, mgr, hideLockon); + } + if (x28_noDrawTicks > 0) + --x28_noDrawTicks; +} + +void CCompoundTargetReticle::DrawGrapplePoint(const CScriptGrapplePoint& point, float t, const CStateManager& mgr, + const zeus::CMatrix3f& rot, bool zEqual) const +{ + zeus::CVector3f orbitPos = point.GetOrbitPosition(mgr); + zeus::CColor color; + if (point.GetGrappleParameters().GetLockSwingTurn()) + color = g_tweakTargeting->GetLockedGrapplePointSelectColor(); + else + color = g_tweakTargeting->GetGrapplePointSelectColor(); + color = zeus::CColor::lerp(color, g_tweakTargeting->GetGrapplePointColor(), t); + zeus::CMatrix3f scale( + CalculateClampedScale(orbitPos, 1.f, g_tweakTargeting->GetGrappleClampMin(), + g_tweakTargeting->GetGrappleClampMax(), mgr) * + (1.f - t) * g_tweakTargeting->GetGrappleScale() + t * g_tweakTargeting->GetGrappleSelectScale()); + zeus::CTransform modelXf(scale, orbitPos); + CGraphics::SetModelMatrix(modelXf); + CModelFlags flags(7, 0, 0, color); + x94_grapple->Draw(flags); +} + +void CCompoundTargetReticle::DrawGrappleGroup(const zeus::CMatrix3f& rot, + const CStateManager& mgr, bool hideLockon) const +{ + if (x28_noDrawTicks > 0) + return; + + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam) && + x94_grapple.IsLoaded() && x20_prevState != EReticleState::Scan) + { + if (hideLockon) + { + for (const CEntity* ent : mgr.GetAllObjectList()) + { + if (TCastToConstPtr point = ent) + { + if (point->GetActive()) + { + if (point->GetAreaIdAlways() != kInvalidAreaId) + { + const CGameArea* area = mgr.GetWorld()->GetAreaAlways(point->GetAreaIdAlways()); + CGameArea::EOcclusionState occState = area->IsPostConstructed() ? + area->GetOcclusionState() : + CGameArea::EOcclusionState::Occluded; + if (occState != CGameArea::EOcclusionState::Visible) + continue; + } + float t = 0.f; + if (point->GetUniqueId() == x1dc_grapplePoint0) + t = x1e0_grapplePoint0T; + else if (point->GetUniqueId() == x1de_grapplePoint1) + t = x1e4_grapplePoint1T; + if (std::fabs(t) < 0.00001f) + DrawGrapplePoint(*point, t, mgr, rot, true); + } + } + } + } + else + { + TCastToConstPtr point0 = mgr.GetObjectById(x1dc_grapplePoint0); + TCastToConstPtr point1 = mgr.GetObjectById(x1de_grapplePoint1); + for (int i=0 ; i<2 ; ++i) + { + const CScriptGrapplePoint* point = i == 0 ? point0.GetPtr() : point1.GetPtr(); + float t = i == 0 ? x1e0_grapplePoint0T : x1e4_grapplePoint1T; + if (point) + DrawGrapplePoint(*point, t, mgr, rot, false); + } + } + } +} + +void CCompoundTargetReticle::DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const +{ + if (x28_noDrawTicks > 0) + return; + + // TODO: Finish +} + +void CCompoundTargetReticle::DrawNextLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const +{ + if (x28_noDrawTicks > 0) + return; + + zeus::CVector3f x408 = x174_.GetTargetPositionWorld(); + float visorFactor = mgr.GetPlayerState()->GetVisorTransitionFactor(); + + bool scanRet = false; + bool xrayRet = false; + bool thermalRet = false; + switch (x20_prevState) + { + case EReticleState::Scan: + scanRet = true; + break; + case EReticleState::XRay: + xrayRet = true; + break; + case EReticleState::Thermal: + thermalRet = true; + break; + default: + break; + } + + if (!xrayRet && x174_.GetFactor() > 0.f && x40_seeker.IsLoaded()) + { + zeus::CMatrix3f scale( + CalculateClampedScale(x408, x174_.GetRadiusWorld(), + x174_.GetMinViewportClampScale() * g_tweakTargeting->GetSeekerClampMin(), + g_tweakTargeting->GetSeekerClampMax(), mgr) * g_tweakTargeting->GetSeekerScale()); + zeus::CTransform modelXf(rot * zeus::CMatrix3f::RotateY(x1ec_seekerAngle) * scale, + x174_.GetTargetPositionWorld()); + CGraphics::SetModelMatrix(modelXf); + zeus::CColor color = g_tweakTargeting->GetSeekerColor(); + color.a *= x174_.GetFactor(); + CModelFlags flags(7, 0, 0, color); + x40_seeker->Draw(flags); + } + + if (xrayRet && xac_xrayRetRing.IsLoaded()) + { + zeus::CMatrix3f scale( + CalculateClampedScale(x408, x174_.GetRadiusWorld(), + x174_.GetMinViewportClampScale() * g_tweakTargeting->GetReticuleClampMin(), + g_tweakTargeting->GetReticuleClampMax(), mgr) * + g_tweakTargeting->GetReticuleScale()); + zeus::CTransform modelXf(rot * scale * zeus::CMatrix3f::RotateY(x1f0_xrayRetAngle), + x174_.GetTargetPositionWorld()); + CGraphics::SetModelMatrix(modelXf); + zeus::CColor color = g_tweakTargeting->GetXRayRetRingColor(); + color.a *= visorFactor; + CModelFlags flags(7, 0, 0, color); + xac_xrayRetRing->Draw(flags); + } + + if (thermalRet && xb8_thermalReticle.IsLoaded()) + { + zeus::CMatrix3f scale( + CalculateClampedScale(x408, x174_.GetRadiusWorld(), + x174_.GetMinViewportClampScale() * g_tweakTargeting->GetReticuleClampMin(), + g_tweakTargeting->GetReticuleClampMax(), mgr) * + g_tweakTargeting->GetReticuleScale()); + zeus::CTransform modelXf(rot * scale, x174_.GetTargetPositionWorld()); + CGraphics::SetModelMatrix(modelXf); + zeus::CColor color = g_tweakTargeting->GetThermalReticuleColor(); + color.a *= visorFactor; + CModelFlags flags(7, 0, 0, color); + xb8_thermalReticle->Draw(flags); + } + + if (scanRet && visorFactor > 0.f) + { + float factor = visorFactor * x174_.GetFactor(); + zeus::CMatrix3f scale( + CalculateClampedScale(x408, x174_.GetRadiusWorld(), + x174_.GetMinViewportClampScale() * g_tweakTargeting->GetScanTargetClampMin(), + g_tweakTargeting->GetScanTargetClampMax(), mgr) * + (1.f / factor)); + zeus::CTransform modelXf(rot * scale, x174_.GetTargetPositionWorld()); + CGraphics::SetModelMatrix(modelXf); + // compare, GX_LESS, no update + float alpha = 0.5f * factor; + zeus::CColor color = g_tweakGuiColors->GetScanReticuleColor(); + color.a *= alpha; + for (int i=0 ; i<2 ; ++i) + { + float lineWidth = i ? 2.5f : 1.f; + auto& rend = *m_scanRetRenderer.m_lineRenderers[i]; + rend.Reset(); + rend.AddVertex({-0.5f, 0.f, 0.f}, color, lineWidth); + rend.AddVertex({-20.5f, 0.f, 0.f}, color, lineWidth); + rend.AddVertex({0.5f, 0.f, 0.f}, color, lineWidth); + rend.AddVertex({20.5f, 0.f, 0.f}, color, lineWidth); + rend.AddVertex({0.f, 0.f, -0.5f}, color, lineWidth); + rend.AddVertex({0.f, 0.f, -20.5f}, color, lineWidth); + rend.AddVertex({0.f, 0.f, 0.5f}, color, lineWidth); + rend.AddVertex({0.f, 0.f, 20.5f}, color, lineWidth); + rend.Render(); + + for (int j=0 ; j<4 ; ++j) + { + float xSign = j < 2 ? -1.f : 1.f; + float zSign = (j & 0x1) ? -1.f : 1.f; + // begin line strip + auto& rend = *m_scanRetRenderer.m_stripRenderers[i][j]; + rend.Reset(); + rend.AddVertex({0.5f * xSign, 0.f, 0.1f * zSign}, color, lineWidth); + rend.AddVertex({0.5f * xSign, 0.f, 0.35f * zSign}, color, lineWidth); + rend.AddVertex({0.35f * xSign, 0.f, 0.5f * zSign}, color, lineWidth); + rend.AddVertex({0.1f * xSign, 0.f, 0.5f * zSign}, color, lineWidth); + rend.Render(); + } + } + } +} + +void CCompoundTargetReticle::DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const +{ + if (x28_noDrawTicks > 0) + return; + + if (x1e8_crosshairsScale > 0.f && x34_crosshairs.IsLoaded()) + { + CGraphics::SetModelMatrix(zeus::CTransform(rot, xf4_targetPos) * zeus::CTransform::Scale(x1e8_crosshairsScale)); + zeus::CColor color = g_tweakTargeting->GetCrosshairsColor(); + color.a *= x1e8_crosshairsScale; + CModelFlags flags(7, 0, 0, color); + x34_crosshairs->Draw(flags); + } +} + +void CCompoundTargetReticle::UpdateTargetParameters(CTargetReticleRenderState& state, const CStateManager& mgr) +{ + if (auto act = TCastToConstPtr(mgr.GetAllObjectList().GetObjectById(state.GetTargetId()))) + { + state.SetRadiusWorld(CalculateRadiusWorld(*act, mgr)); + state.SetTargetPositionWorld(CalculatePositionWorld(*act, mgr)); + } + else if (state.GetIsOrbitZoneIdlePosition()) + { + state.SetRadiusWorld(1.f); + state.SetTargetPositionWorld((x20_prevState == EReticleState::XRay || x20_prevState == EReticleState::Thermal) ? + x100_laggingTargetPos : xf4_targetPos); + } +} + +float CCompoundTargetReticle::CalculateRadiusWorld(const CActor& act, const CStateManager& mgr) const +{ + auto tb = act.GetTouchBounds(); + zeus::CAABox aabb = tb ? *tb : zeus::CAABox(act.GetAimPosition(mgr, 0.f), act.GetAimPosition(mgr, 0.f)); + + float radius; + zeus::CVector3f delta = aabb.max - aabb.min; + switch (g_tweakTargeting->GetTargetRadiusMode()) + { + case 0: + { + radius = std::min(delta.x, std::min(delta.y, delta.z)) * 0.5f; + break; + } + case 1: + { + radius = std::max(delta.x, std::max(delta.y, delta.z)) * 0.5f; + break; + } + default: + { + radius = (delta.x + delta.y + delta.z) / 6.f; + break; + } + } + + return radius > 0.f ? radius : 1.f; +} + +zeus::CVector3f CCompoundTargetReticle::CalculatePositionWorld(const CActor& act, const CStateManager& mgr) const +{ + if (x20_prevState == EReticleState::Scan) + return act.GetOrbitPosition(mgr); + return act.GetAimPosition(mgr, 0.f); +} + +zeus::CVector3f +CCompoundTargetReticle::CalculateOrbitZoneReticlePosition(const CStateManager& mgr, bool lag) const +{ + const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + float distMul = 224.f / float(g_tweakPlayer->GetOrbitScreenBoxHalfExtentY(0)) / + std::tan(zeus::degToRad(0.5f * curCam->GetFov())); + zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); + zeus::CVector3f lookDir = camXf.basis[1]; + if (lag) + lookDir = x10_laggingOrientation.transform(lookDir); + return lookDir * distMul + camXf.origin; +} + +bool CCompoundTargetReticle::IsGrappleTarget(TUniqueId uid, const CStateManager& mgr) const +{ + return TCastToConstPtr(mgr.GetAllObjectList().GetObjectById(uid)).operator bool(); +} float CCompoundTargetReticle::CalculateClampedScale(const zeus::CVector3f& pos, float scale, float clampMin, float clampMax, @@ -69,4 +625,37 @@ float CCompoundTargetReticle::CalculateClampedScale(const zeus::CVector3f& pos, return zeus::clamp(clampMin, unclampedX, clampMax) / unclampedX * scale; } +void CCompoundTargetReticle::Touch() +{ + if (x34_crosshairs.IsLoaded()) + x34_crosshairs->Touch(0); + if (x40_seeker.IsLoaded()) + x40_seeker->Touch(0); + if (x4c_lockConfirm.IsLoaded()) + x4c_lockConfirm->Touch(0); + if (x58_targetFlower.IsLoaded()) + x58_targetFlower->Touch(0); + if (x64_missileBracket.IsLoaded()) + x64_missileBracket->Touch(0); + if (x70_innerBeamIcon.IsLoaded()) + x70_innerBeamIcon->Touch(0); + if (x7c_lockFire.IsLoaded()) + x7c_lockFire->Touch(0); + if (x88_lockDagger.IsLoaded()) + x88_lockDagger->Touch(0); + if (x94_grapple.IsLoaded()) + x94_grapple->Touch(0); + if (xa0_chargeTickFirst.IsLoaded()) + xa0_chargeTickFirst->Touch(0); + if (xac_xrayRetRing.IsLoaded()) + xac_xrayRetRing->Touch(0); + if (xb8_thermalReticle.IsLoaded()) + xb8_thermalReticle->Touch(0); + if (xc4_chargeGauge.x0_model.IsLoaded()) + xc4_chargeGauge.x0_model->Touch(0); + for (SOuterItemInfo& info : xe0_outerBeamIconSquares) + if (info.x0_model.IsLoaded()) + info.x0_model->Touch(0); +} + } diff --git a/Runtime/GuiSys/CCompoundTargetReticle.hpp b/Runtime/GuiSys/CCompoundTargetReticle.hpp index 4c84fb9a8..62d5fc5a9 100644 --- a/Runtime/GuiSys/CCompoundTargetReticle.hpp +++ b/Runtime/GuiSys/CCompoundTargetReticle.hpp @@ -1,43 +1,53 @@ #ifndef __CCOMPOUNDTARGETRETICLE_HPP__ #define __CCOMPOUNDTARGETRETICLE_HPP__ +#include #include "RetroTypes.hpp" #include "zeus/CQuaternion.hpp" #include "CToken.hpp" +#include "Graphics/CLineRenderer.hpp" namespace urde { class CActor; class CModel; class CStateManager; +class CScriptGrapplePoint; + class CTargetReticleRenderState { TUniqueId x0_target; - float x4_; - zeus::CVector3f x8_; - float x14_; - float x18_; - bool x1c_; + float x4_radiusWorld; + zeus::CVector3f x8_positionWorld; + float x14_factor; + float x18_minVpClampScale; + bool x1c_orbitZoneIdlePosition; public: static const CTargetReticleRenderState skZeroRenderState; - CTargetReticleRenderState(TUniqueId, float, const zeus::CVector3f&, float, float, bool); - void SetTargetId(TUniqueId); - void SetFactor(float); - void SetIsOrbitZoneIdlePosition(bool); - float GetMinViewportClampScale() const; - float GetFactor() const; - float GetRadiusWorld() const; - const zeus::CVector3f& GetTargetPositionWorld() const; - bool GetIsOrbitZoneIdlePosition() const; - void SetTargetPositionWorld(const zeus::CVector3f&); - void SetRadiusWorld(float); - TUniqueId GetTargetId() const; - static void InterpolateWithClamp(const CTargetReticleRenderState&, CTargetReticleRenderState&, - const CTargetReticleRenderState&, float); - float SetMinViewportClampScale(float); + CTargetReticleRenderState(TUniqueId target, float radiusWorld, + const zeus::CVector3f& positionWorld, float factor, + float minVpClampScale, bool orbitZoneIdlePosition) + : x0_target(target), x4_radiusWorld(radiusWorld), x8_positionWorld(positionWorld), + x14_factor(factor), x18_minVpClampScale(minVpClampScale), + x1c_orbitZoneIdlePosition(orbitZoneIdlePosition) + {} + void SetTargetId(TUniqueId id) { x0_target = id; } + void SetFactor(float f) { x14_factor = f; } + void SetIsOrbitZoneIdlePosition(bool b) { x1c_orbitZoneIdlePosition = b; } + float GetMinViewportClampScale() const { return x18_minVpClampScale; } + float GetFactor() const { return x14_factor; } + float GetRadiusWorld() const { return x4_radiusWorld; } + const zeus::CVector3f& GetTargetPositionWorld() const { return x8_positionWorld; } + bool GetIsOrbitZoneIdlePosition() const { return x1c_orbitZoneIdlePosition; } + void SetTargetPositionWorld(const zeus::CVector3f& pos) { x8_positionWorld = pos; } + void SetRadiusWorld(float r) { x4_radiusWorld = r; } + TUniqueId GetTargetId() const { return x0_target; } + void SetMinViewportClampScale(float s) { x18_minVpClampScale = s; } + static void InterpolateWithClamp(const CTargetReticleRenderState& a, CTargetReticleRenderState& out, + const CTargetReticleRenderState& b, float t); }; class CCompoundTargetReticle @@ -45,7 +55,7 @@ class CCompoundTargetReticle public: struct SOuterItemInfo { - TToken x0_; + TCachedToken x0_model; float xc_ = 0.f; float x10_ = 0.f; float x14_ = 0.f; @@ -55,6 +65,16 @@ public: private: + enum class EReticleState + { + Combat, + Scan, + XRay, + Thermal, + Four, + Unspecified + }; + static constexpr const char* skCrosshairsReticleAssetName = "CMDL_Crosshairs"; static constexpr const char* skOrbitZoneReticleAssetName = "CMDL_OrbitZone"; static constexpr const char* skSeekerAssetName = "CMDL_Seeker"; @@ -71,31 +91,31 @@ private: static constexpr const char* skXRayRingModelName = "CMDL_XRayRetRing"; static constexpr const char* skThermalReticleAssetName = "CMDL_ThermalRet"; static constexpr const char* skOrbitPointAssetName = "CMDL_OrbitPoint"; - zeus::CQuaternion x0_; - zeus::CQuaternion x10_; - u32 x20_ = 5; - u32 x24_ = 5; - u32 x28_ = 0; + zeus::CQuaternion x0_leadingOrientation; + zeus::CQuaternion x10_laggingOrientation; + EReticleState x20_prevState = EReticleState::Unspecified; + EReticleState x24_nextState = EReticleState::Unspecified; + mutable u32 x28_noDrawTicks = 0; float x2c_overshootOffsetHalf; float x30_premultOvershootOffset; - TToken x34_crosshairs; - TToken x40_seeker; - TToken x4c_lockConfirm; - TToken x58_targetFlower; - TToken x64_missileBracket; - TToken x70_innerBeamIcon; - TToken x7c_lockFire; - TToken x88_lockDagger; - TToken x94_grapple; - TToken xa0_chargeTickFirst; - TToken xac_xrayRetRing; - TToken xb8_thermalReticle; + TCachedToken x34_crosshairs; + TCachedToken x40_seeker; + TCachedToken x4c_lockConfirm; + TCachedToken x58_targetFlower; + TCachedToken x64_missileBracket; + TCachedToken x70_innerBeamIcon; + TCachedToken x7c_lockFire; + TCachedToken x88_lockDagger; + TCachedToken x94_grapple; + TCachedToken xa0_chargeTickFirst; + TCachedToken xac_xrayRetRing; + TCachedToken xb8_thermalReticle; SOuterItemInfo xc4_chargeGauge; std::vector xe0_outerBeamIconSquares; TUniqueId xf0_; TUniqueId xf2_; - zeus::CVector3f xf4_; - zeus::CVector3f x100_; + zeus::CVector3f xf4_targetPos; + zeus::CVector3f x100_laggingTargetPos; CTargetReticleRenderState x10c_ = CTargetReticleRenderState::skZeroRenderState; CTargetReticleRenderState x12c_ = CTargetReticleRenderState::skZeroRenderState; CTargetReticleRenderState x14c_ = CTargetReticleRenderState::skZeroRenderState; @@ -106,50 +126,64 @@ private: CTargetReticleRenderState x1b4_ = CTargetReticleRenderState::skZeroRenderState; float x1d4_ = 0.f; float x1d8_ = 0.f; - TUniqueId x1dc_ = kInvalidUniqueId; - TUniqueId x1de_ = kInvalidUniqueId; - float x1e0_ = 0.f; - float x1e4_ = 0.f; - float x1e8_ = 0.f; - float x1ec_ = 0.f; - float x1f0_ = 0.f; - u8 x1f4_ = 0; + TUniqueId x1dc_grapplePoint0 = kInvalidUniqueId; + TUniqueId x1de_grapplePoint1 = kInvalidUniqueId; + float x1e0_grapplePoint0T = 0.f; + float x1e4_grapplePoint1T = 0.f; + float x1e8_crosshairsScale = 0.f; + float x1ec_seekerAngle = 0.f; + float x1f0_xrayRetAngle = 0.f; + bool x1f4_missileActive = false; float x1f8_ = 0.f; float x1fc_ = 0.f; - u32 x200_ = 0; + CPlayerState::EBeamId x200_beam = CPlayerState::EBeamId::Power; float x204_ = 0.f; float x208_; float x20c_ = 0.f; float x210_ = 0.f; float x214_ = 0.f; - u8 x218_ = 0; - u8 x219_ = 0; - u8 x21a_ = 0; + bool x218_beamShot = false; + bool x219_missileShot = false; + bool x21a_fullyCharged = false; u8 x21b_ = 0; u32 x21c_; u32 x220_; u32 x228_; + + struct SScanReticuleRenderer + { + boo::GraphicsDataToken m_token; + std::experimental::optional m_lineRenderers[2]; + std::experimental::optional m_stripRenderers[2][4]; + SScanReticuleRenderer(); + }; + mutable SScanReticuleRenderer m_scanRetRenderer; + + void DrawGrapplePoint(const CScriptGrapplePoint& point, float t, const CStateManager& mgr, + const zeus::CMatrix3f& rot, bool zEqual) const; + public: CCompoundTargetReticle(const CStateManager&); - void SetLeadingOrientation(const zeus::CQuaternion&); + void SetLeadingOrientation(const zeus::CQuaternion& o) { x0_leadingOrientation = o; } bool CheckLoadComplete() { return true; } - void GetDesiredReticleState(const CStateManager&) const; + EReticleState GetDesiredReticleState(const CStateManager&) const; void Update(float, const CStateManager&); void UpdateCurrLockOnGroup(float, const CStateManager&); - void UpdateUpdateNextLockOnGroup(float, const CStateManager&); + void UpdateNextLockOnGroup(float, const CStateManager&); void UpdateOrbitZoneGroup(float, const CStateManager&); - void Draw(const CStateManager&) const; - void DrawCurrLockOnGroup(const CStateManager&) const; - void DrawNextLockOnGroup(const CStateManager&) const; - void DrawOrbitZoneGroup(const CStateManager&) const; + void Draw(const CStateManager&, bool hideLockon) const; + void DrawGrappleGroup(const zeus::CMatrix3f& rot, const CStateManager&, bool) const; + void DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager&) const; + void DrawNextLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager&) const; + void DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager&) const; void UpdateTargetParameters(CTargetReticleRenderState&, const CStateManager&); float CalculateRadiusWorld(const CActor&, const CStateManager&) const; zeus::CVector3f CalculatePositionWorld(const CActor&, const CStateManager&) const; - zeus::CVector3f CalculateOrbitZoneReticlePosition(const CStateManager&) const; + zeus::CVector3f CalculateOrbitZoneReticlePosition(const CStateManager& mgr, bool lag) const; bool IsGrappleTarget(TUniqueId, const CStateManager&) const; static float CalculateClampedScale(const zeus::CVector3f&, float, float, float, const CStateManager&); - void Touch() const; + void Touch(); }; } diff --git a/Runtime/GuiSys/COrbitPointMarker.cpp b/Runtime/GuiSys/COrbitPointMarker.cpp index e69de29bb..e0d7646f8 100644 --- a/Runtime/GuiSys/COrbitPointMarker.cpp +++ b/Runtime/GuiSys/COrbitPointMarker.cpp @@ -0,0 +1,112 @@ +#include "COrbitPointMarker.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "CStateManager.hpp" +#include "World/CPlayer.hpp" +#include "Camera/CGameCamera.hpp" +#include "zeus/CEulerAngles.hpp" +#include "Graphics/CBooRenderer.hpp" + +namespace urde +{ + +COrbitPointMarker::COrbitPointMarker() +{ + x0_zOffset = g_tweakTargeting->GetOrbitPointZOffset(); + x28_orbitPointModel = g_SimplePool->GetObj("CMDL_OrbitPoint"); +} + +bool COrbitPointMarker::CheckLoadComplete() +{ + return x28_orbitPointModel.IsLoaded(); +} + +void COrbitPointMarker::Update(float dt, const CStateManager& mgr) +{ + x24_curTime += dt; + const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + CPlayer::EPlayerOrbitState orbitState = mgr.GetPlayer().GetOrbitState(); + bool freeOrbit = orbitState >= CPlayer::EPlayerOrbitState::OrbitPoint; + if (freeOrbit != x1c_lastFreeOrbit) + { + if (orbitState == CPlayer::EPlayerOrbitState::OrbitPoint || + orbitState == CPlayer::EPlayerOrbitState::OrbitCarcass) + { + ResetInterpolationTimer(g_tweakTargeting->GetOrbitPointInTime()); + zeus::CVector3f orbitTargetPosition = mgr.GetPlayer().GetHUDOrbitTargetPosition(); + if (!x4_camRelZPos) + x10_lagTargetPos = orbitTargetPosition + zeus::CVector3f(0.f, 0.f, x0_zOffset); + else + x10_lagTargetPos = zeus::CVector3f(orbitTargetPosition.x, orbitTargetPosition.y, + curCam->GetTranslation().z + x0_zOffset); + x8_lagAzimuth = + zeus::CEulerAngles(zeus::CQuaternion(curCam->GetTransform().basis)).z + zeus::degToRad(45.f); + } + else + { + ResetInterpolationTimer(g_tweakTargeting->GetOrbitPointOutTime()); + } + x1c_lastFreeOrbit = !x1c_lastFreeOrbit; + } + + if (x20_interpTimer > 0.f) + x20_interpTimer = std::max(0.f, x20_interpTimer - dt); + + if (!x4_camRelZPos) + { + zeus::CVector3f orbitTargetPosition = mgr.GetPlayer().GetHUDOrbitTargetPosition(); + if ((orbitTargetPosition.z + x0_zOffset) - x10_lagTargetPos.z < 0.1f) + x10_lagTargetPos = orbitTargetPosition + zeus::CVector3f(0.f, 0.f, x0_zOffset); + else if ((orbitTargetPosition.z + x0_zOffset) - x10_lagTargetPos.z < 0.f) + x10_lagTargetPos = zeus::CVector3f(orbitTargetPosition.x, orbitTargetPosition.y, x10_lagTargetPos.z - 0.1f); + else + x10_lagTargetPos = zeus::CVector3f(orbitTargetPosition.x, orbitTargetPosition.y, x10_lagTargetPos.z + 0.1f); + } + else + { + zeus::CVector3f orbitTargetPosition = mgr.GetPlayer().GetHUDOrbitTargetPosition(); + x10_lagTargetPos = zeus::CVector3f(orbitTargetPosition.x, orbitTargetPosition.y, + x0_zOffset + orbitTargetPosition.z); + } + + if (x1c_lastFreeOrbit) + { + float newAzimuth = zeus::CEulerAngles(zeus::CQuaternion(curCam->GetTransform().basis)).z + zeus::degToRad(45.f); + float aziDelta = newAzimuth - xc_azimuth; + if (mgr.GetPlayer().IsInFreeLook()) + x8_lagAzimuth += aziDelta; + xc_azimuth = newAzimuth; + } +} + +void COrbitPointMarker::Draw(const CStateManager& mgr) const +{ + if ((x1c_lastFreeOrbit || x20_interpTimer > 0.f) && g_tweakTargeting->DrawOrbitPoint() && + x28_orbitPointModel.IsLoaded()) + { + const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); + CGraphics::SetViewPointMatrix(camXf); + zeus::CFrustum frustum; + frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), + curCam->GetAspectRatio(), 1.f, 100.f)); + g_Renderer->SetClippingPlanes(frustum); + g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, + curCam->GetNearClipDistance(), curCam->GetFarClipDistance()); + float scale; + if (x1c_lastFreeOrbit) + scale = 1.f - x20_interpTimer / g_tweakTargeting->GetOrbitPointInTime(); + else + scale = x20_interpTimer / g_tweakTargeting->GetOrbitPointOutTime(); + zeus::CTransform modelXf = zeus::CTransform::RotateZ(x8_lagAzimuth); + modelXf.scaleBy(scale); + modelXf.origin += x10_lagTargetPos; + CGraphics::SetModelMatrix(modelXf); + zeus::CColor color = g_tweakTargeting->GetOrbitPointColor(); + color.a *= scale; + CModelFlags flags(7, 0, 0, color); + x28_orbitPointModel->Draw(flags); + } +} + +} diff --git a/Runtime/GuiSys/COrbitPointMarker.hpp b/Runtime/GuiSys/COrbitPointMarker.hpp index 5ac066101..20b8c01c3 100644 --- a/Runtime/GuiSys/COrbitPointMarker.hpp +++ b/Runtime/GuiSys/COrbitPointMarker.hpp @@ -1,13 +1,30 @@ #ifndef __URDE_CORBITPOINTMARKER_HPP__ #define __URDE_CORBITPOINTMARKER_HPP__ -namespace +#include "RetroTypes.hpp" +#include "CToken.hpp" +#include "Graphics/CModel.hpp" + +namespace urde { class CStateManager; class COrbitPointMarker { + float x0_zOffset; + bool x4_camRelZPos = true; + float x8_lagAzimuth = 0.f; + float xc_azimuth = 0.f; + zeus::CVector3f x10_lagTargetPos; + bool x1c_lastFreeOrbit = false; + float x20_interpTimer = 0.f; + float x24_curTime = 0.f; + TLockedToken x28_orbitPointModel; + void ResetInterpolationTimer(float time) { x20_interpTimer = time; } public: - + COrbitPointMarker(); + bool CheckLoadComplete(); + void Update(float dt, const CStateManager& mgr); + void Draw(const CStateManager& mgr) const; }; } #endif // __URDE_CORBITPOINTMARKER_HPP__ diff --git a/Runtime/GuiSys/CTargetingManager.cpp b/Runtime/GuiSys/CTargetingManager.cpp index 1e40fb73f..0691b23a2 100644 --- a/Runtime/GuiSys/CTargetingManager.cpp +++ b/Runtime/GuiSys/CTargetingManager.cpp @@ -1,31 +1,46 @@ #include "CTargetingManager.hpp" +#include "Camera/CGameCamera.hpp" +#include "CStateManager.hpp" +#include "Graphics/CBooRenderer.hpp" +#include "GameGlobalObjects.hpp" namespace urde { -CTargetingManager::CTargetingManager(const CStateManager&) -{ - -} +CTargetingManager::CTargetingManager(const CStateManager& mgr) +: x0_targetReticule(mgr) {} bool CTargetingManager::CheckLoadComplete() { - return false; + return (x0_targetReticule.CheckLoadComplete() && x21c_orbitPointMarker.CheckLoadComplete()); } void CTargetingManager::Update(float dt, const CStateManager& stateMgr) { - + x0_targetReticule.Update(dt, stateMgr); + x21c_orbitPointMarker.Update(dt, stateMgr); } -void CTargetingManager::Draw(const CStateManager& stateMgr, bool hideLockon) const +void CTargetingManager::Draw(const CStateManager& mgr, bool hideLockon) const { - + CGraphics::SetAmbientColor(zeus::CColor::skWhite); + CGraphics::DisableAllLights(); + x21c_orbitPointMarker.Draw(mgr); + const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); + zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); + CGraphics::SetViewPointMatrix(camXf); + zeus::CFrustum frustum; + frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), + curCam->GetAspectRatio(), 1.f, 100.f)); + g_Renderer->SetClippingPlanes(frustum); + g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, + curCam->GetNearClipDistance(), curCam->GetFarClipDistance()); + x0_targetReticule.Draw(mgr, hideLockon); } -void CTargetingManager::Touch() const +void CTargetingManager::Touch() { - + x0_targetReticule.Touch(); } } diff --git a/Runtime/GuiSys/CTargetingManager.hpp b/Runtime/GuiSys/CTargetingManager.hpp index 8b3186828..31b588347 100644 --- a/Runtime/GuiSys/CTargetingManager.hpp +++ b/Runtime/GuiSys/CTargetingManager.hpp @@ -9,14 +9,15 @@ namespace urde class CStateManager; class CTargetingManager { - zeus::CQuaternion x0_rot; + CCompoundTargetReticle x0_targetReticule; + COrbitPointMarker x21c_orbitPointMarker; public: CTargetingManager(const CStateManager& stateMgr); bool CheckLoadComplete(); void Update(float, const CStateManager& stateMgr); void Draw(const CStateManager& stateMgr, bool hideLockon) const; - void Touch() const; - void SetRotation(const zeus::CQuaternion& rot) { x0_rot = rot; } + void Touch(); + CCompoundTargetReticle& CompoundTargetReticle() { return x0_targetReticule; } }; } diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp index ced0d158a..e2bba7b9c 100644 --- a/Runtime/MP1/CSamusHud.cpp +++ b/Runtime/MP1/CSamusHud.cpp @@ -720,7 +720,7 @@ void CSamusHud::UpdateHudLag(float dt, const CStateManager& mgr) zeus::CTransform::Translate(x588_base_basewidget_pivot->GetWorldPosition())); x274_loadedFrmeBaseHud->GetFrameCamera()->SetO2WTransform( BuildFinalCameraTransform(zeus::CQuaternion::skNoRotation, x304_basewidgetIdlePos, x310_cameraPos)); - x8_targetingMgr.SetRotation(zeus::CQuaternion::skNoRotation); + x8_targetingMgr.CompoundTargetReticle().SetLeadingOrientation(zeus::CQuaternion::skNoRotation); } else { @@ -734,7 +734,7 @@ void CSamusHud::UpdateHudLag(float dt, const CStateManager& mgr) zeus::CQuaternion rot = zeus::CQuaternion::lookAt(zeus::CUnitVector3f(x2f8_fpCamDir), fpCamDir, 2.f * M_PIF); rot *= rot; rot *= rot; - x8_targetingMgr.SetRotation(rot); + x8_targetingMgr.CompoundTargetReticle().SetLeadingOrientation(rot); zeus::CVector3f bobTranslation = player.GetCameraBob()->GetHelmetBobTranslation(); diff --git a/specter b/specter index 126de2c01..2e40a111c 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 126de2c01b9acf3ff7917d63b04ba52b2fca3e91 +Subproject commit 2e40a111c7485b569889011e782ad8e69eca3fd2