metaforce/Runtime/Weapon/CIceBeam.cpp

144 lines
4.6 KiB
C++
Raw Normal View History

#include "Runtime/Weapon/CIceBeam.hpp"
#include <array>
#include "Runtime/CSimplePool.hpp"
#include "Runtime/GameGlobalObjects.hpp"
2021-04-10 08:42:06 +00:00
namespace metaforce {
2018-12-08 05:30:43 +00:00
CIceBeam::CIceBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial,
const zeus::CVector3f& scale)
: CGunWeapon(characterId, type, playerId, playerMaterial, scale) {
x21c_iceSmoke = g_SimplePool->GetObj("IceSmoke");
x228_ice2nd1 = g_SimplePool->GetObj("Ice2nd_1");
x234_ice2nd2 = g_SimplePool->GetObj("Ice2nd_2");
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::PreRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf) {
// Empty
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::PostRenderGunFx(const CStateManager& mgr, const zeus::CTransform& xf) {
bool subtractBlend = mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot;
if (subtractBlend)
CElementGen::SetSubtractBlend(true);
if (x240_smokeGen)
x240_smokeGen->Render();
if (x1cc_enabledSecondaryEffect != ESecondaryFxType::None && x244_chargeFx)
x244_chargeFx->Render();
CGunWeapon::PostRenderGunFx(mgr, xf);
if (subtractBlend)
CElementGen::SetSubtractBlend(false);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, const zeus::CTransform& xf) {
if (x240_smokeGen) {
zeus::CTransform beamLoc = x10_solidModelData->GetScaledLocatorTransform("LBEAM");
x240_smokeGen->SetTranslation(beamLoc.origin);
x240_smokeGen->SetOrientation(beamLoc.getRotation());
x240_smokeGen->Update(dt);
}
if (x244_chargeFx) {
if (x248_25_inEndFx && x244_chargeFx->IsSystemDeletable()) {
x1cc_enabledSecondaryEffect = ESecondaryFxType::None;
x244_chargeFx.reset();
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
if (x1cc_enabledSecondaryEffect != ESecondaryFxType::None) {
if (x248_25_inEndFx) {
x244_chargeFx->SetTranslation(xf.origin);
x244_chargeFx->SetOrientation(xf.getRotation());
} else {
x244_chargeFx->SetGlobalOrientAndTrans(xf);
}
x244_chargeFx->Update(dt);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
}
2017-09-07 03:55:31 +00:00
2018-12-08 05:30:43 +00:00
CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::Fire(bool underwater, float dt, EChargeState chargeState, const zeus::CTransform& xf, CStateManager& mgr,
TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) {
static constexpr std::array<u16, 2> soundId{SFXwpn_fire_ice_normal, SFXwpn_fire_ice_charged};
2018-12-08 05:30:43 +00:00
CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1, chargeFactor2);
NWeaponTypes::play_sfx(soundId[size_t(chargeState)], underwater, false, 0.165f);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::EnableFx(bool enable) {
if (x240_smokeGen)
x240_smokeGen->SetParticleEmission(enable);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::EnableSecondaryFx(ESecondaryFxType type) {
switch (type) {
case ESecondaryFxType::CancelCharge:
case ESecondaryFxType::None:
if (x1cc_enabledSecondaryEffect == ESecondaryFxType::None)
break;
2019-02-18 05:47:46 +00:00
[[fallthrough]];
2018-12-08 05:30:43 +00:00
default:
switch (type) {
2017-09-07 03:55:31 +00:00
case ESecondaryFxType::None:
2018-12-08 05:30:43 +00:00
case ESecondaryFxType::ToCombo:
case ESecondaryFxType::CancelCharge:
if (!x248_25_inEndFx) {
x244_chargeFx = std::make_unique<CElementGen>(x234_ice2nd2);
x244_chargeFx->SetGlobalScale(x4_scale);
x248_25_inEndFx = true;
x1cc_enabledSecondaryEffect = ESecondaryFxType::CancelCharge;
}
break;
case ESecondaryFxType::Charge:
x244_chargeFx = std::make_unique<CElementGen>(x228_ice2nd1);
x244_chargeFx->SetGlobalScale(x4_scale);
x248_25_inEndFx = false;
x1cc_enabledSecondaryEffect = type;
break;
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
break;
}
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::Update(float dt, CStateManager& mgr) {
CGunWeapon::Update(dt, mgr);
if (!x248_24_loaded) {
x248_24_loaded = x21c_iceSmoke.IsLoaded() && x228_ice2nd1.IsLoaded() && x234_ice2nd2.IsLoaded();
if (x248_24_loaded) {
x240_smokeGen = std::make_unique<CElementGen>(x21c_iceSmoke);
x240_smokeGen->SetGlobalScale(x4_scale);
x240_smokeGen->SetParticleEmission(false);
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
}
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::Load(CStateManager& mgr, bool subtypeBasePose) {
CGunWeapon::Load(mgr, subtypeBasePose);
x21c_iceSmoke.Lock();
x228_ice2nd1.Lock();
x234_ice2nd2.Lock();
x248_25_inEndFx = false;
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::ReInitVariables() {
x240_smokeGen.reset();
x244_chargeFx.reset();
x248_24_loaded = false;
x248_25_inEndFx = false;
x1cc_enabledSecondaryEffect = ESecondaryFxType::None;
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CIceBeam::Unload(CStateManager& mgr) {
CGunWeapon::Unload(mgr);
x234_ice2nd2.Unlock();
x228_ice2nd1.Unlock();
x21c_iceSmoke.Unlock();
ReInitVariables();
2017-09-07 03:55:31 +00:00
}
2018-12-08 05:30:43 +00:00
bool CIceBeam::IsLoaded() const { return CGunWeapon::IsLoaded() && x248_24_loaded; }
2021-04-10 08:42:06 +00:00
} // namespace metaforce