2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-10 05:07:43 +00:00

Implement CPatterned::KnockBack

This commit is contained in:
Jack Andersen
2018-11-05 20:16:12 -10:00
parent 3ef7386978
commit 0b3a9e1865
42 changed files with 709 additions and 385 deletions

View File

@@ -13,6 +13,7 @@
#include "TCastTo.hpp"
#include "MP1/World/CSpacePirate.hpp"
#include "World/CStateMachine.hpp"
#include "CExplosion.hpp"
namespace urde
{
@@ -68,17 +69,17 @@ x460_knockBackController(kbVariant)
x4fc_ = pInfo.x108_;
x508_colliderType = colliderType;
x50c_thermalMag = actorParms.GetThermalMag();
x514_ = pInfo.x110_particle1Scale;
x540_ = pInfo.x124_particle2Scale;
x514_deathExplosionOffset = pInfo.x110_particle1Scale;
x540_iceDeathExplosionOffset = pInfo.x124_particle2Scale;
if (pInfo.x11c_particle1.IsValid())
x520_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x11c_particle1})};
x520_deathExplosionParticle = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x11c_particle1})};
if (pInfo.x120_electric.IsValid())
x530_ = { g_SimplePool->GetObj({FOURCC('ELSC'), pInfo.x120_electric})};
x530_deathExplosionElectric = { g_SimplePool->GetObj({FOURCC('ELSC'), pInfo.x120_electric})};
if (pInfo.x130_particle2.IsValid())
x54c_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x130_particle2})};
x54c_iceDeathExplosionParticle = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x130_particle2})};
if (x404_contactDamage.GetRadius() > 0.f)
x404_contactDamage.SetRadius(0.f);
@@ -158,19 +159,19 @@ void CPatterned::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState
const CDamageInfo& info = proj->GetDamageInfo();
if (info.GetWeaponMode().GetType() == EWeaponType::Wave)
{
if (x460_knockBackController.x81_26_ && info.GetWeaponMode().IsComboed() && HealthInfo(mgr))
if (x460_knockBackController.x81_26_enableShock && info.GetWeaponMode().IsComboed() && HealthInfo(mgr))
{
x401_31_ = true;
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One, false,
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::Radius, false,
info.GetKnockBackPower());
x460_knockBackController.DeferKnockBack(EWeaponType::Wave);
}
}
else if (info.GetWeaponMode().GetType() == EWeaponType::Plasma)
{
if (x460_knockBackController.x81_27_ && info.GetWeaponMode().IsCharged() && HealthInfo(mgr))
if (x460_knockBackController.x81_27_enableBurn && info.GetWeaponMode().IsCharged() && HealthInfo(mgr))
{
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One,
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::Radius,
false, info.GetKnockBackPower());
x460_knockBackController.DeferKnockBack(EWeaponType::Plasma);
}
@@ -223,13 +224,13 @@ void CPatterned::Think(float dt, CStateManager& mgr)
{
if (x3e0_ > 0.f && x400_29_)
{
SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None);
sub8007ab34(mgr);
SendScriptMsgs(EScriptObjectState::AboutToDie, mgr, EScriptObjectMessage::None);
DoIceDeath(mgr);
}
else
{
SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None);
sub8007ace8(mgr);
SendScriptMsgs(EScriptObjectState::AboutToDie, mgr, EScriptObjectMessage::None);
DoDeath(mgr);
}
}
else if (!x400_29_)
@@ -243,7 +244,7 @@ void CPatterned::Think(float dt, CStateManager& mgr)
bool isDead = false; //sub8007A454(unk, "Dead"sv);
if (!isDead && x330_stateMachineState.x8_time > 15.f)
sub8007ace8(mgr);
DoDeath(mgr);
}
}
}
@@ -263,7 +264,7 @@ void CPatterned::Think(float dt, CStateManager& mgr)
else
x4f0_ = 0.f;
if (x460_knockBackController.x81_26_ && x401_31_ && x402_24_)
if (x460_knockBackController.x81_26_enableShock && x401_31_ && x402_24_)
Shock(0.5f + mgr.GetActiveRandom()->Range(0.f, 0.5f), 0.2f);
x402_24_ = x401_24_;
@@ -282,7 +283,7 @@ void CPatterned::Think(float dt, CStateManager& mgr)
{
if (x3f0_!= 0.f)
{
//x450_bodyController->sub80139f0c(x3f0_);
x450_bodyController->StopElectrocution();
mgr.GetActorModelParticles()->StopElectric(*this);
}
}
@@ -310,7 +311,7 @@ void CPatterned::Think(float dt, CStateManager& mgr)
if (x401_30_)
{
x401_30_ = false;
Death(GetTransform().frontVector(), mgr, EScriptObjectState::DeathRattle);
Death(mgr, GetTransform().frontVector(), EScriptObjectState::DeathRattle);
}
float thinkDt = (x400_25_alive ? dt : dt * sub80078a88());
@@ -407,6 +408,18 @@ zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float
return offset + GetBoundingBox().center();
}
void CPatterned::DeathDelete(CStateManager& mgr)
{
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
if (x450_bodyController->IsElectrocuting())
{
x3f0_ = 0.f;
x450_bodyController->StopElectrocution();
mgr.GetActorModelParticles()->StopElectric(*this);
}
mgr.FreeScriptObject(GetUniqueId());
}
void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info,
EKnockBackType type, bool inDeferred, float magnitude)
{
@@ -414,7 +427,60 @@ void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, c
if (!x401_27_ && !x401_28_ && hInfo)
{
x460_knockBackController.KnockBack(backVec, mgr, *this, info, type, magnitude);
/* TODO: Finish */
if (x450_bodyController->IsFrozen() && x460_knockBackController.GetActiveParms().xc_ >= 0.f)
x450_bodyController->FrozenBreakout();
switch (x460_knockBackController.GetActiveParms().x4_animFollowup)
{
case EKnockBackAnimationFollowUp::Freeze:
Freeze(mgr, zeus::CVector3f::skZero, zeus::CUnitVector3f(x34_transform.transposeRotate(backVec)),
x460_knockBackController.GetActiveParms().x8_followupMagnitude);
break;
case EKnockBackAnimationFollowUp::PhazeOut:
PhazeOut(mgr);
break;
case EKnockBackAnimationFollowUp::Shock:
Shock(x460_knockBackController.GetActiveParms().x8_followupMagnitude, -1.f);
break;
case EKnockBackAnimationFollowUp::Burn:
Burn(x460_knockBackController.GetActiveParms().x8_followupMagnitude, 0.25f);
break;
case EKnockBackAnimationFollowUp::Disintegrate:
x401_29_ = true;
case EKnockBackAnimationFollowUp::FireDeath:
Burn(x460_knockBackController.GetActiveParms().x8_followupMagnitude, -1.f);
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
x400_28_ = x400_29_ = false;
x400_27_ = x401_28_ = true;
x3f4_ = 1.5f;
x402_29_ = false;
x450_bodyController->DouseFlames();
mgr.GetActorModelParticles()->StopThermalHotParticles(*this);
mgr.GetActorModelParticles()->PlayFireSFX(*this);
if (!x401_29_)
{
mgr.GetActorModelParticles()->EnsureFirePopLoaded(*this);
mgr.GetActorModelParticles()->EnsureIceBreakLoaded(*this);
}
break;
case EKnockBackAnimationFollowUp::Death:
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
break;
case EKnockBackAnimationFollowUp::ExplodeDeath:
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
if (GetDeathExplosionParticle() || x530_deathExplosionElectric)
DoDeath(mgr);
else if (x450_bodyController->IsFrozen())
x450_bodyController->FrozenBreakout();
break;
case EKnockBackAnimationFollowUp::IceDeath:
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
if (x54c_iceDeathExplosionParticle)
DoIceDeath(mgr);
else if (x450_bodyController->IsFrozen())
x450_bodyController->FrozenBreakout();
default:
break;
}
}
}
@@ -427,7 +493,71 @@ void CPatterned::BuildBodyController(EBodyType bodyType)
auto anim = x450_bodyController->GetPASDatabase().FindBestAnimation(CPASAnimParmData(24,
CPASAnimParm::FromEnum(0)), -1);
/* TODO: Double check this */
x460_knockBackController.x81_26_ = anim.first != 0.f;
x460_knockBackController.x81_26_enableShock = anim.first != 0.f;
}
void CPatterned::GenerateDeathExplosion(CStateManager& mgr)
{
if (auto particle = GetDeathExplosionParticle())
{
zeus::CTransform xf(GetTransform());
xf.origin = GetTransform() * (x64_modelData->GetScale() * x514_deathExplosionOffset);
CExplosion* explo = new CExplosion(*particle, mgr.AllocateUniqueId(), true,
CEntityInfo(GetAreaIdAlways(), CEntity::NullConnectionList), "", xf, 1,
zeus::CVector3f::skOne, zeus::CColor::skWhite);
mgr.AddObject(explo);
}
else if (x530_deathExplosionElectric)
{
zeus::CTransform xf(GetTransform());
xf.origin = GetTransform() * (x64_modelData->GetScale() * x514_deathExplosionOffset);
CExplosion* explo = new CExplosion(*x530_deathExplosionElectric, mgr.AllocateUniqueId(), true,
CEntityInfo(GetAreaIdAlways(), CEntity::NullConnectionList), "", xf, 1,
zeus::CVector3f::skOne, zeus::CColor::skWhite);
mgr.AddObject(explo);
}
}
void CPatterned::DoDeath(CStateManager& mgr)
{
CSfxManager::AddEmitter(x454_deathSfx, GetTranslation(), zeus::CVector3f::skZero,
true, false, 0x7f, kInvalidAreaId);
if (!x401_28_)
{
SendScriptMsgs(EScriptObjectState::DeathExplosion, mgr, EScriptObjectMessage::None);
GenerateDeathExplosion(mgr);
}
DeathDelete(mgr);
x400_28_ = x400_29_ = false;
}
void CPatterned::GenerateIceDeathExplosion(CStateManager& mgr)
{
if (x54c_iceDeathExplosionParticle)
{
zeus::CTransform xf(GetTransform());
xf.origin = GetTransform() * (x64_modelData->GetScale() * x540_iceDeathExplosionOffset);
CExplosion* explo = new CExplosion(*x54c_iceDeathExplosionParticle, mgr.AllocateUniqueId(), true,
CEntityInfo(GetAreaIdAlways(), CEntity::NullConnectionList), "", xf, 1,
zeus::CVector3f::skOne, zeus::CColor::skWhite);
mgr.AddObject(explo);
}
}
void CPatterned::DoIceDeath(CStateManager& mgr)
{
if (x458_iceShatterSfx == 0xffff)
x458_iceShatterSfx = x454_deathSfx;
CSfxManager::AddEmitter(x458_iceShatterSfx, GetTranslation(), zeus::CVector3f::skZero,
true, false, 0x7f, kInvalidAreaId);
SendScriptMsgs(EScriptObjectState::IceDeathExplosion, mgr, EScriptObjectMessage::None);
GenerateIceDeathExplosion(mgr);
float toPlayerDist = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude();
if (toPlayerDist < 40.f)
mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPatternedExplodeShakeData(
GetTranslation(), 0.25f, 0.3f, 40.f), true);
DeathDelete(mgr);
x400_28_ = x400_29_ = false;
}
zeus::CVector3f CPatterned::GetGunEyePos() const
@@ -458,7 +588,7 @@ float CPatterned::sub80078a88()
void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
#if 1
if (mgr.GetPlayerState()->GetActiveVisor(mgr ) == CPlayerState::EPlayerVisor::Thermal)
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
{
SetCalculateLighting(false);
x90_actorLights->BuildConstantAmbientLighting(zeus::CColor::skWhite);