mirror of https://github.com/AxioDL/metaforce.git
Finish CProjectileWeapon
This commit is contained in:
parent
083571e693
commit
3754962301
|
@ -160,7 +160,7 @@ public:
|
||||||
FourCC Get4CharId() const { return FOURCC('SWHC'); }
|
FourCC Get4CharId() const { return FOURCC('SWHC'); }
|
||||||
void SetRenderGaps(bool r) { x1d0_27_renderGaps = r; }
|
void SetRenderGaps(bool r) { x1d0_27_renderGaps = r; }
|
||||||
|
|
||||||
void DoBallSwooshWarmup()
|
void DoWarmupUpdate()
|
||||||
{
|
{
|
||||||
x1d0_26_disableUpdate = true;
|
x1d0_26_disableUpdate = true;
|
||||||
Update(0.0);
|
Update(0.0);
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct SCollisionResponseData
|
||||||
SCollisionResponseData() = default;
|
SCollisionResponseData() = default;
|
||||||
SCollisionResponseData(CToken&& tok, bool found)
|
SCollisionResponseData(CToken&& tok, bool found)
|
||||||
: m_res(std::move(tok)), m_found(found) {}
|
: m_res(std::move(tok)), m_found(found) {}
|
||||||
|
operator bool() const { return m_found; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CWeaponDescription
|
class CWeaponDescription
|
||||||
|
|
|
@ -23,7 +23,7 @@ CGameProjectile::CGameProjectile(bool active, const TToken<CWeaponDescription>&
|
||||||
{EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}),
|
{EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, matType, EMaterialTypes::Solid}),
|
||||||
CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()),
|
CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()),
|
||||||
x158_visorParticle(visorParticle), x168_visorSfx(visorSfx), x170_projectile(wDesc, xf.origin, xf.basis, scale,
|
x158_visorParticle(visorParticle), x168_visorSfx(visorSfx), x170_projectile(wDesc, xf.origin, xf.basis, scale,
|
||||||
(attribs & EProjectileAttrib::Sixteen) != EProjectileAttrib::None), x298_(xf.origin),
|
(attribs & EProjectileAttrib::Sixteen) == EProjectileAttrib::Sixteen), x298_(xf.origin),
|
||||||
x2a4_((xe8_projectileAttribs & EProjectileAttrib::Ten) == EProjectileAttrib::Ten ? 0.25f : 0.1f),
|
x2a4_((xe8_projectileAttribs & EProjectileAttrib::Ten) == EProjectileAttrib::Ten ? 0.25f : 0.1f),
|
||||||
x2c0_homingTargetId(homingTarget), x2cc_wpscId(wDesc.GetObjectTag()->id)
|
x2c0_homingTargetId(homingTarget), x2cc_wpscId(wDesc.GetObjectTag()->id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,14 +1,82 @@
|
||||||
#include "CProjectileWeapon.hpp"
|
#include "CProjectileWeapon.hpp"
|
||||||
|
#include "Graphics/CModel.hpp"
|
||||||
|
#include "Particle/CParticleGlobals.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
u16 CProjectileWeapon::g_GlobalSeed = 99;
|
u16 CProjectileWeapon::g_GlobalSeed = 99;
|
||||||
|
|
||||||
CProjectileWeapon::CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f&, const zeus::CTransform&,
|
CProjectileWeapon::CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f& worldOffset,
|
||||||
const zeus::CVector3f&, s32)
|
const zeus::CTransform& localToWorld, const zeus::CVector3f& scale, s32 flags)
|
||||||
: x4_weaponDesc(wDesc)
|
: x4_weaponDesc(wDesc), x10_random(g_GlobalSeed), x14_localToWorldXf(localToWorld), x74_worldOffset(worldOffset),
|
||||||
|
xe4_flags(flags)
|
||||||
{
|
{
|
||||||
|
x124_24_active = true;
|
||||||
|
CGlobalRandom gr(x10_random);
|
||||||
|
x124_31_VMD2 = x4_weaponDesc->x10_VMD2;
|
||||||
|
x124_25_APSO = x4_weaponDesc->x28_APSO;
|
||||||
|
if (x4_weaponDesc->x34_APSM)
|
||||||
|
{
|
||||||
|
xfc_APSMGen = std::make_unique<CElementGen>(x4_weaponDesc->x34_APSM.m_token,
|
||||||
|
CElementGen::EModelOrientationType::Normal,
|
||||||
|
(xe4_flags & 0x1) == 0x1 ?
|
||||||
|
CElementGen::EOptionalSystemFlags::Two :
|
||||||
|
CElementGen::EOptionalSystemFlags::One);
|
||||||
|
xfc_APSMGen->SetGlobalScale(scale);
|
||||||
|
}
|
||||||
|
if (x4_weaponDesc->x44_APS2)
|
||||||
|
{
|
||||||
|
x100_APS2Gen = std::make_unique<CElementGen>(x4_weaponDesc->x44_APS2.m_token,
|
||||||
|
CElementGen::EModelOrientationType::Normal,
|
||||||
|
(xe4_flags & 0x1) == 0x1 ?
|
||||||
|
CElementGen::EOptionalSystemFlags::Two :
|
||||||
|
CElementGen::EOptionalSystemFlags::One);
|
||||||
|
x100_APS2Gen->SetGlobalScale(scale);
|
||||||
|
}
|
||||||
|
if (x4_weaponDesc->x54_ASW1)
|
||||||
|
{
|
||||||
|
x118_swoosh1 = std::make_unique<CParticleSwoosh>(x4_weaponDesc->x54_ASW1.m_token, 0);
|
||||||
|
x118_swoosh1->SetGlobalScale(scale);
|
||||||
|
}
|
||||||
|
if (x4_weaponDesc->x64_ASW2)
|
||||||
|
{
|
||||||
|
x11c_swoosh2 = std::make_unique<CParticleSwoosh>(x4_weaponDesc->x64_ASW2.m_token, 0);
|
||||||
|
x11c_swoosh2->SetGlobalScale(scale);
|
||||||
|
}
|
||||||
|
if (x4_weaponDesc->x74_ASW3)
|
||||||
|
{
|
||||||
|
x120_swoosh3 = std::make_unique<CParticleSwoosh>(x4_weaponDesc->x74_ASW3.m_token, 0);
|
||||||
|
x120_swoosh3->SetGlobalScale(scale);
|
||||||
|
}
|
||||||
|
if (CIntElement* pslt = x4_weaponDesc->x14_PSLT.get())
|
||||||
|
pslt->GetValue(0, xe8_lifetime);
|
||||||
|
else
|
||||||
|
xe8_lifetime = 0x7FFFFF;
|
||||||
|
if (CVectorElement* ivec = x4_weaponDesc->x4_IVEC.get())
|
||||||
|
ivec->GetValue(0, xb0_velocity);
|
||||||
|
if (CVectorElement* iorn = x4_weaponDesc->x0_IORN.get())
|
||||||
|
{
|
||||||
|
zeus::CTransform xf;
|
||||||
|
zeus::CVector3f orn;
|
||||||
|
iorn->GetValue(0, orn);
|
||||||
|
xf.rotateLocalX(zeus::degToRad(orn.x));
|
||||||
|
xf.rotateLocalY(zeus::degToRad(orn.y));
|
||||||
|
xf.rotateLocalZ(zeus::degToRad(orn.z));
|
||||||
|
SetRelativeOrientation(xf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetRelativeOrientation(zeus::CTransform::Identity());
|
||||||
|
}
|
||||||
|
if (x4_weaponDesc->x84_OHEF)
|
||||||
|
x108_model.emplace(x4_weaponDesc->x84_OHEF.m_token);
|
||||||
|
x124_26_AP11 = x4_weaponDesc->x2a_AP11;
|
||||||
|
x124_27_AP21 = x4_weaponDesc->x2b_AP21;
|
||||||
|
x124_28_AS11 = x4_weaponDesc->x2c_AS11;
|
||||||
|
x124_29_AS12 = x4_weaponDesc->x2d_AS12;
|
||||||
|
x124_30_AS13 = x4_weaponDesc->x2e_AS13;
|
||||||
|
UpdateChildParticleSystems(1.f / 60.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CTransform CProjectileWeapon::GetTransform() const
|
zeus::CTransform CProjectileWeapon::GetTransform() const
|
||||||
|
@ -18,27 +86,315 @@ zeus::CTransform CProjectileWeapon::GetTransform() const
|
||||||
|
|
||||||
zeus::CVector3f CProjectileWeapon::GetTranslation() const
|
zeus::CVector3f CProjectileWeapon::GetTranslation() const
|
||||||
{
|
{
|
||||||
return x14_localToWorldXf * (x44_localXf * x8c_ + x80_) + x74_;
|
return x14_localToWorldXf * (x44_localXf * x8c_projOffset + x80_localOffset) + x74_worldOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CProjectileWeapon::GetAudibleFallOff() const
|
||||||
|
{
|
||||||
|
if (!x4_weaponDesc->x94_COLR)
|
||||||
|
return 0.f;
|
||||||
|
return x4_weaponDesc->x94_COLR.m_res->GetAudibleFallOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
float CProjectileWeapon::GetAudibleRange() const
|
||||||
|
{
|
||||||
|
if (!x4_weaponDesc->x94_COLR)
|
||||||
|
return 0.f;
|
||||||
|
return x4_weaponDesc->x94_COLR.m_res->GetAudibleRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
rstl::optional_object<TLockedToken<CDecalDescription>>
|
||||||
|
CProjectileWeapon::GetDecalForCollision(EWeaponCollisionResponseTypes type) const
|
||||||
|
{
|
||||||
|
if (!x4_weaponDesc->x94_COLR)
|
||||||
|
return {};
|
||||||
|
return x4_weaponDesc->x94_COLR.m_res->GetDecalDescription(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 CProjectileWeapon::GetSoundIdForCollision(EWeaponCollisionResponseTypes type) const
|
||||||
|
{
|
||||||
|
if (!x4_weaponDesc->x94_COLR)
|
||||||
|
return 0xffff;
|
||||||
|
return u16(x4_weaponDesc->x94_COLR.m_res->GetSoundEffectId(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
rstl::optional_object<TLockedToken<CGenDescription>>
|
||||||
|
CProjectileWeapon::CollisionOccured(EWeaponCollisionResponseTypes type, bool alive, bool b2,
|
||||||
|
const zeus::CVector3f& v1, const zeus::CVector3f& v2,
|
||||||
|
const zeus::CVector3f& target)
|
||||||
|
{
|
||||||
|
x80_localOffset = x14_localToWorldXf.transposeRotate(v1 - x74_worldOffset) - x8c_projOffset;
|
||||||
|
zeus::CVector3f posToTarget = target - GetTranslation();
|
||||||
|
if (alive)
|
||||||
|
{
|
||||||
|
if (b2 && posToTarget.canBeNormalized())
|
||||||
|
{
|
||||||
|
SetWorldSpaceOrientation(zeus::lookAt(zeus::CVector3f::skZero, posToTarget.normalized()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zeus::CTransform xf = GetTransform();
|
||||||
|
SetWorldSpaceOrientation(
|
||||||
|
zeus::lookAt(zeus::CVector3f::skZero, xf.basis[1] - v2 * (v2.dot(xf.basis[1]) * 2.f), v2));
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x124_24_active = false;
|
||||||
|
if (xfc_APSMGen)
|
||||||
|
xfc_APSMGen->SetParticleEmission(false);
|
||||||
|
if (x100_APS2Gen)
|
||||||
|
x100_APS2Gen->SetParticleEmission(false);
|
||||||
|
if (x118_swoosh1)
|
||||||
|
x118_swoosh1->SetParticleEmission(false);
|
||||||
|
if (x11c_swoosh2)
|
||||||
|
x11c_swoosh2->SetParticleEmission(false);
|
||||||
|
if (x120_swoosh3)
|
||||||
|
x120_swoosh3->SetParticleEmission(false);
|
||||||
|
if (!x4_weaponDesc->x94_COLR)
|
||||||
|
return {};
|
||||||
|
return x4_weaponDesc->x94_COLR.m_res->GetParticleDescription(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProjectileWeapon::RenderParticles() const
|
void CProjectileWeapon::RenderParticles() const
|
||||||
{
|
{
|
||||||
|
if (xfc_APSMGen)
|
||||||
|
xfc_APSMGen->Render();
|
||||||
|
if (x100_APS2Gen)
|
||||||
|
x100_APS2Gen->Render();
|
||||||
|
if (x118_swoosh1)
|
||||||
|
x118_swoosh1->Render();
|
||||||
|
if (x11c_swoosh2)
|
||||||
|
x11c_swoosh2->Render();
|
||||||
|
if (x120_swoosh3)
|
||||||
|
x120_swoosh3->Render();
|
||||||
|
if (x104_)
|
||||||
|
x104_->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProjectileWeapon::Update(float dt)
|
void CProjectileWeapon::UpdateParticles(double dt)
|
||||||
{
|
{
|
||||||
|
if (xfc_APSMGen)
|
||||||
|
xfc_APSMGen->Update(dt);
|
||||||
|
if (x100_APS2Gen)
|
||||||
|
x100_APS2Gen->Update(dt);
|
||||||
|
if (x118_swoosh1)
|
||||||
|
x118_swoosh1->Update(dt);
|
||||||
|
if (x11c_swoosh2)
|
||||||
|
x11c_swoosh2->Update(dt);
|
||||||
|
if (x120_swoosh3)
|
||||||
|
x120_swoosh3->Update(dt);
|
||||||
|
if (x104_)
|
||||||
|
x104_->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProjectileWeapon::UpdateParticleFx()
|
void CProjectileWeapon::Render() const
|
||||||
{
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime || !x124_24_active || !x108_model)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CGraphics::SetModelMatrix(zeus::CTransform::Translate(x74_worldOffset) * x14_localToWorldXf *
|
||||||
|
zeus::CTransform::Translate(x44_localXf * x8c_projOffset + x80_localOffset + xa4_localOffset2) *
|
||||||
|
zeus::CTransform::Scale(x98_scale) * x44_localXf);
|
||||||
|
|
||||||
|
std::vector<CLight> useLights;
|
||||||
|
useLights.push_back(CLight::BuildLocalAmbient({}, xc8_ambientLightColor));
|
||||||
|
const_cast<CModel&>(**x108_model).GetInstance().ActivateLights(useLights);
|
||||||
|
CModelFlags flags(0, 0, 3, zeus::CColor::skWhite);
|
||||||
|
(*x108_model)->Draw(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProjectileWeapon::IsSystemDeletable() const
|
||||||
|
{
|
||||||
|
if (xfc_APSMGen && !xfc_APSMGen->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x100_APS2Gen && !x100_APS2Gen->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x118_swoosh1 && !x118_swoosh1->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x11c_swoosh2 && !x11c_swoosh2->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x120_swoosh3 && !x120_swoosh3->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x104_ && !x104_->IsSystemDeletable())
|
||||||
|
return false;
|
||||||
|
if (x124_24_active)
|
||||||
|
return xf4_curFrame >= xe8_lifetime;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProjectileWeapon::UpdateChildParticleSystems(float dt)
|
void CProjectileWeapon::UpdateChildParticleSystems(float dt)
|
||||||
{
|
{
|
||||||
|
double useDt;
|
||||||
|
if (zeus::close_enough(dt, 1.f / 60.f))
|
||||||
|
useDt = 1.0 / 60.0;
|
||||||
|
else
|
||||||
|
useDt = dt;
|
||||||
|
|
||||||
|
if (xfc_APSMGen)
|
||||||
|
{
|
||||||
|
if (xf8_lastParticleFrame != xf4_curFrame)
|
||||||
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime)
|
||||||
|
{
|
||||||
|
xfc_APSMGen->SetParticleEmission(false);
|
||||||
|
xfc_APSMGen->EndLifetime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x124_26_AP11)
|
||||||
|
xfc_APSMGen->SetGlobalTranslation(GetTranslation());
|
||||||
|
else
|
||||||
|
xfc_APSMGen->SetTranslation(GetTranslation());
|
||||||
|
if (x124_25_APSO)
|
||||||
|
xfc_APSMGen->SetOrientation(GetTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfc_APSMGen->Update(useDt);
|
||||||
|
if (xfc_APSMGen->IsSystemDeletable())
|
||||||
|
xfc_APSMGen.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x100_APS2Gen)
|
||||||
|
{
|
||||||
|
if (xf8_lastParticleFrame != xf4_curFrame)
|
||||||
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime)
|
||||||
|
{
|
||||||
|
x100_APS2Gen->SetParticleEmission(false);
|
||||||
|
x100_APS2Gen->EndLifetime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x124_27_AP21)
|
||||||
|
x100_APS2Gen->SetGlobalTranslation(GetTranslation());
|
||||||
|
else
|
||||||
|
x100_APS2Gen->SetTranslation(GetTranslation());
|
||||||
|
if (x124_25_APSO)
|
||||||
|
x100_APS2Gen->SetOrientation(GetTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x100_APS2Gen->Update(useDt);
|
||||||
|
if (x100_APS2Gen->IsSystemDeletable())
|
||||||
|
x100_APS2Gen.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x118_swoosh1)
|
||||||
|
{
|
||||||
|
if (xf8_lastParticleFrame != xf4_curFrame)
|
||||||
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime)
|
||||||
|
{
|
||||||
|
x118_swoosh1->SetParticleEmission(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x124_28_AS11)
|
||||||
|
x118_swoosh1->SetGlobalTranslation(GetTranslation());
|
||||||
|
else
|
||||||
|
x118_swoosh1->SetTranslation(GetTranslation());
|
||||||
|
x118_swoosh1->SetOrientation(GetTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x118_swoosh1->DoWarmupUpdate();
|
||||||
|
if (x118_swoosh1->IsSystemDeletable())
|
||||||
|
x118_swoosh1.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x11c_swoosh2)
|
||||||
|
{
|
||||||
|
if (xf8_lastParticleFrame != xf4_curFrame)
|
||||||
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime)
|
||||||
|
{
|
||||||
|
x11c_swoosh2->SetParticleEmission(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x124_29_AS12)
|
||||||
|
x11c_swoosh2->SetGlobalTranslation(GetTranslation());
|
||||||
|
else
|
||||||
|
x11c_swoosh2->SetTranslation(GetTranslation());
|
||||||
|
x11c_swoosh2->SetOrientation(GetTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x11c_swoosh2->DoWarmupUpdate();
|
||||||
|
if (x11c_swoosh2->IsSystemDeletable())
|
||||||
|
x11c_swoosh2.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x120_swoosh3)
|
||||||
|
{
|
||||||
|
if (xf8_lastParticleFrame != xf4_curFrame)
|
||||||
|
{
|
||||||
|
if (xf4_curFrame > xe8_lifetime)
|
||||||
|
{
|
||||||
|
x120_swoosh3->SetParticleEmission(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x124_30_AS13)
|
||||||
|
x120_swoosh3->SetGlobalTranslation(GetTranslation());
|
||||||
|
else
|
||||||
|
x120_swoosh3->SetTranslation(GetTranslation());
|
||||||
|
x120_swoosh3->SetOrientation(GetTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x120_swoosh3->DoWarmupUpdate();
|
||||||
|
if (x120_swoosh3->IsSystemDeletable())
|
||||||
|
x120_swoosh3.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x104_)
|
||||||
|
{
|
||||||
|
x104_->Update(useDt);
|
||||||
|
if (x104_->IsSystemDeletable())
|
||||||
|
x104_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
xf8_lastParticleFrame = xf4_curFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProjectileWeapon::UpdatePSTranslationAndOrientation()
|
||||||
|
{
|
||||||
|
if (xe8_lifetime < xf4_curFrame || !x124_24_active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (CModVectorElement* psvm = x4_weaponDesc->xc_PSVM.get())
|
||||||
|
psvm->GetValue(xf4_curFrame, xb0_velocity, x80_localOffset);
|
||||||
|
|
||||||
|
if (x124_31_VMD2)
|
||||||
|
x80_localOffset += x44_localXf * xb0_velocity;
|
||||||
|
else
|
||||||
|
x80_localOffset += xb0_velocity;
|
||||||
|
|
||||||
|
xb0_velocity += xbc_gravity / 60.f;
|
||||||
|
|
||||||
|
if (CVectorElement* psov = x4_weaponDesc->x8_PSOV.get())
|
||||||
|
{
|
||||||
|
zeus::CVector3f orient;
|
||||||
|
psov->GetValue(xf4_curFrame, orient);
|
||||||
|
|
||||||
|
zeus::CTransform xf = x44_localXf;
|
||||||
|
xf.rotateLocalX(zeus::degToRad(orient.x));
|
||||||
|
xf.rotateLocalY(zeus::degToRad(orient.y));
|
||||||
|
xf.rotateLocalZ(zeus::degToRad(orient.z));
|
||||||
|
SetRelativeOrientation(xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CVectorElement* pscl = x4_weaponDesc->x18_PSCL.get())
|
||||||
|
pscl->GetValue(xf4_curFrame, x98_scale);
|
||||||
|
|
||||||
|
if (CColorElement* pcol = x4_weaponDesc->x1c_PCOL.get())
|
||||||
|
pcol->GetValue(xf4_curFrame, xc8_ambientLightColor);
|
||||||
|
|
||||||
|
if (CVectorElement* pofs = x4_weaponDesc->x20_POFS.get())
|
||||||
|
pofs->GetValue(xf4_curFrame, xa4_localOffset2);
|
||||||
|
|
||||||
|
if (CVectorElement* ofst = x4_weaponDesc->x24_OFST.get())
|
||||||
|
ofst->GetValue(xf4_curFrame, x8c_projOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProjectileWeapon::SetWorldSpaceOrientation(const zeus::CTransform& xf)
|
void CProjectileWeapon::SetWorldSpaceOrientation(const zeus::CTransform& xf)
|
||||||
|
@ -46,4 +402,51 @@ void CProjectileWeapon::SetWorldSpaceOrientation(const zeus::CTransform& xf)
|
||||||
x44_localXf = x14_localToWorldXf.inverse() * xf;
|
x44_localXf = x14_localToWorldXf.inverse() * xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CProjectileWeapon::UpdateParticleFX()
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<xec_childSystemUpdateRate ; ++i)
|
||||||
|
UpdateChildParticleSystems(1.f / 60.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProjectileWeapon::Update(float dt)
|
||||||
|
{
|
||||||
|
CGlobalRandom gr(x10_random);
|
||||||
|
xec_childSystemUpdateRate = 0;
|
||||||
|
double useDt;
|
||||||
|
if (zeus::close_enough(dt, 1.f / 60.f))
|
||||||
|
useDt = 1.0 / 60.0;
|
||||||
|
else
|
||||||
|
useDt = dt;
|
||||||
|
useDt = std::max(0.0, useDt);
|
||||||
|
xd0_curTime += useDt;
|
||||||
|
|
||||||
|
double actualTime = xf4_curFrame * (1.0 / 60.0);
|
||||||
|
|
||||||
|
while (actualTime < xd0_curTime && !zeus::close_enough(actualTime, xd0_curTime))
|
||||||
|
{
|
||||||
|
if (xf4_curFrame < xe8_lifetime)
|
||||||
|
{
|
||||||
|
CParticleGlobals::SetEmitterTime(xf4_curFrame);
|
||||||
|
CParticleGlobals::SetParticleLifetime(xe8_lifetime);
|
||||||
|
CParticleGlobals::UpdateParticleLifetimeTweenValues(xf4_curFrame);
|
||||||
|
UpdatePSTranslationAndOrientation();
|
||||||
|
}
|
||||||
|
actualTime += (1.0 / 60.0);
|
||||||
|
++xf4_curFrame;
|
||||||
|
++xec_childSystemUpdateRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zeus::close_enough(actualTime, xd0_curTime))
|
||||||
|
xd0_curTime = actualTime;
|
||||||
|
|
||||||
|
xd8_remainderTime = (actualTime - xd0_curTime) * 60.0;
|
||||||
|
|
||||||
|
if (xf4_curFrame < xe8_lifetime)
|
||||||
|
{
|
||||||
|
xe0_maxTurnRate = 0.f;
|
||||||
|
if (CRealElement* trat = x4_weaponDesc->x30_TRAT.get())
|
||||||
|
trat->GetValue(0, xe0_maxTurnRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,14 @@
|
||||||
#include "Particle/CGenDescription.hpp"
|
#include "Particle/CGenDescription.hpp"
|
||||||
#include "Particle/CSwooshDescription.hpp"
|
#include "Particle/CSwooshDescription.hpp"
|
||||||
#include "Particle/CWeaponDescription.hpp"
|
#include "Particle/CWeaponDescription.hpp"
|
||||||
|
#include "Collision/CCollisionResponseData.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
class CModel;
|
class CModel;
|
||||||
|
class CDecalDescription;
|
||||||
|
class CGenDescription;
|
||||||
|
|
||||||
class CProjectileWeapon
|
class CProjectileWeapon
|
||||||
{
|
{
|
||||||
static u16 g_GlobalSeed;
|
static u16 g_GlobalSeed;
|
||||||
|
@ -21,28 +25,27 @@ class CProjectileWeapon
|
||||||
CRandom16 x10_random;
|
CRandom16 x10_random;
|
||||||
zeus::CTransform x14_localToWorldXf;
|
zeus::CTransform x14_localToWorldXf;
|
||||||
zeus::CTransform x44_localXf;
|
zeus::CTransform x44_localXf;
|
||||||
zeus::CVector3f x74_ = zeus::CVector3f::skZero;
|
zeus::CVector3f x74_worldOffset;
|
||||||
zeus::CVector3f x80_ = zeus::CVector3f::skZero;
|
zeus::CVector3f x80_localOffset = zeus::CVector3f::skZero;
|
||||||
zeus::CVector3f x8c_ = zeus::CVector3f::skZero;
|
zeus::CVector3f x8c_projOffset = zeus::CVector3f::skZero;
|
||||||
zeus::CVector3f x98_ = zeus::CVector3f::skOne;
|
zeus::CVector3f x98_scale = zeus::CVector3f::skOne;
|
||||||
zeus::CVector3f xa4_ = zeus::CVector3f::skZero;
|
zeus::CVector3f xa4_localOffset2 = zeus::CVector3f::skZero;
|
||||||
zeus::CVector3f xb0_ = zeus::CVector3f::skZero;
|
zeus::CVector3f xb0_velocity = zeus::CVector3f::skZero;
|
||||||
zeus::CVector3f xbc_ = zeus::CVector3f::skZero;
|
zeus::CVector3f xbc_gravity = zeus::CVector3f::skZero;
|
||||||
zeus::CColor xc8_ = zeus::CColor::skWhite;
|
zeus::CColor xc8_ambientLightColor = zeus::CColor::skWhite;
|
||||||
double xd0_ = 0.0;
|
double xd0_curTime = 0.0;
|
||||||
double xd8_ = 0.0;
|
double xd8_remainderTime = 0.0;
|
||||||
float xe0_maxTurnRate;
|
float xe0_maxTurnRate = 0.f;
|
||||||
u32 xe4_;
|
int xe4_flags;
|
||||||
u32 xe8_lifetime = 0x7FFFFF;
|
int xe8_lifetime = 0;
|
||||||
u32 xec_ = 0;
|
int xec_childSystemUpdateRate = 0;
|
||||||
u32 xf0_ = 0;
|
int xf0_ = 0;
|
||||||
u32 xf4_ = 0;
|
int xf4_curFrame = 0;
|
||||||
u32 xf8_ = 0;
|
int xf8_lastParticleFrame = -1;
|
||||||
u32 xfc_ = 0;
|
std::unique_ptr<CElementGen> xfc_APSMGen;
|
||||||
std::unique_ptr<CElementGen> x104_particle1;
|
std::unique_ptr<CElementGen> x100_APS2Gen;
|
||||||
std::unique_ptr<CElementGen> x104_particle2;
|
std::unique_ptr<CElementGen> x104_;
|
||||||
TToken<CModel> x108_model;
|
rstl::optional_object<TLockedToken<CModel>> x108_model;
|
||||||
bool x114_hasModel = false;
|
|
||||||
std::unique_ptr<CParticleSwoosh> x118_swoosh1;
|
std::unique_ptr<CParticleSwoosh> x118_swoosh1;
|
||||||
std::unique_ptr<CParticleSwoosh> x11c_swoosh2;
|
std::unique_ptr<CParticleSwoosh> x11c_swoosh2;
|
||||||
std::unique_ptr<CParticleSwoosh> x120_swoosh3;
|
std::unique_ptr<CParticleSwoosh> x120_swoosh3;
|
||||||
|
@ -51,31 +54,47 @@ class CProjectileWeapon
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool x124_24_active : 1;
|
bool x124_24_active : 1;
|
||||||
bool x124_25_ : 1;
|
bool x124_25_APSO : 1;
|
||||||
bool x124_26_ap11 : 1;
|
bool x124_26_AP11 : 1;
|
||||||
bool x124_27_ap21 : 1;
|
bool x124_27_AP21 : 1;
|
||||||
bool x124_28_as11 : 1;
|
bool x124_28_AS11 : 1;
|
||||||
bool x124_29_as12 : 1;
|
bool x124_29_AS12 : 1;
|
||||||
bool x124_30_as13 : 1;
|
bool x124_30_AS13 : 1;
|
||||||
|
bool x124_31_VMD2 : 1;
|
||||||
};
|
};
|
||||||
u32 _dummy = 0;
|
u32 _dummy = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f& pos,
|
CProjectileWeapon(const TToken<CWeaponDescription>& wDesc, const zeus::CVector3f& worldOffset,
|
||||||
const zeus::CTransform& orient, const zeus::CVector3f& scale, s32);
|
const zeus::CTransform& orient, const zeus::CVector3f& scale, s32);
|
||||||
virtual ~CProjectileWeapon() = default;
|
virtual ~CProjectileWeapon() = default;
|
||||||
bool IsProjectileActive() const { return x124_24_active; }
|
bool IsProjectileActive() const { return x124_24_active; }
|
||||||
virtual zeus::CTransform GetTransform() const;
|
const zeus::CVector3f& GetVelocity() const { return xb0_velocity; }
|
||||||
virtual zeus::CVector3f GetTranslation() const;
|
void SetVelocity(const zeus::CVector3f& vel) { xb0_velocity = vel; }
|
||||||
float GetMaxTurnRate() const { return xe0_maxTurnRate; }
|
float GetMaxTurnRate() const { return xe0_maxTurnRate; }
|
||||||
|
float GetAudibleFallOff() const;
|
||||||
|
float GetAudibleRange() const;
|
||||||
|
rstl::optional_object<TLockedToken<CDecalDescription>>
|
||||||
|
GetDecalForCollision(EWeaponCollisionResponseTypes type) const;
|
||||||
|
u16 GetSoundIdForCollision(EWeaponCollisionResponseTypes type) const;
|
||||||
|
rstl::optional_object<TLockedToken<CGenDescription>>
|
||||||
|
CollisionOccured(EWeaponCollisionResponseTypes type, bool alive, bool b2, const zeus::CVector3f& v1,
|
||||||
|
const zeus::CVector3f& v2, const zeus::CVector3f& target);
|
||||||
TLockedToken<CWeaponDescription> GetWeaponDescription() const { return x4_weaponDesc; }
|
TLockedToken<CWeaponDescription> GetWeaponDescription() const { return x4_weaponDesc; }
|
||||||
virtual void RenderParticles() const;
|
void RenderParticles() const;
|
||||||
virtual void Update(float);
|
virtual void UpdateParticles(double dt);
|
||||||
void UpdateParticleFx();
|
virtual void Render() const;
|
||||||
|
bool IsSystemDeletable() const;
|
||||||
void UpdateChildParticleSystems(float);
|
void UpdateChildParticleSystems(float);
|
||||||
|
void UpdatePSTranslationAndOrientation();
|
||||||
void SetWorldSpaceOrientation(const zeus::CTransform& xf);
|
void SetWorldSpaceOrientation(const zeus::CTransform& xf);
|
||||||
void SetRelativeOrientation(const zeus::CTransform& xf) { x44_localXf = xf; }
|
void SetRelativeOrientation(const zeus::CTransform& xf) { x44_localXf = xf; }
|
||||||
|
virtual zeus::CVector3f GetTranslation() const;
|
||||||
|
virtual zeus::CTransform GetTransform() const;
|
||||||
|
void UpdateParticleFX();
|
||||||
|
virtual void Update(float dt);
|
||||||
|
void SetGravity(const zeus::CVector3f& grav) { xbc_gravity = grav; }
|
||||||
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
|
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1202,19 +1202,19 @@ void CMorphBall::UpdateEffects(float dt, CStateManager& mgr)
|
||||||
zeus::CTransform swooshToWorld = GetSwooshToWorld();
|
zeus::CTransform swooshToWorld = GetSwooshToWorld();
|
||||||
x19b8_slowBlueTailSwooshGen->SetTranslation(swooshToWorld.rotate({0.1f, 0.f, 0.f}) + swooshToWorld.origin);
|
x19b8_slowBlueTailSwooshGen->SetTranslation(swooshToWorld.rotate({0.1f, 0.f, 0.f}) + swooshToWorld.origin);
|
||||||
x19b8_slowBlueTailSwooshGen->SetOrientation(swooshToWorld.getRotation());
|
x19b8_slowBlueTailSwooshGen->SetOrientation(swooshToWorld.getRotation());
|
||||||
x19b8_slowBlueTailSwooshGen->DoBallSwooshWarmup();
|
x19b8_slowBlueTailSwooshGen->DoWarmupUpdate();
|
||||||
x19bc_slowBlueTailSwooshGen2->SetTranslation(swooshToWorld.rotate({-0.1f, 0.f, 0.f}) + swooshToWorld.origin);
|
x19bc_slowBlueTailSwooshGen2->SetTranslation(swooshToWorld.rotate({-0.1f, 0.f, 0.f}) + swooshToWorld.origin);
|
||||||
x19bc_slowBlueTailSwooshGen2->SetOrientation(swooshToWorld.getRotation());
|
x19bc_slowBlueTailSwooshGen2->SetOrientation(swooshToWorld.getRotation());
|
||||||
x19bc_slowBlueTailSwooshGen2->DoBallSwooshWarmup();
|
x19bc_slowBlueTailSwooshGen2->DoWarmupUpdate();
|
||||||
x19c0_slowBlueTailSwoosh2Gen->SetTranslation(swooshToWorld.rotate({0.f, 0.f, 0.65f}) + swooshToWorld.origin);
|
x19c0_slowBlueTailSwoosh2Gen->SetTranslation(swooshToWorld.rotate({0.f, 0.f, 0.65f}) + swooshToWorld.origin);
|
||||||
x19c0_slowBlueTailSwoosh2Gen->SetOrientation(swooshToWorld.getRotation());
|
x19c0_slowBlueTailSwoosh2Gen->SetOrientation(swooshToWorld.getRotation());
|
||||||
x19c0_slowBlueTailSwoosh2Gen->DoBallSwooshWarmup();
|
x19c0_slowBlueTailSwoosh2Gen->DoWarmupUpdate();
|
||||||
x19c4_slowBlueTailSwoosh2Gen2->SetTranslation(swooshToWorld.rotate({0.f, 0.f, -0.65f}) + swooshToWorld.origin);
|
x19c4_slowBlueTailSwoosh2Gen2->SetTranslation(swooshToWorld.rotate({0.f, 0.f, -0.65f}) + swooshToWorld.origin);
|
||||||
x19c4_slowBlueTailSwoosh2Gen2->SetOrientation(swooshToWorld.getRotation());
|
x19c4_slowBlueTailSwoosh2Gen2->SetOrientation(swooshToWorld.getRotation());
|
||||||
x19c4_slowBlueTailSwoosh2Gen2->DoBallSwooshWarmup();
|
x19c4_slowBlueTailSwoosh2Gen2->DoWarmupUpdate();
|
||||||
x19c8_jaggyTrailGen->SetTranslation(swooshToWorld.origin);
|
x19c8_jaggyTrailGen->SetTranslation(swooshToWorld.origin);
|
||||||
x19c8_jaggyTrailGen->SetOrientation(swooshToWorld.getRotation());
|
x19c8_jaggyTrailGen->SetOrientation(swooshToWorld.getRotation());
|
||||||
x19c8_jaggyTrailGen->DoBallSwooshWarmup();
|
x19c8_jaggyTrailGen->DoWarmupUpdate();
|
||||||
x19cc_wallSparkGen->Update(dt);
|
x19cc_wallSparkGen->Update(dt);
|
||||||
x1bc8_wakeEffectGens[7]->Update(dt);
|
x1bc8_wakeEffectGens[7]->Update(dt);
|
||||||
bool emitRainWake = (x0_player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::OnGround &&
|
bool emitRainWake = (x0_player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::OnGround &&
|
||||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit c22f78e2e2de5361a13c2f4b9558a52820f9db14
|
Subproject commit f1d71e3e86f241ebd959b0a4e07f77913b34be63
|
Loading…
Reference in New Issue