mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-07-31 11:25:35 +00:00
1377 lines
58 KiB
C++
1377 lines
58 KiB
C++
#include "Runtime/GuiSys/CCompoundTargetReticle.hpp"
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "Runtime/GameGlobalObjects.hpp"
|
|
#include "Runtime/CSimplePool.hpp"
|
|
#include "Runtime/CStateManager.hpp"
|
|
#include "Runtime/Camera/CGameCamera.hpp"
|
|
#include "Runtime/World/CPlayer.hpp"
|
|
#include "Runtime/World/CScriptGrapplePoint.hpp"
|
|
#include "Runtime/World/CWorld.hpp"
|
|
|
|
#include "TCastTo.hpp" // Generated file, do not modify include path
|
|
|
|
namespace urde {
|
|
namespace {
|
|
constexpr char skCrosshairsReticleAssetName[] = "CMDL_Crosshairs";
|
|
[[maybe_unused]] constexpr char skOrbitZoneReticleAssetName[] = "CMDL_OrbitZone";
|
|
constexpr char skSeekerAssetName[] = "CMDL_Seeker";
|
|
constexpr char skLockConfirmAssetName[] = "CMDL_LockConfirm";
|
|
constexpr char skTargetFlowerAssetName[] = "CMDL_TargetFlower";
|
|
constexpr char skMissileBracketAssetName[] = "CMDL_MissileBracket";
|
|
constexpr char skChargeGaugeAssetName[] = "CMDL_ChargeGauge";
|
|
constexpr char skChargeBeamTickAssetName[] = "CMDL_ChargeTickFirst";
|
|
constexpr char skOuterBeamIconSquareNameBase[] = "CMDL_BeamSquare";
|
|
constexpr char skInnerBeamIconName[] = "CMDL_InnerBeamIcon";
|
|
constexpr char skLockFireAssetName[] = "CMDL_LockFire";
|
|
constexpr char skLockDaggerAssetName[] = "CMDL_LockDagger0";
|
|
constexpr char skGrappleReticleAssetName[] = "CMDL_Grapple";
|
|
constexpr char skXRayRingModelName[] = "CMDL_XRayRetRing";
|
|
constexpr char skThermalReticleAssetName[] = "CMDL_ThermalRet";
|
|
[[maybe_unused]] constexpr char skOrbitPointAssetName[] = "CMDL_OrbitPoint";
|
|
// RS5
|
|
constexpr char skCombatAimingCenter[] = "CMDL_CombatAimingCenter";
|
|
constexpr char skCombatAimingArm[] = "CMDL_CombatAimingArm";
|
|
constexpr char skOrbitLockArm[] = "CMDL_OrbitLockArm";
|
|
constexpr char skOrbitLockTech[] = "CMDL_OrbitLockTech";
|
|
constexpr char skOrbitLockBrackets[] = "CMDL_OrbitLockBrackets";
|
|
constexpr char skOrbitLockBase[] = "CMDL_OrbitLockBase";
|
|
constexpr char skOffScreen[] = "CMDL_OffScreen";
|
|
constexpr char skScanReticleRing[] = "CMDL_ScanReticleRing";
|
|
constexpr char skScanReticleBracket[] = "CMDL_ScanReticleBracket";
|
|
constexpr char skScanReticleProgress[] = "CMDL_ScanReticleProgress";
|
|
|
|
float offshoot_func(float f1, float f2, float f3) { return (f1 * 0.5f) + std::sin((f3 - 0.5f) * f2); }
|
|
|
|
float calculate_premultiplied_overshoot_offset(float f1) { return 2.f * (M_PIF - std::asin(1.f / f1)); }
|
|
} // Anonymous namespace
|
|
|
|
const CTargetReticleRenderState CTargetReticleRenderState::skZeroRenderState(kInvalidUniqueId, 1.f,
|
|
zeus::skZero3f, 0.f, 1.f, true);
|
|
|
|
CCompoundTargetReticle::SOuterItemInfo::SOuterItemInfo(std::string_view res) : x0_model(g_SimplePool->GetObj(res)) {}
|
|
|
|
CCompoundTargetReticle::CCompoundTargetReticle(const CStateManager& mgr)
|
|
: x0_leadingOrientation(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f())
|
|
, x10_laggingOrientation(mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTransform().buildMatrix3f())
|
|
, x2c_overshootOffsetHalf(0.5f * g_tweakTargeting->GetChargeGaugeOvershootOffset())
|
|
, x30_premultOvershootOffset(
|
|
calculate_premultiplied_overshoot_offset(g_tweakTargeting->GetChargeGaugeOvershootOffset()))
|
|
, x34_crosshairs(g_SimplePool->GetObj(skCrosshairsReticleAssetName))
|
|
, x40_seeker(g_SimplePool->GetObj(skSeekerAssetName))
|
|
, x4c_lockConfirm(g_SimplePool->GetObj(skLockConfirmAssetName))
|
|
, x58_targetFlower(g_SimplePool->GetObj(skTargetFlowerAssetName))
|
|
, x64_missileBracket(g_SimplePool->GetObj(skMissileBracketAssetName))
|
|
, x70_innerBeamIcon(g_SimplePool->GetObj(skInnerBeamIconName))
|
|
, x7c_lockFire(g_SimplePool->GetObj(skLockFireAssetName))
|
|
, x88_lockDagger(g_SimplePool->GetObj(skLockDaggerAssetName))
|
|
, x94_grapple(g_SimplePool->GetObj(skGrappleReticleAssetName))
|
|
, xa0_chargeTickFirst(g_SimplePool->GetObj(skChargeBeamTickAssetName))
|
|
, xac_xrayRetRing(g_SimplePool->GetObj(skXRayRingModelName))
|
|
, xb8_thermalReticle(g_SimplePool->GetObj(skThermalReticleAssetName))
|
|
, xc4_chargeGauge(skChargeGaugeAssetName)
|
|
, xf4_targetPos(CalculateOrbitZoneReticlePosition(mgr, false))
|
|
, x100_laggingTargetPos(CalculateOrbitZoneReticlePosition(mgr, true))
|
|
, x208_lockonTimer(g_tweakTargeting->GetLockonDuration())
|
|
, x38c_combatAimingCenter(g_SimplePool->GetObj(skCombatAimingCenter))
|
|
, x398_combatAimingArm(g_SimplePool->GetObj(skCombatAimingArm))
|
|
, x3a4_orbitLockArm(g_SimplePool->GetObj(skOrbitLockArm))
|
|
, x3b0_orbitLockTech(g_SimplePool->GetObj(skOrbitLockTech))
|
|
, x3bc_orbitLockBrackets(g_SimplePool->GetObj(skOrbitLockBrackets))
|
|
, x3c8_orbitLockBase(g_SimplePool->GetObj(skOrbitLockBase))
|
|
, x3d4_offScreen(g_SimplePool->GetObj(skOffScreen))
|
|
, x3e0_scanReticleRing(g_SimplePool->GetObj(skScanReticleRing))
|
|
, x3ec_scanReticleBracket(g_SimplePool->GetObj(skScanReticleBracket))
|
|
, x3f8_scanReticleProgress(g_SimplePool->GetObj(skScanReticleProgress)) {
|
|
xe0_outerBeamIconSquares.reserve(9);
|
|
for (u32 i = 0; i < 9; ++i)
|
|
xe0_outerBeamIconSquares.emplace_back(fmt::format(fmt("{}{}"), skOuterBeamIconSquareNameBase, i));
|
|
x34_crosshairs.Lock();
|
|
}
|
|
|
|
CCompoundTargetReticle::SScanReticuleRenderer::SScanReticuleRenderer() {
|
|
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, true);
|
|
for (int j = 0; j < 4; ++j)
|
|
m_stripRenderers[i][j].emplace(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true, true);
|
|
}
|
|
return true;
|
|
} BooTrace);
|
|
}
|
|
|
|
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->GetAngularLagSpeed() * 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);
|
|
// TODO more
|
|
UpdateNewGroup1(dt, mgr);
|
|
UpdateNewGroup2(dt, mgr);
|
|
// TODO more
|
|
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_fullChargeFadeTimer = std::min(dt / g_tweakTargeting->GetFullChargeFadeDuration() + x214_fullChargeFadeTimer,
|
|
g_tweakTargeting->GetFullChargeFadeDuration());
|
|
else
|
|
x214_fullChargeFadeTimer =
|
|
std::max(x214_fullChargeFadeTimer - dt / g_tweakTargeting->GetFullChargeFadeDuration(), 0.f);
|
|
bool missileActive = gun->GetMissleMode() == CPlayerGun::EMissleMode::Active;
|
|
if (missileActive != x1f4_missileActive) {
|
|
if (x1f8_missileBracketTimer != 0.f)
|
|
x1f8_missileBracketTimer = FLT_EPSILON - x1f8_missileBracketTimer;
|
|
else
|
|
x1f8_missileBracketTimer = FLT_EPSILON;
|
|
x1f4_missileActive = missileActive;
|
|
}
|
|
CPlayerState::EBeamId beam = gun->GetCurrentBeam();
|
|
if (beam != x200_beam) {
|
|
x204_chargeGaugeOvershootTimer = g_tweakTargeting->GetChargeGaugeOvershootDuration();
|
|
for (int i = 0; i < 9; ++i) {
|
|
zeus::CRelAngle baseAngle = g_tweakTargeting->GetOuterBeamSquareAngles(int(beam))[i];
|
|
baseAngle.makeRel();
|
|
SOuterItemInfo& icon = xe0_outerBeamIconSquares[i];
|
|
zeus::CRelAngle offshootAngleDelta = baseAngle.asRadians() - icon.x10_rotAng;
|
|
if ((i & 0x1) == 1)
|
|
offshootAngleDelta =
|
|
(baseAngle > 0.f) ? zeus::CRelAngle(-2.f * M_PIF - baseAngle) : zeus::CRelAngle(2.f * M_PIF + baseAngle);
|
|
icon.xc_offshootBaseAngle = icon.x10_rotAng;
|
|
icon.x18_offshootAngleDelta = offshootAngleDelta;
|
|
icon.x14_baseAngle = baseAngle;
|
|
}
|
|
zeus::CRelAngle baseAngle = g_tweakTargeting->GetChargeGaugeAngle(int(beam));
|
|
baseAngle.makeRel();
|
|
float offshootAngleDelta = baseAngle.asRadians() - xc4_chargeGauge.x10_rotAng;
|
|
if ((rand() & 0x1) == 1)
|
|
offshootAngleDelta =
|
|
(offshootAngleDelta > 0.f) ? -2.f * M_PIF - offshootAngleDelta : 2.f * M_PIF + offshootAngleDelta;
|
|
xc4_chargeGauge.xc_offshootBaseAngle = xc4_chargeGauge.x10_rotAng;
|
|
xc4_chargeGauge.x18_offshootAngleDelta = offshootAngleDelta;
|
|
xc4_chargeGauge.x14_baseAngle = baseAngle;
|
|
x200_beam = beam;
|
|
x208_lockonTimer = 0.f;
|
|
}
|
|
if (gun->GetLastFireButtonStates() & 0x1) {
|
|
if (!x218_beamShot)
|
|
x210_lockFireTimer = g_tweakTargeting->GetLockFireDuration();
|
|
x218_beamShot = true;
|
|
} else {
|
|
x218_beamShot = false;
|
|
}
|
|
if (gun->GetLastFireButtonStates() & 0x2) {
|
|
if (!x219_missileShot)
|
|
x1fc_missileBracketScaleTimer = g_tweakTargeting->GetMissileBracketScaleDuration();
|
|
x219_missileShot = true;
|
|
} else {
|
|
x219_missileShot = false;
|
|
}
|
|
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(xf2_nextTargetId)) {
|
|
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).asRel();
|
|
x1ec_seekerAngle = zeus::CRelAngle(zeus::degToRad(g_tweakTargeting->GetSeekerAngleSpeed() * dt) + x1ec_seekerAngle).
|
|
asRel();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static bool IsDamageOrbit(CPlayer::EPlayerOrbitRequest req) {
|
|
switch (req) {
|
|
case CPlayer::EPlayerOrbitRequest::Five:
|
|
case CPlayer::EPlayerOrbitRequest::ActivateOrbitSource:
|
|
case CPlayer::EPlayerOrbitRequest::ProjectileCollide:
|
|
case CPlayer::EPlayerOrbitRequest::Freeze:
|
|
case CPlayer::EPlayerOrbitRequest::DamageOnGrapple:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void CCompoundTargetReticle::UpdateNewGroup1(float dt, const class CStateManager& mgr) {
|
|
CPlayer& player = mgr.GetPlayer();
|
|
TUniqueId nextTargetId = player.GetOrbitNextTargetId();
|
|
|
|
x2a4_ = g_tweakTargeting->x2e0_;
|
|
x290_ = zeus::CVector3f(g_tweakTargeting->x2cc_);
|
|
if (nextTargetId != kInvalidUniqueId)
|
|
x29c_ = g_tweakTargeting->x2d0_;
|
|
|
|
if (auto act = TCastToConstPtr<CActor>(mgr.GetObjectById(nextTargetId)))
|
|
x2b4_ = act->GetOrbitPosition(mgr);
|
|
else
|
|
x2b4_ = x2c0_;
|
|
|
|
const CGameCamera* camera = mgr.GetCameraManager()->GetCurrentCamera(mgr);
|
|
const zeus::CTransform cameraTransform = camera->GetTransform();
|
|
const zeus::CVector3f vec1 = cameraTransform.frontVector().normalized();
|
|
const zeus::CVector3f cameraOrigin = vec1 - cameraTransform.origin;
|
|
const zeus::CVector3f normalizedCamOrigin = cameraOrigin.normalized();
|
|
const float dot = 1.25f / vec1.dot(normalizedCamOrigin);
|
|
const zeus::CVector3f final = cameraTransform.origin + (normalizedCamOrigin * dot);
|
|
x2d8_ = final;
|
|
|
|
if (nextTargetId != kInvalidUniqueId && x27c_ != nextTargetId) {
|
|
if (x2a0_ == 0.f) {
|
|
x2e4_ = final;
|
|
} else {
|
|
x2e4_ = x2c0_;
|
|
x2cc_ = true;
|
|
x2d0_ = g_tweakTargeting->x2f0_;
|
|
x2d4_ = 0.f;
|
|
}
|
|
}
|
|
|
|
float dVar19 = g_tweakTargeting->x2d4_;
|
|
float dVar18 = dt * (dVar19 / g_tweakTargeting->x2ec_);
|
|
if (nextTargetId == kInvalidUniqueId) {
|
|
float dVar16 = x2a0_ - dVar18;
|
|
float check1 = 0.f;
|
|
if ((0.f - dVar16) <= 0.f) {
|
|
check1 = dVar16;
|
|
}
|
|
if (dVar19 <= 0.f) {
|
|
dVar19 = check1;
|
|
}
|
|
x2a0_ = dVar19;
|
|
} else {
|
|
float dVar16 = x2a0_ + dVar18;
|
|
float check1 = 0.f;
|
|
if ((0.f - dVar16) <= 0.f) {
|
|
check1 = dVar16;
|
|
}
|
|
if (dVar19 <= 0.f) {
|
|
dVar19 = check1;
|
|
}
|
|
x2a0_ = dVar19;
|
|
}
|
|
|
|
if (!x2cc_ || x2d0_ <= 0.f) {
|
|
x280_ = x2d8_;
|
|
x2c0_ = x2b4_;
|
|
} else {
|
|
float f1 = x2d4_ + dt;
|
|
float result = 0.f;
|
|
if ((0.f - f1) <= 0.f) {
|
|
result = f1;
|
|
}
|
|
f1 = x2d0_;
|
|
if (f1 <= 0.f) {
|
|
f1 = result;
|
|
}
|
|
x2d4_ = f1;
|
|
if (x2d0_ <= f1) {
|
|
x2cc_ = false;
|
|
x280_ = x2d8_;
|
|
x2c0_ = x2b4_;
|
|
} else {
|
|
const zeus::CVector3f origin = (x2e4_ - cameraTransform.origin).normalized();
|
|
float dot2 = 1.25f / origin.dot(vec1);
|
|
const zeus::CVector3f vec = (origin * dot2) + cameraOrigin;
|
|
|
|
float div = x2d4_ / x2d0_;
|
|
float oneMinusDiv = 1.f - div;
|
|
const zeus::CVector3f vec2 = (vec * oneMinusDiv) + (x2d8_ * div);
|
|
x280_ = vec2;
|
|
|
|
const zeus::CVector3f vec3 = (vec2 - cameraOrigin).normalized();
|
|
float mag = (x2b4_ - cameraOrigin).magnitude();
|
|
x2c0_ = cameraOrigin + (vec3 * mag);
|
|
}
|
|
}
|
|
|
|
x27c_ = nextTargetId;
|
|
x28c_ = x28c_ + zeus::degToRad(dt * g_tweakTargeting->x2f4_);
|
|
}
|
|
|
|
void CCompoundTargetReticle::UpdateNewGroup2(float dt, const class CStateManager& mgr) {
|
|
CPlayer& player = mgr.GetPlayer();
|
|
TUniqueId targetId = player.GetOrbitTargetId();
|
|
bool bVar1 = false;
|
|
if (targetId != kInvalidUniqueId) {
|
|
TCastToConstPtr<CScriptGrapplePoint> prevPoint = mgr.GetObjectById(x27c_);
|
|
TCastToConstPtr<CScriptGrapplePoint> currPoint = mgr.GetObjectById(targetId);
|
|
bVar1 = currPoint.operator bool();
|
|
if (!prevPoint) {
|
|
x27c_ = kInvalidUniqueId;
|
|
x2a0_ = 0.f;
|
|
}
|
|
}
|
|
|
|
const CGameCamera* camera = mgr.GetCameraManager()->GetCurrentCamera(mgr);
|
|
zeus::CTransform cameraTransform = camera->GetTransform();
|
|
zeus::CQuaternion quat_304 = cameraTransform.getRotation().buildMatrix3f();
|
|
zeus::CVector3f vec3f_17c = quat_304.transform(zeus::CVector3f(0.f, 1.25f, 0.f));
|
|
x2f2_ = cameraTransform.origin + vec3f_17c;
|
|
|
|
bool bVar11 = false;
|
|
auto uVar14 = ((u32)kInvalidUniqueId.id) - ((u32)targetId.id) | ((u32)targetId.id) - ((u32)kInvalidUniqueId.id);
|
|
if (((s32) uVar14) > -1 && player.x1188_) { // < 0
|
|
bVar11 = true;
|
|
}
|
|
|
|
if (targetId == kInvalidUniqueId || targetId != x2f0_) {
|
|
if (targetId == kInvalidUniqueId && x2f0_ != kInvalidUniqueId) {
|
|
if (bVar11) {
|
|
TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(x2f0_);
|
|
if (x20_prevState == EReticleState::Combat && !point.operator bool()) {
|
|
x350_ = 1.f;
|
|
}
|
|
}
|
|
} else {
|
|
x324_ = 0.f;
|
|
}
|
|
} else {
|
|
x324_ += dt;
|
|
}
|
|
|
|
x300_ = g_tweakTargeting->x2d8_;
|
|
zeus::CColor _1d4 = g_tweakTargeting->x304_;
|
|
if (IsGrappleTarget(targetId, mgr)) {
|
|
x300_ = g_tweakTargeting->x320_;
|
|
_1d4 = g_tweakTargeting->x320_;
|
|
}
|
|
|
|
if (((s32) uVar14) < 0) {
|
|
x37c_ = std::max(0.f, g_tweakTargeting->x318_);
|
|
x380_ = std::max(0.f, g_tweakTargeting->x31c_);
|
|
} else {
|
|
if (bVar11) {
|
|
x380_ = std::max(0.f, g_tweakTargeting->x318_);
|
|
x37c_ = std::max(0.f, g_tweakTargeting->x31c_);
|
|
} else {
|
|
x37c_ = std::max(0.f, g_tweakTargeting->x318_);
|
|
x380_ = std::max(0.f, g_tweakTargeting->x31c_);
|
|
}
|
|
}
|
|
|
|
float fVar2 = g_tweakTargeting->x354_;
|
|
float fVar3 = 0.f;
|
|
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) {
|
|
fVar3 = g_tweakTargeting->x358_;
|
|
}
|
|
float fVar4 = 1.f;
|
|
if (fVar3 > 0.f) {
|
|
fVar4 = dt * (fVar2 / fVar3);
|
|
}
|
|
fVar4 = x350_ - fVar4;
|
|
fVar3 = 0.f;
|
|
if (0.f - fVar4 <= 0.f) {
|
|
fVar3 = fVar4;
|
|
}
|
|
if (fVar2 <= 0.f) {
|
|
fVar2 = fVar3;
|
|
}
|
|
x350_ = fVar2;
|
|
|
|
float dVar31 = x37c_ / g_tweakTargeting->x318_;
|
|
float dVar30 = x380_ / g_tweakTargeting->x31c_;
|
|
x36c_lerped_color_ = zeus::CColor::lerp(g_tweakTargeting->x30c_, _1d4, dVar31);
|
|
x378_ = dVar30;
|
|
|
|
x370_ = ((1.f - dVar31) * g_tweakTargeting->x310_) + (dVar31 * g_tweakTargeting->x308_);
|
|
x374_ = ((1.f - dVar30) * 0.f) + (dVar30 * g_tweakTargeting->x314_);
|
|
|
|
float local_140 = g_tweakTargeting->x338_;
|
|
x328_ = x290_ + local_140;
|
|
|
|
x308_orbitLockBaseColor = g_tweakTargeting->x328_;
|
|
x30c_orbitLockBaseAlpha = g_tweakTargeting->x32c_;
|
|
|
|
dVar30 = (x324_ - g_tweakTargeting->x33c_) / g_tweakTargeting->x340_;
|
|
float dVar27 = 0.f;
|
|
if ((float)(0.f - dVar30) <= 0.00000000) {
|
|
dVar27 = dVar30;
|
|
}
|
|
dVar30 = 1.f;
|
|
if ((float)(dVar27 - 1.f) <= 0.00000000) {
|
|
dVar30 = dVar27;
|
|
}
|
|
x334_ = ((1.f - dVar30) * 0.f) + (dVar30 * g_tweakTargeting->x32c_);
|
|
|
|
zeus::CVector3f _14c(player.GetTransform().basis.m[1][0], player.GetTransform().basis.m[1][1], 0.f); // params probably not right
|
|
_14c.normalize();
|
|
float fVar27 = zeus::CVector3f::getAngleDiff(_14c, zeus::skForward);
|
|
float fVar2_ = 360.f * (0.15915494f /*1/(2*PI)*/ * fVar27);
|
|
|
|
float out;
|
|
if (0.f <= _14c.x()) { // local_1b0 = local_14c.x * local_158.y - local_158.x * local_14c.y;
|
|
float rad = zeus::degToRad(fVar2_);
|
|
float d = rad - (((int) (rad * M_PI_2)) * M_2_PI);
|
|
if (d < 0.f)
|
|
d += M_2_PI;
|
|
out = d;
|
|
} else {
|
|
float rad = zeus::degToRad(360.f - fVar2_);
|
|
float d = rad - (((int) (rad * M_PI_2)) * M_2_PI);
|
|
if (d < 0.f)
|
|
d += M_2_PI;
|
|
out = d;
|
|
}
|
|
|
|
if (dVar30 < 1.f) {
|
|
x338_ = 0.f;
|
|
} else {
|
|
x338_ = x338_ + (out - x33c_angle_);
|
|
}
|
|
x33c_angle_ = out;
|
|
x340_ = 0.496f;
|
|
if ((x324_ - g_tweakTargeting->x344_) / g_tweakTargeting->x348_ < 1.f) {
|
|
x344_ = 0.f;
|
|
} else {
|
|
x344_ += zeus::degToRad(g_tweakTargeting->x34c_ * dt);
|
|
}
|
|
x348_inverse_angle_ = out;
|
|
|
|
if (x20_prevState != EReticleState::Combat && x20_prevState != EReticleState::Unspecified) {
|
|
bVar1 = true;
|
|
x374_ = 0.f;
|
|
}
|
|
if (bVar1) {
|
|
x304_ = 0.f;
|
|
} else {
|
|
float g = g_tweakTargeting->x2dc_;
|
|
float f3 = 1.f;
|
|
if (0.f < g_tweakTargeting->x2fc_) {
|
|
f3 = (dt * (g / g_tweakTargeting->x2fc_));
|
|
}
|
|
if (x324_ < g_tweakTargeting->x2f8_) {
|
|
x304_ = g;
|
|
} else {
|
|
float f4 = g_tweakTargeting->x300_;
|
|
if (f4 <= 0.f) {
|
|
f4 = x304_ - f3;
|
|
}
|
|
if (g <= 0.f) {
|
|
g = f4;
|
|
}
|
|
x304_ = g;
|
|
}
|
|
}
|
|
x34c_ = bVar11;
|
|
x2f0_ = targetId;
|
|
}
|
|
|
|
void CCompoundTargetReticle::UpdateCurrLockOnGroup(float dt, const CStateManager& mgr) {
|
|
TUniqueId targetId = mgr.GetPlayer().GetOrbitTargetId();
|
|
if (targetId != xf0_targetId) {
|
|
if (targetId != kInvalidUniqueId) {
|
|
if (TCastToConstPtr<CScriptGrapplePoint> point = mgr.GetObjectById(targetId))
|
|
CSfxManager::SfxStart(SFXui_lockon_grapple, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
|
else
|
|
CSfxManager::SfxStart(SFXui_lockon_poi, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
|
}
|
|
|
|
if (targetId == kInvalidUniqueId) {
|
|
x12c_currGroupA = x10c_currGroupInterp;
|
|
x14c_currGroupB.SetFactor(0.f);
|
|
x16c_currGroupDur =
|
|
IsDamageOrbit(mgr.GetPlayer().GetOrbitRequest()) ? 0.65f : g_tweakTargeting->GetCurrLockOnEnterDuration();
|
|
} else {
|
|
x12c_currGroupA = x10c_currGroupInterp;
|
|
if (xf0_targetId == kInvalidUniqueId)
|
|
x12c_currGroupA.SetTargetId(targetId);
|
|
x14c_currGroupB = CTargetReticleRenderState(
|
|
targetId, 1.f, zeus::skZero3f, 1.f,
|
|
IsGrappleTarget(targetId, mgr) ? g_tweakTargeting->GetGrappleMinClampScale() : 1.f, false);
|
|
x16c_currGroupDur = xf0_targetId == kInvalidUniqueId ? g_tweakTargeting->GetCurrLockOnExitDuration()
|
|
: g_tweakTargeting->GetCurrLockOnSwitchDuration();
|
|
}
|
|
x170_currGroupTimer = x16c_currGroupDur;
|
|
xf0_targetId = targetId;
|
|
}
|
|
if (x170_currGroupTimer > 0.f) {
|
|
UpdateTargetParameters(x12c_currGroupA, mgr);
|
|
UpdateTargetParameters(x14c_currGroupB, mgr);
|
|
x170_currGroupTimer = std::max(0.f, x170_currGroupTimer - dt);
|
|
CTargetReticleRenderState::InterpolateWithClamp(x12c_currGroupA, x10c_currGroupInterp, x14c_currGroupB,
|
|
1.f - x170_currGroupTimer / x16c_currGroupDur);
|
|
} else {
|
|
UpdateTargetParameters(x10c_currGroupInterp, mgr);
|
|
}
|
|
if (x1f8_missileBracketTimer != 0.f && x1f8_missileBracketTimer < g_tweakTargeting->GetMissileBracketDuration()) {
|
|
if (x1f8_missileBracketTimer < 0.f)
|
|
x1f8_missileBracketTimer = std::min(0.f, x1f8_missileBracketTimer + dt);
|
|
else
|
|
x1f8_missileBracketTimer = std::min(g_tweakTargeting->GetMissileBracketDuration(), x1f8_missileBracketTimer + dt);
|
|
}
|
|
if (x204_chargeGaugeOvershootTimer > 0.f) {
|
|
x204_chargeGaugeOvershootTimer = std::max(0.f, x204_chargeGaugeOvershootTimer - dt);
|
|
if (x204_chargeGaugeOvershootTimer == 0.f) {
|
|
for (int i = 0; i < 9; ++i)
|
|
xe0_outerBeamIconSquares[i].x10_rotAng = xe0_outerBeamIconSquares[i].x14_baseAngle;
|
|
xc4_chargeGauge.x10_rotAng = xc4_chargeGauge.x14_baseAngle;
|
|
x208_lockonTimer = FLT_EPSILON;
|
|
} else {
|
|
float offshoot =
|
|
offshoot_func(x2c_overshootOffsetHalf, x30_premultOvershootOffset,
|
|
1.f - x204_chargeGaugeOvershootTimer / g_tweakTargeting->GetChargeGaugeOvershootDuration());
|
|
for (int i = 0; i < 9; ++i) {
|
|
SOuterItemInfo& item = xe0_outerBeamIconSquares[i];
|
|
item.x10_rotAng = zeus::CRelAngle(item.x18_offshootAngleDelta * offshoot + item.xc_offshootBaseAngle).
|
|
asRel();
|
|
}
|
|
xc4_chargeGauge.x10_rotAng =
|
|
zeus::CRelAngle(xc4_chargeGauge.x18_offshootAngleDelta * offshoot + xc4_chargeGauge.xc_offshootBaseAngle).
|
|
asRel();
|
|
}
|
|
}
|
|
if (x208_lockonTimer > 0.f && x208_lockonTimer < g_tweakTargeting->GetLockonDuration())
|
|
x208_lockonTimer = std::min(g_tweakTargeting->GetLockonDuration(), x208_lockonTimer + dt);
|
|
if (x210_lockFireTimer > 0.f)
|
|
x210_lockFireTimer = std::max(0.f, x210_lockFireTimer - dt);
|
|
if (x1fc_missileBracketScaleTimer > 0.f)
|
|
x1fc_missileBracketScaleTimer = std::max(0.f, x1fc_missileBracketScaleTimer - dt);
|
|
if (x20_prevState == EReticleState::Scan && x456_ != kInvalidUniqueId)
|
|
x404_ = std::min(1.f, x404_ + (dt / g_tweakTargeting->x360_));
|
|
else
|
|
x404_ = std::max(0.f, x404_ - (dt / g_tweakTargeting->x360_));
|
|
if (mgr.GetPlayer().GetScanningObjectId() == kInvalidUniqueId)
|
|
x214_ = std::min(1.f, x214_ + (dt * 4.f));
|
|
else
|
|
x214_ = std::max(0.f, x214_ - (dt * 4.f));
|
|
}
|
|
|
|
void CCompoundTargetReticle::UpdateNextLockOnGroup(float dt, const CStateManager& mgr) {
|
|
TUniqueId nextTargetId = mgr.GetPlayer().GetOrbitNextTargetId();
|
|
if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan &&
|
|
mgr.GetPlayer().GetOrbitTargetId() != kInvalidUniqueId)
|
|
nextTargetId = mgr.GetPlayer().GetOrbitTargetId();
|
|
if (nextTargetId != xf2_nextTargetId) {
|
|
if (nextTargetId == kInvalidUniqueId) {
|
|
x194_nextGroupA = x174_nextGroupInterp;
|
|
x1b4_nextGroupB = CTargetReticleRenderState(
|
|
kInvalidUniqueId, 1.f,
|
|
(x20_prevState == EReticleState::XRay || x20_prevState == EReticleState::Thermal) ? x100_laggingTargetPos
|
|
: xf4_targetPos,
|
|
0.f, 1.f, true);
|
|
x1d4_nextGroupDur = x1d8_nextGroupTimer = g_tweakTargeting->GetNextLockOnExitDuration();
|
|
xf2_nextTargetId = nextTargetId;
|
|
} else {
|
|
x194_nextGroupA = x174_nextGroupInterp;
|
|
x1b4_nextGroupB = CTargetReticleRenderState(
|
|
nextTargetId, 1.f, zeus::skZero3f, 1.f,
|
|
IsGrappleTarget(nextTargetId, mgr) ? g_tweakTargeting->GetGrappleMinClampScale() : 1.f, true);
|
|
x1d4_nextGroupDur = x1d8_nextGroupTimer = xf2_nextTargetId == kInvalidUniqueId
|
|
? g_tweakTargeting->GetNextLockOnEnterDuration()
|
|
: g_tweakTargeting->GetNextLockOnSwitchDuration();
|
|
xf2_nextTargetId = nextTargetId;
|
|
}
|
|
}
|
|
if (x1d8_nextGroupTimer > 0.f) {
|
|
UpdateTargetParameters(x194_nextGroupA, mgr);
|
|
UpdateTargetParameters(x1b4_nextGroupB, mgr);
|
|
x1d8_nextGroupTimer = std::max(0.f, x1d8_nextGroupTimer - dt);
|
|
CTargetReticleRenderState::InterpolateWithClamp(x194_nextGroupA, x174_nextGroupInterp, x1b4_nextGroupB,
|
|
1.f - x1d8_nextGroupTimer / x1d4_nextGroupDur);
|
|
} else {
|
|
UpdateTargetParameters(x174_nextGroupInterp, mgr);
|
|
}
|
|
}
|
|
|
|
void CCompoundTargetReticle::UpdateOrbitZoneGroup(float dt, const CStateManager& mgr) {
|
|
if (xf0_targetId == kInvalidUniqueId && xf2_nextTargetId != kInvalidUniqueId)
|
|
x20c_ = std::min(1.f, 2.f * dt + x20c_);
|
|
else
|
|
x20c_ = std::max(0.f, x20c_ - 2.f * dt);
|
|
if (mgr.GetPlayer().IsShowingCrosshairs() &&
|
|
mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan)
|
|
x1e8_crosshairsScale = std::min(1.f, dt / g_tweakTargeting->GetCrosshairsScaleDuration() + x1e8_crosshairsScale);
|
|
else
|
|
x1e8_crosshairsScale = std::max(0.f, x1e8_crosshairsScale - dt / g_tweakTargeting->GetCrosshairsScaleDuration());
|
|
}
|
|
|
|
void CCompoundTargetReticle::Draw(const CStateManager& mgr, bool hideLockon) const {
|
|
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed &&
|
|
!mgr.GetCameraManager()->IsInCinematicCamera()) {
|
|
SCOPED_GRAPHICS_DEBUG_GROUP("CCompoundTargetReticle::Draw", zeus::skCyan);
|
|
zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
|
|
CGraphics::SetViewPointMatrix(camXf);
|
|
if (!hideLockon) {
|
|
DrawNewGroup1(camXf.basis, mgr);
|
|
DrawNewGroup2(camXf.basis, mgr);
|
|
// 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::DrawNewGroup1(const zeus::CMatrix3f& rot, const CStateManager& mgr) const {
|
|
if (x2a0_ > 0) {
|
|
for (int i = 0; i < 3; i++) {
|
|
zeus::CTransform transform_184(zeus::CMatrix3f(), x2a4_);
|
|
zeus::CMatrix3f mat3f_220 = zeus::CMatrix3f::RotateY(x28c_ + zeus::degToRad(120.f * i));
|
|
zeus::CMatrix3f mat3f_704 = mat3f_220 * zeus::CMatrix3f(x290_);
|
|
zeus::CTransform transform_304(mat3f_704 /*, zeus::skZero3f*/);
|
|
zeus::CTransform transform_352(rot, x280_);
|
|
zeus::CTransform transform_752 = transform_352 * transform_304;
|
|
zeus::CTransform transform_400 = transform_752 * transform_184;
|
|
CGraphics::SetModelMatrix(transform_400);
|
|
|
|
zeus::CColor color = x29c_;
|
|
color.a() = x2a0_;
|
|
CModelFlags flags(5, 0, 0, color);
|
|
x3a4_orbitLockArm->Draw(flags);
|
|
}
|
|
}
|
|
|
|
if (x350_ > 0) {
|
|
for (int i = 0; i < 3; i++) {
|
|
zeus::CTransform transform_184(zeus::CMatrix3f(), x2a4_);
|
|
zeus::CMatrix3f mat3f_220 = zeus::CMatrix3f::RotateY(x28c_ + zeus::degToRad(120.f * i));
|
|
zeus::CMatrix3f mat3f_704 = mat3f_220 * zeus::CMatrix3f(x290_);
|
|
zeus::CTransform transform_304(mat3f_704 /*, zeus::skZero3f*/);
|
|
zeus::CTransform transform_352(rot, x2f2_);
|
|
zeus::CTransform transform_752 = transform_352 * transform_304;
|
|
zeus::CTransform transform_400 = transform_752 * transform_184;
|
|
CGraphics::SetModelMatrix(transform_400);
|
|
|
|
zeus::CColor color = g_tweakTargeting->x2d0_;
|
|
color.a() = x350_;
|
|
CModelFlags flags(5, 0, 0, color);
|
|
x3a4_orbitLockArm->Draw(flags);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCompoundTargetReticle::DrawNewGroup2(const zeus::CMatrix3f& rot, const CStateManager& mgr) const {
|
|
if (x2f0_ != kInvalidUniqueId && x304_ > 0) {
|
|
for (int i = 0; i < 3; i++) {
|
|
zeus::CTransform transform_192(zeus::CMatrix3f(), x2a4_);
|
|
zeus::CMatrix3f mat3f_228 = zeus::CMatrix3f::RotateY(zeus::degToRad(120.f * i));
|
|
zeus::CMatrix3f mat3f_1016 = mat3f_228 * zeus::CMatrix3f(x290_);
|
|
zeus::CTransform transform_360(rot, x2f2_);
|
|
zeus::CTransform transform_1064 = transform_360 * mat3f_1016;
|
|
zeus::CTransform transform_408 = transform_1064 * transform_192;
|
|
CGraphics::SetModelMatrix(transform_408);
|
|
|
|
zeus::CColor color = x300_;
|
|
color.a() = x304_;
|
|
CModelFlags flags(5, 0, 0, color);
|
|
x3a4_orbitLockArm->Draw(flags);
|
|
|
|
zeus::CTransform transform_496(mat3f_228 * zeus::CMatrix3f(x328_));
|
|
zeus::CTransform transform_544 = transform_360 * transform_496;
|
|
CGraphics::SetModelMatrix(transform_544);
|
|
|
|
zeus::CColor baseColor = x308_orbitLockBaseColor;
|
|
baseColor.a() = x30c_orbitLockBaseAlpha;
|
|
CModelFlags baseFlags(5, 0, 0, baseColor);
|
|
x3c8_orbitLockBase->Draw(baseFlags);
|
|
}
|
|
|
|
zeus::CTransform transform_644(zeus::CMatrix3f::RotateY(x338_) * zeus::CMatrix3f(x290_));
|
|
zeus::CTransform transform_712(rot, x2f2_);
|
|
CGraphics::SetModelMatrix(transform_712 * transform_644);
|
|
// thunk_FUN_802fe1e0(7,0,0,7,0); ??
|
|
|
|
zeus::CColor bracketsColor = x308_orbitLockBaseColor;
|
|
bracketsColor.a() = x334_;
|
|
CModelFlags bracketsFlags(5, 0, 0, bracketsColor);
|
|
x3bc_orbitLockBrackets->Draw(bracketsFlags);
|
|
|
|
if (x340_ > 0) {
|
|
zeus::CTransform transform_880(zeus::CMatrix3f::RotateY(x334_) * zeus::CMatrix3f(x290_));
|
|
zeus::CTransform transform_928(rot, x2f2_);
|
|
CGraphics::SetModelMatrix(transform_928 * transform_880);
|
|
// thunk_FUN_802fe1e0(7,0,0,7,0); ??
|
|
|
|
zeus::CColor techColor = x308_orbitLockBaseColor;
|
|
techColor.a() = x30c_orbitLockBaseAlpha;
|
|
CModelFlags techFlags(5, 0, 0, techColor);
|
|
x3b0_orbitLockTech->Draw(techFlags);
|
|
}
|
|
}
|
|
}
|
|
|
|
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(g_tweakTargeting->GetGrapplePointColor(), color, 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(rot * 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<CScriptGrapplePoint> 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<CScriptGrapplePoint> point0 = mgr.GetObjectById(x1dc_grapplePoint0);
|
|
TCastToConstPtr<CScriptGrapplePoint> 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;
|
|
if (x1e0_grapplePoint0T + x1e4_grapplePoint1T > 0 || x10c_currGroupInterp.GetFactor() == 0.f)
|
|
return;
|
|
|
|
float lockBreakAlpha = x10c_currGroupInterp.GetFactor();
|
|
float visorFactor = mgr.GetPlayerState()->GetVisorTransitionFactor();
|
|
bool lockConfirm = false;
|
|
bool lockReticule = false;
|
|
switch (x20_prevState) {
|
|
case EReticleState::Combat:
|
|
lockConfirm = true;
|
|
lockReticule = true;
|
|
break;
|
|
case EReticleState::Scan:
|
|
lockConfirm = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
zeus::CMatrix3f lockBreakXf;
|
|
zeus::CColor lockBreakColor = zeus::skClear;
|
|
if (IsDamageOrbit(mgr.GetPlayer().GetOrbitRequest()) && x14c_currGroupB.GetFactor() == 0.f) {
|
|
zeus::CMatrix3f lockBreakRM;
|
|
for (int i = 0; i < 4; ++i) {
|
|
int a = rand() % 9;
|
|
auto b = std::div(a, 3);
|
|
lockBreakRM[b.rem][b.quot] += rand() / float(RAND_MAX) - 0.5f;
|
|
}
|
|
lockBreakXf = lockBreakRM.transposed();
|
|
if (x10c_currGroupInterp.GetFactor() > 0.8f)
|
|
lockBreakColor = zeus::CColor(1.f, (x10c_currGroupInterp.GetFactor() - 0.8f) * 0.3f / 0.2f);
|
|
lockBreakAlpha = x10c_currGroupInterp.GetFactor() > 0.75f
|
|
? 1.f
|
|
: std::max(0.f, (x10c_currGroupInterp.GetFactor() - 0.55f) / 0.2f);
|
|
}
|
|
|
|
if (lockConfirm && x4c_lockConfirm.IsLoaded()) {
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetLockConfirmClampMin(),
|
|
g_tweakTargeting->GetLockConfirmClampMax(), mgr) *
|
|
g_tweakTargeting->GetLockConfirmScale() / x10c_currGroupInterp.GetFactor());
|
|
zeus::CTransform modelXf(lockBreakXf * (rot * zeus::CMatrix3f::RotateY(x1ec_seekerAngle) * scale),
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetLockConfirmColor();
|
|
color.a() *= lockBreakAlpha;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x4c_lockConfirm->Draw(flags);
|
|
}
|
|
|
|
if (lockReticule) {
|
|
if (x58_targetFlower.IsLoaded()) {
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetTargetFlowerClampMin(),
|
|
g_tweakTargeting->GetTargetFlowerClampMax(), mgr) *
|
|
g_tweakTargeting->GetTargetFlowerScale() / lockBreakAlpha);
|
|
zeus::CTransform modelXf(lockBreakXf * (rot * zeus::CMatrix3f::RotateY(x1f0_xrayRetAngle) * scale),
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetTargetFlowerColor();
|
|
color.a() *= lockBreakAlpha * visorFactor;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x58_targetFlower->Draw(flags);
|
|
}
|
|
if (x1f8_missileBracketTimer != 0.f && x64_missileBracket.IsLoaded()) {
|
|
float t = std::fabs((x1fc_missileBracketScaleTimer - 0.5f * g_tweakTargeting->GetMissileBracketScaleDuration()) /
|
|
0.5f * g_tweakTargeting->GetMissileBracketScaleDuration());
|
|
float tscale = ((1.f - t) * g_tweakTargeting->GetMissileBracketScaleEnd() +
|
|
t * g_tweakTargeting->GetMissileBracketScaleStart());
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetMissileBracketClampMin(),
|
|
g_tweakTargeting->GetMissileBracketClampMax(), mgr) *
|
|
std::fabs(x1f8_missileBracketTimer) / g_tweakTargeting->GetMissileBracketDuration() *
|
|
tscale / x10c_currGroupInterp.GetFactor());
|
|
for (int i = 0; i < 4; ++i) {
|
|
zeus::CTransform modelXf(
|
|
lockBreakXf * rot * zeus::CMatrix3f(zeus::CVector3f{i < 2 ? 1.f : -1.f, 1.f, i & 0x1 ? 1.f : -1.f}) * scale,
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetMissileBracketColor();
|
|
color.a() *= lockBreakAlpha * visorFactor;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x64_missileBracket->Draw(flags);
|
|
}
|
|
}
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetChargeGaugeClampMin(),
|
|
g_tweakTargeting->GetChargeGaugeClampMax(), mgr) *
|
|
1.f / x10c_currGroupInterp.GetFactor() * g_tweakTargeting->GetOuterBeamSquaresScale());
|
|
zeus::CMatrix3f outerBeamXf = rot * scale;
|
|
for (int i = 0; i < 9; ++i) {
|
|
const SOuterItemInfo& info = xe0_outerBeamIconSquares[i];
|
|
if (info.x0_model.IsLoaded()) {
|
|
zeus::CTransform modelXf(lockBreakXf * outerBeamXf * zeus::CMatrix3f::RotateY(info.x10_rotAng),
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetOuterBeamSquareColor();
|
|
color.a() *= lockBreakAlpha * visorFactor;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
info.x0_model->Draw(flags);
|
|
}
|
|
}
|
|
if (xc4_chargeGauge.x0_model.IsLoaded()) {
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetChargeGaugeClampMin(),
|
|
g_tweakTargeting->GetChargeGaugeClampMax(), mgr) *
|
|
g_tweakTargeting->GetChargeGaugeScale() / x10c_currGroupInterp.GetFactor());
|
|
zeus::CMatrix3f chargeGaugeXf = rot * scale * zeus::CMatrix3f::RotateY(xc4_chargeGauge.x10_rotAng);
|
|
float pulseT = std::fabs(std::fmod(CGraphics::GetSecondsMod900(), g_tweakTargeting->GetChargeGaugePulsePeriod()));
|
|
zeus::CColor gaugeColor =
|
|
zeus::CColor::lerp(g_tweakTargeting->GetChargeGaugeNonFullColor(),
|
|
zeus::CColor::lerp(g_tweakTargeting->GetChargeGaugePulseColorHigh(),
|
|
g_tweakTargeting->GetChargeGaugePulseColorLow(),
|
|
pulseT < 0.5f * g_tweakTargeting->GetChargeGaugePulsePeriod()
|
|
? pulseT / (0.5f * g_tweakTargeting->GetChargeGaugePulsePeriod())
|
|
: (g_tweakTargeting->GetChargeGaugePulsePeriod() - pulseT) /
|
|
(0.5f * g_tweakTargeting->GetChargeGaugePulsePeriod())),
|
|
x214_fullChargeFadeTimer / g_tweakTargeting->GetFullChargeFadeDuration());
|
|
zeus::CTransform modelXf(lockBreakXf * chargeGaugeXf, x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = gaugeColor;
|
|
color.a() *= lockBreakAlpha * visorFactor;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
xc4_chargeGauge.x0_model->Draw(flags);
|
|
|
|
if (xa0_chargeTickFirst.IsLoaded()) {
|
|
const CPlayerGun* gun = mgr.GetPlayer().GetPlayerGun();
|
|
int numTicks =
|
|
int(g_tweakTargeting->GetChargeTickCount() * (gun->IsCharging() ? gun->GetChargeBeamFactor() : 0.f));
|
|
for (int i = 0; i < numTicks; ++i) {
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
xa0_chargeTickFirst->Draw(flags);
|
|
modelXf.rotateLocalY(g_tweakTargeting->GetChargeTickAnglePitch());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
}
|
|
}
|
|
}
|
|
if (x208_lockonTimer > 0.f && x70_innerBeamIcon.IsLoaded()) {
|
|
const zeus::CColor* iconColor;
|
|
switch (x200_beam) {
|
|
case CPlayerState::EBeamId::Power:
|
|
iconColor = &g_tweakTargeting->GetInnerBeamColorPower();
|
|
break;
|
|
case CPlayerState::EBeamId::Ice:
|
|
iconColor = &g_tweakTargeting->GetInnerBeamColorIce();
|
|
break;
|
|
case CPlayerState::EBeamId::Wave:
|
|
iconColor = &g_tweakTargeting->GetInnerBeamColorWave();
|
|
break;
|
|
default:
|
|
iconColor = &g_tweakTargeting->GetInnerBeamColorPlasma();
|
|
break;
|
|
}
|
|
zeus::CMatrix3f scale(
|
|
CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(), x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetInnerBeamClampMin(),
|
|
g_tweakTargeting->GetInnerBeamClampMax(), mgr) *
|
|
g_tweakTargeting->GetInnerBeamScale() * (x208_lockonTimer / g_tweakTargeting->GetLockonDuration()) /
|
|
x10c_currGroupInterp.GetFactor());
|
|
zeus::CTransform modelXf(lockBreakXf * rot * scale, x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = *iconColor;
|
|
color.a() *= lockBreakAlpha * visorFactor;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x70_innerBeamIcon->Draw(flags);
|
|
}
|
|
if (x210_lockFireTimer > 0.f && x7c_lockFire.IsLoaded()) {
|
|
zeus::CMatrix3f scale(CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(),
|
|
x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetLockFireClampMin(),
|
|
g_tweakTargeting->GetLockFireClampMax(), mgr) *
|
|
g_tweakTargeting->GetLockFireScale() / x10c_currGroupInterp.GetFactor());
|
|
zeus::CTransform modelXf(lockBreakXf * rot * scale * zeus::CMatrix3f::RotateY(x1f0_xrayRetAngle),
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetLockFireColor();
|
|
color.a() *= visorFactor * lockBreakAlpha * (x210_lockFireTimer / g_tweakTargeting->GetLockFireDuration());
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x7c_lockFire->Draw(flags);
|
|
}
|
|
if (x208_lockonTimer > 0.f && x88_lockDagger.IsLoaded()) {
|
|
float t = std::fabs((x210_lockFireTimer - 0.5f * g_tweakTargeting->GetLockFireDuration()) / 0.5f *
|
|
g_tweakTargeting->GetLockFireDuration());
|
|
float tscale =
|
|
((1.f - t) * g_tweakTargeting->GetLockDaggerScaleEnd() + t * g_tweakTargeting->GetLockDaggerScaleStart());
|
|
zeus::CMatrix3f scale(
|
|
CalculateClampedScale(x10c_currGroupInterp.GetTargetPositionWorld(), x10c_currGroupInterp.GetRadiusWorld(),
|
|
x10c_currGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetLockDaggerClampMin(),
|
|
g_tweakTargeting->GetLockDaggerClampMax(), mgr) *
|
|
tscale * (x208_lockonTimer / g_tweakTargeting->GetLockonDuration()) / x10c_currGroupInterp.GetFactor());
|
|
zeus::CMatrix3f lockDaggerXf = rot * scale;
|
|
for (int i = 0; i < 3; ++i) {
|
|
float ang;
|
|
switch (i) {
|
|
case 0:
|
|
ang = g_tweakTargeting->GetLockDaggerAngle0();
|
|
break;
|
|
case 1:
|
|
ang = g_tweakTargeting->GetLockDaggerAngle1();
|
|
break;
|
|
default:
|
|
ang = g_tweakTargeting->GetLockDaggerAngle2();
|
|
break;
|
|
}
|
|
zeus::CTransform modelXf(lockBreakXf * lockDaggerXf * zeus::CMatrix3f::RotateY(ang),
|
|
x10c_currGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetLockDaggerColor();
|
|
color.a() *= visorFactor * lockBreakAlpha;
|
|
CModelFlags flags(7, 0, 0, lockBreakColor + color);
|
|
x88_lockDagger->Draw(flags);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCompoundTargetReticle::DrawNextLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const {
|
|
if (x28_noDrawTicks > 0)
|
|
return;
|
|
|
|
zeus::CVector3f position = x174_nextGroupInterp.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_nextGroupInterp.GetFactor() > 0.f && x40_seeker.IsLoaded()) {
|
|
zeus::CMatrix3f scale(
|
|
CalculateClampedScale(position, x174_nextGroupInterp.GetRadiusWorld(),
|
|
x174_nextGroupInterp.GetMinViewportClampScale() * g_tweakTargeting->GetSeekerClampMin(),
|
|
g_tweakTargeting->GetSeekerClampMax(), mgr) *
|
|
g_tweakTargeting->GetSeekerScale());
|
|
zeus::CTransform modelXf(rot * zeus::CMatrix3f::RotateY(x1ec_seekerAngle) * scale,
|
|
x174_nextGroupInterp.GetTargetPositionWorld());
|
|
CGraphics::SetModelMatrix(modelXf);
|
|
zeus::CColor color = g_tweakTargeting->GetSeekerColor();
|
|
color.a() *= x174_nextGroupInterp.GetFactor();
|
|
CModelFlags flags(7, 0, 0, color);
|
|
x40_seeker->Draw(flags);
|
|
}
|
|
|
|
if (xrayRet && xac_xrayRetRing.IsLoaded()) {
|
|
zeus::CMatrix3f scale(
|
|
CalculateClampedScale(position, x174_nextGroupInterp.GetRadiusWorld(),
|
|
x174_nextGroupInterp.GetMinViewportClampScale() * g_tweakTargeting->GetReticuleClampMin(),
|
|
g_tweakTargeting->GetReticuleClampMax(), mgr) *
|
|
g_tweakTargeting->GetReticuleScale());
|
|
zeus::CTransform modelXf(rot * scale * zeus::CMatrix3f::RotateY(x1f0_xrayRetAngle),
|
|
x174_nextGroupInterp.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(position, x174_nextGroupInterp.GetRadiusWorld(),
|
|
x174_nextGroupInterp.GetMinViewportClampScale() * g_tweakTargeting->GetReticuleClampMin(),
|
|
g_tweakTargeting->GetReticuleClampMax(), mgr) *
|
|
g_tweakTargeting->GetReticuleScale());
|
|
zeus::CTransform modelXf(rot * scale, x174_nextGroupInterp.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_nextGroupInterp.GetFactor();
|
|
zeus::CMatrix3f scale(CalculateClampedScale(position, x174_nextGroupInterp.GetRadiusWorld(),
|
|
x174_nextGroupInterp.GetMinViewportClampScale() *
|
|
g_tweakTargeting->GetScanTargetClampMin(),
|
|
g_tweakTargeting->GetScanTargetClampMax(), mgr) *
|
|
(1.f / factor));
|
|
zeus::CTransform modelXf(rot * scale, x174_nextGroupInterp.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<CActor>(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 {
|
|
const TCastToConstPtr<CScriptGrapplePoint>& ptr = TCastToConstPtr<CScriptGrapplePoint>(mgr.GetObjectById(uid));
|
|
return ptr.operator bool() && ptr->GetActive();
|
|
}
|
|
|
|
float CCompoundTargetReticle::CalculateClampedScale(const zeus::CVector3f& pos, float scale, float clampMin,
|
|
float clampMax, const CStateManager& mgr) {
|
|
const CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
|
|
mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
|
|
zeus::CVector3f viewPos = cam->GetTransform().transposeRotate(pos - cam->GetTransform().origin);
|
|
viewPos = zeus::CVector3f(viewPos.x(), viewPos.z(), -viewPos.y());
|
|
float realX = cam->GetPerspectiveMatrix().multiplyOneOverW(viewPos).x();
|
|
float offsetX = cam->GetPerspectiveMatrix().multiplyOneOverW(viewPos + zeus::CVector3f(scale, 0.f, 0.f)).x();
|
|
float unclampedX = (offsetX - realX) * 640;
|
|
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);
|
|
if (x38c_combatAimingCenter.IsLoaded())
|
|
x38c_combatAimingCenter->Touch(0);
|
|
if (x398_combatAimingArm.IsLoaded())
|
|
x398_combatAimingArm->Touch(0);
|
|
if (x3a4_orbitLockArm.IsLoaded())
|
|
x3a4_orbitLockArm->Touch(0);
|
|
if (x3b0_orbitLockTech.IsLoaded())
|
|
x3b0_orbitLockTech->Touch(0);
|
|
if (x3bc_orbitLockBrackets.IsLoaded())
|
|
x3bc_orbitLockBrackets->Touch(0);
|
|
if (x3c8_orbitLockBase.IsLoaded())
|
|
x3c8_orbitLockBase->Touch(0);
|
|
if (x3d4_offScreen.IsLoaded())
|
|
x3d4_offScreen->Touch(0);
|
|
if (x3e0_scanReticleRing.IsLoaded())
|
|
x3e0_scanReticleRing->Touch(0);
|
|
if (x3ec_scanReticleBracket.IsLoaded())
|
|
x3ec_scanReticleBracket->Touch(0);
|
|
if (x3f8_scanReticleProgress.IsLoaded())
|
|
x3f8_scanReticleProgress->Touch(0);
|
|
for (SOuterItemInfo& info : xe0_outerBeamIconSquares)
|
|
if (info.x0_model.IsLoaded())
|
|
info.x0_model->Touch(0);
|
|
}
|
|
|
|
} // namespace urde
|