mirror of https://github.com/AxioDL/metaforce.git
316 lines
12 KiB
C++
316 lines
12 KiB
C++
#include "CHudMissileInterface.hpp"
|
|
#include "CGuiFrame.hpp"
|
|
#include "CAuiEnergyBarT01.hpp"
|
|
#include "CGuiTextPane.hpp"
|
|
#include "GameGlobalObjects.hpp"
|
|
#include "CStateManager.hpp"
|
|
#include "CGuiModel.hpp"
|
|
#include "CStringTable.hpp"
|
|
|
|
namespace urde
|
|
{
|
|
|
|
static const CAuiEnergyBarT01::FCoordFunc CoordFuncs[] =
|
|
{
|
|
CHudMissileInterface::CombatMissileBarCoordFunc,
|
|
nullptr,
|
|
CHudMissileInterface::XRayMissileBarCoordFunc,
|
|
CHudMissileInterface::ThermalMissileBarCoordFunc,
|
|
nullptr
|
|
};
|
|
|
|
static const float IconTranslateRanges[] =
|
|
{
|
|
6.05f, 0.f, 0.f, 8.4f, 0.f
|
|
};
|
|
|
|
CHudMissileInterface::CHudMissileInterface(CGuiFrame& selHud, int missileCapacity, int numMissiles,
|
|
float chargeFactor, bool missilesActive, EHudType hudType,
|
|
const CStateManager& mgr)
|
|
: x0_hudType(hudType), x4_missileCapacity(missileCapacity),
|
|
x8_numMissles(numMissiles), x4c_chargeBeamFactor(chargeFactor)
|
|
{
|
|
x58_24_missilesActive = missilesActive;
|
|
x58_25_visibleDebug = true;
|
|
x58_26_visibleGame = true;
|
|
|
|
x5c_basewidget_missileicon = selHud.FindWidget("basewidget_missileicon");
|
|
x60_textpane_missiledigits = static_cast<CGuiTextPane*>(selHud.FindWidget("textpane_missiledigits"));
|
|
x64_energybart01_missilebar = static_cast<CAuiEnergyBarT01*>(selHud.FindWidget("energybart01_missilebar"));
|
|
x68_textpane_missilewarning = static_cast<CGuiTextPane*>(selHud.FindWidget("textpane_missilewarning"));
|
|
x6c_model_missilearrowup = static_cast<CGuiModel*>(selHud.FindWidget("model_missilearrowup"));
|
|
x70_model_missilearrowdown = static_cast<CGuiModel*>(selHud.FindWidget("model_missilearrowdown"));
|
|
x74_basewidget_missileicon = selHud.FindWidget("basewidget_missileicon");
|
|
|
|
x58_27_hasArrows = x6c_model_missilearrowup && x70_model_missilearrowdown;
|
|
x58_28_notXRay = hudType != EHudType::XRay;
|
|
|
|
x10_missleIconXf = x74_basewidget_missileicon->GetLocalTransform();
|
|
|
|
x60_textpane_missiledigits->TextSupport().SetFontColor(g_tweakGuiColors->GetMissileDigitsFont());
|
|
x60_textpane_missiledigits->TextSupport().SetOutlineColor(g_tweakGuiColors->GetMissileDigitsOutline());
|
|
x74_basewidget_missileicon->SetColor(g_tweakGuiColors->GetMissileIconColorInactive());
|
|
x64_energybart01_missilebar->SetEmptyColor(g_tweakGuiColors->GetMissileBarEmpty());
|
|
x64_energybart01_missilebar->SetFilledColor(g_tweakGuiColors->GetMissileBarFilled());
|
|
x64_energybart01_missilebar->SetShadowColor(g_tweakGuiColors->GetMissileBarShadow());
|
|
x64_energybart01_missilebar->SetCoordFunc(CoordFuncs[int(hudType)]);
|
|
x64_energybart01_missilebar->SetTesselation(hudType == EHudType::Combat ? 1.f : 0.1f);
|
|
x64_energybart01_missilebar->SetMaxEnergy(5.f);
|
|
x64_energybart01_missilebar->SetFilledDrainSpeed(g_tweakGui->GetEnergyBarFilledSpeed());
|
|
x64_energybart01_missilebar->SetShadowDrainSpeed(g_tweakGui->GetEnergyBarShadowSpeed());
|
|
x64_energybart01_missilebar->SetShadowDrainDelay(g_tweakGui->GetEnergyBarDrainDelay());
|
|
x64_energybart01_missilebar->SetIsAlwaysResetTimer(true);
|
|
|
|
if (x68_textpane_missilewarning)
|
|
{
|
|
x68_textpane_missilewarning->TextSupport().SetFontColor(g_tweakGuiColors->GetMissileWarningFont());
|
|
x68_textpane_missilewarning->TextSupport().SetOutlineColor(g_tweakGuiColors->GetMissileWarningOutline());
|
|
}
|
|
|
|
SetNumMissiles(x8_numMissles, mgr);
|
|
x44_latestStatus = GetMissileInventoryStatus();
|
|
}
|
|
|
|
void CHudMissileInterface::UpdateVisibility(const CStateManager& mgr)
|
|
{
|
|
bool vis = x58_25_visibleDebug && x58_26_visibleGame;
|
|
x5c_basewidget_missileicon->SetVisibility(vis, ETraversalMode::Children);
|
|
x64_energybart01_missilebar->SetVisibility(vis, ETraversalMode::Children);
|
|
if (vis)
|
|
Update(0.f, mgr);
|
|
}
|
|
|
|
void CHudMissileInterface::Update(float dt, const CStateManager& mgr)
|
|
{
|
|
if (x4_missileCapacity < 1)
|
|
x5c_basewidget_missileicon->SetIsVisible(false);
|
|
else
|
|
x5c_basewidget_missileicon->SetIsVisible(true);
|
|
|
|
if (x54_missileIconIncrement < 0.f)
|
|
{
|
|
x54_missileIconIncrement -= 3.f * dt;
|
|
if (x54_missileIconIncrement <= -1.f)
|
|
x54_missileIconIncrement = 1.f;
|
|
}
|
|
else if (x54_missileIconIncrement > 0.f)
|
|
{
|
|
x54_missileIconIncrement = std::max(0.f, x54_missileIconIncrement - dt);
|
|
}
|
|
|
|
zeus::CColor addColor = g_tweakGuiColors->GetMissileIconColorActive() * x54_missileIconIncrement;
|
|
|
|
if (x50_missileIconAltDeplete > 0.f)
|
|
{
|
|
x74_basewidget_missileicon->SetColor(
|
|
zeus::CColor::lerp(g_tweakGuiColors->GetMissileIconColorInactive(),
|
|
g_tweakGuiColors->GetMissileIconColorDepleteAlt(), x50_missileIconAltDeplete) + addColor);
|
|
}
|
|
else
|
|
{
|
|
if (x4c_chargeBeamFactor > 0.f)
|
|
{
|
|
float factor = std::min(x4c_chargeBeamFactor / CPlayerState::GetMissileComboChargeFactor(), 1.f);
|
|
if (x8_numMissles > mgr.GetPlayerState()->GetMissileCostForAltAttack())
|
|
{
|
|
x74_basewidget_missileicon->SetColor(
|
|
zeus::CColor::lerp(g_tweakGuiColors->GetMissileIconColorInactive(),
|
|
g_tweakGuiColors->GetMissileIconColorChargedCanAlt(), factor) + addColor);
|
|
}
|
|
else
|
|
{
|
|
x74_basewidget_missileicon->SetColor(
|
|
zeus::CColor::lerp(g_tweakGuiColors->GetMissileIconColorInactive(),
|
|
g_tweakGuiColors->GetMissileIconColorChargedNoAlt(), factor) + addColor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (x58_24_missilesActive)
|
|
x74_basewidget_missileicon->SetColor(g_tweakGuiColors->GetMissileIconColorActive() + addColor);
|
|
else
|
|
x74_basewidget_missileicon->SetColor(g_tweakGuiColors->GetMissileIconColorInactive() + addColor);
|
|
}
|
|
}
|
|
|
|
x50_missileIconAltDeplete = std::max(0.f, x50_missileIconAltDeplete - dt);
|
|
|
|
x64_energybart01_missilebar->SetMaxEnergy(x4_missileCapacity);
|
|
x64_energybart01_missilebar->SetCurrEnergy(x8_numMissles, CAuiEnergyBarT01::ESetMode::Normal);
|
|
|
|
if (x58_28_notXRay)
|
|
{
|
|
x74_basewidget_missileicon->SetLocalTransform(x10_missleIconXf *
|
|
zeus::CTransform::Translate(0.f, 0.f, x8_numMissles *
|
|
IconTranslateRanges[int(x0_hudType)] / float(x4_missileCapacity)));
|
|
}
|
|
|
|
if (x58_27_hasArrows)
|
|
{
|
|
if (xc_arrowTimer > 0.f)
|
|
{
|
|
xc_arrowTimer = std::max(0.f, xc_arrowTimer - dt);
|
|
zeus::CColor color = g_tweakGuiColors->GetMissileIconColorActive();
|
|
color.a *= xc_arrowTimer / g_tweakGui->GetMissileArrowVisTime();
|
|
x6c_model_missilearrowup->SetColor(color);
|
|
x70_model_missilearrowdown->SetIsVisible(false);
|
|
}
|
|
else if (xc_arrowTimer < 0.f)
|
|
{
|
|
xc_arrowTimer = std::min(0.f, xc_arrowTimer + dt);
|
|
zeus::CColor color = g_tweakGuiColors->GetMissileIconColorActive();
|
|
color.a *= -xc_arrowTimer / g_tweakGui->GetMissileArrowVisTime();
|
|
x70_model_missilearrowdown->SetColor(color);
|
|
x6c_model_missilearrowup->SetIsVisible(false);
|
|
}
|
|
else
|
|
{
|
|
x6c_model_missilearrowup->SetIsVisible(false);
|
|
x70_model_missilearrowdown->SetIsVisible(false);
|
|
}
|
|
}
|
|
|
|
if (x68_textpane_missilewarning)
|
|
{
|
|
EInventoryStatus curStatus = GetMissileInventoryStatus();
|
|
if (curStatus != x44_latestStatus)
|
|
{
|
|
std::u16string string;
|
|
switch (curStatus)
|
|
{
|
|
case EInventoryStatus::Warning:
|
|
string = g_MainStringTable->GetString(12); // Missiles Low
|
|
break;
|
|
case EInventoryStatus::Depleted:
|
|
string = g_MainStringTable->GetString(13); // Depleted
|
|
default: break;
|
|
}
|
|
x68_textpane_missilewarning->TextSupport().SetText(string);
|
|
|
|
if (x44_latestStatus == EInventoryStatus::Normal && curStatus == EInventoryStatus::Warning)
|
|
{
|
|
CSfxManager::SfxStart(SFXui_missile_warning, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
|
x48_missileWarningPulse = g_tweakGui->GetMissileWarningPulseTime();
|
|
}
|
|
else if (curStatus == EInventoryStatus::Depleted)
|
|
{
|
|
CSfxManager::SfxStart(SFXui_missile_warning, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
|
x48_missileWarningPulse = g_tweakGui->GetMissileWarningPulseTime();
|
|
}
|
|
|
|
x44_latestStatus = curStatus;
|
|
}
|
|
|
|
x48_missileWarningPulse = std::max(0.f, x48_missileWarningPulse - dt);
|
|
float warnPulse = std::min(x48_missileWarningPulse, 1.f);
|
|
|
|
if (x44_latestStatus != EInventoryStatus::Normal)
|
|
x40_missileWarningAlpha = std::min(x40_missileWarningAlpha + 2.f * dt, 1.f);
|
|
else
|
|
x40_missileWarningAlpha = std::max(0.f, x40_missileWarningAlpha - 2.f * dt);
|
|
|
|
float tmp = std::fabs(std::fmod(CGraphics::GetSecondsMod900(), 0.5f));
|
|
if (tmp < 0.25f)
|
|
tmp = tmp / 0.25f;
|
|
else
|
|
tmp = (0.5f - tmp) / 0.25f;
|
|
|
|
zeus::CColor color = zeus::CColor::skWhite;
|
|
color.a = x40_missileWarningAlpha * tmp * warnPulse;
|
|
x68_textpane_missilewarning->SetColor(color);
|
|
if (x68_textpane_missilewarning->GetGeometryColor().a)
|
|
x68_textpane_missilewarning->SetIsVisible(true);
|
|
else
|
|
x68_textpane_missilewarning->SetIsVisible(false);
|
|
}
|
|
}
|
|
|
|
void CHudMissileInterface::SetIsVisibleGame(bool v, const CStateManager& mgr)
|
|
{
|
|
x58_26_visibleGame = v;
|
|
UpdateVisibility(mgr);
|
|
}
|
|
|
|
void CHudMissileInterface::SetIsVisibleDebug(bool v, const CStateManager& mgr)
|
|
{
|
|
x58_25_visibleDebug = v;
|
|
UpdateVisibility(mgr);
|
|
}
|
|
|
|
void CHudMissileInterface::SetIsMissilesActive(bool active)
|
|
{
|
|
x58_24_missilesActive = active;
|
|
}
|
|
|
|
void CHudMissileInterface::SetChargeBeamFactor(float t)
|
|
{
|
|
x4c_chargeBeamFactor = t;
|
|
}
|
|
|
|
void CHudMissileInterface::SetNumMissiles(int numMissiles, const CStateManager& mgr)
|
|
{
|
|
numMissiles = zeus::clamp(0, numMissiles, 999);
|
|
|
|
x60_textpane_missiledigits->TextSupport().SetText(hecl::Format("%3d", numMissiles));
|
|
|
|
if (x8_numMissles < numMissiles)
|
|
{
|
|
xc_arrowTimer = g_tweakGui->GetMissileArrowVisTime();
|
|
x54_missileIconIncrement = -FLT_EPSILON;
|
|
}
|
|
else if (x8_numMissles > numMissiles)
|
|
{
|
|
xc_arrowTimer = -g_tweakGui->GetMissileArrowVisTime();
|
|
}
|
|
|
|
if (mgr.GetPlayerState()->GetMissileCostForAltAttack() + numMissiles <= x8_numMissles)
|
|
x50_missileIconAltDeplete = 1.f;
|
|
|
|
x8_numMissles = numMissiles;
|
|
}
|
|
|
|
void CHudMissileInterface::SetMissileCapacity(int missileCapacity)
|
|
{
|
|
x4_missileCapacity = missileCapacity;
|
|
}
|
|
|
|
CHudMissileInterface::EInventoryStatus CHudMissileInterface::GetMissileInventoryStatus()
|
|
{
|
|
if (x64_energybart01_missilebar->GetSetEnergy() == 0.f)
|
|
return EInventoryStatus::Depleted;
|
|
return EInventoryStatus(x64_energybart01_missilebar->GetActualFraction() <
|
|
g_tweakGui->GetMissileWarningFraction());
|
|
}
|
|
|
|
std::pair<zeus::CVector3f, zeus::CVector3f> CHudMissileInterface::CombatMissileBarCoordFunc(float t)
|
|
{
|
|
float z = t * IconTranslateRanges[int(EHudType::Combat)];
|
|
return {zeus::CVector3f(0.f, 0.f, z), zeus::CVector3f(0.3f, 0.f, z)};
|
|
}
|
|
|
|
std::pair<zeus::CVector3f, zeus::CVector3f> CHudMissileInterface::XRayMissileBarCoordFunc(float t)
|
|
{
|
|
float theta = 0.8f * (t - 0.5f);
|
|
float x = 9.55f * std::cos(theta);
|
|
float z = 9.55f * std::sin(theta);
|
|
return {zeus::CVector3f(x - 0.4f, 0.f, z), zeus::CVector3f(x, 0.f, z)};
|
|
}
|
|
|
|
std::pair<zeus::CVector3f, zeus::CVector3f> CHudMissileInterface::ThermalMissileBarCoordFunc(float t)
|
|
{
|
|
float transRange = IconTranslateRanges[int(EHudType::Thermal)];
|
|
float a = 0.08f * transRange;
|
|
float b = t * transRange;
|
|
float c;
|
|
if (b < a)
|
|
c = b / a;
|
|
else if (b < transRange - a)
|
|
c = 1.f;
|
|
else
|
|
c = 1.f - (b - (transRange - a)) / a;
|
|
|
|
return {zeus::CVector3f(-0.5f * c - 0.1f, 0.f, b), zeus::CVector3f(-0.1f, 0.f, b)};
|
|
}
|
|
|
|
}
|