mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-09-21 04:29:36 +00:00
124 lines
4.2 KiB
C++
124 lines
4.2 KiB
C++
#include "MetroidPrime/Weapons/CElectricBeamProjectile.hpp"
|
|
|
|
#include "MetaRender/CCubeRenderer.hpp"
|
|
|
|
#include "Kyoto/Math/CloseEnough.hpp"
|
|
#include "Kyoto/Particles/CElementGen.hpp"
|
|
#include "Kyoto/Particles/CParticleElectric.hpp"
|
|
|
|
|
|
#include "rstl/math.hpp"
|
|
|
|
CElectricBeamProjectile::CElectricBeamProjectile(const TToken< CWeaponDescription >& wDesc,
|
|
EWeaponType wType, const SElectricBeamInfo& elec,
|
|
const CTransform4f& xf, EMaterialTypes matTypes,
|
|
const CDamageInfo& dInfo, TUniqueId uid,
|
|
TAreaId areaId, TUniqueId owner,
|
|
EProjectileAttrib attribs)
|
|
: CBeamProjectile(wDesc, rstl::string_l("ElectricBeamProjectile"), wType, xf, elec.x8_maxLength,
|
|
elec.xc_radius, elec.x10_travelSpeed, matTypes, dInfo, uid, areaId, owner,
|
|
attribs, false)
|
|
, x468_electric(rs_new CParticleElectric(elec.x0_electricDescription))
|
|
, x46c_genDescription(gpSimplePool->GetObj(SObjectTag('PART', elec.x14_particleId)))
|
|
, x478_elementGen(rs_new CElementGen(x46c_genDescription))
|
|
, x47c_fadeSpeed(elec.x18_fadeSpeed)
|
|
, x484_damageTimer(0.f)
|
|
, x488_damageInterval(elec.x1c_damageInterval)
|
|
, x48c_(false) {
|
|
x478_elementGen->SetParticleEmission(false);
|
|
x468_electric->SetParticleEmission(false);
|
|
}
|
|
|
|
void CElectricBeamProjectile::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|
|
|
|
void CElectricBeamProjectile::Touch(CActor&, CStateManager&) {}
|
|
|
|
void CElectricBeamProjectile::AddToRenderer(const CFrustumPlanes&, const CStateManager& mgr) const {
|
|
if (GetActive()) {
|
|
gpRender->AddParticleGen(*x478_elementGen);
|
|
gpRender->AddParticleGen(*x468_electric);
|
|
}
|
|
}
|
|
|
|
void CElectricBeamProjectile::UpdateFx(const CTransform4f& xf, float dt, CStateManager& mgr) {
|
|
if (!GetActive())
|
|
return;
|
|
|
|
if (x484_damageTimer <= 0.f)
|
|
CauseDamage(true);
|
|
|
|
if (GetDamageType() == kDT_Actor) {
|
|
x484_damageTimer = x488_damageInterval;
|
|
CauseDamage(false);
|
|
}
|
|
|
|
x484_damageTimer -= dt;
|
|
if (!close_enough(x47c_fadeSpeed, 0.f)) {
|
|
float fVar1 = x48c_ ? 1.f : -1.f;
|
|
x480_intensity = rstl::min_val(1.f, dt * (fVar1 / x47c_fadeSpeed) + x480_intensity);
|
|
if (x480_intensity < 0.f) {
|
|
ResetBeam(mgr, true);
|
|
}
|
|
} else {
|
|
x480_intensity = 1.f;
|
|
}
|
|
|
|
CBeamProjectile::UpdateFx(xf, dt, mgr);
|
|
|
|
x478_elementGen->SetModulationColor(
|
|
CColor::Lerp(CColor::Black(), CColor::White(), x480_intensity));
|
|
bool hasDamage = GetDamageType() != kDT_None;
|
|
if (hasDamage) {
|
|
x478_elementGen->SetGlobalOrientation(
|
|
CTransform4f::LookAt(CVector3f::Zero(), GetSurfaceNormal(), CVector3f::Up()));
|
|
x478_elementGen->SetGlobalTranslation(GetCurrentPos() + (0.001f * GetSurfaceNormal()));
|
|
}
|
|
x478_elementGen->SetParticleEmission(hasDamage);
|
|
x478_elementGen->Update(dt);
|
|
|
|
x468_electric->SetModulationColor(CColor::Lerp(CColor::Black(), CColor::White(), x480_intensity));
|
|
x468_electric->SetParticleEmission(true);
|
|
CVector3f dist = GetCurrentPos() - GetBeamTransform().GetTranslation();
|
|
if (dist.CanBeNormalized()) {
|
|
dist.Normalize();
|
|
}
|
|
x468_electric->SetOverrideIPos(GetBeamTransform().GetTranslation());
|
|
x468_electric->SetOverrideIVel(dist);
|
|
x468_electric->SetOverrideFPos(GetCurrentPos());
|
|
x468_electric->SetOverrideFVel(-dist);
|
|
x468_electric->Update(dt);
|
|
}
|
|
|
|
void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) {
|
|
if (b) {
|
|
SetActive(false);
|
|
x478_elementGen->SetParticleEmission(false);
|
|
x468_electric->SetParticleEmission(false);
|
|
CBeamProjectile::ResetBeam(mgr, true);
|
|
} else {
|
|
x48c_ = false;
|
|
}
|
|
}
|
|
|
|
void CElectricBeamProjectile::Fire(const CTransform4f&, CStateManager&, bool) {
|
|
x48c_ = true;
|
|
SetActive(true);
|
|
x480_intensity = 0.f;
|
|
}
|
|
|
|
void CElectricBeamProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
|
|
CStateManager& mgr) {
|
|
switch (msg) {
|
|
case kSM_Registered:
|
|
mgr.AddWeaponId(GetOwnerId(), GetType());
|
|
CauseDamage(true);
|
|
break;
|
|
case kSM_Deleted:
|
|
DeleteProjectileLight(mgr);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
CGameProjectile::AcceptScriptMsg(msg, uid, mgr);
|
|
}
|