Additional HUD work

This commit is contained in:
Jack Andersen 2017-04-08 10:40:36 -10:00
parent 4a8bae2351
commit e070844e8a
25 changed files with 1049 additions and 94 deletions

View File

@ -35,9 +35,21 @@ struct ITweakGui : ITweak
virtual float GetEnergyBarShadowSpeed() const=0;
virtual float GetEnergyBarDrainDelay() const=0;
virtual bool GetEnergyBarAlwaysResetDelay() const=0;
virtual float GetHudDamageLightSpotAngle() const=0;
virtual float GetDamageLightAngleC() const=0;
virtual float GetDamageLightAngleL() const=0;
virtual float GetDamageLightAngleQ() const=0;
virtual atVec3f GetDamageLightPreTranslate() const=0;
virtual atVec3f GetDamageLightCenterTranslate() const=0;
virtual float GetDamageLightXfXAngle() const=0;
virtual float GetDamageLightXfZAngle() const=0;
virtual atUint32 GetHudCamFovTweak() const=0;
virtual atUint32 GetHudCamYTweak() const=0;
virtual atUint32 GetHudCamZTweak() const=0;
virtual float GetBeamVisorMenuAnimTime() const=0;
virtual float GetVisorBeamMenuItemActiveScale() const=0;
virtual float GetVisorBeamMenuItemInactiveScale() const=0;
virtual float GetVisorBeamMenuItemTranslate() const=0;
virtual float GetMaxThreatEnergy() const=0;
virtual float GetRadarScopeCoordRadius() const=0;
virtual float GetRadarPlayerPaintRadius() const=0;
@ -50,6 +62,9 @@ struct ITweakGui : ITweak
virtual atUint32 GetEnablePlayerVisor() const=0;
virtual float GetThreatWarningFraction() const=0;
virtual float GetMissileWarningFraction() const=0;
virtual float GetFreeLookFadeTime() const=0;
virtual float GetFreeLookSfxPitchScale() const=0;
virtual bool GetNoAbsoluteFreeLookSfxPitch() const=0;
virtual float GetMissileWarningPulseTime() const=0;
virtual float GetScanAppearanceOffset() const=0;
virtual float GetBallViewportYReduction() const=0;

View File

@ -29,9 +29,16 @@ struct ITweakGuiColors : BigYAML
virtual zeus::CColor GetHudMessageOutline() const=0;
virtual zeus::CColor GetHudFrameColor() const=0;
virtual zeus::CColor GetMissileIconColorActive() const=0;
virtual zeus::CColor GetVisorBeamMenuItemActive() const=0;
virtual zeus::CColor GetVisorBeamMenuItemInactive() const=0;
virtual zeus::CColor GetEnergyBarFilledLowEnergy() const=0;
virtual zeus::CColor GetEnergyBarShadowLowEnergy() const=0;
virtual zeus::CColor GetEnergyBarEmptyLowEnergy() const=0;
virtual zeus::CColor GetHudDamageLightColor() const=0;
virtual zeus::CColor GetVisorMenuTextFont() const=0;
virtual zeus::CColor GetVisorMenuTextOutline() const=0;
virtual zeus::CColor GetBeamMenuTextFont() const=0;
virtual zeus::CColor GetBeamMenuTextOutline() const=0;
virtual zeus::CColor GetEnergyWarningFont() const=0;
virtual zeus::CColor GetThreatWarningFont() const=0;
virtual zeus::CColor GetMissileWarningFont() const=0;
@ -49,6 +56,7 @@ struct ITweakGuiColors : BigYAML
virtual zeus::CColor GetMissileIconColorChargedCanAlt() const=0;
virtual zeus::CColor GetMissileIconColorChargedNoAlt() const=0;
virtual zeus::CColor GetMissileIconColorDepleteAlt() const=0;
virtual zeus::CColor GetVisorBeamMenuLozColor() const=0;
virtual zeus::CColor GetEnergyWarningOutline() const=0;
virtual zeus::CColor GetThreatWarningOutline() const=0;
virtual zeus::CColor GetMissileWarningOutline() const=0;

View File

@ -30,14 +30,14 @@ struct CTweakGui : ITweakGui
Value<float> x48_;
Value<float> x4c_;
Value<float> x50_;
Value<float> x54_;
Value<float> x58_;
Value<float> x5c_;
Value<float> x60_;
Value<atVec3f> x64_;
Value<atVec3f> x70_;
Value<float> x7c_;
Value<float> x80_;
Value<float> x54_hudDamageLightSpotAngle;
Value<float> x58_damageLightAngleC;
Value<float> x5c_damageLightAngleL;
Value<float> x60_damageLightAngleQ;
Value<atVec3f> x64_damageLightPreTranslate;
Value<atVec3f> x70_damageLightCenterTranslate;
Value<float> x7c_damageLightXfXAngle;
Value<float> x80_damageLightXfZAngle;
Value<float> x84_;
Value<float> x88_;
Value<float> x8c_;
@ -53,10 +53,10 @@ struct CTweakGui : ITweakGui
Value<float> xb4_;
Value<float> xb8_;
Value<float> xbc_;
Value<float> xc0_;
Value<float> xc4_;
Value<float> xc8_;
Value<float> xcc_;
Value<float> xc0_beamVisorMenuAnimTime;
Value<float> xc4_visorBeamMenuItemActiveScale;
Value<float> xc8_visorBeamMenuItemInactiveScale;
Value<float> xcc_visorBeamMenuItemTranslate;
Value<float> xd0_;
Value<atUint32> xd4_;
Value<float> xd8_;
@ -75,13 +75,13 @@ struct CTweakGui : ITweakGui
Value<atUint32> x10c_enablePlayerVisor;
Value<float> x110_threatWarningFraction;
Value<float> x114_missileWarningFraction;
Value<float> x118_;
Value<float> x118_freeLookFadeTime;
Value<float> x11c_;
Value<float> x120_;
Value<float> x124_;
Value<float> x128_;
Value<float> x12c_;
Value<bool> x130_;
Value<float> x12c_freeLookSfxPitchScale;
Value<bool> x130_noAbsoluteFreeLookSfxPitch;
Value<float> x134_;
Value<float> x138_;
Value<atUint32> x13c_;
@ -203,9 +203,21 @@ struct CTweakGui : ITweakGui
float GetEnergyBarShadowSpeed() const { return x38_energyBarShadowSpeed; }
float GetEnergyBarDrainDelay() const { return x3c_energyBarDrainDelay; }
bool GetEnergyBarAlwaysResetDelay() const { return x40_energyBarAlwaysResetDelay; }
float GetHudDamageLightSpotAngle() const { return x54_hudDamageLightSpotAngle; }
float GetDamageLightAngleC() const { return x58_damageLightAngleC; }
float GetDamageLightAngleL() const { return x5c_damageLightAngleL; }
float GetDamageLightAngleQ() const { return x60_damageLightAngleQ; }
atVec3f GetDamageLightPreTranslate() const { return x64_damageLightPreTranslate; }
atVec3f GetDamageLightCenterTranslate() const { return x70_damageLightCenterTranslate; }
float GetDamageLightXfXAngle() const { return x7c_damageLightXfXAngle; }
float GetDamageLightXfZAngle() const { return x80_damageLightXfZAngle; }
atUint32 GetHudCamFovTweak() const { return xa8_hudCamFovTweak; }
atUint32 GetHudCamYTweak() const { return xac_hudCamYTweak; }
atUint32 GetHudCamZTweak() const { return xb0_hudCamZTweak; }
float GetBeamVisorMenuAnimTime() const { return xc0_beamVisorMenuAnimTime; }
float GetVisorBeamMenuItemActiveScale() const { return xc4_visorBeamMenuItemActiveScale; }
float GetVisorBeamMenuItemInactiveScale() const { return xc8_visorBeamMenuItemInactiveScale; }
float GetVisorBeamMenuItemTranslate() const { return xcc_visorBeamMenuItemTranslate; }
float GetMaxThreatEnergy() const { return xe4_maxThreatEnergy; }
float GetRadarScopeCoordRadius() const { return xe8_radarScopeCoordRadius; }
float GetRadarPlayerPaintRadius() const { return xec_radarPlayerPaintRadius; }
@ -218,6 +230,9 @@ struct CTweakGui : ITweakGui
atUint32 GetEnablePlayerVisor() const { return x10c_enablePlayerVisor; }
float GetThreatWarningFraction() const { return x110_threatWarningFraction; }
float GetMissileWarningFraction() const { return x114_missileWarningFraction; }
float GetFreeLookFadeTime() const { return x118_freeLookFadeTime; }
float GetFreeLookSfxPitchScale() const { return x12c_freeLookSfxPitchScale; }
bool GetNoAbsoluteFreeLookSfxPitch() const { return x130_noAbsoluteFreeLookSfxPitch; }
float GetMissileWarningPulseTime() const { return x1a0_missileWarningPulseTime; }
float GetScanAppearanceOffset() const { return x244_scanAppearanceOffset; }
float GetBallViewportYReduction() const { return x254_ballViewportYReduction; }

View File

@ -20,18 +20,18 @@ struct CTweakGuiColors : public ITweakGuiColors
DNAColor x20_;
DNAColor x24_;
DNAColor x28_missileIconColorActive;
DNAColor x2c_;
DNAColor x30_;
DNAColor x2c_visorBeamMenuItemActive;
DNAColor x30_visorBeamMenuColorInactive;
DNAColor x34_energyBarFilledLowEnergy;
DNAColor x38_energyBarShadowLowEnergy;
DNAColor x3c_energyBarEmptyLowEnergy;
DNAColor x40_;
DNAColor x40_hudDamageLightColor;
DNAColor x44_;
DNAColor x48_;
DNAColor x4c_;
DNAColor x50_;
DNAColor x54_;
DNAColor x58_;
DNAColor x4c_visorMenuTextFont;
DNAColor x50_visorMenuTextOutline;
DNAColor x54_beamMenuTextFont;
DNAColor x58_beamMenuTextOutline;
DNAColor x5c_energyWarningFont;
DNAColor x60_threatWarningFont;
DNAColor x64_missileWarningFont;
@ -53,7 +53,7 @@ struct CTweakGuiColors : public ITweakGuiColors
DNAColor xa4_;
DNAColor xa8_;
DNAColor xac_;
DNAColor xb0_;
DNAColor xb0_visorBeamMenuLozColor;
DNAColor xb4_energyWarningOutline;
DNAColor xb8_threatWarningOutline;
DNAColor xbc_missileWarningOutline;
@ -147,9 +147,16 @@ struct CTweakGuiColors : public ITweakGuiColors
zeus::CColor GetHudMessageOutline() const { return x18_hudMessageOutline; }
zeus::CColor GetHudFrameColor() const { return x1c_hudFrameColor; }
zeus::CColor GetMissileIconColorActive() const { return x28_missileIconColorActive; }
zeus::CColor GetVisorBeamMenuItemActive() const { return x2c_visorBeamMenuItemActive; }
zeus::CColor GetVisorBeamMenuItemInactive() const { return x30_visorBeamMenuColorInactive; }
zeus::CColor GetEnergyBarFilledLowEnergy() const { return x34_energyBarFilledLowEnergy; }
zeus::CColor GetEnergyBarShadowLowEnergy() const { return x38_energyBarShadowLowEnergy; }
zeus::CColor GetEnergyBarEmptyLowEnergy() const { return x3c_energyBarEmptyLowEnergy; }
zeus::CColor GetHudDamageLightColor() const { return x40_hudDamageLightColor; }
zeus::CColor GetVisorMenuTextFont() const { return x4c_visorMenuTextFont; }
zeus::CColor GetVisorMenuTextOutline() const { return x50_visorMenuTextOutline; }
zeus::CColor GetBeamMenuTextFont() const { return x54_beamMenuTextFont; }
zeus::CColor GetBeamMenuTextOutline() const { return x58_beamMenuTextOutline; }
zeus::CColor GetEnergyWarningFont() const { return x5c_energyWarningFont; }
zeus::CColor GetThreatWarningFont() const { return x60_threatWarningFont; }
zeus::CColor GetMissileWarningFont() const { return x64_missileWarningFont; }
@ -167,6 +174,7 @@ struct CTweakGuiColors : public ITweakGuiColors
zeus::CColor GetMissileIconColorChargedCanAlt() const { return x98_missileIconColorChargedCanAlt; }
zeus::CColor GetMissileIconColorChargedNoAlt() const { return x9c_missileIconColorChargedNoAlt; }
zeus::CColor GetMissileIconColorDepleteAlt() const { return xa0_missileIconColorDepleteAlt; }
zeus::CColor GetVisorBeamMenuLozColor() const { return xb0_visorBeamMenuLozColor; }
zeus::CColor GetEnergyWarningOutline() const { return xb4_energyWarningOutline; }
zeus::CColor GetThreatWarningOutline() const { return xb8_threatWarningOutline; }
zeus::CColor GetMissileWarningOutline() const { return xbc_missileWarningOutline; }

View File

@ -305,6 +305,17 @@ float CSfxManager::GetReverbAmount()
return m_reverbAmount;
}
void CSfxManager::PitchBend(const CSfxHandle& handle, float pitch)
{
if (!handle->IsPlaying())
CSfxManager::Update(0.f);
if (handle->IsPlaying())
{
m_doUpdate = true;
handle->GetVoice()->setPitchWheel(pitch);
}
}
u16 CSfxManager::TranslateSFXID(u16 id)
{
if (mpSfxTranslationTable == nullptr)

View File

@ -196,7 +196,7 @@ public:
static void ApplyReverb();
static float GetReverbAmount();
static void RemoveEmitter(const CSfxHandle&) {}
static void PitchBend(const CSfxHandle&, s32) {}
static void PitchBend(const CSfxHandle& handle, float pitch);
static u16 TranslateSFXID(u16);
static void SfxStop(const CSfxHandle& handle);
static CSfxHandle SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId);

View File

@ -448,6 +448,9 @@ public:
u32 GetParticleFlags() const { return xf34_particleFlags; }
const CFinalInput& GetFinalInput() const { return xb54_finalInput; }
void SetBossParams(TUniqueId bossId, float maxEnergy, u32 stringIdx);
TUniqueId GetBossId() const { return xf18_bossId; }
float GetTotalBossEnergy() const { return xf1c_totalBossEnergy; }
u32 GetBossStringIdx() const { return xf20_bossStringIdx; }
static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit;

View File

@ -6,15 +6,15 @@ namespace urde
CGuiLight::CGuiLight(const CGuiWidgetParms& parms, const CLight& light)
: CGuiWidget(parms),
xf8_type(light.x1c_type),
xfc_spotCutoff(light.x20_spotCutoff),
x100_distC(light.x24_distC),
x104_distL(light.x28_distL),
x108_distQ(light.x2c_distQ),
x10c_angleC(light.x30_angleC),
x110_angleL(light.x34_angleL),
x114_angleQ(light.x38_angleQ),
x118_loadedIdx(light.x40_loadedIdx)
xb8_type(light.x1c_type),
xbc_spotCutoff(light.x20_spotCutoff),
xc0_distC(light.x24_distC),
xc4_distL(light.x28_distL),
xc8_distQ(light.x2c_distQ),
xcc_angleC(light.x30_angleC),
xd0_angleL(light.x34_angleL),
xd4_angleQ(light.x38_angleQ),
xd8_loadedIdx(light.x40_loadedIdx)
{}
CGuiLight::~CGuiLight()
@ -26,10 +26,10 @@ CLight CGuiLight::BuildLight() const
{
CLight ret = CLight::BuildLocalAmbient(zeus::CVector3f::skZero, zeus::CColor::skBlack);
switch (xf8_type)
switch (xb8_type)
{
case ELightType::Spot:
ret = CLight::BuildSpot(GetWorldPosition(), x34_worldXF.basis[1], xa4_color, xfc_spotCutoff);
ret = CLight::BuildSpot(GetWorldPosition(), x34_worldXF.basis[1], xa4_color, xbc_spotCutoff);
break;
case ELightType::Point:
ret = CLight::BuildPoint(GetWorldPosition(), xa4_color);
@ -40,8 +40,8 @@ CLight CGuiLight::BuildLight() const
default: break;
}
ret.SetAttenuation(x100_distC, x104_distL, x108_distQ);
ret.SetAngleAttenuation(x10c_angleC, x110_angleL, x114_angleQ);
ret.SetAttenuation(xc0_distC, xc4_distL, xc8_distQ);
ret.SetAngleAttenuation(xcc_angleC, xd0_angleL, xd4_angleQ);
return ret;
}

View File

@ -10,16 +10,16 @@ class CSimplePool;
class CGuiLight : public CGuiWidget
{
ELightType xf8_type;
float xfc_spotCutoff;
float x100_distC;
float x104_distL;
float x108_distQ;
float x10c_angleC;
float x110_angleL;
float x114_angleQ;
u32 x118_loadedIdx;
zeus::CColor x11c_color = zeus::CColor::skBlack;
ELightType xb8_type;
float xbc_spotCutoff;
float xc0_distC;
float xc4_distL;
float xc8_distQ;
float xcc_angleC;
float xd0_angleL;
float xd4_angleQ;
u32 xd8_loadedIdx;
zeus::CColor xdc_color = zeus::CColor::skBlack;
public:
~CGuiLight();
CGuiLight(const CGuiWidgetParms& parms, const CLight& light);
@ -27,8 +27,17 @@ public:
CLight BuildLight() const;
void SetIsVisible(bool vis);
u32 GetLoadedIdx() const {return x118_loadedIdx;}
const zeus::CColor& GetColor() const {return x11c_color;}
u32 GetLoadedIdx() const {return xd8_loadedIdx;}
const zeus::CColor& GetColor() const {return xdc_color;}
void SetSpotCutoff(float v) {xbc_spotCutoff = v;}
void SetDistC(float v) {xc0_distC = v;}
void SetDistL(float v) {xc4_distL = v;}
void SetDistQ(float v) {xc8_distQ = v;}
void SetAngleC(float v) {xcc_angleC = v;}
void SetAngleL(float v) {xd0_angleL = v;}
void SetAngleQ(float v) {xd4_angleQ = v;}
void SetLoadedIdx(u32 idx) {xd8_loadedIdx = idx;}
void SetColor(const zeus::CColor& color) {xdc_color = color;}
static std::shared_ptr<CGuiWidget> Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp);

View File

@ -9,9 +9,9 @@
namespace urde
{
CHudBallInterface::CHudBallInterface(CGuiFrame& selHud, int bombAmount, int bombCapacity,
CHudBallInterface::CHudBallInterface(CGuiFrame& selHud, int pbAmount, int pbCapacity,
int availableBombs, bool hasBombs, bool hasPb)
: x40_bombAmount(bombAmount), x44_bombCapacity(bombCapacity),
: x40_pbAmount(pbAmount), x44_pbCapacity(pbCapacity),
x48_availableBombs(availableBombs), x4c_hasPb(hasPb)
{
x0_camera = selHud.GetFrameCamera();
@ -35,19 +35,19 @@ CHudBallInterface::CHudBallInterface(CGuiFrame& selHud, int bombAmount, int bomb
x34_camPos = x0_camera->GetLocalPosition();
if (CGuiWidget* w = selHud.FindWidget("basewidget_energydeco"))
w->SetColor(g_tweakGuiColors->GetBallBombEnergyColor());
SetBombParams(bombAmount, bombCapacity, availableBombs, hasBombs, hasPb, true);
SetBombParams(pbAmount, pbCapacity, availableBombs, hasBombs, hasPb, true);
}
void CHudBallInterface::UpdatePowerBombReadoutColors()
{
zeus::CColor fontColor;
zeus::CColor outlineColor;
if (x40_bombAmount > 0)
if (x40_pbAmount > 0)
{
fontColor = g_tweakGuiColors->GetPowerBombDigitAvailableFont();
outlineColor = g_tweakGuiColors->GetPowerBombDigitAvailableOutline();
}
else if (x44_bombCapacity > 0)
else if (x44_pbCapacity > 0)
{
fontColor = g_tweakGuiColors->GetPowerBombDigitDelpetedFont();
outlineColor = g_tweakGuiColors->GetPowerBombDigitDelpetedOutline();
@ -61,9 +61,9 @@ void CHudBallInterface::UpdatePowerBombReadoutColors()
x10_textpane_bombdigits->TextSupport()->SetOutlineColor(outlineColor);
zeus::CColor iconColor;
if (x40_bombAmount > 0 && x4c_hasPb)
if (x40_pbAmount > 0 && x4c_hasPb)
iconColor = g_tweakGuiColors->GetPowerBombIconAvailableColor();
else if (x44_bombCapacity > 0)
else if (x44_pbCapacity > 0)
iconColor = g_tweakGuiColors->GetPowerBombIconDepletedColor();
else
iconColor = zeus::CColor::skClear;
@ -71,19 +71,19 @@ void CHudBallInterface::UpdatePowerBombReadoutColors()
xc_model_bombicon->SetColor(iconColor);
}
void CHudBallInterface::SetBombParams(int bombAmount, int bombCapacity, int availableBombs,
void CHudBallInterface::SetBombParams(int pbAmount, int pbCapacity, int availableBombs,
bool hasBombs, bool hasPb, bool init)
{
if (bombAmount != x40_bombAmount || init)
if (pbAmount != x40_pbAmount || init)
{
x10_textpane_bombdigits->TextSupport()->SetText(hecl::Format("%02d", bombAmount));
x40_bombAmount = bombAmount;
x10_textpane_bombdigits->TextSupport()->SetText(hecl::Format("%02d", pbAmount));
x40_pbAmount = pbAmount;
UpdatePowerBombReadoutColors();
}
if (x44_bombCapacity != bombCapacity || init)
if (x44_pbCapacity != pbCapacity || init)
{
x44_bombCapacity = bombCapacity;
x44_pbCapacity = pbCapacity;
UpdatePowerBombReadoutColors();
}
@ -102,7 +102,7 @@ void CHudBallInterface::SetBombParams(int bombAmount, int bombCapacity, int avai
x48_availableBombs = availableBombs;
x8_basewidget_bombdeco->SetVisibility(hasBombs && x44_bombCapacity > 0, ETraversalMode::Children);
x8_basewidget_bombdeco->SetVisibility(hasBombs && x44_pbCapacity > 0, ETraversalMode::Children);
}
void CHudBallInterface::SetBallModeFactor(float t)

View File

@ -22,15 +22,15 @@ class CHudBallInterface
rstl::reserved_vector<CGuiWidget*, 3> x14_group_bombfilled;
rstl::reserved_vector<CGuiWidget*, 3> x24_group_bombempty;
zeus::CVector3f x34_camPos;
int x40_bombAmount;
int x44_bombCapacity;
int x40_pbAmount;
int x44_pbCapacity;
int x48_availableBombs;
bool x4c_hasPb;
void UpdatePowerBombReadoutColors();
public:
CHudBallInterface(CGuiFrame& selHud, int bombAmount, int bombCapacity,
CHudBallInterface(CGuiFrame& selHud, int pbAmount, int pbCapacity,
int availableBombs, bool hasBombs, bool hasPb);
void SetBombParams(int bombAmount, int bombCapacity, int availableBombs,
void SetBombParams(int pbAmount, int pbCapacity, int availableBombs,
bool hasBombs, bool hasPb, bool init);
void SetBallModeFactor(float t);
};

View File

@ -13,6 +13,13 @@
namespace urde
{
void IHudDecoInterface::SetReticuleTransform(const zeus::CMatrix3f& xf) {}
void IHudDecoInterface::SetDecoRotation(float angle) {}
void IHudDecoInterface::SetFrameColorValue(float v) {}
void IHudDecoInterface::Draw() const {}
void IHudDecoInterface::ProcessInput(const CFinalInput& input) {}
float IHudDecoInterface::GetHudTextAlpha() const { return 1.f; }
CHudDecoInterfaceCombat::CHudDecoInterfaceCombat(CGuiFrame& selHud)
{
x68_24_visDebug = true;

View File

@ -25,16 +25,16 @@ public:
virtual void SetIsVisibleGame(bool v)=0;
virtual void SetHudRotation(const zeus::CQuaternion& rot)=0;
virtual void SetHudOffset(const zeus::CVector3f& off)=0;
virtual void SetReticuleTransform(const zeus::CMatrix3f& xf) {}
virtual void SetDecoRotation(float angle) {}
virtual void SetReticuleTransform(const zeus::CMatrix3f& xf);
virtual void SetDecoRotation(float angle);
virtual void SetDamageTransform(const zeus::CMatrix3f& rotation, const zeus::CVector3f& position)=0;
virtual void SetFrameColorValue(float v);
virtual void Update(float dt, const CStateManager& stateMgr)=0;
virtual void Draw() const {}
virtual void ProcessInput(const CFinalInput& input) {}
virtual void Draw() const;
virtual void ProcessInput(const CFinalInput& input);
virtual void UpdateCameraDebugSettings(float fov, float y, float z)=0;
virtual void UpdateHudAlpha()=0;
virtual float GetHudTextAlpha() const { return 1.f; }
virtual float GetHudTextAlpha() const;
virtual ~IHudDecoInterface() = default;
};

View File

@ -1,60 +1,172 @@
#include "CHudFreeLookInterface.hpp"
#include "CGuiFrame.hpp"
#include "CGuiModel.hpp"
#include "GameGlobalObjects.hpp"
namespace urde
{
CHudFreeLookInterface::CHudFreeLookInterface(CGuiFrame& selHud, EHudType hudType, bool inFreeLook,
bool lookControlHeld, bool lockedOnObj)
: x4_hudType(hudType)
{
x70_24_inFreeLook = inFreeLook;
x70_25_lookControlHeld = lookControlHeld;
x70_26_lockedOnObj = lockedOnObj;
x70_27_visibleDebug = true;
x70_28_visibleGame = true;
x6c_lockOnInterp = (lockedOnObj && hudType == EHudType::Scan) ? 0.f : 1.f;
x74_basewidget_freelookleft = selHud.FindWidget("basewidget_freelookleft");
x78_model_shieldleft = static_cast<CGuiModel*>(selHud.FindWidget("model_shieldleft"));
x7c_model_freelookleft = static_cast<CGuiModel*>(selHud.FindWidget("model_freelookleft"));
x80_basewidget_freelookright = selHud.FindWidget("basewidget_freelookright");
x84_model_shieldright = static_cast<CGuiModel*>(selHud.FindWidget("model_shieldright"));
x88_model_freelookright = static_cast<CGuiModel*>(selHud.FindWidget("model_freelookright"));
x8c_basewidget_outlinesb = selHud.FindWidget("basewidget_outlinesb");
x8_freeLookLeftXf = x7c_model_freelookleft->GetTransform();
x38_freeLookRightXf = x88_model_freelookright->GetTransform();
x78_model_shieldleft->SetDepthWrite(true);
x84_model_shieldright->SetDepthWrite(true);
}
void CHudFreeLookInterface::Update(float dt)
{
if (x70_24_inFreeLook)
x68_freeLookInterp = std::min(x68_freeLookInterp + dt / g_tweakGui->GetFreeLookFadeTime(), 1.f);
else
x68_freeLookInterp = std::max(0.f, x68_freeLookInterp - dt / g_tweakGui->GetFreeLookFadeTime());
if (x70_26_lockedOnObj && x4_hudType == EHudType::Scan)
x6c_lockOnInterp = std::min(x6c_lockOnInterp + 2.f * dt, 1.f);
else
x6c_lockOnInterp = std::max(0.f, x6c_lockOnInterp - 2.f * dt);
}
void CHudFreeLookInterface::SetIsVisibleDebug(bool v)
{
x70_27_visibleDebug = v;
UpdateVisibility();
}
void CHudFreeLookInterface::SetIsVisibleGame(bool v)
{
x70_28_visibleGame = v;
UpdateVisibility();
}
void CHudFreeLookInterface::UpdateVisibility()
{
bool vis = x70_27_visibleDebug && x70_28_visibleGame;
x74_basewidget_freelookleft->SetVisibility(vis, ETraversalMode::Children);
x80_basewidget_freelookright->SetVisibility(vis, ETraversalMode::Children);
if (vis)
Update(0.f);
}
void CHudFreeLookInterface::SetFreeLookState(bool inFreeLook, bool lookControlHeld,
bool lockedOnObj, float vertLookAngle)
{
x70_24_inFreeLook = inFreeLook;
vertLookAngle *= 8.f;
x70_25_lookControlHeld = lookControlHeld;
x70_26_lockedOnObj = lockedOnObj;
x7c_model_freelookleft->SetLocalTransform(
x8_freeLookLeftXf * zeus::CTransform::Translate(0.f, 0.f, vertLookAngle));
x88_model_freelookright->SetLocalTransform(
x38_freeLookRightXf * zeus::CTransform::Translate(0.f, 0.f, vertLookAngle));
zeus::CColor color = zeus::CColor::skWhite;
float totalInterp = x68_freeLookInterp * (1.f - x6c_lockOnInterp);
color.a = totalInterp;
x74_basewidget_freelookleft->SetColor(color);
x80_basewidget_freelookright->SetColor(color);
if (x8c_basewidget_outlinesb)
{
color.a = 0.7f * totalInterp + 0.3f;
x8c_basewidget_outlinesb->SetColor(color);
}
if (totalInterp == 0.f)
{
x74_basewidget_freelookleft->SetVisibility(false, ETraversalMode::Children);
x80_basewidget_freelookright->SetVisibility(false, ETraversalMode::Children);
}
else
{
x74_basewidget_freelookleft->SetVisibility(true, ETraversalMode::Children);
x80_basewidget_freelookright->SetVisibility(true, ETraversalMode::Children);
}
}
CHudFreeLookInterfaceXRay::CHudFreeLookInterfaceXRay(CGuiFrame& selHud, bool inFreeLook,
bool lookControlHeld, bool lockedOnObj)
{
x20_inFreeLook = inFreeLook;
x21_lookControlHeld = lookControlHeld;
x22_24_visibleDebug = true;
x22_25_visibleGame = true;
x24_basewidget_freelook = selHud.FindWidget("basewidget_freelook");
x28_model_shield = static_cast<CGuiModel*>(selHud.FindWidget("model_shield"));
x2c_model_freelookleft = static_cast<CGuiModel*>(selHud.FindWidget("model_freelookleft"));
x30_model_freelookright = static_cast<CGuiModel*>(selHud.FindWidget("model_freelookright"));
x4_freeLookLeftPos = x2c_model_freelookleft->GetLocalPosition();
x10_freeLookRightPos = x30_model_freelookright->GetLocalPosition();
x28_model_shield->SetDepthWrite(true);
}
void CHudFreeLookInterfaceXRay::Update(float dt)
{
if (x20_inFreeLook)
x1c_freeLookInterp = std::min(x1c_freeLookInterp + dt / g_tweakGui->GetFreeLookFadeTime(), 1.f);
else
x1c_freeLookInterp = std::max(0.f, x1c_freeLookInterp - dt / g_tweakGui->GetFreeLookFadeTime());
}
void CHudFreeLookInterfaceXRay::UpdateVisibility()
{
bool vis = x22_24_visibleDebug && x22_25_visibleGame;
x2c_model_freelookleft->SetVisibility(vis, ETraversalMode::Children);
x30_model_freelookright->SetVisibility(vis, ETraversalMode::Children);
if (vis)
Update(0.f);
}
void CHudFreeLookInterfaceXRay::SetIsVisibleDebug(bool v)
{
x22_24_visibleDebug = v;
UpdateVisibility();
}
void CHudFreeLookInterfaceXRay::SetIsVisibleGame(bool v)
{
x22_25_visibleGame = v;
UpdateVisibility();
}
void CHudFreeLookInterfaceXRay::SetFreeLookState(bool inFreeLook, bool lookControlHeld,
bool lockedOnObj, float vertLookAngle)
{
x2c_model_freelookleft->SetLocalTransform(
zeus::CTransform(zeus::CMatrix3f::RotateY(vertLookAngle), x4_freeLookLeftPos));
x30_model_freelookright->SetLocalTransform(
zeus::CTransform(zeus::CMatrix3f::RotateY(-vertLookAngle), x10_freeLookRightPos));
zeus::CColor color = zeus::CColor::skWhite;
color.a = x1c_freeLookInterp;
x24_basewidget_freelook->SetColor(color);
if (x1c_freeLookInterp == 0.f)
x24_basewidget_freelook->SetVisibility(false, ETraversalMode::Children);
else
x24_basewidget_freelook->SetVisibility(true, ETraversalMode::Children);
}
}

View File

@ -66,8 +66,8 @@ class CHudFreeLookInterfaceXRay : public IFreeLookInterface
float x1c_freeLookInterp = 0.f;
bool x20_inFreeLook;
bool x21_lookControlHeld;
bool x22_24_inFreeLook : 1;
bool x22_25_lookControlHeld : 1;
bool x22_24_visibleDebug : 1;
bool x22_25_visibleGame : 1;
CGuiWidget* x24_basewidget_freelook;
CGuiModel* x28_model_shield;
CGuiModel* x2c_model_freelookleft;

View File

@ -79,7 +79,7 @@ void CHudRadarInterface::Update(float dt, const CStateManager& mgr)
float visorTransFactor = (playerState.GetCurrentVisor() == CPlayerState::EPlayerVisor::Combat) ?
playerState.GetVisorTransitionFactor() : 0.f;
zeus::CColor color = g_tweakGuiColors->GetRadarStuffColor();
color.a *= g_GameState->GameOptions().GetHUDAlpha() * visorTransFactor;
color.a *= g_GameState->GameOptions().GetHUDAlpha() / 255.f * visorTransFactor;
x40_BaseWidget_RadarStuff->SetColor(color);
bool tweakVis = g_tweakGui->GetHudVisMode() >= ITweakGui::EHudVisMode::Three;
if (tweakVis != x3c_25_visibleDebug)
@ -92,7 +92,7 @@ void CHudRadarInterface::Update(float dt, const CStateManager& mgr)
void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) const
{
alpha *= g_GameState->GameOptions().GetHUDAlpha();
alpha *= g_GameState->GameOptions().GetHUDAlpha() / 255.f;
if (g_tweakGui->GetHudVisMode() == ITweakGui::EHudVisMode::Zero || !x3c_24_visibleGame ||
!x0_txtrRadarPaint || !x0_txtrRadarPaint.IsLoaded())
return;

View File

@ -1,22 +1,339 @@
#include "CHudVisorBeamMenu.hpp"
#include "GameGlobalObjects.hpp"
#include "CGameState.hpp"
#include "CGuiFrame.hpp"
#include "CGuiModel.hpp"
#include "CGuiTextPane.hpp"
#include "CStringTable.hpp"
#include "Audio/CSfxManager.hpp"
namespace urde
{
CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame* baseHud, EHudVisorBeamMenu type,
rstl::prereserved_vector<bool, 4> enables)
static const char* BaseMenuNames[] =
{
"BaseWidget_VisorMenu",
"BaseWidget_BeamMenu"
};
static const char* TextNames[] =
{
"TextPane_VisorMenu",
"TextPane_BeamMenu"
};
static const char* BaseTitleNames[] =
{
"basewidget_visormenutitle",
"basewidget_beammenutitle"
};
static const char* ModelNames[] =
{
"model_visor",
"model_beam"
};
static const char MenuItemOrders[2][4] =
{
{'1', '0', '3', '2'},
{'3', '2', '1', '0'}
};
static const int MenuStringIdx[2][4] =
{
{0, 2, 1, 3}, // Combat, XRay, Scan, Thermal
{4, 5, 6, 7} // Power, Ice, Wave, Plasma
};
static const u16 SelectionSfxs[] =
{
1395, 1398
};
CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
const rstl::prereserved_vector<bool, 4>& enables)
: x0_baseHud(baseHud), x4_type(type)
{
x14_24_visibleDebug = true;
x14_25_visibleGame = true;
x14_26_dirty = true;
x7c_animDur = g_tweakGui->GetBeamVisorMenuAnimTime();
x80_24_swapBeamControls = g_GameState->GameOptions().GetSwapBeamControls();
EHudVisorBeamMenu swappedType;
if (x80_24_swapBeamControls)
swappedType = EHudVisorBeamMenu(1 - int(x4_type));
else
swappedType = x4_type;
x20_textpane_menu = static_cast<CGuiTextPane*>(x0_baseHud.FindWidget(TextNames[int(swappedType)]));
x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[int(swappedType)]);
x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[int(swappedType)]);
x24_model_ghost = static_cast<CGuiModel*>(x0_baseHud.FindWidget(hecl::Format("%sghost", ModelNames[int(x4_type)])));
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
item.x0_model_loz = static_cast<CGuiModel*>(x0_baseHud.FindWidget(hecl::Format("%sloz%c",
ModelNames[int(x4_type)], MenuItemOrders[int(x4_type)][i])));
item.x4_model_icon = static_cast<CGuiModel*>(x0_baseHud.FindWidget(hecl::Format("%sicon%c",
ModelNames[int(x4_type)], MenuItemOrders[int(x4_type)][i])));
item.xc_opacity = enables[i] ? 1.f : 0.f;
}
if (x4_type == EHudVisorBeamMenu::Visor)
{
x20_textpane_menu->TextSupport()->SetFontColor(g_tweakGuiColors->GetVisorMenuTextFont());
x20_textpane_menu->TextSupport()->SetOutlineColor(g_tweakGuiColors->GetVisorMenuTextOutline());
}
else
{
x20_textpane_menu->TextSupport()->SetFontColor(g_tweakGuiColors->GetBeamMenuTextFont());
x20_textpane_menu->TextSupport()->SetOutlineColor(g_tweakGuiColors->GetBeamMenuTextOutline());
}
zeus::CColor titleColor = zeus::CColor::skWhite;
titleColor.a = 0.f;
x1c_basewidget_menutitle->SetColor(titleColor);
x20_textpane_menu->TextSupport()->SetText(g_MainStringTable->GetString(MenuStringIdx[int(x4_type)][x8_selectedItem]));
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
item.x0_model_loz->SetColor(g_tweakGuiColors->GetVisorBeamMenuLozColor());
UpdateMenuWidgetTransform(i, *item.x0_model_loz, 1.f);
}
Update(0.f, true);
}
void CHudVisorBeamMenu::UpdateMenuWidgetTransform(int idx, CGuiWidget& w, float t)
{
float translate = t * g_tweakGui->GetVisorBeamMenuItemTranslate();
float scale = t * g_tweakGui->GetVisorBeamMenuItemInactiveScale() +
(1.f - t) * g_tweakGui->GetVisorBeamMenuItemActiveScale();
if (x4_type == EHudVisorBeamMenu::Visor)
{
if (idx == 2)
idx = 3;
else if (idx == 3)
idx = 2;
}
else
{
if (idx == 1)
idx = 2;
else if (idx == 2)
idx = 1;
}
switch (idx)
{
case 0:
w.SetO2WTransform(x18_basewidget_menu->GetWorldTransform() *
zeus::CTransform::Translate(0.f, 0.f, translate) *
zeus::CTransform::Scale(scale));
case 1:
w.SetO2WTransform(x18_basewidget_menu->GetWorldTransform() *
zeus::CTransform::Translate(translate, 0.f, 0.f) *
zeus::CTransform::Scale(scale));
case 2:
w.SetO2WTransform(x18_basewidget_menu->GetWorldTransform() *
zeus::CTransform::Translate(0.f, 0.f, -translate) *
zeus::CTransform::Scale(scale));
case 3:
w.SetO2WTransform(x18_basewidget_menu->GetWorldTransform() *
zeus::CTransform::Translate(-translate, 0.f, 0.f) *
zeus::CTransform::Scale(scale));
default: break;
}
}
void CHudVisorBeamMenu::Update(float dt, bool init)
{
bool curSwapBeamControls = g_GameState->GameOptions().GetSwapBeamControls();
if (x80_24_swapBeamControls != curSwapBeamControls)
{
x80_24_swapBeamControls = curSwapBeamControls;
EHudVisorBeamMenu swappedType;
if (x80_24_swapBeamControls)
swappedType = EHudVisorBeamMenu(1 - int(x4_type));
else
swappedType = x4_type;
x18_basewidget_menu = x0_baseHud.FindWidget(BaseMenuNames[int(swappedType)]);
x20_textpane_menu = static_cast<CGuiTextPane*>(x0_baseHud.FindWidget(TextNames[int(swappedType)]));
x1c_basewidget_menutitle = x0_baseHud.FindWidget(BaseTitleNames[int(swappedType)]);
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
UpdateMenuWidgetTransform(i, *item.x4_model_icon, item.x8_positioner);
UpdateMenuWidgetTransform(i, *item.x0_model_loz, 1.f);
}
UpdateMenuWidgetTransform(x8_selectedItem, *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner);
}
zeus::CColor activeColor = g_tweakGuiColors->GetVisorBeamMenuItemActive();
zeus::CColor inactiveColor = g_tweakGuiColors->GetVisorBeamMenuItemInactive();
zeus::CColor lozColor = g_tweakGuiColors->GetVisorBeamMenuLozColor();
zeus::CColor tmpColors[4];
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
if (item.xc_opacity > 0.f)
item.xc_opacity = std::min(item.xc_opacity + dt, 1.f);
tmpColors[i] = zeus::CColor::lerp(activeColor, zeus::CColor::skClear, item.xc_opacity);
}
switch (x6c_animPhase)
{
case EAnimPhase::Steady:
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
zeus::CColor& color0 = (x8_selectedItem == i) ? activeColor : inactiveColor;
zeus::CColor& color1 = (x8_selectedItem == i) ? lozColor : inactiveColor;
zeus::CColor iconColor = (item.xc_opacity == 0.f) ? zeus::CColor::skClear : color0 + tmpColors[i];
zeus::CColor lColor = (item.xc_opacity == 0.f) ? lozColor : color1 + tmpColors[i];
item.x4_model_icon->SetColor(iconColor);
item.x0_model_loz->SetColor(lColor);
item.x8_positioner = (x8_selectedItem == i) ? 0.f : 1.f;
}
x24_model_ghost->SetColor(activeColor);
break;
case EAnimPhase::SelectFlash:
{
zeus::CColor color = zeus::CColor::skWhite;
color.a = 0.f;
x1c_basewidget_menutitle->SetColor(color);
zeus::CColor& color0 = std::fmod(x10_interp, 0.1f) > 0.05f ? activeColor : inactiveColor;
SMenuItem& item0 = x28_menuItems[xc_pendingSelection];
color = color0 + tmpColors[xc_pendingSelection];
item0.x4_model_icon->SetColor(color);
item0.x0_model_loz->SetColor(color);
SMenuItem& item1 = x28_menuItems[x8_selectedItem];
color = zeus::CColor::lerp(inactiveColor, activeColor, x10_interp) + tmpColors[x8_selectedItem];
item1.x4_model_icon->SetColor(color);
item1.x0_model_loz->SetColor(lozColor);
for (int i=0 ; i<4 ; ++i)
x28_menuItems[i].x8_positioner = (x8_selectedItem == i) ? 1.f - x10_interp : 1.f;
x24_model_ghost->SetColor(zeus::CColor::lerp(activeColor, inactiveColor, item1.x8_positioner));
break;
}
case EAnimPhase::Animate:
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
zeus::CColor& color0 = (x8_selectedItem == i) ? activeColor : inactiveColor;
zeus::CColor iconColor = (item.xc_opacity == 0.f) ? zeus::CColor::skClear : color0 + tmpColors[i];
item.x4_model_icon->SetColor(iconColor);
item.x0_model_loz->SetColor((item.xc_opacity == 0.f || x8_selectedItem == i) ? lozColor : inactiveColor);
item.x8_positioner = (x8_selectedItem == i) ? 1.f - x10_interp : 1.f;
}
x24_model_ghost->SetColor(zeus::CColor::lerp(activeColor, inactiveColor, x28_menuItems[x8_selectedItem].x8_positioner));
break;
default: break;
}
if (x78_textFader > 0.f)
{
x78_textFader = std::max(0.f, x78_textFader - dt);
zeus::CColor color = zeus::CColor::skWhite;
color.a = x78_textFader / x7c_animDur;
x1c_basewidget_menutitle->SetColor(color);
}
if (x14_26_dirty || init)
{
x14_26_dirty = false;
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
UpdateMenuWidgetTransform(i, *item.x4_model_icon, item.x8_positioner);
}
UpdateMenuWidgetTransform(x8_selectedItem, *x24_model_ghost, x28_menuItems[x8_selectedItem].x8_positioner);
}
if (x1c_basewidget_menutitle->GetGeometryColor().a)
x1c_basewidget_menutitle->SetVisibility(true, ETraversalMode::Children);
else
x1c_basewidget_menutitle->SetVisibility(false, ETraversalMode::Children);
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
if (item.x4_model_icon->GetGeometryColor().a)
item.x4_model_icon->SetIsVisible(true);
else
item.x4_model_icon->SetIsVisible(false);
}
}
void CHudVisorBeamMenu::UpdateHudAlpha(float alpha)
{
zeus::CColor color = zeus::CColor::skWhite;
color.a = g_GameState->GameOptions().GetHUDAlpha() / 255.f * alpha;
x18_basewidget_menu->SetColor(color);
}
void CHudVisorBeamMenu::SetIsVisibleGame(bool v)
{
x14_25_visibleGame = v;
bool vis = x14_24_visibleDebug && x14_25_visibleGame;
x18_basewidget_menu->SetVisibility(vis, ETraversalMode::Children);
if (vis)
Update(0.f, true);
}
void CHudVisorBeamMenu::SetPlayerHas(const rstl::prereserved_vector<bool, 4>& enables)
{
for (int i=0 ; i<4 ; ++i)
{
SMenuItem& item = x28_menuItems[i];
if (item.xc_opacity == 0.f && enables[i])
item.xc_opacity = FLT_EPSILON;
}
}
void CHudVisorBeamMenu::SetSelection(int selection, int pending, float interp)
{
if (x8_selectedItem == selection && xc_pendingSelection == pending && x10_interp == interp)
return;
if (pending != selection)
{
if (x6c_animPhase != EAnimPhase::SelectFlash)
CSfxManager::SfxStart(SelectionSfxs[int(x4_type)], 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x6c_animPhase = EAnimPhase::SelectFlash;
}
else if (interp < 1.f)
{
x6c_animPhase = EAnimPhase::Animate;
x20_textpane_menu->TextSupport()->SetText(g_MainStringTable->GetString(MenuStringIdx[int(x4_type)][x8_selectedItem]));
x20_textpane_menu->TextSupport()->SetTypeWriteEffectOptions(true, 0.1f, 16.f);
}
else
{
if (x6c_animPhase != EAnimPhase::Steady)
x78_textFader = x7c_animDur;
x6c_animPhase = EAnimPhase::Steady;
}
x14_26_dirty = true;
x8_selectedItem = selection;
xc_pendingSelection = pending;
x10_interp = interp;
}
}

View File

@ -6,6 +6,9 @@
namespace urde
{
class CGuiFrame;
class CGuiWidget;
class CGuiTextPane;
class CGuiModel;
class CHudVisorBeamMenu
{
@ -16,10 +19,52 @@ public:
Beam
};
private:
struct SMenuItem
{
CGuiModel* x0_model_loz = nullptr;
CGuiModel* x4_model_icon = nullptr;
float x8_positioner = 0.f;
float xc_opacity = 0.f;
};
enum class EAnimPhase
{
None,
Steady,
SelectFlash,
Animate
};
CGuiFrame& x0_baseHud;
EHudVisorBeamMenu x4_type;
u32 x8_selectedItem = 0;
u32 xc_pendingSelection = 0;
float x10_interp = 1.f;
bool x14_24_visibleDebug : 1;
bool x14_25_visibleGame : 1;
bool x14_26_dirty : 1;
CGuiWidget* x18_basewidget_menu;
CGuiWidget* x1c_basewidget_menutitle;
CGuiTextPane* x20_textpane_menu;
CGuiModel* x24_model_ghost;
rstl::reserved_vector<SMenuItem, 4> x28_menuItems;
EAnimPhase x6c_animPhase = EAnimPhase::Steady;
float x70_ = FLT_EPSILON;
float x74_ = FLT_EPSILON;
float x78_textFader = 0.f;
float x7c_animDur;
bool x80_24_swapBeamControls : 1;
void UpdateMenuWidgetTransform(int, CGuiWidget& w, float);
public:
CHudVisorBeamMenu(CGuiFrame* baseHud, EHudVisorBeamMenu type, rstl::prereserved_vector<bool, 4> enables);
CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
const rstl::prereserved_vector<bool, 4>& enables);
void Update(float dt, bool init);
void UpdateHudAlpha(float alpha);
void SetIsVisibleGame(bool v);
void SetPlayerHas(const rstl::prereserved_vector<bool, 4>& enables);
void SetSelection(int, int, float);
};
}

View File

@ -87,5 +87,30 @@ void CScanDisplay::StartScan(TUniqueId id, const CScannableObjectInfo& scanInfo,
void CScanDisplay::StopScan()
{
}
void CScanDisplay::InitializeFrame(float)
{
}
void CScanDisplay::Update(float, float)
{
}
void CScanDisplay::SetBackgroundBucketOccluded(s32, float)
{
}
bool CScanDisplay::PanelCoversBucketBackground(CScannableObjectInfo::EPanelType, s32)
{
return false;
}
void CScanDisplay::Draw() const
{
}
}

View File

@ -33,6 +33,7 @@ CSamusHud::CSamusHud(CStateManager& stateMgr)
x5d8_guiLights.resize(4);
x7ac_.resize(15);
UpdateStateTransition(1.f, stateMgr);
g_SamusHud = this;
for (int i=0 ; i<16 ; ++i)
x5ec_camFovTweaks[i] = 5.f * i + 40.f;
@ -46,12 +47,12 @@ CSamusHud::CSamusHud(CStateManager& stateMgr)
x2a0_helmetIntf = std::make_unique<CHudHelmetInterface>(*x264_loadedFrmeHelmet);
rstl::prereserved_vector<bool, 4> hasVisors = BuildPlayerHasVisors(stateMgr);
x2a4_visorMenu = std::make_unique<CHudVisorBeamMenu>(x274_loadedFrmeBaseHud,
x2a4_visorMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
CHudVisorBeamMenu::EHudVisorBeamMenu::Visor,
hasVisors);
rstl::prereserved_vector<bool, 4> hasBeams = BuildPlayerHasBeams(stateMgr);
x2a8_beamMenu = std::make_unique<CHudVisorBeamMenu>(x274_loadedFrmeBaseHud,
x2a8_beamMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
CHudVisorBeamMenu::EHudVisorBeamMenu::Beam,
hasBeams);
@ -63,6 +64,13 @@ CSamusHud::CSamusHud(CStateManager& stateMgr)
UpdateBallMode(stateMgr, true);
}
CSamusHud::~CSamusHud()
{
if (x3a4_damageSfx)
CSfxManager::RemoveEmitter(x3a4_damageSfx);
g_SamusHud = nullptr;
}
rstl::prereserved_vector<bool, 4> CSamusHud::BuildPlayerHasVisors(const CStateManager& mgr)
{
rstl::prereserved_vector<bool, 4> ret;
@ -120,22 +128,385 @@ void CSamusHud::InitializeFrameGluePermanent(const CStateManager& mgr)
void CSamusHud::InitializeFrameGlueMutable(const CStateManager& mgr)
{
float lastTankEnergy = std::fmod(x2d0_playerHealth, CPlayerState::GetEnergyTankCapacity());
u32 tanksFilled = x2d0_playerHealth / CPlayerState::GetEnergyTankCapacity();
CPlayer& player = mgr.GetPlayer();
CPlayerState& playerState = *mgr.GetPlayerState();
CPlayerGun& gun = *player.GetPlayerGun();
float chargeFactor = gun.IsCharging() ? gun.GetChargeBeamFactor() : 0.f;
bool missilesActive = gun.GetMissleMode() == CPlayerGun::EMissleMode::Active;
bool lockedOnObj = player.GetLockonObjectId() != kInvalidUniqueId;
switch (x2bc_nextState)
{
case EHudState::Combat:
{
x2b4_bossEnergyIntf = std::make_unique<CHudBossEnergyInterface>(*x288_loadedSelectedHud);
x28c_energyIntf = std::make_unique<CHudEnergyInterface>(*x288_loadedSelectedHud, lastTankEnergy,
x2d4_totalEnergyTanks, tanksFilled,
bool(x2e0_27_energyLow), EHudType::Combat);
if (!x290_threatIntf)
x290_threatIntf = std::make_unique<CHudThreatInterface>(*x288_loadedSelectedHud, EHudType::Combat,
9999.f);
else
x290_threatIntf->SetIsVisibleGame(true);
if (!x294_missileIntf)
x294_missileIntf = std::make_unique<CHudMissileInterface>(*x288_loadedSelectedHud, x2dc_missileCapacity,
x2d8_missileAmount, chargeFactor, missilesActive,
EHudType::Combat, mgr);
else
x294_missileIntf->SetIsVisibleGame(true, mgr);
if (!x298_freeLookIntf)
x298_freeLookIntf = std::make_unique<CHudFreeLookInterface>(*x288_loadedSelectedHud, EHudType::Combat,
bool(x2e0_24_inFreeLook), bool(x2e0_25_lookControlHeld),
lockedOnObj);
else
x298_freeLookIntf->SetIsVisibleGame(true);
if (!x29c_decoIntf)
x29c_decoIntf = std::make_unique<CHudDecoInterfaceCombat>(*x288_loadedSelectedHud);
else
x29c_decoIntf->SetIsVisibleGame(true);
x2ac_radarIntf->SetIsVisibleGame(true);
x2a4_visorMenu->SetIsVisibleGame(true);
x2a8_beamMenu->SetIsVisibleGame(true);
InitializeDamageLight();
UpdateEnergy(0.f, mgr, true);
break;
}
case EHudState::Ball:
{
u32 numPBs = playerState.GetItemAmount(CPlayerState::EItemType::PowerBombs);
u32 pbCap = playerState.GetItemCapacity(CPlayerState::EItemType::PowerBombs);
u32 bombsAvailable;
if (gun.IsBombReady())
bombsAvailable = gun.GetBombCount();
else
bombsAvailable = 0;
x2b0_ballIntf = std::make_unique<CHudBallInterface>(*x288_loadedSelectedHud, numPBs, pbCap,
bombsAvailable, gun.IsPowerBombReady() &&
player.GetMorphballTransitionState() ==
CPlayer::EPlayerMorphBallState::Morphed,
playerState.HasPowerUp(
CPlayerState::EItemType::MorphBallBombs));
x28c_energyIntf = std::make_unique<CHudEnergyInterface>(*x288_loadedSelectedHud, lastTankEnergy,
x2d4_totalEnergyTanks, tanksFilled,
bool(x2e0_27_energyLow), EHudType::Ball);
x290_threatIntf.reset();
x294_missileIntf.reset();
x298_freeLookIntf.reset();
x29c_decoIntf.reset();
x3d4_damageLight = nullptr;
x2ac_radarIntf->SetIsVisibleGame(false);
x2a4_visorMenu->SetIsVisibleGame(false);
x2a8_beamMenu->SetIsVisibleGame(false);
UpdateEnergy(0.f, mgr, true);
break;
}
case EHudState::Scan:
{
x2b4_bossEnergyIntf.reset();
x28c_energyIntf = std::make_unique<CHudEnergyInterface>(*x288_loadedSelectedHud, lastTankEnergy,
x2d4_totalEnergyTanks, tanksFilled,
bool(x2e0_27_energyLow), EHudType::Scan);
x290_threatIntf.reset();
x294_missileIntf.reset();
x298_freeLookIntf = std::make_unique<CHudFreeLookInterface>(*x288_loadedSelectedHud, EHudType::Scan,
bool(x2e0_24_inFreeLook), bool(x2e0_25_lookControlHeld),
lockedOnObj);
x29c_decoIntf = std::make_unique<CHudDecoInterfaceScan>(*x288_loadedSelectedHud);
InitializeDamageLight();
UpdateEnergy(0.f, mgr, true);
break;
}
case EHudState::XRay:
{
x2b4_bossEnergyIntf = std::make_unique<CHudBossEnergyInterface>(*x288_loadedSelectedHud);
x28c_energyIntf = std::make_unique<CHudEnergyInterface>(*x288_loadedSelectedHud, lastTankEnergy,
x2d4_totalEnergyTanks, tanksFilled,
bool(x2e0_27_energyLow), EHudType::XRay);
x290_threatIntf = std::make_unique<CHudThreatInterface>(*x288_loadedSelectedHud, EHudType::XRay,
9999.f);
x294_missileIntf = std::make_unique<CHudMissileInterface>(*x288_loadedSelectedHud, x2dc_missileCapacity,
x2d8_missileAmount, chargeFactor, missilesActive,
EHudType::XRay, mgr);
x298_freeLookIntf = std::make_unique<CHudFreeLookInterfaceXRay>(*x288_loadedSelectedHud,
bool(x2e0_24_inFreeLook), bool(x2e0_25_lookControlHeld),
lockedOnObj);
x29c_decoIntf = std::make_unique<CHudDecoInterfaceXRay>(*x288_loadedSelectedHud);
InitializeDamageLight();
x2a4_visorMenu->SetIsVisibleGame(true);
x2a8_beamMenu->SetIsVisibleGame(true);
UpdateEnergy(0.f, mgr, true);
break;
}
case EHudState::Thermal:
{
x2b4_bossEnergyIntf = std::make_unique<CHudBossEnergyInterface>(*x288_loadedSelectedHud);
x28c_energyIntf = std::make_unique<CHudEnergyInterface>(*x288_loadedSelectedHud, lastTankEnergy,
x2d4_totalEnergyTanks, tanksFilled,
bool(x2e0_27_energyLow), EHudType::Thermal);
x290_threatIntf = std::make_unique<CHudThreatInterface>(*x288_loadedSelectedHud, EHudType::Thermal,
9999.f);
x294_missileIntf = std::make_unique<CHudMissileInterface>(*x288_loadedSelectedHud, x2dc_missileCapacity,
x2d8_missileAmount, chargeFactor, missilesActive,
EHudType::Thermal, mgr);
x298_freeLookIntf = std::make_unique<CHudFreeLookInterface>(*x288_loadedSelectedHud, EHudType::Thermal,
bool(x2e0_24_inFreeLook), bool(x2e0_25_lookControlHeld),
lockedOnObj);
x29c_decoIntf = std::make_unique<CHudDecoInterfaceThermal>(*x288_loadedSelectedHud);
InitializeDamageLight();
x2a4_visorMenu->SetIsVisibleGame(true);
x2a8_beamMenu->SetIsVisibleGame(true);
UpdateEnergy(0.f, mgr, true);
break;
}
case EHudState::None:
UninitializeFrameGlueMutable();
default: break;
}
}
void CSamusHud::UninitializeFrameGlueMutable()
{
x2b4_bossEnergyIntf.reset();
x28c_energyIntf.reset();
x29c_decoIntf.reset();
x290_threatIntf.reset();
x294_missileIntf.reset();
x298_freeLookIntf.reset();
x2b0_ballIntf.reset();
x3d4_damageLight = nullptr;
}
void CSamusHud::InitializeDamageLight()
{
s16 lightId = x288_loadedSelectedHud->GetWidgetIdDB().AddWidget("DamageSpotLight");
s16 parentId = x288_loadedSelectedHud->FindWidget("basewidget_pivot")->GetSelfId();
CGuiWidget::CGuiWidgetParms parms(x288_loadedSelectedHud, false, lightId,
parentId, true, true, false,
g_tweakGuiColors->GetHudDamageLightColor(),
CGuiWidget::EGuiModelDrawFlags::Alpha, false, false);
std::shared_ptr<CGuiLight> light = std::make_shared<CGuiLight>(
parms, CLight::BuildSpot(zeus::CVector3f::skZero, zeus::CVector3f::skForward,
zeus::CColor::skWhite, g_tweakGui->GetHudDamageLightSpotAngle()));
x3d4_damageLight = light.get();
x3d4_damageLight->SetColor(zeus::CColor::skWhite);
zeus::CColor lightColor = g_tweakGuiColors->GetHudFrameColor();
lightColor.r *= lightColor.a;
lightColor.g *= lightColor.a;
lightColor.b *= lightColor.a;
lightColor.a = 1.f;
x3d4_damageLight->SetColor(lightColor);
x3d4_damageLight->SetDistC(1.f);
x3d4_damageLight->SetDistL(0.f);
x3d4_damageLight->SetAngleC(g_tweakGui->GetDamageLightAngleC());
x3d4_damageLight->SetAngleL(g_tweakGui->GetDamageLightAngleL());
x3d4_damageLight->SetAngleQ(g_tweakGui->GetDamageLightAngleQ());
x3d4_damageLight->SetLoadedIdx(4);
x3d4_damageLight->SetLocalTransform(zeus::CTransform::Identity());
x288_loadedSelectedHud->RegisterLight(std::move(light));
x288_loadedSelectedHud->FindWidget(parentId)->AddChildWidget(x3d4_damageLight, false, true);
x288_loadedSelectedHud->AddLight(x3d4_damageLight);
zeus::CTransform lightXf = zeus::CTransform::Translate(g_tweakGui->GetDamageLightPreTranslate());
x3d8_lightTransforms.clear();
x3d8_lightTransforms.reserve(10);
zeus::CTransform negX = zeus::CTransform::RotateX(zeus::degToRad(-g_tweakGui->GetDamageLightXfXAngle()));
zeus::CTransform posX = zeus::CTransform::RotateX(zeus::degToRad(g_tweakGui->GetDamageLightXfXAngle()));
zeus::CTransform negZ = zeus::CTransform::RotateZ(zeus::degToRad(-g_tweakGui->GetDamageLightXfZAngle()));
zeus::CTransform posZ = zeus::CTransform::RotateZ(zeus::degToRad(g_tweakGui->GetDamageLightXfZAngle()));
x3d8_lightTransforms.push_back(lightXf);
x3d8_lightTransforms.push_back(zeus::CTransform::Translate(g_tweakGui->GetDamageLightCenterTranslate()) * lightXf);
x3d8_lightTransforms.push_back(posX * lightXf);
x3d8_lightTransforms.push_back(posX * negZ * lightXf);
x3d8_lightTransforms.push_back(negZ * lightXf);
x3d8_lightTransforms.push_back(negX * negZ * lightXf);
x3d8_lightTransforms.push_back(negX * lightXf);
x3d8_lightTransforms.push_back(negX * posZ * lightXf);
x3d8_lightTransforms.push_back(posZ * lightXf);
x3d8_lightTransforms.push_back(posX * posZ * lightXf);
}
void CSamusHud::UpdateEnergy(float dt, const CStateManager& mgr, bool init)
{
CPlayer& player = mgr.GetPlayer();
CPlayerState& playerState = *mgr.GetPlayerState();
float energy = std::max(0.f, std::ceil(playerState.GetHealthInfo().GetHP()));
u32 numEnergyTanks = playerState.GetItemCapacity(CPlayerState::EItemType::EnergyTanks);
x2e0_27_energyLow = player.IsEnergyLow(mgr);
if (init || energy != x2d0_playerHealth || numEnergyTanks != x2d4_totalEnergyTanks)
{
float lastTankEnergy = energy;
u32 filledTanks = 0;
while (lastTankEnergy > CPlayerState::GetBaseHealthCapacity())
{
++filledTanks;
lastTankEnergy -= CPlayerState::GetEnergyTankCapacity();
}
if (x2bc_nextState != EHudState::None)
{
if (x28c_energyIntf)
{
float curLastTankEnergy = x2d0_playerHealth;
while (curLastTankEnergy > CPlayerState::GetBaseHealthCapacity())
curLastTankEnergy -= CPlayerState::GetEnergyTankCapacity();
x28c_energyIntf->SetCurrEnergy(lastTankEnergy, curLastTankEnergy < lastTankEnergy);
}
x2d0_playerHealth = energy;
if (x28c_energyIntf)
{
x28c_energyIntf->SetNumTotalEnergyTanks(numEnergyTanks);
x28c_energyIntf->SetNumFilledEnergyTanks(filledTanks);
x28c_energyIntf->SetEnergyLow(x2e0_27_energyLow);
}
x2d4_totalEnergyTanks = numEnergyTanks;
}
}
if (x2b4_bossEnergyIntf)
{
const CEntity* bossEnt = mgr.GetObjectById(mgr.GetBossId());
if (TCastToConstPtr<CActor> act = bossEnt)
{
if (const CHealthInfo* hInfo = act->GetHealthInfo())
{
float bossEnergy = std::ceil(hInfo->GetHP());
x2b4_bossEnergyIntf->SetBossParams(true, g_MainStringTable->GetString(mgr.GetBossStringIdx()),
bossEnergy, mgr.GetTotalBossEnergy());
}
else
{
x2b4_bossEnergyIntf->SetBossParams(false, u"", 0.f, 0.f);
}
}
else
{
x2b4_bossEnergyIntf->SetBossParams(false, u"", 0.f, 0.f);
}
}
}
void CSamusHud::UpdateFreeLook(float dt, const CStateManager& mgr)
{
TCastToConstPtr<CFirstPersonCamera> fpCam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
CPlayer& player = mgr.GetPlayer();
bool inFreeLook = player.IsInFreeLook() && fpCam;
bool lookControlHeld = player.IsLookControlHeld();
if (x2e0_24_inFreeLook != inFreeLook)
{
if (inFreeLook)
CSfxManager::SfxStart(1392, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
else
CSfxManager::SfxStart(1390, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
x2e0_24_inFreeLook = inFreeLook;
}
float deltaFrames = 60.f * dt * 0.999999f;
float oldLookDeltaDot = x574_lookDeltaDot;
zeus::CVector3f fpCamDir;
if (!fpCam)
fpCamDir = x568_fpCamDir;
else
fpCamDir = fpCam->GetTransform().basis[1];
bool lookAdj = inFreeLook ? lookControlHeld : false;
if (lookAdj)
{
x574_lookDeltaDot = fpCamDir.dot(x568_fpCamDir);
if (std::fabs(x574_lookDeltaDot) > 1.f)
x574_lookDeltaDot = (x574_lookDeltaDot >= 0.f) ? 1.f : -1.f;
}
else
{
x574_lookDeltaDot = 1.f;
}
x568_fpCamDir = fpCamDir;
if ((oldLookDeltaDot >= deltaFrames && x574_lookDeltaDot < deltaFrames) ||
(oldLookDeltaDot < deltaFrames && x574_lookDeltaDot >= deltaFrames))
{
x578_freeLookSfxCycleTimer = 0.f;
}
else if (x578_freeLookSfxCycleTimer < 0.05f)
{
x578_freeLookSfxCycleTimer = std::min(x578_freeLookSfxCycleTimer + dt, 0.05f);
if (x578_freeLookSfxCycleTimer == 0.05f)
{
if (x574_lookDeltaDot < deltaFrames)
{
if (!x564_freeLookSfx)
x564_freeLookSfx = CSfxManager::SfxStart(1394, 1.f, 0.f, true, 0x7f, true, kInvalidAreaId);
}
else
{
CSfxManager::SfxStop(x564_freeLookSfx);
x564_freeLookSfx.reset();
}
}
}
if (fpCam)
{
zeus::CMatrix3f camRot = fpCam->GetTransform().buildMatrix3f();
zeus::CVector3f camDir(camRot[1]);
zeus::CUnitVector3f camDirNoZ(camDir.x, camDir.y, 0.f);
float offHorizonDot = camDir.dot(camDirNoZ);
if (std::fabs(offHorizonDot) > 1.f)
offHorizonDot = (offHorizonDot >= 0.f) ? 1.f : -1.f;
float offHorizonAngle = std::fabs(std::acos(offHorizonDot));
if (camDir.z < 0.f)
offHorizonAngle = -offHorizonAngle;
if (x298_freeLookIntf)
x298_freeLookIntf->SetFreeLookState(inFreeLook, lookControlHeld,
player.GetLockonObjectId() != kInvalidUniqueId,
offHorizonAngle);
if (x564_freeLookSfx)
{
float pitch = offHorizonAngle * (g_tweakGui->GetFreeLookSfxPitchScale() / 8192.f) / (M_PIF / 2.f);
if (!g_tweakGui->GetNoAbsoluteFreeLookSfxPitch())
pitch = std::fabs(pitch);
CSfxManager::PitchBend(x564_freeLookSfx, pitch);
}
}
}
void CSamusHud::UpdateMissile(float dt, const CStateManager& mgr, bool init)
@ -479,8 +850,8 @@ void CSamusHud::Update(float dt, const CStateManager& mgr,
x288_loadedSelectedHud->Update(dt);
if (x2b4_bossEnergyIntf)
x2b4_bossEnergyIntf->Update(dt);
if (x28c_ballEnergyIntf)
x28c_ballEnergyIntf->Update(dt, x580_energyLowPulse);
if (x28c_energyIntf)
x28c_energyIntf->Update(dt, x580_energyLowPulse);
if (x290_threatIntf)
x290_threatIntf->Update(dt);
if (x294_missileIntf)

View File

@ -104,7 +104,7 @@ class CSamusHud
CGuiFrame* x274_loadedFrmeBaseHud = nullptr;
TLockedToken<CGuiFrame> x278_selectedHud; // used to be optional
CGuiFrame* x288_loadedSelectedHud = nullptr;
std::unique_ptr<CHudEnergyInterface> x28c_ballEnergyIntf;
std::unique_ptr<CHudEnergyInterface> x28c_energyIntf;
std::unique_ptr<CHudThreatInterface> x290_threatIntf;
std::unique_ptr<CHudMissileInterface> x294_missileIntf;
std::unique_ptr<IFreeLookInterface> x298_freeLookIntf;
@ -152,7 +152,7 @@ class CSamusHud
rstl::reserved_vector<SCachedHudLight, 3> x340_hudLights;
CSfxHandle x3a4_damageSfx;
CCameraFilterPass x3a8_camFilter;
CGuiWidget* x3d4_selected_basewidget_pivot = nullptr;
CGuiLight* x3d4_damageLight = nullptr;
std::vector<zeus::CTransform> x3d8_lightTransforms;
float x3e8_ = 0.f;
float x3ec_ = 0.f;
@ -185,10 +185,10 @@ class CSamusHud
float x558_messageTextAlpha = 0.f;
float x55c_lastSfxChars = 0.f;
float x560_messageTextScale = 0.f;
u32 x564_ = 0;
CSfxHandle x564_freeLookSfx;
zeus::CVector3f x568_fpCamDir;
float x574_ = 1.f;
float x578_ = 0.f;
float x574_lookDeltaDot = 1.f;
float x578_freeLookSfxCycleTimer = 0.f;
float x57c_energyLowTimer = 0.f;
float x580_energyLowPulse = 0.f;
float x584_abuttonPulse = 0.f;
@ -212,6 +212,7 @@ class CSamusHud
void InitializeFrameGluePermanent(const CStateManager& mgr);
void InitializeFrameGlueMutable(const CStateManager& mgr);
void UninitializeFrameGlueMutable();
void InitializeDamageLight();
void UpdateEnergy(float dt, const CStateManager& mgr, bool init);
void UpdateFreeLook(float dt, const CStateManager& mgr);
void UpdateMissile(float dt, const CStateManager& mgr, bool init);
@ -233,6 +234,7 @@ class CSamusHud
public:
CSamusHud(CStateManager& stateMgr);
~CSamusHud();
void Update(float dt, const CStateManager& mgr,
DataSpec::ITweakGui::EHelmetVisMode helmetVis,
bool hudVis, bool targetingManager);

View File

@ -195,8 +195,8 @@ private:
bool x835_25_ : 1;
bool x835_26_ : 1;
bool x835_27_ : 1;
bool x835_28_ : 1;
bool x835_29_ : 1;
bool x835_28_bombReady : 1;
bool x835_29_powerBombReady : 1;
bool x835_30_ : 1;
bool x835_31_ : 1;
};
@ -209,6 +209,11 @@ public:
void AsyncLoadSuit(CStateManager& mgr);
void TouchModel(CStateManager& stateMgr);
EMissleMode GetMissleMode() const { return x31c_missileMode; }
bool IsCharging() const { return x834_24_charging; }
float GetChargeBeamFactor() const { return x340_chargeBeamFactor; }
bool IsBombReady() const { return x835_28_bombReady; }
u32 GetBombCount() const { return x308_bombCount; }
bool IsPowerBombReady() const { return x835_29_powerBombReady; }
};
}

View File

@ -162,6 +162,7 @@ public:
bool CanDrawStatic() const;
bool GetE7_29() const { return xe7_29_; }
const CScannableObjectInfo* GetScannableObjectInfo() const;
const CHealthInfo* GetHealthInfo() const { return const_cast<CActor*>(this)->HealthInfo(); }
};
}

View File

@ -42,6 +42,7 @@ public:
T& back() const { x4_data[(x0_size == 0) ? 0 : x0_size - 1]; }
T& front() const { return x4_data[0]; }
T& operator[](size_t idx) { return x4_data[idx]; }
const T& operator[](size_t idx) const { return x4_data[idx]; }
};
}

@ -1 +1 @@
Subproject commit d936dc71939f5e33776754e3ea2196bdfe4b1613
Subproject commit 1b6e3472d3a2f5d8cc6e3b0283e26071fcc8755f