Merge pull request #430 from shiiion/wavebuster

Fixed wavebuster rendering, plus tiny targeting preference (issue?)
This commit is contained in:
Phillip Stephens 2021-10-30 17:26:49 -07:00 committed by GitHub
commit d0838701f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 108 additions and 90 deletions

View File

@ -25,8 +25,8 @@ CWaveBuster::CWaveBuster(const TToken<CWeaponDescription>& desc, EWeaponType typ
, x360_busterSwoosh2(g_SimplePool->GetObj("BusterSwoosh2")) , x360_busterSwoosh2(g_SimplePool->GetObj("BusterSwoosh2"))
, x36c_busterSparks(g_SimplePool->GetObj("BusterSparks")) , x36c_busterSparks(g_SimplePool->GetObj("BusterSparks"))
, x378_busterLight(g_SimplePool->GetObj("BusterLight")) , x378_busterLight(g_SimplePool->GetObj("BusterLight"))
, m_lineRenderer1(CLineRenderer::EPrimitiveMode::LineStrip, 36, nullptr, true) , m_lineRenderer1(CLineRenderer::EPrimitiveMode::LineStrip, 36 * 6, nullptr, true)
, m_lineRenderer2(CLineRenderer::EPrimitiveMode::LineStrip, 36, nullptr, true) { , m_lineRenderer2(CLineRenderer::EPrimitiveMode::LineStrip, 36 * 6, nullptr, true) {
x354_busterSwoosh1.GetObj(); x354_busterSwoosh1.GetObj();
x360_busterSwoosh2.GetObj(); x360_busterSwoosh2.GetObj();
x36c_busterSparks.GetObj(); x36c_busterSparks.GetObj();
@ -35,6 +35,11 @@ CWaveBuster::CWaveBuster(const TToken<CWeaponDescription>& desc, EWeaponType typ
x388_busterSwoosh2Gen = std::make_unique<CParticleSwoosh>(x360_busterSwoosh2, 0); x388_busterSwoosh2Gen = std::make_unique<CParticleSwoosh>(x360_busterSwoosh2, 0);
x38c_busterSparksGen = std::make_unique<CElementGen>(x36c_busterSparks); x38c_busterSparksGen = std::make_unique<CElementGen>(x36c_busterSparks);
x390_busterLightGen = std::make_unique<CElementGen>(x378_busterLight); x390_busterLightGen = std::make_unique<CElementGen>(x378_busterLight);
for (size_t i = 0; i < x384_busterSwoosh1Gen->GetSwooshDataCount() - 1; i++) {
x384_busterSwoosh1Gen->ForceOneUpdate(0.f);
x388_busterSwoosh2Gen->ForceOneUpdate(0.f);
}
} }
void CWaveBuster::Accept(IVisitor& visitor) { visitor.Visit(this); } void CWaveBuster::Accept(IVisitor& visitor) { visitor.Visit(this); }
@ -50,14 +55,12 @@ void CWaveBuster::Think(float dt, CStateManager& mgr) {
} }
x3d0_27_ = false; x3d0_27_ = false;
x3d0_28_ = false; x3d0_28_ = false;
zeus::CVector3f local_160 = x2e8_originalXf.origin; const zeus::CVector3f beamForward = x2e8_originalXf.frontVector().normalized();
zeus::CVector3f local_184 = x2e8_originalXf.frontVector();
zeus::CVector3f local_16c = local_184.normalized();
float dVar17 = 0.f; float beamDistance = 25.f;
if (!x3d0_25_ && !x3d0_26_) { if (!x3d0_25_ && !x3d0_26_trackingTarget) {
TUniqueId uid = kInvalidUniqueId; TUniqueId uid = kInvalidUniqueId;
CRayCastResult res = SeekDamageTarget(uid, local_160, local_16c, mgr, dt); CRayCastResult res = SeekDamageTarget(uid, x2e8_originalXf.origin, beamForward, mgr, dt);
if (res.IsValid() && res.GetT() < 25.f) { if (res.IsValid() && res.GetT() < 25.f) {
if (TCastToPtr<CActor> act = mgr.ObjectById(uid)) { if (TCastToPtr<CActor> act = mgr.ObjectById(uid)) {
act->Touch(*this, mgr); act->Touch(*this, mgr);
@ -67,13 +70,13 @@ void CWaveBuster::Think(float dt, CStateManager& mgr) {
x3d0_28_ = true; x3d0_28_ = true;
} }
x3d0_27_ = true; x3d0_27_ = true;
dVar17 = res.GetT(); beamDistance = res.GetT();
} }
} }
if (x2c0_homingTargetId == kInvalidUniqueId || !x3d0_26_) { if (x2c0_homingTargetId == kInvalidUniqueId || !x3d0_26_trackingTarget) {
dVar17 = std::max(1.f, dVar17); beamDistance = std::max(1.f, beamDistance);
x348_targetPoint = local_160 + (dVar17 * local_16c); x348_targetPoint = x2e8_originalXf.origin + (beamDistance * beamForward);
if (!x3d0_25_) { if (!x3d0_25_) {
const float x = mgr.GetActiveRandom()->Range(-1.f, 1.f); const float x = mgr.GetActiveRandom()->Range(-1.f, 1.f);
const float z = mgr.GetActiveRandom()->Range(-1.f, 1.f); const float z = mgr.GetActiveRandom()->Range(-1.f, 1.f);
@ -90,14 +93,15 @@ void CWaveBuster::Think(float dt, CStateManager& mgr) {
ResetBeam(true); ResetBeam(true);
} }
zeus::CVector3f vec = x2c0_homingTargetId != kInvalidUniqueId && x3d0_26_ zeus::CVector3f vec = x2c0_homingTargetId != kInvalidUniqueId && x3d0_26_trackingTarget
? GetTransform() * zeus::CTransform::RotateY(x3c4_) * zeus::CVector3f{0.f, -3.f, -1.5f} ? GetTransform() * zeus::CTransform::RotateY(x3c4_) * zeus::CVector3f{0.f, -3.f, -1.5f}
: (GetTranslation() + -1.5f) * GetTransform().basis[1].normalized(); : (GetTransform().frontVector() * -1.5f) + GetTransform().origin;
if (x3a0_ >= 0.5f || x2c0_homingTargetId == kInvalidUniqueId) { if (x3a0_ >= 0.5f || x2c0_homingTargetId == kInvalidUniqueId) {
x330_ = x324_; x330_ = x324_bezierC;
x324_ = vec; x324_bezierC = vec;
x3a0_ = 0.5f;
} else { } else {
x324_ = x330_ * (1.f - x330_) + vec * (x3a0_ / 0.5f); x324_bezierC = x330_ * (1.f - x330_) + vec * (x3a0_ / 0.5f);
x3a0_ += 0.125f * dt; x3a0_ += 0.125f * dt;
} }
@ -111,12 +115,12 @@ void CWaveBuster::Think(float dt, CStateManager& mgr) {
} }
} }
x3c8_ += 20.f * dt; x3c8_innerSwooshColorT += 20.f * dt;
if (x3c8_ > 1.f) { if (x3c8_innerSwooshColorT > 1.f) {
++x3cc_; ++x3cc_innerSwooshColorIdx;
if (x3cc_ > 2) if (x3cc_innerSwooshColorIdx > 2)
x3cc_ = 0; x3cc_innerSwooshColorIdx = 0;
x3c8_ = 0.f; x3c8_innerSwooshColorT = 0.f;
} }
x38c_busterSparksGen->Update(dt); x38c_busterSparksGen->Update(dt);
} }
@ -143,8 +147,8 @@ void CWaveBuster::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId senderId,
// Thermal hot // Thermal hot
xe6_27_thermalVisorFlags = 2; xe6_27_thermalVisorFlags = 2;
x318_ = x2e8_originalXf.origin; x318_bezierB = x2e8_originalXf.origin;
x324_ = x34_transform.origin; x324_bezierC = x34_transform.origin;
x330_ = x34_transform.origin; x330_ = x34_transform.origin;
} }
@ -165,7 +169,10 @@ void CWaveBuster::UpdateFx(const zeus::CTransform& xf, float dt, CStateManager&
} }
x2e8_originalXf = xf; x2e8_originalXf = xf;
x398_ -= std::max(0.f, x398_ - (60.f * dt)); x398_spiralOffset -= 60.f * dt;
if (x398_spiralOffset < 0.f) {
x398_spiralOffset = 2.f * M_PIF;
}
x170_projectile.SetVelocity(zeus::CVector3f{0.f, x3d0_25_ ? 1.6f : 0.f, 0.f}); x170_projectile.SetVelocity(zeus::CVector3f{0.f, x3d0_25_ ? 1.6f : 0.f, 0.f});
} }
@ -177,16 +184,16 @@ void CWaveBuster::ResetBeam(bool deactivate) {
SetActive(false); SetActive(false);
x3d0_24_firing = false; x3d0_24_firing = false;
x38c_busterSparksGen->SetParticleEmission(false); x38c_busterSparksGen->SetParticleEmission(false);
x398_ = 2.f * M_PIF; x398_spiralOffset = 2.f * M_PIF;
} }
} }
void CWaveBuster::SetNewTarget(TUniqueId id, CStateManager& mgr) { void CWaveBuster::SetNewTarget(TUniqueId id, CStateManager& mgr) {
x2c0_homingTargetId = id; x2c0_homingTargetId = id;
if (id == kInvalidUniqueId) { if (id == kInvalidUniqueId) {
x3d0_26_ = false; x3d0_26_trackingTarget = false;
} else { } else {
x3d0_26_ = true; x3d0_26_trackingTarget = true;
CSfxManager::AddEmitter(SFXsfx06FF, GetTranslation(), zeus::skZero3f, true, false, 255, kInvalidAreaId); CSfxManager::AddEmitter(SFXsfx06FF, GetTranslation(), zeus::skZero3f, true, false, 255, kInvalidAreaId);
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, 0.5f, ERumblePriority::Three); mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, 0.5f, ERumblePriority::Three);
} }
@ -199,35 +206,40 @@ void CWaveBuster::RenderParticles() {
{1.f, 0.f, 0.f, 1.f}, {1.f, 0.f, 0.f, 1.f},
{0.f, 0.f, 1.f, 1.f}, {0.f, 0.f, 1.f, 1.f},
}}; }};
zeus::CTransform CStack152 = x2e8_originalXf.getRotation(); zeus::CTransform originalRotation = x2e8_originalXf.getRotation();
zeus::CVector3f local_d4 = x2e8_originalXf.origin;
x38c_busterSparksGen->SetParticleEmission(true); x38c_busterSparksGen->SetParticleEmission(true);
zeus::CColor col = zeus::CColor::lerp(skCols[x3cc_], skCols[x3cc_ + 1], x3c8_); const zeus::CColor col = zeus::CColor::lerp(skCols[x3cc_innerSwooshColorIdx], skCols[x3cc_innerSwooshColorIdx + 1], x3c8_innerSwooshColorT);
float dVar8 = x388_busterSwoosh2Gen->GetSwooshData(x388_busterSwoosh2Gen->GetSwooshDataCount()).x30_irot; float prevSwoosh2Rot = x388_busterSwoosh2Gen->GetSwooshData(x388_busterSwoosh2Gen->GetSwooshDataCount() - 1).x30_irot;
float dVar9 = x384_busterSwoosh1Gen->GetSwooshData(x384_busterSwoosh1Gen->GetSwooshDataCount()).x30_irot; float prevSwoosh1Rot = x384_busterSwoosh1Gen->GetSwooshData(x384_busterSwoosh1Gen->GetSwooshDataCount() - 1).x30_irot;
float t = 0.f;
for (int i = 0; i < x384_busterSwoosh1Gen->GetSwooshDataCount(); i++) {
zeus::CVector3f point = zeus::getBezierPoint(GetTranslation(), x324_bezierC, x318_bezierB, x2e8_originalXf.origin, t);
CParticleSwoosh::SSwooshData& swoosh1 = x384_busterSwoosh1Gen->GetSwooshData(i);
CParticleSwoosh::SSwooshData& swoosh2 = x388_busterSwoosh2Gen->GetSwooshData(i);
float fVar1 = 0.f;
int iVar3 = 0;
while (iVar3 < x384_busterSwoosh1Gen->GetSwooshDataCount()) {
float dVar10 = fVar1;
auto& swoosh1 = x384_busterSwoosh1Gen->GetSwooshData(iVar3);
auto& swoosh2 = x388_busterSwoosh2Gen->GetSwooshData(iVar3);
zeus::CVector3f point = zeus::getBezierPoint(GetTranslation(), x324_, x318_, local_d4, fVar1);
swoosh1.xc_translation = point; swoosh1.xc_translation = point;
swoosh2.xc_translation = point; swoosh2.xc_translation = point;
swoosh1.x38_orientation = CStack152;
swoosh2.x38_orientation = CStack152; swoosh1.x38_orientation = originalRotation;
swoosh2.x38_orientation = originalRotation;
swoosh2.x6c_color = col; swoosh2.x6c_color = col;
float dVar6 = swoosh1.x30_irot;
float dVar7 = swoosh2.x30_irot; const float curSwoosh1Rot = swoosh1.x30_irot;
swoosh1.x30_irot = dVar9; const float curSwoosh2Rot = swoosh2.x30_irot;
swoosh2.x30_irot = dVar8;
swoosh1.x30_irot = prevSwoosh1Rot;
swoosh2.x30_irot = prevSwoosh2Rot;
x38c_busterSparksGen->SetTranslation(point); x38c_busterSparksGen->SetTranslation(point);
fVar1 = dVar10 + 0.4f; x38c_busterSparksGen->ForceParticleCreation(1);
++iVar3; t += 0.04f;
dVar8 = dVar7;
dVar9 = dVar6; prevSwoosh1Rot = curSwoosh1Rot;
prevSwoosh2Rot = curSwoosh2Rot;
} }
x38c_busterSparksGen->SetParticleEmission(false); x38c_busterSparksGen->SetParticleEmission(false);
x384_busterSwoosh1Gen->Render(GetActorLights()); x384_busterSwoosh1Gen->Render(GetActorLights());
x388_busterSwoosh2Gen->Render(GetActorLights()); x388_busterSwoosh2Gen->Render(GetActorLights());
@ -237,29 +249,31 @@ void CWaveBuster::RenderParticles() {
void CWaveBuster::RenderBeam() { void CWaveBuster::RenderBeam() {
const zeus::CTransform inv = x2e8_originalXf.inverse(); const zeus::CTransform inv = x2e8_originalXf.inverse();
const zeus::CVector3f vecA = inv * x2e8_originalXf.origin; const zeus::CVector3f vecA = inv * x2e8_originalXf.origin;
const zeus::CVector3f vecB = inv * x318_; const zeus::CVector3f vecB = inv * x318_bezierB;
const zeus::CVector3f vecC = inv * x324_; const zeus::CVector3f vecC = inv * x324_bezierC;
const zeus::CVector3f vecD = inv * GetTranslation(); const zeus::CVector3f vecD = inv * GetTranslation();
float variation = 0.f; float spiralRadius = 0.f;
rstl::reserved_vector<zeus::CVector3f, 36> linePoints; // Used to be L2Cache access rstl::reserved_vector<zeus::CVector3f, 36 * 6> linePoints; // Used to be L2Cache access
linePoints.resize(36); linePoints.resize(36 * 6);
float t = 0.16; float t = 0.16;
zeus::CVector3f lastPoint = vecA; zeus::CVector3f lastPoint = vecA;
int splineBaseIndex = 0;
while (t <= 1.f) { while (t <= 1.f) {
const zeus::CVector3f point = zeus::getBezierPoint(vecA, vecB, vecC, vecD, t); const zeus::CVector3f point = zeus::getBezierPoint(vecA, vecB, vecC, vecD, t);
float angle = 0.f; float angle = 0.f;
for (size_t i = 0; i < 36; ++i) { for (size_t i = 0; i < 36; ++i) {
const float randX = x394_rand.Range(-0.041667f, 0.041667f); const float randX = x394_rand.Range(-0.041667f, 0.041667f);
const float randZ = x394_rand.Range(-0.041667f, 0.041667f); const float randZ = x394_rand.Range(-0.041667f, 0.041667f);
const float offX = variation * std::cos(angle + x398_) + randX; const float offX = spiralRadius * std::cos(angle + x398_spiralOffset) + randX;
const float offZ = variation * std::sin(angle + x398_) + randZ; const float offZ = spiralRadius * std::sin(angle + x398_spiralOffset) + randZ;
const float d = angle / (2.f * M_PIF); const float angleRad = angle / (2.f * M_PIF);
linePoints[i] = lastPoint * (1.f - d) + point * d + zeus::CVector3f{offX, 0.f, offZ}; linePoints[i + splineBaseIndex] = lastPoint * (1.f - angleRad) + point * angleRad + zeus::CVector3f{offX, 0.f, offZ};
angle += zeus::degToRad(10.f); angle += zeus::degToRad(10.f);
} }
variation = 0.25f; spiralRadius = 0.25f;
t += 0.16; t += 0.16;
lastPoint = point; lastPoint = point;
splineBaseIndex += 36;
} }
g_Renderer->SetModelMatrix(x2e8_originalXf); g_Renderer->SetModelMatrix(x2e8_originalXf);
m_lineRenderer1.Reset(); m_lineRenderer1.Reset();
@ -283,16 +297,17 @@ CRayCastResult CWaveBuster::SeekDamageTarget(TUniqueId& uid, const zeus::CVector
CRayCastResult physRes; CRayCastResult physRes;
CRayCastResult actRes; CRayCastResult actRes;
RayCastTarget(mgr, physId, actId, pos, dir, 25.f, physRes, actRes); RayCastTarget(mgr, physId, actId, pos, dir, 25.f, physRes, actRes);
if (actRes.IsValid() && ApplyDamageToTarget(physId, actRes, physRes, res, mgr, dt)) {
uid = actId;
return actRes;
}
if (physRes.IsValid() && ApplyDamageToTarget(actId, actRes, physRes, res, mgr, dt)) { if (physRes.IsValid() && ApplyDamageToTarget(actId, actRes, physRes, res, mgr, dt)) {
uid = physId; uid = physId;
return physRes; return physRes;
} }
if (actRes.IsValid() && ApplyDamageToTarget(physId, actRes, physRes, res, mgr, dt)) {
uid = actId;
return actRes;
}
return res; return res;
} }
@ -315,16 +330,16 @@ bool CWaveBuster::ApplyDamageToTarget(TUniqueId damagee, const CRayCastResult& a
void CWaveBuster::UpdateTargetSeek(float dt, CStateManager& mgr) { void CWaveBuster::UpdateTargetSeek(float dt, CStateManager& mgr) {
TUniqueId uid = kInvalidUniqueId; TUniqueId uid = kInvalidUniqueId;
SeekTarget(dt, uid, mgr); SeekTarget(dt, uid, mgr);
if (x2c0_homingTargetId == kInvalidUniqueId && !x3d0_26_ && if (x2c0_homingTargetId == kInvalidUniqueId && !x3d0_26_trackingTarget &&
(GetTranslation() - x2e8_originalXf.origin).magSquared() > 625.f) { (GetTranslation() - x2e8_originalXf.origin).magSquared() > 625.f) {
x3d0_25_ = false; x3d0_25_ = false;
} else if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(x2c0_homingTargetId)) { } else if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(x2c0_homingTargetId)) {
zeus::CVector3f vec = zeus::skForward; zeus::CVector3f vec = zeus::skForward;
if (GetViewAngleToTarget(vec, *act) <= zeus::degToRad(90.f) && x3d0_26_) { if (GetViewAngleToTarget(vec, *act) <= zeus::degToRad(90.f) && x3d0_26_trackingTarget) {
x3d0_25_ = false; x3d0_25_ = false;
} else { } else {
x2c0_homingTargetId = kInvalidUniqueId; x2c0_homingTargetId = kInvalidUniqueId;
x3d0_26_ = false; x3d0_26_trackingTarget = false;
} }
} }
} }
@ -333,8 +348,8 @@ void CWaveBuster::UpdateTargetDamage(float dt, CStateManager& mgr) {
if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(x2c0_homingTargetId)) { if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(x2c0_homingTargetId)) {
const CHealthInfo* hInfo = act->GetHealthInfo(mgr); const CHealthInfo* hInfo = act->GetHealthInfo(mgr);
if (hInfo != nullptr && hInfo->GetHP() > 0.f) { if (hInfo != nullptr && hInfo->GetHP() > 0.f) {
x33c_ = act->GetAimPosition(mgr, 0.f); x33c_homingTargetPoint = act->GetAimPosition(mgr, 0.f);
SetTranslation(x33c_); SetTranslation(x33c_homingTargetPoint);
mgr.ApplyDamage(GetUniqueId(), x2c0_homingTargetId, GetOwnerId(), CDamageInfo(x12c_curDamageInfo, dt), xf8_filter, mgr.ApplyDamage(GetUniqueId(), x2c0_homingTargetId, GetOwnerId(), CDamageInfo(x12c_curDamageInfo, dt), xf8_filter,
zeus::skZero3f); zeus::skZero3f);
return; return;
@ -383,7 +398,7 @@ bool CWaveBuster::UpdateBeamFrame(CStateManager& mgr, float dt) {
x3ac_ += x3a4_ * dt; x3ac_ += x3a4_ * dt;
x3b0_ += x3b4_ * dt; x3b0_ += x3b4_ * dt;
x3c4_ += x3bc_ * dt; x3c4_ += x3bc_ * dt;
x318_ = x2e8_originalXf * zeus::CTransform::RotateY(x3ac_) * x318_bezierB = x2e8_originalXf * zeus::CTransform::RotateY(x3ac_) *
zeus::CVector3f(0.f, 2.f, 1.5f * ((x2c0_homingTargetId == kInvalidUniqueId ? 1.f : 1.25f) - x3b0_ * x3b0_)); zeus::CVector3f(0.f, 2.f, 1.5f * ((x2c0_homingTargetId == kInvalidUniqueId ? 1.f : 1.25f) - x3b0_ * x3b0_));
return viewAngle > zeus::degToRad(90.f); return viewAngle > zeus::degToRad(90.f);
} }
@ -411,27 +426,28 @@ void CWaveBuster::RayCastTarget(CStateManager& mgr, TUniqueId& physId, TUniqueId
length = 100000.f; length = 100000.f;
} }
float prevT = length; float nearestPhysT = length;
float nearestActorT = length;
for (TUniqueId uid : nearList) { for (TUniqueId uid : nearList) {
if (const TCastToConstPtr<CPhysicsActor> pAct = mgr.GetObjectById(uid)) { if (const TCastToConstPtr<CPhysicsActor> pAct = mgr.GetObjectById(uid)) {
CRayCastResult res = CRayCastResult res =
pAct->GetCollisionPrimitive()->CastRay(start, end, length, xf8_filter, pAct->GetPrimitiveTransform()); pAct->GetCollisionPrimitive()->CastRay(start, end, length, xf8_filter, pAct->GetPrimitiveTransform());
if (!res.IsValid() || res.GetT() >= length) { if (!res.IsValid() || res.GetT() >= nearestPhysT) {
continue; continue;
} }
actorRes = res; actorRes = res;
actId = pAct->GetUniqueId(); actId = pAct->GetUniqueId();
prevT = res.GetT(); nearestPhysT = res.GetT();
} else if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(uid)) { } else if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(uid)) {
if (auto bounds = act->GetTouchBounds()) { if (auto bounds = act->GetTouchBounds()) {
CCollidableAABox collidableBox{*bounds, GetMaterialList()}; CCollidableAABox collidableBox(*bounds, act->GetMaterialList());
CRayCastResult res = collidableBox.CastRay(start, end, length, xf8_filter, zeus::CTransform{}); CRayCastResult res = collidableBox.CastRay(start, end, length, xf8_filter, zeus::CTransform{});
if (!res.IsValid() || res.GetT() >= prevT) { if (!res.IsValid() || res.GetT() >= nearestActorT) {
continue; continue;
} }
actorRes = res; actorRes = res;
actId = act->GetUniqueId(); actId = act->GetUniqueId();
prevT = res.GetT(); nearestActorT = res.GetT();
} }
} }
} }
@ -452,7 +468,7 @@ CRayCastResult CWaveBuster::SeekTarget(float dt, TUniqueId& uid, CStateManager&
if (uid == kInvalidUniqueId || uid != x2c0_homingTargetId) { if (uid == kInvalidUniqueId || uid != x2c0_homingTargetId) {
x2c0_homingTargetId = kInvalidUniqueId; x2c0_homingTargetId = kInvalidUniqueId;
} else { } else {
x3d0_26_ = true; x3d0_26_trackingTarget = true;
CSfxManager::AddEmitter(SFXsfx06FF, res.GetPoint(), zeus::skZero3f, true, false, 255, kInvalidAreaId); CSfxManager::AddEmitter(SFXsfx06FF, res.GetPoint(), zeus::skZero3f, true, false, 255, kInvalidAreaId);
} }
} }

View File

@ -13,10 +13,12 @@ namespace metaforce {
class CWaveBuster : public CGameProjectile { class CWaveBuster : public CGameProjectile {
zeus::CTransform x2e8_originalXf; zeus::CTransform x2e8_originalXf;
zeus::CVector3f x318_; // Wavebuster is rendered as a cubic bezier
zeus::CVector3f x324_; // points A & D are at the arm cannon and endpoint/target respectively
zeus::CVector3f x318_bezierB;
zeus::CVector3f x324_bezierC;
zeus::CVector3f x330_; zeus::CVector3f x330_;
zeus::CVector3f x33c_; zeus::CVector3f x33c_homingTargetPoint;
zeus::CVector3f x348_targetPoint; zeus::CVector3f x348_targetPoint;
TCachedToken<CSwooshDescription> x354_busterSwoosh1; TCachedToken<CSwooshDescription> x354_busterSwoosh1;
TCachedToken<CSwooshDescription> x360_busterSwoosh2; TCachedToken<CSwooshDescription> x360_busterSwoosh2;
@ -27,7 +29,7 @@ class CWaveBuster : public CGameProjectile {
std::unique_ptr<CElementGen> x38c_busterSparksGen; std::unique_ptr<CElementGen> x38c_busterSparksGen;
std::unique_ptr<CElementGen> x390_busterLightGen; std::unique_ptr<CElementGen> x390_busterLightGen;
CRandom16 x394_rand{99}; CRandom16 x394_rand{99};
float x398_ = 2.f * M_PIF; float x398_spiralOffset = 2.f * M_PIF;
float x39c_ = 0.5f; float x39c_ = 0.5f;
float x3a0_ = 0.5f; float x3a0_ = 0.5f;
float x3a4_ = 0.f; float x3a4_ = 0.f;
@ -39,13 +41,13 @@ class CWaveBuster : public CGameProjectile {
float x3bc_ = 0.f; float x3bc_ = 0.f;
float x3c0_ = 0.f; float x3c0_ = 0.f;
float x3c4_ = 0.f; float x3c4_ = 0.f;
float x3c8_ = 0.f; float x3c8_innerSwooshColorT = 0.f;
u32 x3cc_ = 0; u32 x3cc_innerSwooshColorIdx = 0;
bool x3d0_24_firing : 1; bool x3d0_24_firing : 1 = true;
bool x3d0_25_ : 1; bool x3d0_25_ : 1 = true;
bool x3d0_26_ : 1; bool x3d0_26_trackingTarget : 1 = false;
bool x3d0_27_ : 1; bool x3d0_27_ : 1 = false;
bool x3d0_28_ : 1; bool x3d0_28_ : 1 = true;
CLineRenderer m_lineRenderer1; CLineRenderer m_lineRenderer1;
CLineRenderer m_lineRenderer2; CLineRenderer m_lineRenderer2;