diff --git a/Runtime/MP1/World/CAtomicBeta.cpp b/Runtime/MP1/World/CAtomicBeta.cpp index 72a37fe78..02f0ce563 100644 --- a/Runtime/MP1/World/CAtomicBeta.cpp +++ b/Runtime/MP1/World/CAtomicBeta.cpp @@ -50,10 +50,11 @@ void CAtomicBeta::CreateBeams(CStateManager& mgr) { const SElectricBeamInfo beamInfo{x600_electricWeapon, 50.f, x634_beamRadius, 10.f, x62c_beamParticle, x630_, x638_}; for (size_t i = 0; i < kBombCount; ++i) { - x568_projectileIds.push_back(mgr.AllocateUniqueId()); + const TUniqueId id = mgr.AllocateUniqueId(); + x568_projectileIds.push_back(id); mgr.AddObject(new CElectricBeamProjectile(x608_, EWeaponType::AI, beamInfo, {}, EMaterialTypes::Character, - x610_projectileDamage, x568_projectileIds[i], GetAreaIdAlways(), - GetUniqueId(), EProjectileAttrib::None)); + x610_projectileDamage, id, GetAreaIdAlways(), GetUniqueId(), + EProjectileAttrib::None)); } } @@ -62,9 +63,9 @@ void CAtomicBeta::UpdateBeams(CStateManager& mgr, bool fireBeam) { return; } - for (size_t i = 0; i < kBombCount; ++i) { - //zeus::CTransform xf = GetTransform() * GetScaledLocatorTransform(skBombLocators[i]); - //zeus::CTransform newXf = zeus::lookAt(xf.origin, xf.origin + xf.basis[1], zeus::skUp); + for (size_t i = 0; i < x568_projectileIds.size(); ++i) { + // zeus::CTransform xf = GetTransform() * GetScaledLocatorTransform(skBombLocators[i]); + // zeus::CTransform newXf = zeus::lookAt(xf.origin, xf.origin + xf.basis[1], zeus::skUp); if (auto* const proj = static_cast(mgr.ObjectById(x568_projectileIds[i]))) { if (fireBeam) { proj->Fire(GetTransform() * GetScaledLocatorTransform(skBombLocators[i]), mgr, false); @@ -130,19 +131,20 @@ void CAtomicBeta::Think(float dt, CStateManager& mgr) { UpdateOrCreateEmitter(x654_, x648_, GetTranslation(), 96 / 127.f); DestroyEmitter(x64c_); } else { + UpdateBeams(mgr, false); DestroyEmitter(x650_); DestroyEmitter(x654_); UpdateOrCreateEmitter(x64c_, x644_, GetTranslation(), 96 / 127.f); } - for (size_t i = 0; i < kBombCount; ++i) { + // was hardcoded to 3 (kBombCount), but that segfaults after FreeBeams + for (size_t i = 0; i < x568_projectileIds.size(); ++i) { if (auto* const proj = static_cast(mgr.ObjectById(x568_projectileIds[i]))) { if (!proj->GetActive()) { continue; } - const zeus::CTransform xf = GetTransform() * GetScaledLocatorTransform(skBombLocators[i]); - proj->UpdateFx(zeus::lookAt(xf.origin, xf.origin + xf.basis[1], zeus::skUp), dt, mgr); + proj->UpdateFx(zeus::lookAt(xf.origin, xf.origin + xf.frontVector(), zeus::skUp), dt, mgr); } } @@ -168,6 +170,6 @@ void CAtomicBeta::Death(CStateManager& mgr, const zeus::CVector3f& dir, EScriptO bool CAtomicBeta::IsPlayerBeamChargedEnough(const CStateManager& mgr) { const CPlayerGun* gun = mgr.GetPlayer().GetPlayerGun(); - return (gun->IsCharging() ? gun->GetChargeBeamFactor() : 0.f) > .1f; + return (gun->IsCharging() ? gun->GetChargeBeamFactor() : 0.f) > 0.1f; } -} // namespace urde::MP1 \ No newline at end of file +} // namespace urde::MP1 diff --git a/Runtime/Weapon/CElectricBeamProjectile.cpp b/Runtime/Weapon/CElectricBeamProjectile.cpp index 7b0376b11..9b420bdc0 100644 --- a/Runtime/Weapon/CElectricBeamProjectile.cpp +++ b/Runtime/Weapon/CElectricBeamProjectile.cpp @@ -59,12 +59,41 @@ void CElectricBeamProjectile::UpdateFx(const zeus::CTransform& xf, float dt, CSt } x484_ -= dt; - float f2 = zeus::close_enough(x47c_, 0.f) && x48c_ != 0 ? 1.f : -1.f; - /* TODO: Finish */ + if (zeus::close_enough(x47c_, 0.f)) { + x480_ = 1.f; + } else { + float fVar1 = x48c_ ? 1.f : -1.f; + x480_ = std::min(1.f, dt * (fVar1 / x47c_) + x480_); + if (x480_ < 0.f) { + ResetBeam(mgr, true); + } + } + + CBeamProjectile::UpdateFx(xf, dt, mgr); + + x478_elementGen->SetModulationColor(zeus::CColor::lerp(zeus::skBlack, zeus::skWhite, x480_)); + bool hasDamage = GetDamageType() != EDamageType::None; + if (hasDamage) { + x478_elementGen->SetGlobalOrientation(zeus::lookAt(zeus::skZero3f, GetSurfaceNormal(), zeus::skUp)); + x478_elementGen->SetGlobalTranslation(GetCurrentPos() + (0.001f * GetSurfaceNormal())); + } + x478_elementGen->SetParticleEmission(hasDamage); + x478_elementGen->Update(dt); + + x468_electric->SetModulationColor(zeus::CColor::lerp(zeus::skBlack, zeus::skWhite, x480_)); + x468_electric->SetParticleEmission(true); + zeus::CVector3f dist = GetCurrentPos() - GetBeamTransform().origin; + if (dist.canBeNormalized()) { + dist.normalize(); + } + x468_electric->SetOverrideIPos(GetBeamTransform().origin); + x468_electric->SetOverrideIVel(dist); + x468_electric->SetOverrideFPos(GetCurrentPos()); + x468_electric->SetOverrideFVel(-dist); + x468_electric->Update(dt); } -void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) -{ +void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) { if (b) { SetActive(false); x478_elementGen->SetParticleEmission(false); @@ -80,4 +109,4 @@ void CElectricBeamProjectile::Fire(const zeus::CTransform&, CStateManager&, bool SetActive(true); x480_ = 0.f; } -} // namespace urde \ No newline at end of file +} // namespace urde diff --git a/Runtime/Weapon/CElectricBeamProjectile.hpp b/Runtime/Weapon/CElectricBeamProjectile.hpp index ce6c506e1..ce537d816 100644 --- a/Runtime/Weapon/CElectricBeamProjectile.hpp +++ b/Runtime/Weapon/CElectricBeamProjectile.hpp @@ -14,9 +14,10 @@ struct SElectricBeamInfo { float x18_; float x1c_; }; + class CElectricBeamProjectile : public CBeamProjectile { std::unique_ptr x468_electric; - TToken x46c_genDescription; + TCachedToken x46c_genDescription; std::unique_ptr x478_elementGen; float x47c_; float x480_; @@ -37,4 +38,4 @@ public: void ResetBeam(CStateManager&, bool) override; void Fire(const zeus::CTransform&, CStateManager&, bool) override; }; -} // namespace urde \ No newline at end of file +} // namespace urde