diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index e8b90d784..601dbab9d 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -255,15 +255,69 @@ const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVe } zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { - return CPatterned::GetOrbitPosition(mgr); + if (x772_launcherId != kInvalidUniqueId && + mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { + if (const CActor* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { + return sub_80228864(actor); + } + } + if (sub_802273a8()) { + if (TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { + return actor->GetTranslation(); + } + } + return GetLctrTransform("lockon_target_LCTR").origin; } zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) const { - return CPatterned::GetAimPosition(mgr, dt); + std::shared_ptr playerState = mgr.GetPlayerState(); + if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && + playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { + if (TCastToConstPtr actor = mgr.GetObjectById(x79c_)) { + return actor->GetTranslation(); + } + } + return GetOrbitPosition(mgr); } void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { - CPatterned::DoUserAnimEvent(mgr, node, type, dt); + bool handled = false; + switch (type) { + case EUserEventType::Projectile: + if (x772_launcherId != kInvalidUniqueId) { + CEntity* launcher = mgr.ObjectById(x772_launcherId); + mgr.SendScriptMsg(launcher, GetUniqueId(), EScriptObjectMessage::Action); + } + handled = true; + break; + case EUserEventType::DamageOn: + handled = true; + x988_24_ = true; + break; + case EUserEventType::DamageOff: + handled = true; + x988_24_ = false; + break; + case EUserEventType::ScreenShake: + sub_802273a8(); + handled = true; + break; + case EUserEventType::BeginAction: { + zeus::CTransform xf; // TODO + mgr.AddObject(new CShockWave(mgr.AllocateUniqueId(), "Shock Wave", {GetAreaIdAlways(), CEntity::NullConnectionList}, + xf, GetUniqueId(), GetShockWaveData(), sub_802273b0() ? 2.f : 1.3f, + sub_802273b0() ? 0.4f : 0.5f)); + break; + } + case EUserEventType::BecomeShootThrough: + // TODO + break; + default: + break; + } + if (!handled) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); + } } const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } @@ -545,4 +599,9 @@ void CElitePirate::sub_80228920(CStateManager& mgr, bool b, TUniqueId uid) { mgr.SendScriptMsg(entity, GetUniqueId(), b ? EScriptObjectMessage::Start : EScriptObjectMessage::Stop); } } + +zeus::CVector3f CElitePirate::sub_80228864(const CActor* actor) const { + const zeus::CTransform& targetTransform = actor->GetLocatorTransform("lockon_target_LCTR"); + return actor->GetTranslation() + actor->GetTransform().rotate(targetTransform.origin); +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index c416af305..04aa80767 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -2,10 +2,11 @@ #include "Runtime/Character/CBoneTracking.hpp" #include "Runtime/Collision/CJointCollisionDescription.hpp" +#include "Runtime/MP1/World/CShockWave.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" -#include "Runtime/World/CPatterned.hpp" #include "Runtime/World/CPathFindSearch.hpp" +#include "Runtime/World/CPatterned.hpp" namespace urde { class CCollisionActorManager; @@ -62,21 +63,6 @@ class CElitePirate : public CPatterned { SUnknownStruct(float f) : x0_(f * f) {} }; - struct SUnknownStruct2 { - u32 x0_ = 8; - CAssetId x4_particleDesc; - CDamageInfo x8_damageInfo; - float x24_ = 0.f; - float x28_ = 0.5f; - float x2c_ = 16.5217f; - float x30_ = 0.f; - CAssetId x34_weaponDesc; - s16 x38_sfx; - - SUnknownStruct2(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, s16 sfx) - : x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_sfx(sfx) {} - }; - s32 x568_ = -1; CDamageVulnerability x56c_vulnerability; std::unique_ptr x5d4_collisionActorMgr1; @@ -162,11 +148,11 @@ public: bool ShouldSpecialAttack(CStateManager&, float arg) override; bool ShouldCallForBackup(CStateManager&, float arg) override; CPathFindSearch* GetSearchPath() override; - virtual bool sub_802273a8() { return true; } - virtual bool sub_802273b0() { return true; } + virtual bool sub_802273a8() const { return true; } + virtual bool sub_802273b0() const { return true; } virtual void sub_80229114(CStateManager& mgr); virtual void sub_802289b0(CStateManager& mgr, bool b); - virtual SUnknownStruct2 sub_802273b8() const { + virtual SShockWaveData GetShockWaveData() const { return {x5d8_data.GetXF8(), x5d8_data.GetXFC(), x5d8_data.GetX118(), x5d8_data.GetX11C()}; } @@ -186,6 +172,7 @@ private: void sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf); void sub_8022902c(CStateManager& mgr, TUniqueId uid); void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid); + zeus::CVector3f sub_80228864(const CActor* actor) const; }; } // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index bcaa95109..53e5ac55e 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -1,43 +1,45 @@ set(MP1_WORLD_SOURCES - CNewIntroBoss.hpp CNewIntroBoss.cpp - CBeetle.hpp CBeetle.cpp - CWarWasp.hpp CWarWasp.cpp - CElitePirate.hpp CElitePirate.cpp - CBloodFlower.hpp CBloodFlower.cpp - CChozoGhost.hpp CChozoGhost.cpp - CSpacePirate.hpp CSpacePirate.cpp - CParasite.hpp CParasite.cpp - CBabygoth.hpp CBabygoth.cpp - CTryclops.hpp CTryclops.cpp - CFireFlea.hpp CFireFlea.cpp - CEnergyBall.hpp CEnergyBall.cpp - CEyeball.hpp CEyeball.cpp + CActorContraption.hpp CActorContraption.cpp CAtomicAlpha.hpp CAtomicAlpha.cpp CAtomicBeta.hpp CAtomicBeta.cpp + CBabygoth.hpp CBabygoth.cpp + CBeetle.hpp CBeetle.cpp + CBloodFlower.hpp CBloodFlower.cpp + CBurrower.hpp CBurrower.cpp + CChozoGhost.hpp CChozoGhost.cpp + CElitePirate.hpp CElitePirate.cpp + CEnergyBall.hpp CEnergyBall.cpp + CEyeball.hpp CEyeball.cpp + CFireFlea.hpp CFireFlea.cpp + CFlaahgra.hpp CFlaahgra.cpp + CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp + CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp CFlickerBat.hpp CFlickerBat.cpp CFlyingPirate.hpp CFlyingPirate.cpp CGrenadeLauncher.hpp CGrenadeLauncher.cpp CJellyZap.hpp CJellyZap.cpp - CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp + CMagdolite.hpp CMagdolite.cpp + CMetaree.hpp CMetaree.cpp + CMetroid.hpp CMetroid.cpp + CMetroidBeta.hpp CMetroidBeta.cpp CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp CMetroidPrimeProjectile.hpp CMetroidPrimeProjectile.cpp - CActorContraption.hpp CActorContraption.cpp - CThardusRockProjectile.hpp CThardusRockProjectile.cpp - CMetroidBeta.hpp CMetroidBeta.cpp - CMetroid.hpp CMetroid.cpp - CMetaree.hpp CMetaree.cpp - CBurrower.hpp CBurrower.cpp - CPuffer.hpp CPuffer.cpp - CMagdolite.hpp CMagdolite.cpp - CSeedling.hpp CSeedling.cpp - CRidley.hpp CRidley.cpp - CPuddleToadGamma.hpp CPuddleToadGamma.cpp - CFlaahgra.hpp CFlaahgra.cpp - CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp - CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp - CSpankWeed.hpp CSpankWeed.cpp + CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp + CNewIntroBoss.hpp CNewIntroBoss.cpp + CParasite.hpp CParasite.cpp CPuddleSpore.hpp CPuddleSpore.cpp + CPuddleToadGamma.hpp CPuddleToadGamma.cpp + CPuffer.hpp CPuffer.cpp + CRidley.hpp CRidley.cpp CRipper.hpp CRipper.cpp - CThardus.hpp CThardus.cpp) + CSeedling.hpp CSeedling.cpp + CShockWave.hpp CShockWave.cpp + CSpacePirate.hpp CSpacePirate.cpp + CSpankWeed.hpp CSpankWeed.cpp + CThardus.hpp CThardus.cpp + CThardusRockProjectile.hpp CThardusRockProjectile.cpp + CTryclops.hpp CTryclops.cpp + CWarWasp.hpp CWarWasp.cpp +) runtime_add_list(World MP1_WORLD_SOURCES) diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp new file mode 100644 index 000000000..4d55b753f --- /dev/null +++ b/Runtime/MP1/World/CShockWave.cpp @@ -0,0 +1,65 @@ +#include "Runtime/MP1/World/CShockWave.hpp" + +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/World/CActorParameters.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +namespace urde { +namespace MP1 { +CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + TUniqueId parent, const SShockWaveData& data, float f1, float f2) +: CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), {EMaterialTypes::Projectile}, + CActorParameters::None(), kInvalidUniqueId) +, xe8_id1(parent) +, xec_damageInfo(data.x8_damageInfo) +, x108_elementGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.x4_particleDesc})) +, x110_elementGen(std::make_unique(x108_elementGenDesc)) +, x114_data(data) +, x150_(data.x24_) +, x154_(data.x2c_) +, x15c_(f1) +, x160_(f2) { + if (data.x34_weaponDesc.IsValid()) { + x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.x34_weaponDesc}); + } + x110_elementGen->SetParticleEmission(true); + x110_elementGen->SetOrientation(GetTransform().getRotation()); + x110_elementGen->SetGlobalTranslation(GetTranslation()); + xe6_27_thermalVisorFlags = 2; +} + +void CShockWave::Accept(IVisitor& visitor) { visitor.Visit(this); } + +void CShockWave::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + // TODO + CActor::AcceptScriptMsg(msg, uid, mgr); +} + +void CShockWave::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + CActor::AddToRenderer(frustum, mgr); + g_Renderer->AddParticleGen(*x110_elementGen); +} + +std::optional CShockWave::GetTouchBounds() const { + // TODO + return CActor::GetTouchBounds(); +} + +void CShockWave::Render(const CStateManager& mgr) const { + CActor::Render(mgr); + x110_elementGen->Render(); +} + +void CShockWave::Think(float dt, CStateManager& mgr) { + // TODO +} + +void CShockWave::Touch(CActor& actor, CStateManager& mgr) { + // TODO +} +} // namespace MP1 +} // namespace urde diff --git a/Runtime/MP1/World/CShockWave.hpp b/Runtime/MP1/World/CShockWave.hpp new file mode 100644 index 000000000..19e3e479a --- /dev/null +++ b/Runtime/MP1/World/CShockWave.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "Runtime/World/CActor.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/Particle/CElementGen.hpp" + +namespace urde { +namespace MP1 { +struct SShockWaveData { + u32 x0_ = 8; + CAssetId x4_particleDesc; + CDamageInfo x8_damageInfo; + float x24_ = 0.f; + float x28_ = 0.5f; + float x2c_ = 16.5217f; + float x30_ = 0.f; + CAssetId x34_weaponDesc; + s16 x38_sfx; + + SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, s16 sfx) + : x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_sfx(sfx) {} +}; + +class CShockWave : public CActor { +public: + TUniqueId xe8_id1; + CDamageInfo xec_damageInfo; + TToken x108_elementGenDesc; + std::unique_ptr x110_elementGen; + SShockWaveData x114_data; + float x150_; + float x154_; + float x158_ = 0.f; + float x15c_; + float x160_; + float x164_ = 0.f; + float x168_ = 0.f; + char x16c_flags1; + char x16d_flags2; + // x368 => very large reserved_vector of ? + std::optional> x974_electricDesc; + TUniqueId x980_id2 = kInvalidUniqueId; + + CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + TUniqueId parent, const SShockWaveData& data, float f1, float f2); + + void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + std::optional GetTouchBounds() const override; + void Render(const CStateManager& mgr) const override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& actor, CStateManager& mgr) override; +}; +} // namespace MP1 +} // namespace urde