From e5df60967346e9ffec39e78ebb9653b3cc37f269 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 8 Mar 2020 19:52:21 -0700 Subject: [PATCH 01/26] CElitePirate: Initial stubbing --- Runtime/MP1/World/CElitePirate.cpp | 84 ++++++++++++++++++- Runtime/MP1/World/CElitePirate.hpp | 129 +++++++++++++++++++++++++++-- 2 files changed, 206 insertions(+), 7 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index d0316d5e5..3775fec07 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -1,7 +1,13 @@ #include "Runtime/MP1/World/CElitePirate.hpp" +#include "Runtime/Collision/CCollisionActorManager.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/ScriptLoader.hpp" +#include "TCastTo.hpp" // Generated file, do not modify include path + namespace urde::MP1 { CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) : x0_(in.readFloatBig()) @@ -44,5 +50,81 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, const CElitePirateData& eliteData) : CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, - EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) {} + EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) +, x56c_(pInfo.GetDamageVulnerability()) +, x5d8_(eliteData) +, x6f8_(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), + EBoneTrackingFlags::None) +, x738_(GetBoundingBox(), GetMaterialList()) +, x7d0_(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) { + if (x5d8_.GetX20().IsValid()) { + x760_ = g_SimplePool->GetObj({SBIG('PART'), x5d8_.GetX20()}); + } + + x460_knockBackController.SetEnableFreeze(false); + x460_knockBackController.SetAutoResetImpulse(false); + x460_knockBackController.SetEnableBurn(false); + x460_knockBackController.SetEnableExplodeDeath(false); + x460_knockBackController.SetEnableLaggedBurnDeath(false); + sub80229248(); +} +void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } +void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } +void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); +} +void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } +const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { return CAi::GetDamageVulnerability(); } +const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const { + return CActor::GetDamageVulnerability(pos, dir, dInfo); +} +zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { + return CPatterned::GetOrbitPosition(mgr); +} +zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) const { + return CPatterned::GetAimPosition(mgr, dt); +} +void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); +} +const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { + return CPhysicsActor::GetCollisionPrimitive(); +} +void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) { + CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); +} +void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float arg) { CPatterned::TakeDamage(pos, arg); } +void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } +void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } +void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { + CPatterned::TargetPatrol(mgr, msg, dt); +} +void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Halt(mgr, msg, dt); } +void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Run(mgr, msg, dt); } +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Generate(mgr, msg, dt); } +void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } +void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } +void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { + CAi::ProjectileAttack(mgr, msg, dt); +} +void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } +void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) { CAi::CallForBackup(mgr, msg, dt); } +bool CElitePirate::TooClose(CStateManager& mgr, float arg) { return CPatterned::TooClose(mgr, arg); } +bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { return CPatterned::InDetectionRange(mgr, arg); } +bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } +bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } +bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } +bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } +bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) { return CAi::ShouldTurn(mgr, arg); } +bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { return CAi::AggressionCheck(mgr, arg); } +bool CElitePirate::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); } +bool CElitePirate::ShouldFire(CStateManager& mgr, float arg) { return CAi::ShouldFire(mgr, arg); } +bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return CAi::ShotAt(mgr, arg); } +bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } +bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return CAi::ShouldCallForBackup(mgr, arg); } +CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); } +void CElitePirate::V181(CStateManager& mgr) {} +void CElitePirate::v182(CStateManager& mgr, bool b) {} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 0f7d31de0..6ff8e3ead 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -1,13 +1,16 @@ #pragma once -#include +#include "Runtime/Character/CBoneTracking.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" #include "Runtime/World/CPatterned.hpp" +#include "Runtime/World/CPathFindSearch.hpp" -namespace urde::MP1 { +namespace urde { +class CCollisionActorManager; +class CGenDescription; +namespace MP1 { class CElitePirateData { float x0_; float x4_; @@ -47,13 +50,127 @@ class CElitePirateData { public: CElitePirateData(CInputStream&, u32 propCount); + + CAssetId GetX20() const { return x20_; } + CAssetId GetXF8() const { return xf8_; } + const CDamageInfo& GetXFC() const { return xfc_; } + CAssetId GetX118() const { return x118_; } + s16 GetX11C() const { return x11c_; } }; class CElitePirate : public CPatterned { + struct SUnknownStruct { + float x0_; + s32 x4_ = 0; + 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_; + std::unique_ptr x5d4_; + CElitePirateData x5d8_; + CBoneTracking x6f8_; + std::unique_ptr x730_; + s32 x734_; + CCollidableAABox x738_; + std::optional> x760_; + TUniqueId x770_ = kInvalidUniqueId; + TUniqueId x772_ = kInvalidUniqueId; + s32 x774_ = 0; + s32 x788_ = 0; + TUniqueId x79c_ = kInvalidUniqueId; + float x7a0_; + float x7a4_ = 1.f; + float x7a8_ = 0.f; + float x7ac_ = 0.f; + float x7b0_ = 1.f; + float x7b4_ = 0.f; + float x7b8_ = 0.f; + float x7bc_ = 0.f; + float x7c0_ = 0.f; + float x7c4_ = 0.f; + s32 x7c8_ = -1; + s32 x7cc_ = 0; + CPathFindSearch x7d0_; + zeus::CVector3f x8b4_; + SUnknownStruct x8c0_ = SUnknownStruct(5.f); + bool x988_24_ : 1; + bool x988_25_ : 1; + bool x988_26_ : 1; + bool x988_27_ : 1; + bool x988_28_ : 1; + bool x988_29_ : 1; + bool x988_30_ : 1; + bool x988_31_ : 1; + bool x989_24_ : 1; + void sub80229248() {} + public: DEFINE_PATTERNED(ElitePirate) - CElitePirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, - const CPatternedInfo&, const CActorParameters&, const CElitePirateData&); + CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, + const CElitePirateData& data); + + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + const CDamageVulnerability* GetDamageVulnerability() const override; + const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const override; + zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const override; + zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const CCollisionPrimitive* GetCollisionPrimitive() const override; + void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, + float magnitude) override; + void TakeDamage(const zeus::CVector3f&, float arg) override; + void Patrol(CStateManager&, EStateMsg msg, float dt) override; + void PathFind(CStateManager&, EStateMsg msg, float dt) override; + void TargetPatrol(CStateManager&, EStateMsg msg, float dt) override; + void Halt(CStateManager&, EStateMsg msg, float dt) override; + void Run(CStateManager&, EStateMsg msg, float dt) override; + void Generate(CStateManager&, EStateMsg msg, float dt) override; + void Attack(CStateManager&, EStateMsg msg, float dt) override; + void Taunt(CStateManager&, EStateMsg msg, float dt) override; + void ProjectileAttack(CStateManager&, EStateMsg msg, float dt) override; + void SpecialAttack(CStateManager&, EStateMsg msg, float dt) override; + void CallForBackup(CStateManager&, EStateMsg msg, float dt) override; + bool TooClose(CStateManager&, float arg) override; + bool InDetectionRange(CStateManager&, float arg) override; + bool SpotPlayer(CStateManager&, float arg) override; + bool AnimOver(CStateManager&, float arg) override; + bool ShouldAttack(CStateManager&, float arg) override; + bool InPosition(CStateManager&, float arg) override; + bool ShouldTurn(CStateManager&, float arg) override; + bool AggressionCheck(CStateManager&, float arg) override; + bool ShouldTaunt(CStateManager&, float arg) override; + bool ShouldFire(CStateManager&, float arg) override; + bool ShotAt(CStateManager&, float arg) override; + bool ShouldSpecialAttack(CStateManager&, float arg) override; + bool ShouldCallForBackup(CStateManager&, float arg) override; + CPathFindSearch* GetSearchPath() override; + virtual bool V179() { return true; } + virtual bool V180() { return true; } + virtual void V181(CStateManager& mgr); + virtual void v182(CStateManager& mgr, bool b); + virtual SUnknownStruct2 V182() const {return {x5d8_.GetXF8(), x5d8_.GetXFC(), x5d8_.GetX118(), x5d8_.GetX11C()}; } }; -} // namespace urde::MP1 \ No newline at end of file +} // namespace MP1 +} // namespace urde \ No newline at end of file From 566c3566124d3de3203f89b33dd20161419ad173 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 11 Mar 2020 05:25:45 -0700 Subject: [PATCH 02/26] Initial ElitePirate imps --- Runtime/MP1/World/CElitePirate.cpp | 40 ++++++++++++++++++++++++++---- Runtime/MP1/World/CElitePirate.hpp | 5 ++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 3775fec07..bb7334b49 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -2,6 +2,7 @@ #include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/ScriptLoader.hpp" @@ -39,6 +40,7 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , xec_(zeus::degToRad(in.readFloatBig())) , xf0_(in.readUint32Big()) , xf4_(CSfxManager::TranslateSFXID(in.readUint32Big())) +, xf6_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf8_(in) , xfc_(in) , x118_(in) @@ -71,6 +73,36 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + + switch (msg) { + case EScriptObjectMessage::Activate: { + if (V179()) + x730_->SetActive(mgr, true); + if (CEntity* ent = mgr.ObjectById(x772_)) + ent->SetActive(true); + break; + } + case EScriptObjectMessage::Deactivate: { + if (V179()) + x730_->SetActive(mgr, false); + x5d4_->SetActive(mgr, false); + + if (CEntity* ent = mgr.ObjectById(x772_)) + ent->SetActive(false); + break; + } + case EScriptObjectMessage::Alert: + x988_28_ = true; + break; + case EScriptObjectMessage::Touched: + break; + case EScriptObjectMessage::Registered: + x450_bodyController->Activate(mgr); + SetupCollisionManager(mgr); + default: + break; + } + CPatterned::AcceptScriptMsg(msg, uid, mgr); } void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } @@ -91,16 +123,14 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } -void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, - bool inDeferred, float magnitude) { +void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, + EKnockBackType type, bool inDeferred, float magnitude) { CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); } void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float arg) { CPatterned::TakeDamage(pos, arg); } void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } -void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { - CPatterned::TargetPatrol(mgr, msg, dt); -} +void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); } void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Halt(mgr, msg, dt); } void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Run(mgr, msg, dt); } void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Generate(mgr, msg, dt); } diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 6ff8e3ead..4f4c2a733 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -40,7 +40,8 @@ class CElitePirateData { float xe8_; float xec_; u32 xf0_; - u32 xf4_; + u16 xf4_; + u16 xf6_; CAssetId xf8_; CDamageInfo xfc_; CAssetId x118_; @@ -170,7 +171,7 @@ public: virtual bool V180() { return true; } virtual void V181(CStateManager& mgr); virtual void v182(CStateManager& mgr, bool b); - virtual SUnknownStruct2 V182() const {return {x5d8_.GetXF8(), x5d8_.GetXFC(), x5d8_.GetX118(), x5d8_.GetX11C()}; } + virtual SUnknownStruct2 V183() const {return {x5d8_.GetXF8(), x5d8_.GetXFC(), x5d8_.GetX118(), x5d8_.GetX11C()}; } }; } // namespace MP1 } // namespace urde \ No newline at end of file From c33703bd93c8b7ea55ec621b26a9b962778b8669 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Thu, 26 Mar 2020 03:30:54 -0400 Subject: [PATCH 03/26] CElitePirate: Start impl; create CGrenadeLauncher --- Runtime/MP1/World/CElitePirate.cpp | 274 ++++++++++++++++++++++--- Runtime/MP1/World/CElitePirate.hpp | 56 +++-- Runtime/MP1/World/CGrenadeLauncher.cpp | 34 +++ Runtime/MP1/World/CGrenadeLauncher.hpp | 102 +++++++++ Runtime/MP1/World/CMakeLists.txt | 3 +- Runtime/World/CDamageVulnerability.cpp | 4 +- Runtime/World/CPathFindSearch.hpp | 3 + 7 files changed, 425 insertions(+), 51 deletions(-) create mode 100644 Runtime/MP1/World/CGrenadeLauncher.cpp create mode 100644 Runtime/MP1/World/CGrenadeLauncher.hpp diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index bb7334b49..fbc2693ac 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -1,15 +1,41 @@ #include "Runtime/MP1/World/CElitePirate.hpp" +#include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CPlayer.hpp" #include "Runtime/World/ScriptLoader.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { +namespace { +static constexpr std::array skJointInfoL{{ + {"L_shoulder", "L_elbow", 1.f, 1.5f}, + {"L_wrist", "L_elbow", 0.9f, 1.3f}, + {"L_knee", "L_ankle", 0.9f, 1.3f}, +}}; + +static constexpr std::array skJointInfoR{{ + {"R_shoulder", "R_elbow", 1.f, 1.5f}, + {"R_wrist", "R_elbow", 0.9f, 1.3f}, + {"R_knee", "R_ankle", 0.9f, 1.3f}, +}}; + +static constexpr std::array skSphereJointInfo{{ + {"Head_1", 1.2f}, + {"L_Palm_LCTR", 1.5f}, + {"R_Palm_LCTR", 1.5f}, + {"Spine_1", 1.5f}, + {"Collar", 1.2f}, + {"L_Ball", 0.8f}, + {"R_Ball", 0.8f}, +}}; +} // namespace + CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) : x0_(in.readFloatBig()) , x4_(in.readFloatBig()) @@ -22,7 +48,7 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , x20_(in) , x24_(CSfxManager::TranslateSFXID(in.readUint32Big())) , x28_(ScriptLoader::LoadActorParameters(in)) -, x90_(ScriptLoader::LoadAnimationParameters(in)) +, x90_launcherParams(ScriptLoader::LoadAnimationParameters(in)) , x9c_(in) , xa0_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xa4_(in) @@ -53,14 +79,24 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn const CElitePirateData& eliteData) : CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) -, x56c_(pInfo.GetDamageVulnerability()) -, x5d8_(eliteData) -, x6f8_(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), - EBoneTrackingFlags::None) +, x56c_vulnerability(pInfo.GetDamageVulnerability()) +, x5d8_data(eliteData) +, x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), + EBoneTrackingFlags::None) , x738_(GetBoundingBox(), GetMaterialList()) -, x7d0_(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) { - if (x5d8_.GetX20().IsValid()) { - x760_ = g_SimplePool->GetObj({SBIG('PART'), x5d8_.GetX20()}); +, x7d0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) +, x8c0_(5.f) +, x988_24_(false) +, x988_25_(false) +, x988_26_(false) +, x988_27_(false) +, x988_28_alert(false) +, x988_29_(false) +, x988_30_(false) +, x988_31_(false) +, x989_24_(false) { + if (x5d8_data.GetX20().IsValid()) { + x760_ = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()}); } x460_knockBackController.SetEnableFreeze(false); @@ -68,41 +104,82 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn x460_knockBackController.SetEnableBurn(false); x460_knockBackController.SetEnableExplodeDeath(false); x460_knockBackController.SetEnableLaggedBurnDeath(false); - sub80229248(); + sub_80229248(); } void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { - switch (msg) { case EScriptObjectMessage::Activate: { - if (V179()) - x730_->SetActive(mgr, true); - if (CEntity* ent = mgr.ObjectById(x772_)) + if (sub_802273a8()) { + x730_collisionActorMgr2->SetActive(mgr, true); + } + if (CEntity* ent = mgr.ObjectById(x772_)) { ent->SetActive(true); + } break; } case EScriptObjectMessage::Deactivate: { - if (V179()) - x730_->SetActive(mgr, false); - x5d4_->SetActive(mgr, false); - - if (CEntity* ent = mgr.ObjectById(x772_)) + if (sub_802273a8()) { + x730_collisionActorMgr2->SetActive(mgr, false); + } + x5d4_collisionActorMgr1->SetActive(mgr, false); + if (CEntity* ent = mgr.ObjectById(x772_)) { ent->SetActive(false); + } break; } case EScriptObjectMessage::Alert: - x988_28_ = true; + x988_28_alert = true; break; - case EScriptObjectMessage::Touched: + case EScriptObjectMessage::Touched: { + if (HealthInfo(mgr)->GetHP() <= 0.f) + break; + TCastToPtr actor = mgr.ObjectById(uid); + if (!actor) { + if (uid == x772_ && x772_ != kInvalidUniqueId) { + sub_8022759c(true, mgr); + } + break; + } + const TUniqueId& touchedUid = actor->GetLastTouchedObject(); + if (touchedUid != GetUniqueId()) { + if (TCastToPtr projectile = mgr.ObjectById(touchedUid)) { + sub_8022759c(true, mgr); + } + break; + } + if (!x988_31_) { // TODO is this right? + if (x420_curDamageRemTime <= 0.f) { + CDamageInfo info = GetContactDamage(); + info.SetDamage(0.5f * info.GetDamage()); + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), info, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + x420_curDamageRemTime = x424_damageWaitTime; + } + break; + } + if ((!x988_25_ || !sub_802293f8(uid, x774_collisionRJointIds)) && + (!x988_26_ || !sub_802293f8(uid, x788_collisionLJointIds))) { + break; + } + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + x420_curDamageRemTime = x424_damageWaitTime; + x988_24_ = false; break; + } case EScriptObjectMessage::Registered: x450_bodyController->Activate(mgr); - SetupCollisionManager(mgr); + SetupCollisionManagers(mgr); + // TODO + break; default: break; } + // TODO + CPatterned::AcceptScriptMsg(msg, uid, mgr); } void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } @@ -120,14 +197,12 @@ zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { CPatterned::DoUserAnimEvent(mgr, node, type, dt); } -const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { - return CPhysicsActor::GetCollisionPrimitive(); -} +const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); } -void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float arg) { CPatterned::TakeDamage(pos, arg); } +void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); } @@ -155,6 +230,151 @@ bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return CAi::ShotAt(mg bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return CAi::ShouldCallForBackup(mgr, arg); } CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); } -void CElitePirate::V181(CStateManager& mgr) {} -void CElitePirate::v182(CStateManager& mgr, bool b) {} +void CElitePirate::sub_80229114(CStateManager& mgr) {} +void CElitePirate::sub_802289b0(CStateManager& mgr, bool b) {} + +void CElitePirate::sub_80229248() { + float scale = 1.5f * GetModelData()->GetScale().y(); + float fVar1 = sub_802273b0() ? 5.f : 1.f; + zeus::CAABox box{{-scale, -scale, 0.f}, {scale, scale, fVar1 * scale}}; + SetBoundingBox(box); + x738_.SetBox(box); + x7d0_pathFindSearch.SetCharacterRadius(scale); + x7d0_pathFindSearch.SetCharacterHeight(3.f * scale); +} + +void CElitePirate::sub_8022759c(bool param_1, CStateManager& mgr) { + if (!sub_802273b0() || x7b4_ <= 0.f || !param_1) { + x988_27_ = param_1; + } else if (HealthInfo(mgr)->GetHP() / x7b4_ <= x7b0_) { + x7b0_ -= 0.2f; + x988_27_ = true; + } + if (x988_27_) { + x7c0_ = mgr.GetActiveRandom()->Float() * x5d8_data.x18_ + x5d8_data.x14_; + } else { + x7c0_ = 0.f; + } +} + +bool CElitePirate::sub_802293f8(TUniqueId uid, const rstl::reserved_vector& vec) const { + return std::find(vec.begin(), vec.end(), uid) != vec.end(); +} + +void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count, + std::vector& outJoints) const { + const CAnimData* animData = GetModelData()->GetAnimationData(); + + for (size_t i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId from = animData->GetLocatorSegId(joint.from); + const CSegId to = animData->GetLocatorSegId(joint.to); + + if (to.IsInvalid() || from.IsInvalid()) { + continue; + } + + outJoints.emplace_back(CJointCollisionDescription::SphereSubdivideCollision( + to, from, joint.radius, joint.separation, CJointCollisionDescription::EOrientationType::One, joint.from, 10.f)); + } +} + +void CElitePirate::AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, + std::vector& outJoints) const { + const CAnimData* animData = GetModelData()->GetAnimationData(); + + for (size_t i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId seg = animData->GetLocatorSegId(joint.name); + + if (seg.IsInvalid()) { + continue; + } + + outJoints.emplace_back(CJointCollisionDescription::SphereCollision(seg, joint.radius, joint.name, 10.f)); + } +} + +void CElitePirate::SetupCollisionManagers(CStateManager& mgr) { + constexpr size_t jointInfoCount = skJointInfoL.size() + skJointInfoR.size() + skSphereJointInfo.size(); + std::vector joints(jointInfoCount); + AddCollisionList(skJointInfoL.data(), skJointInfoL.size(), joints); + AddCollisionList(skJointInfoR.data(), skJointInfoL.size(), joints); + AddSphereCollisionList(skSphereJointInfo.data(), skSphereJointInfo.size(), joints); + if (sub_802273a8()) { + x730_collisionActorMgr2 = + std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, true); + x730_collisionActorMgr2->SetActive(mgr, GetActive()); + } + x774_collisionRJointIds.clear(); + x788_collisionLJointIds.clear(); + + const CAnimData* animData = GetModelData()->GetAnimationData(); + constexpr zeus::CVector3f bounds{4.f, 4.f, 2.f}; + joints.emplace_back(CJointCollisionDescription::OBBCollision(animData->GetLocatorSegId("L_Palm_LCTR"sv), bounds, + zeus::skZero3f, "Shield"sv, 10.f)); + x5d4_collisionActorMgr1 = + std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, false); + + sub_80229818(mgr); + sub_80229114(mgr); + + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( + {EMaterialTypes::Solid}, + {EMaterialTypes::CollisionActor, EMaterialTypes::AIPassthrough, EMaterialTypes::Player})); + AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); +} + +void CElitePirate::sub_80229818(CStateManager& mgr) { + if (sub_802273a8()) { + for (size_t i = 0; i < x730_collisionActorMgr2->GetNumCollisionActors(); ++i) { + const auto& colDesc = x730_collisionActorMgr2->GetCollisionDescFromIndex(i); + const TUniqueId& uid = colDesc.GetCollisionActorId(); + if (TCastToPtr act = mgr.ObjectById(uid)) { + if (colDesc.GetName() == "Head_1"sv) { + x770_collisionHeadId = uid; + } else if (sub_8022943c(colDesc.GetName(), "R_Palm_LCTR"sv, skJointInfoR.data(), skJointInfoR.size())) { + x774_collisionRJointIds.push_back(uid); + } else if (sub_8022943c(colDesc.GetName(), "L_Palm_LCTR"sv, skJointInfoL.data(), skJointInfoL.size())) { + x788_collisionLJointIds.push_back(uid); + } + if (uid != x770_collisionHeadId) { + act->SetDamageVulnerability(CDamageVulnerability::ReflectVulnerabilty()); + } + } + } + x730_collisionActorMgr2->AddMaterial( + mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough, EMaterialTypes::Immovable}); + } + + const CJointCollisionDescription& description = x5d4_collisionActorMgr1->GetCollisionDescFromIndex(0); + x79c_ = description.GetCollisionActorId(); + if (TCastToPtr act = mgr.ObjectById(x79c_)) { + act->SetWeaponCollisionResponseType(EWeaponCollisionResponseTypes::None); + } + x5d4_collisionActorMgr1->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough}); +} + +bool CElitePirate::sub_8022943c(std::string_view name, std::string_view locator, const SJointInfo* info, + size_t infoCount) { + if (name == locator) { + return true; + } + for (size_t i = 0; i < infoCount; ++i) { + if (name == info[i].from) { + return true; + } + } + return false; +} + +void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { + CAnimationParameters& params = x5d8_data.x90_launcherParams; + if (!params.GetACSFile().IsValid()) { + return; + } + CModelData data(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), + params.GetInitialAnimation(), true)); + // TODO +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 4f4c2a733..f06623e45 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -1,7 +1,7 @@ #pragma once #include "Runtime/Character/CBoneTracking.hpp" - +#include "Runtime/Collision/CJointCollisionDescription.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" #include "Runtime/World/CPatterned.hpp" @@ -12,6 +12,7 @@ class CCollisionActorManager; class CGenDescription; namespace MP1 { class CElitePirateData { +public: float x0_; float x4_; float x8_; @@ -23,7 +24,7 @@ class CElitePirateData { CAssetId x20_; s16 x24_; CActorParameters x28_; - CAnimationParameters x90_; + CAnimationParameters x90_launcherParams; CAssetId x9c_; s16 xa0_; CAssetId xa4_; @@ -49,7 +50,6 @@ class CElitePirateData { bool x11e_; bool x11f_; -public: CElitePirateData(CInputStream&, u32 propCount); CAssetId GetX20() const { return x20_; } @@ -82,18 +82,18 @@ class CElitePirate : public CPatterned { }; s32 x568_ = -1; - CDamageVulnerability x56c_; - std::unique_ptr x5d4_; - CElitePirateData x5d8_; - CBoneTracking x6f8_; - std::unique_ptr x730_; + CDamageVulnerability x56c_vulnerability; + std::unique_ptr x5d4_collisionActorMgr1; + CElitePirateData x5d8_data; + CBoneTracking x6f8_boneTracking; + std::unique_ptr x730_collisionActorMgr2; s32 x734_; CCollidableAABox x738_; std::optional> x760_; - TUniqueId x770_ = kInvalidUniqueId; + TUniqueId x770_collisionHeadId = kInvalidUniqueId; TUniqueId x772_ = kInvalidUniqueId; - s32 x774_ = 0; - s32 x788_ = 0; + rstl::reserved_vector x774_collisionRJointIds; + rstl::reserved_vector x788_collisionLJointIds; TUniqueId x79c_ = kInvalidUniqueId; float x7a0_; float x7a4_ = 1.f; @@ -107,19 +107,18 @@ class CElitePirate : public CPatterned { float x7c4_ = 0.f; s32 x7c8_ = -1; s32 x7cc_ = 0; - CPathFindSearch x7d0_; + CPathFindSearch x7d0_pathFindSearch; zeus::CVector3f x8b4_; - SUnknownStruct x8c0_ = SUnknownStruct(5.f); + SUnknownStruct x8c0_; bool x988_24_ : 1; bool x988_25_ : 1; bool x988_26_ : 1; bool x988_27_ : 1; - bool x988_28_ : 1; + bool x988_28_alert : 1; bool x988_29_ : 1; bool x988_30_ : 1; bool x988_31_ : 1; bool x989_24_ : 1; - void sub80229248() {} public: DEFINE_PATTERNED(ElitePirate) @@ -167,11 +166,26 @@ public: bool ShouldSpecialAttack(CStateManager&, float arg) override; bool ShouldCallForBackup(CStateManager&, float arg) override; CPathFindSearch* GetSearchPath() override; - virtual bool V179() { return true; } - virtual bool V180() { return true; } - virtual void V181(CStateManager& mgr); - virtual void v182(CStateManager& mgr, bool b); - virtual SUnknownStruct2 V183() const {return {x5d8_.GetXF8(), x5d8_.GetXFC(), x5d8_.GetX118(), x5d8_.GetX11C()}; } + virtual bool sub_802273a8() { return true; } + virtual bool sub_802273b0() { return true; } + virtual void sub_80229114(CStateManager& mgr); + virtual void sub_802289b0(CStateManager& mgr, bool b); + virtual SUnknownStruct2 sub_802273b8() const { + return {x5d8_data.GetXF8(), x5d8_data.GetXFC(), x5d8_data.GetX118(), x5d8_data.GetX11C()}; + } + +private: + void sub_80229248(); + void sub_8022759c(bool param_1, CStateManager& mgr); + bool sub_802293f8(TUniqueId uid, const rstl::reserved_vector& vec) const; + void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, + std::vector& outJoints) const; + void AddCollisionList(const SJointInfo* joints, size_t count, + std::vector& outJoints) const; + void SetupCollisionManagers(CStateManager& mgr); + void sub_80229818(CStateManager& mgr); + bool sub_8022943c(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount); + void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); }; } // namespace MP1 -} // namespace urde \ No newline at end of file +} // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp new file mode 100644 index 000000000..6f46604e0 --- /dev/null +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -0,0 +1,34 @@ +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" + +#include "Runtime/CSimplePool.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Character/CPASAnimParm.hpp" +#include "Runtime/Character/CPASAnimParmData.hpp" + +namespace urde { +namespace MP1 { +CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, + const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, + const CActorParameters& actParams, TUniqueId otherId, + const CGrenadeLauncherData& data, float f1) +: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Character, EMaterialTypes::Solid}, bounds, + {1000.f}, actParams, 0.3f, 0.1f) +, x25c_(healthInfo) +, x264_vulnerability(vulnerability) +, x2cc_otherId(otherId) +, x2d0_data(data) +, x328_cSphere({{}, mData.GetScale().z()}, {EMaterialTypes::Character, EMaterialTypes::Solid}) +, x350_actParms(actParams) +, x3c0_particleGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.x40_})) +, x3d8_(actParams.GetThermalMag()) +, x3f8_(f1) { + GetModelData()->EnableLooping(true); + const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); + for (int i = 0; i < 4; i++) { + const auto result = pasDatabase.FindBestAnimation({22, CPASAnimParm::FromEnum(i)}, -1); + x3c8_animIds[i] = result.second; + } +} +} // namespace MP1 +} // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp new file mode 100644 index 000000000..a0fc980e5 --- /dev/null +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -0,0 +1,102 @@ +#pragma once + +#include "Runtime/Character/CModelData.hpp" +#include "Runtime/Collision/CCollidableSphere.hpp" +#include "Runtime/Particle/CGenDescription.hpp" +#include "Runtime/RetroTypes.hpp" +#include "Runtime/World/CActorParameters.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/World/CDamageVulnerability.hpp" +#include "Runtime/World/CEntityInfo.hpp" +#include "Runtime/World/CHealthInfo.hpp" +#include "Runtime/World/CPhysicsActor.hpp" +#include "Runtime/World/CPhysicsActor.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +#include +#include +#include +#include +#include + +namespace urde { +namespace MP1 { +struct SGrenadeLauncherData { + CHealthInfo x0_healthInfo; + CDamageInfo x8_damageInfo; + u32 x24_; + u32 x28_; + u32 x2c_; + u32 x30_; + u32 x34_; + u16 x38_; + u16 x3a_; +}; + +class CGrenadeLauncherData { +public: + SGrenadeLauncherData x0_; + u32 x3c_; + CAssetId x40_; + u16 x44_sfx; + zeus::CQuaternion x48_quat; + + CGrenadeLauncherData(const SGrenadeLauncherData& data, u32 w1, CAssetId w2, u16 sfx, const zeus::CQuaternion& quat) + : x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_quat(quat){}; +}; + +class CGrenadeLauncher : public CPhysicsActor { +public: + int x258_ = 0; + CHealthInfo x25c_; + CDamageVulnerability x264_vulnerability; + TUniqueId x2cc_otherId; + CGrenadeLauncherData x2d0_data; + CCollidableSphere x328_cSphere; + float x348_ = -1.f; + zeus::CColor x34c_color1{1.f}; + CActorParameters x350_actParms; + // was TToken + TLockedToken x3c0_particleGenDesc; + std::array x3c8_animIds; + float x3d8_ = 0.f; + float x3dc_ = 0.f; + float x3e0_ = 0.f; + float x3e4_ = 0.f; + float x3e8_thermalMag; + float x3ec_ = 0.f; + zeus::CColor x3f0_color2{0.5f, 0.f, 0.f}; + zeus::CColor x3f4_color3{0.f}; + float x3f8_; + bool x3fc_ = false; + bool x3fd_ = true; + bool x3fe_ = true; + + CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, + const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId otherId, + const CGrenadeLauncherData& data, float f1); + + void Accept(IVisitor& visitor) override { visitor.Visit(this); } + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } + const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } + std::optional GetTouchBounds() const override; + CHealthInfo* HealthInfo(CStateManager& mgr) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void Render(const CStateManager& mgr) const override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& act, CStateManager& mgr) override; + +protected: + void UpdateCollision(); + void UpdateColor(float arg); + void sub_8022f69c(float arg); + void sub_8022f770(CStateManager& mgr); + void sub_8022f9e0(CStateManager& mgr, float arg); + void sub_80230438(); +}; +} // namespace MP1 +} // namespace urde diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 4ac6f702a..bcaa95109 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -15,8 +15,9 @@ set(MP1_WORLD_SOURCES CAtomicAlpha.hpp CAtomicAlpha.cpp CAtomicBeta.hpp CAtomicBeta.cpp CFlickerBat.hpp CFlickerBat.cpp - CJellyZap.hpp CJellyZap.cpp CFlyingPirate.hpp CFlyingPirate.cpp + CGrenadeLauncher.hpp CGrenadeLauncher.cpp + CJellyZap.hpp CJellyZap.cpp CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp CMetroidPrimeProjectile.hpp CMetroidPrimeProjectile.cpp diff --git a/Runtime/World/CDamageVulnerability.cpp b/Runtime/World/CDamageVulnerability.cpp index c0c367c52..cb48efc37 100644 --- a/Runtime/World/CDamageVulnerability.cpp +++ b/Runtime/World/CDamageVulnerability.cpp @@ -17,14 +17,14 @@ const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability( EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None); -/* LOL, thanks retro */ + const CDamageVulnerability CDamageVulnerability::sReflectVulnerability( EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, - EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None); + EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::One); const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability( EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, diff --git a/Runtime/World/CPathFindSearch.hpp b/Runtime/World/CPathFindSearch.hpp index 62adc4133..ce5a37d6e 100644 --- a/Runtime/World/CPathFindSearch.hpp +++ b/Runtime/World/CPathFindSearch.hpp @@ -14,6 +14,7 @@ class CPathFindSearch; class CPathFindVisualizer { CLineRenderer m_spline = {CLineRenderer::EPrimitiveMode::LineStrip, 16, {}, true}; + public: void Draw(const CPathFindSearch& path); }; @@ -56,6 +57,8 @@ public: void SetArea(CPFArea* area) { x0_area = area; } float GetCharacterHeight() const { return xd0_chHeight; } void SetCharacterHeight(float h) { xd0_chHeight = h; } + float GetCharacterRadius() const { return xd4_chRadius; } + void SetCharacterRadius(float r) { xd4_chRadius = r; } void SetPadding(float padding) { xd8_padding = padding; } float RemainingPathDistance(const zeus::CVector3f& pos) const; void DebugDraw() const; From 6150548e91ef63a815bafd25c5f9f4580ae417b6 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Thu, 26 Mar 2020 15:24:56 -0400 Subject: [PATCH 04/26] CElitePirate: Finish implementing AcceptScriptMsg --- Runtime/MP1/World/CElitePirate.cpp | 230 +++++++++++++++++++++---- Runtime/MP1/World/CElitePirate.hpp | 26 +-- Runtime/MP1/World/CGrenadeLauncher.hpp | 27 ++- 3 files changed, 232 insertions(+), 51 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index fbc2693ac..e8b90d784 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -5,8 +5,12 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" +#include "Runtime/World/CExplosion.hpp" #include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CWorld.hpp" #include "Runtime/World/ScriptLoader.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -46,9 +50,9 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , x18_(in.readFloatBig()) , x1c_(in.readFloatBig()) , x20_(in) -, x24_(CSfxManager::TranslateSFXID(in.readUint32Big())) -, x28_(ScriptLoader::LoadActorParameters(in)) -, x90_launcherParams(ScriptLoader::LoadAnimationParameters(in)) +, x24_sfxAbsorb(CSfxManager::TranslateSFXID(in.readUint32Big())) +, x28_launcherActParams(ScriptLoader::LoadActorParameters(in)) +, x90_launcherAnimParams(ScriptLoader::LoadAnimationParameters(in)) , x9c_(in) , xa0_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xa4_(in) @@ -58,13 +62,9 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , xcc_(in) , xd0_(in) , xd4_(in) -, xd8_(in.readFloatBig()) -, xdc_(in.readFloatBig()) -, xe0_(in.readFloatBig()) -, xe4_(in.readFloatBig()) -, xe8_(zeus::degToRad(in.readFloatBig())) -, xec_(zeus::degToRad(in.readFloatBig())) -, xf0_(in.readUint32Big()) +, xd8_(in) +, xe0_(in.readFloatBig(), in.readFloatBig(), zeus::degToRad(in.readFloatBig()), zeus::degToRad(in.readFloatBig())) +, xf0_(in) , xf4_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf6_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf8_(in) @@ -106,15 +106,20 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn x460_knockBackController.SetEnableLaggedBurnDeath(false); sub_80229248(); } + void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } + void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } + void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + bool shouldPass = true; + switch (msg) { case EScriptObjectMessage::Activate: { if (sub_802273a8()) { x730_collisionActorMgr2->SetActive(mgr, true); } - if (CEntity* ent = mgr.ObjectById(x772_)) { + if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { ent->SetActive(true); } break; @@ -124,7 +129,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta x730_collisionActorMgr2->SetActive(mgr, false); } x5d4_collisionActorMgr1->SetActive(mgr, false); - if (CEntity* ent = mgr.ObjectById(x772_)) { + if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { ent->SetActive(false); } break; @@ -137,7 +142,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta break; TCastToPtr actor = mgr.ObjectById(uid); if (!actor) { - if (uid == x772_ && x772_ != kInvalidUniqueId) { + if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { sub_8022759c(true, mgr); } break; @@ -169,69 +174,183 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta x988_24_ = false; break; } - case EScriptObjectMessage::Registered: + case EScriptObjectMessage::Registered: { x450_bodyController->Activate(mgr); SetupCollisionManagers(mgr); - // TODO + x772_launcherId = mgr.AllocateUniqueId(); + CreateGrenadeLauncher(mgr, x772_launcherId); + const auto& bodyStateInfo = x450_bodyController->GetBodyStateInfo(); + if (bodyStateInfo.GetMaxSpeed() > 0.f) { + x7a4_ = (0.99f * bodyStateInfo.GetLocomotionSpeed(pas::ELocomotionAnim::Walk)) / bodyStateInfo.GetMaxSpeed(); + } + x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_, x7a4_); break; + } + case EScriptObjectMessage::Deleted: + if (sub_802273a8()) { + x730_collisionActorMgr2->Destroy(mgr); + } + x5d4_collisionActorMgr1->Destroy(mgr); + mgr.FreeScriptObject(x772_launcherId); + break; + case EScriptObjectMessage::InitializedInArea: + x7d0_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); + break; + case EScriptObjectMessage::Damage: + shouldPass = false; + if (TCastToPtr actor = mgr.ObjectById(uid)) { + if (TCastToPtr projectile = mgr.ObjectById(actor->GetLastTouchedObject())) { + if (uid == x770_collisionHeadId) { + x428_damageCooldownTimer = 0.33f; + const auto& damageInfo = projectile->GetDamageInfo(); + KnockBack(projectile->GetTranslation() - projectile->GetPreviousPos(), mgr, damageInfo, + EKnockBackType::Radius, false, damageInfo.GetKnockBackPower()); + CPatterned::AcceptScriptMsg(msg, uid, mgr); + } else if (uid == x79c_ && x760_->IsLoaded()) { + sub_802281d8(mgr, projectile->GetTransform()); + } + sub_8022759c(true, mgr); + } + } else if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCKnockBackCmd(GetTransform().frontVector(), pas::ESeverity::Eight)); + } else { + sub_80227464(mgr, uid); + } + break; + case EScriptObjectMessage::InvulnDamage: { + sub_8022759c(true, mgr); + TCastToPtr actor = mgr.ObjectById(uid); + if (!actor) { + sub_80227464(mgr, uid); + } + break; + } default: break; } - // TODO - - CPatterned::AcceptScriptMsg(msg, uid, mgr); + if (shouldPass) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); + } } -void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } -const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { return CAi::GetDamageVulnerability(); } + +void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CPatterned::PreRender(mgr, frustum); + auto modelData = GetModelData(); + x6f8_boneTracking.PreRender(mgr, *modelData->GetAnimationData(), GetTransform(), modelData->GetScale(), + *x450_bodyController); + auto numMaterialSets = modelData->GetNumMaterialSets(); + xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_ ? numMaterialSets - 1 : x7cc_; +} + +const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { + return &CDamageVulnerability::PassThroughVulnerabilty(); +} + const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const CDamageInfo& dInfo) const { - return CActor::GetDamageVulnerability(pos, dir, dInfo); + return &CDamageVulnerability::PassThroughVulnerabilty(); } + zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { return CPatterned::GetOrbitPosition(mgr); } + zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) const { return CPatterned::GetAimPosition(mgr, dt); } + void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { CPatterned::DoUserAnimEvent(mgr, node, type, dt); } + const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } + void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); } + void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} + void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } + void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } + void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); } + void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Halt(mgr, msg, dt); } + void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Run(mgr, msg, dt); } + void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Generate(mgr, msg, dt); } + void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } + void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } + void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::ProjectileAttack(mgr, msg, dt); } + void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } + void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) { CAi::CallForBackup(mgr, msg, dt); } + bool CElitePirate::TooClose(CStateManager& mgr, float arg) { return CPatterned::TooClose(mgr, arg); } + bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { return CPatterned::InDetectionRange(mgr, arg); } + bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } -bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } + +bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return x568_ == 3; } + bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } + bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } + bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) { return CAi::ShouldTurn(mgr, arg); } -bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { return CAi::AggressionCheck(mgr, arg); } + +bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { + if (x772_launcherId == kInvalidUniqueId && !PathShagged(mgr, arg)) { + if (!x988_31_) { + return 4.f * x300_maxAttackRange * x300_maxAttackRange < + (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); + } + return true; + } + return false; +} + bool CElitePirate::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); } + bool CElitePirate::ShouldFire(CStateManager& mgr, float arg) { return CAi::ShouldFire(mgr, arg); } + bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return CAi::ShotAt(mgr, arg); } + bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } + bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return CAi::ShouldCallForBackup(mgr, arg); } + CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); } -void CElitePirate::sub_80229114(CStateManager& mgr) {} -void CElitePirate::sub_802289b0(CStateManager& mgr, bool b) {} + +void CElitePirate::sub_80229114(CStateManager& mgr) { + const CHealthInfo* const health = HealthInfo(mgr); + x7b4_hp = health->GetHP(); + if (sub_802273a8()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + auto actHealth = actor->HealthInfo(mgr); + actHealth->SetHP(health->GetHP()); + actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); + actor->SetDamageVulnerability(x56c_vulnerability); + } + } + sub_8022902c(mgr, x772_launcherId); +} + +void CElitePirate::sub_802289b0(CStateManager& mgr, bool b) { sub_80228920(mgr, b, x772_launcherId); } void CElitePirate::sub_80229248() { float scale = 1.5f * GetModelData()->GetScale().y(); @@ -244,9 +363,9 @@ void CElitePirate::sub_80229248() { } void CElitePirate::sub_8022759c(bool param_1, CStateManager& mgr) { - if (!sub_802273b0() || x7b4_ <= 0.f || !param_1) { + if (!sub_802273b0() || x7b4_hp <= 0.f || !param_1) { x988_27_ = param_1; - } else if (HealthInfo(mgr)->GetHP() / x7b4_ <= x7b0_) { + } else if (HealthInfo(mgr)->GetHP() / x7b4_hp <= x7b0_) { x7b0_ -= 0.2f; x988_27_ = true; } @@ -369,12 +488,61 @@ bool CElitePirate::sub_8022943c(std::string_view name, std::string_view locator, } void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { - CAnimationParameters& params = x5d8_data.x90_launcherParams; + CAnimationParameters& params = x5d8_data.x90_launcherAnimParams; if (!params.GetACSFile().IsValid()) { return; } - CModelData data(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), - params.GetInitialAnimation(), true)); - // TODO + CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), + params.GetInitialAnimation(), true)); + SGrenadeLauncherData transfer{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_, + x5d8_data.xd4_, x5d8_data.xf0_, x5d8_data.xf4_, x5d8_data.xf6_}; + CGrenadeLauncherData launcherData{transfer, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, x5d8_data.xe0_}; + mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, + GetTransform(), std::move(mData), mData.GetBounds(GetTransform().getRotation()), + CHealthInfo(x5d8_data.xc4_, 10.f), x56c_vulnerability, + x5d8_data.x28_launcherActParams, GetUniqueId(), launcherData, 0.f)); +} + +void CElitePirate::sub_80227464(CStateManager& mgr, TUniqueId uid) { + if (!sub_802273a8()) { + return; + } + if (TCastToPtr weapon = mgr.ObjectById(uid)) { + CDamageInfo damageInfo = weapon->GetDamageInfo(); + damageInfo.SetRadius(0.f); + mgr.ApplyDamage(uid, x770_collisionHeadId, weapon->GetOwnerId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + } +} + +void CElitePirate::sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf) { + if (x7ac_ > 0.f) { + return; + } + mgr.AddObject(new CExplosion(*x760_, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList}, + "Absorb energy Fx", xf, 0, GetModelData()->GetScale(), zeus::skWhite)); + CSfxManager::AddEmitter(x5d8_data.x24_sfxAbsorb, GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); + x7ac_ = 0.25f; +} + +void CElitePirate::sub_8022902c(CStateManager& mgr, TUniqueId uid) { + const CHealthInfo* const health = HealthInfo(mgr); + if (uid != kInvalidUniqueId) { + if (TCastToPtr actor = mgr.ObjectById(uid)) { + auto actHealth = actor->HealthInfo(mgr); + actHealth->SetHP(x5d8_data.xc4_); + actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); + actor->SetDamageVulnerability(x56c_vulnerability); + } + } +} + +void CElitePirate::sub_80228920(CStateManager& mgr, bool b, TUniqueId uid) { + if (uid == kInvalidUniqueId) { + return; + } + if (auto entity = mgr.ObjectById(uid)) { + mgr.SendScriptMsg(entity, GetUniqueId(), b ? EScriptObjectMessage::Start : EScriptObjectMessage::Stop); + } } } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index f06623e45..c416af305 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -22,11 +22,11 @@ public: float x18_; float x1c_; CAssetId x20_; - s16 x24_; - CActorParameters x28_; - CAnimationParameters x90_launcherParams; + s16 x24_sfxAbsorb; + CActorParameters x28_launcherActParams; + CAnimationParameters x90_launcherAnimParams; CAssetId x9c_; - s16 xa0_; + u16 xa0_; CAssetId xa4_; CDamageInfo xa8_; float xc4_; @@ -34,13 +34,9 @@ public: CAssetId xcc_; CAssetId xd0_; CAssetId xd4_; - float xd8_; - float xdc_; - float xe0_; - float xe4_; - float xe8_; - float xec_; - u32 xf0_; + CHealthInfo xd8_; // FIXME probably wrong type + zeus::CQuaternion xe0_; // FIXME probably wrong type + CAssetId xf0_; u16 xf4_; u16 xf6_; CAssetId xf8_; @@ -91,7 +87,7 @@ class CElitePirate : public CPatterned { CCollidableAABox x738_; std::optional> x760_; TUniqueId x770_collisionHeadId = kInvalidUniqueId; - TUniqueId x772_ = kInvalidUniqueId; + TUniqueId x772_launcherId = kInvalidUniqueId; rstl::reserved_vector x774_collisionRJointIds; rstl::reserved_vector x788_collisionLJointIds; TUniqueId x79c_ = kInvalidUniqueId; @@ -100,7 +96,7 @@ class CElitePirate : public CPatterned { float x7a8_ = 0.f; float x7ac_ = 0.f; float x7b0_ = 1.f; - float x7b4_ = 0.f; + float x7b4_hp = 0.f; float x7b8_ = 0.f; float x7bc_ = 0.f; float x7c0_ = 0.f; @@ -186,6 +182,10 @@ private: void sub_80229818(CStateManager& mgr); bool sub_8022943c(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount); void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); + void sub_80227464(CStateManager& mgr, TUniqueId uid); + 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); }; } // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index a0fc980e5..e7ee730cf 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -25,24 +25,37 @@ namespace MP1 { struct SGrenadeLauncherData { CHealthInfo x0_healthInfo; CDamageInfo x8_damageInfo; - u32 x24_; - u32 x28_; - u32 x2c_; - u32 x30_; - u32 x34_; + CAssetId x24_; + CAssetId x28_; + CAssetId x2c_; + CAssetId x30_; + CAssetId x34_; u16 x38_; u16 x3a_; + + SGrenadeLauncherData(const CHealthInfo& healthInfo, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, + CAssetId w3, CAssetId w4, CAssetId w5, u16 s1, u16 s2) + : x0_healthInfo(healthInfo) + , x8_damageInfo(damageInfo) + , x24_(w1) + , x28_(w2) + , x2c_(w3) + , x30_(w4) + , x34_(w5) + , x38_(s1) + , x3a_(s2){}; }; class CGrenadeLauncherData { public: SGrenadeLauncherData x0_; - u32 x3c_; + CAssetId x3c_; CAssetId x40_; u16 x44_sfx; zeus::CQuaternion x48_quat; - CGrenadeLauncherData(const SGrenadeLauncherData& data, u32 w1, CAssetId w2, u16 sfx, const zeus::CQuaternion& quat) + CGrenadeLauncherData(const SGrenadeLauncherData& data, CAssetId w1, CAssetId w2, u16 sfx, + const zeus::CQuaternion& quat) : x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_quat(quat){}; }; From 0886a39d819b20762bc92dd28648f5d0364db24f Mon Sep 17 00:00:00 2001 From: Luke Street Date: Thu, 26 Mar 2020 18:09:50 -0400 Subject: [PATCH 05/26] CElitePirate: DoUserAnimEvent; create CShockWave --- Runtime/MP1/World/CElitePirate.cpp | 65 ++++++++++++++++++++++++++++-- Runtime/MP1/World/CElitePirate.hpp | 25 +++--------- Runtime/MP1/World/CMakeLists.txt | 62 ++++++++++++++-------------- Runtime/MP1/World/CShockWave.cpp | 65 ++++++++++++++++++++++++++++++ Runtime/MP1/World/CShockWave.hpp | 56 +++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 52 deletions(-) create mode 100644 Runtime/MP1/World/CShockWave.cpp create mode 100644 Runtime/MP1/World/CShockWave.hpp 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 From 108fd502bf1996c718aa2601727f9e8b0d459193 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Thu, 26 Mar 2020 21:42:18 -0400 Subject: [PATCH 06/26] CElitePirate/CFlyingPirate: Updates from symbol map --- Runtime/MP1/World/CElitePirate.cpp | 46 +++++++++++++++-------------- Runtime/MP1/World/CElitePirate.hpp | 16 +++++----- Runtime/MP1/World/CFlyingPirate.cpp | 14 +++++---- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 601dbab9d..f994d649e 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -17,19 +17,19 @@ namespace urde::MP1 { namespace { -static constexpr std::array skJointInfoL{{ +static constexpr std::array skLeftArmJointList{{ {"L_shoulder", "L_elbow", 1.f, 1.5f}, {"L_wrist", "L_elbow", 0.9f, 1.3f}, {"L_knee", "L_ankle", 0.9f, 1.3f}, }}; -static constexpr std::array skJointInfoR{{ +static constexpr std::array skRightArmJointList{{ {"R_shoulder", "R_elbow", 1.f, 1.5f}, {"R_wrist", "R_elbow", 0.9f, 1.3f}, {"R_knee", "R_ankle", 0.9f, 1.3f}, }}; -static constexpr std::array skSphereJointInfo{{ +static constexpr std::array skSphereJointList{{ {"Head_1", 1.2f}, {"L_Palm_LCTR", 1.5f}, {"R_Palm_LCTR", 1.5f}, @@ -164,8 +164,8 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } break; } - if ((!x988_25_ || !sub_802293f8(uid, x774_collisionRJointIds)) && - (!x988_26_ || !sub_802293f8(uid, x788_collisionLJointIds))) { + if ((!x988_25_ || !IsArmClawCollider(uid, x774_collisionRJointIds)) && + (!x988_26_ || !IsArmClawCollider(uid, x788_collisionLJointIds))) { break; } mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), @@ -176,7 +176,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } case EScriptObjectMessage::Registered: { x450_bodyController->Activate(mgr); - SetupCollisionManagers(mgr); + SetupCollisionManager(mgr); x772_launcherId = mgr.AllocateUniqueId(); CreateGrenadeLauncher(mgr, x772_launcherId); const auto& bodyStateInfo = x450_bodyController->GetBodyStateInfo(); @@ -390,7 +390,7 @@ bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return C CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); } -void CElitePirate::sub_80229114(CStateManager& mgr) { +void CElitePirate::SetupHealthInfo(CStateManager& mgr) { const CHealthInfo* const health = HealthInfo(mgr); x7b4_hp = health->GetHP(); if (sub_802273a8()) { @@ -401,7 +401,7 @@ void CElitePirate::sub_80229114(CStateManager& mgr) { actor->SetDamageVulnerability(x56c_vulnerability); } } - sub_8022902c(mgr, x772_launcherId); + UpdateHealthInfo(mgr, x772_launcherId); } void CElitePirate::sub_802289b0(CStateManager& mgr, bool b) { sub_80228920(mgr, b, x772_launcherId); } @@ -430,7 +430,7 @@ void CElitePirate::sub_8022759c(bool param_1, CStateManager& mgr) { } } -bool CElitePirate::sub_802293f8(TUniqueId uid, const rstl::reserved_vector& vec) const { +bool CElitePirate::IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const { return std::find(vec.begin(), vec.end(), uid) != vec.end(); } @@ -468,12 +468,12 @@ void CElitePirate::AddSphereCollisionList(const SSphereJointInfo* joints, size_t } } -void CElitePirate::SetupCollisionManagers(CStateManager& mgr) { - constexpr size_t jointInfoCount = skJointInfoL.size() + skJointInfoR.size() + skSphereJointInfo.size(); +void CElitePirate::SetupCollisionManager(CStateManager& mgr) { + constexpr size_t jointInfoCount = skLeftArmJointList.size() + skRightArmJointList.size() + skSphereJointList.size(); std::vector joints(jointInfoCount); - AddCollisionList(skJointInfoL.data(), skJointInfoL.size(), joints); - AddCollisionList(skJointInfoR.data(), skJointInfoL.size(), joints); - AddSphereCollisionList(skSphereJointInfo.data(), skSphereJointInfo.size(), joints); + AddCollisionList(skLeftArmJointList.data(), skLeftArmJointList.size(), joints); + AddCollisionList(skRightArmJointList.data(), skLeftArmJointList.size(), joints); + AddSphereCollisionList(skSphereJointList.data(), skSphereJointList.size(), joints); if (sub_802273a8()) { x730_collisionActorMgr2 = std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, true); @@ -489,8 +489,8 @@ void CElitePirate::SetupCollisionManagers(CStateManager& mgr) { x5d4_collisionActorMgr1 = std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, false); - sub_80229818(mgr); - sub_80229114(mgr); + SetupCollisionActorInfo(mgr); + SetupHealthInfo(mgr); SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( {EMaterialTypes::Solid}, @@ -498,7 +498,7 @@ void CElitePirate::SetupCollisionManagers(CStateManager& mgr) { AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); } -void CElitePirate::sub_80229818(CStateManager& mgr) { +void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) { if (sub_802273a8()) { for (size_t i = 0; i < x730_collisionActorMgr2->GetNumCollisionActors(); ++i) { const auto& colDesc = x730_collisionActorMgr2->GetCollisionDescFromIndex(i); @@ -506,9 +506,11 @@ void CElitePirate::sub_80229818(CStateManager& mgr) { if (TCastToPtr act = mgr.ObjectById(uid)) { if (colDesc.GetName() == "Head_1"sv) { x770_collisionHeadId = uid; - } else if (sub_8022943c(colDesc.GetName(), "R_Palm_LCTR"sv, skJointInfoR.data(), skJointInfoR.size())) { + } else if (IsArmClawCollider(colDesc.GetName(), "R_Palm_LCTR"sv, skRightArmJointList.data(), + skRightArmJointList.size())) { x774_collisionRJointIds.push_back(uid); - } else if (sub_8022943c(colDesc.GetName(), "L_Palm_LCTR"sv, skJointInfoL.data(), skJointInfoL.size())) { + } else if (IsArmClawCollider(colDesc.GetName(), "L_Palm_LCTR"sv, skLeftArmJointList.data(), + skLeftArmJointList.size())) { x788_collisionLJointIds.push_back(uid); } if (uid != x770_collisionHeadId) { @@ -528,8 +530,8 @@ void CElitePirate::sub_80229818(CStateManager& mgr) { x5d4_collisionActorMgr1->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough}); } -bool CElitePirate::sub_8022943c(std::string_view name, std::string_view locator, const SJointInfo* info, - size_t infoCount) { +bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, + size_t infoCount) { if (name == locator) { return true; } @@ -579,7 +581,7 @@ void CElitePirate::sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf) x7ac_ = 0.25f; } -void CElitePirate::sub_8022902c(CStateManager& mgr, TUniqueId uid) { +void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { const CHealthInfo* const health = HealthInfo(mgr); if (uid != kInvalidUniqueId) { if (TCastToPtr actor = mgr.ObjectById(uid)) { diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 04aa80767..63d490828 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -74,8 +74,8 @@ class CElitePirate : public CPatterned { std::optional> x760_; TUniqueId x770_collisionHeadId = kInvalidUniqueId; TUniqueId x772_launcherId = kInvalidUniqueId; - rstl::reserved_vector x774_collisionRJointIds; - rstl::reserved_vector x788_collisionLJointIds; + rstl::reserved_vector x774_collisionRJointIds; + rstl::reserved_vector x788_collisionLJointIds; TUniqueId x79c_ = kInvalidUniqueId; float x7a0_; float x7a4_ = 1.f; @@ -150,7 +150,7 @@ public: CPathFindSearch* GetSearchPath() override; virtual bool sub_802273a8() const { return true; } virtual bool sub_802273b0() const { return true; } - virtual void sub_80229114(CStateManager& mgr); + virtual void SetupHealthInfo(CStateManager& mgr); virtual void sub_802289b0(CStateManager& mgr, bool b); virtual SShockWaveData GetShockWaveData() const { return {x5d8_data.GetXF8(), x5d8_data.GetXFC(), x5d8_data.GetX118(), x5d8_data.GetX11C()}; @@ -159,18 +159,18 @@ public: private: void sub_80229248(); void sub_8022759c(bool param_1, CStateManager& mgr); - bool sub_802293f8(TUniqueId uid, const rstl::reserved_vector& vec) const; + bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const; void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, std::vector& outJoints) const; void AddCollisionList(const SJointInfo* joints, size_t count, std::vector& outJoints) const; - void SetupCollisionManagers(CStateManager& mgr); - void sub_80229818(CStateManager& mgr); - bool sub_8022943c(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount); + void SetupCollisionManager(CStateManager& mgr); + void SetupCollisionActorInfo(CStateManager& mgr); + bool IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount); void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); void sub_80227464(CStateManager& mgr, TUniqueId uid); void sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf); - void sub_8022902c(CStateManager& mgr, TUniqueId uid); + void UpdateHealthInfo(CStateManager& mgr, TUniqueId uid); void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid); zeus::CVector3f sub_80228864(const CActor* actor) const; }; diff --git a/Runtime/MP1/World/CFlyingPirate.cpp b/Runtime/MP1/World/CFlyingPirate.cpp index 685f31c24..563666e5a 100644 --- a/Runtime/MP1/World/CFlyingPirate.cpp +++ b/Runtime/MP1/World/CFlyingPirate.cpp @@ -21,7 +21,7 @@ namespace urde::MP1 { namespace { -constexpr std::array skBurst1{{ +constexpr std::array skBurstsFlying{{ {4, {3, 4, 11, 12, -1, 0, 0, 0}, 0.1f, 0.05f}, {20, {2, 3, 4, 5, -1, 0, 0, 0}, 0.1f, 0.05f}, {20, {10, 11, 12, 13, -1, 0, 0, 0}, 0.1f, 0.05f}, @@ -30,7 +30,7 @@ constexpr std::array skBurst1{{ {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, }}; -constexpr std::array skBurst2{{ +constexpr std::array skBurstsFlyingOutOfView{{ {5, {3, 4, 8, 12, -1, 0, 0, 0}, 0.1f, 0.05f}, {10, {2, 3, 4, 5, -1, 0, 0, 0}, 0.1f, 0.05f}, {10, {10, 11, 12, 13, -1, 0, 0, 0}, 0.1f, 0.05f}, @@ -39,7 +39,7 @@ constexpr std::array skBurst2{{ {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, }}; -constexpr std::array skBurst3{{ +constexpr std::array skBurstsLanded{{ {30, {3, 4, 5, 11, 12, 4, -1, 0}, 0.1f, 0.05f}, {20, {2, 3, 4, 5, 4, 3, -1, 0}, 0.1f, 0.05f}, {20, {5, 4, 3, 13, 12, 11, -1, 0}, 0.1f, 0.05f}, @@ -47,7 +47,7 @@ constexpr std::array skBurst3{{ {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, }}; -constexpr std::array skBurst4{{ +constexpr std::array skBurstsLandedOutOfView{{ {10, {6, 5, 4, 14, 13, 12, -1, 0}, 0.1f, 0.05f}, {20, {14, 13, 12, 11, 10, 9, -1, 0}, 0.1f, 0.05f}, {20, {14, 15, 16, 11, 10, 9, -1, 0}, 0.1f, 0.05f}, @@ -56,7 +56,11 @@ constexpr std::array skBurst4{{ }}; constexpr std::array skBursts{ - skBurst1.data(), skBurst2.data(), skBurst3.data(), skBurst4.data(), nullptr, + skBurstsFlying.data(), + skBurstsFlyingOutOfView.data(), + skBurstsLanded.data(), + skBurstsLandedOutOfView.data(), + nullptr, }; constexpr std::array skParts{ From 4f7e0a85a3382746277194e4fa5345369daedf9f Mon Sep 17 00:00:00 2001 From: Luke Street Date: Fri, 27 Mar 2020 02:47:34 -0400 Subject: [PATCH 07/26] CElitePirate: More function implementations --- Runtime/MP1/World/CElitePirate.cpp | 240 +++++++++++++++++++++++++++-- Runtime/MP1/World/CElitePirate.hpp | 6 +- 2 files changed, 231 insertions(+), 15 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index f994d649e..23dc1be20 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -303,14 +303,31 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node handled = true; break; case EUserEventType::BeginAction: { - zeus::CTransform xf; // TODO + const zeus::CVector3f& origin = GetTranslation(); + const zeus::CVector3f& front = GetTransform().frontVector(); + float dot = (GetLctrTransform(node.GetLocatorName()).origin - origin).dot(front); + const zeus::CTransform& xf = zeus::CTransform::Translate({ + origin.x() + dot * front.x(), + origin.y() + dot * front.y(), + origin.z(), + }); 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)); + handled = true; break; } case EUserEventType::BecomeShootThrough: - // TODO + if (sub_802273a8()) { + u32 numCollisionActors = x730_collisionActorMgr2->GetNumCollisionActors(); + for (u32 i = 0; i < numCollisionActors; i++) { + const auto& description = x730_collisionActorMgr2->GetCollisionDescFromIndex(i); + if (TCastToPtr actor = mgr.ObjectById(description.GetCollisionActorId())) { + actor->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); + } + } + } + handled = true; break; default: break; @@ -324,29 +341,179 @@ const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { + if (!sub_80227430(info)) { + return; + } CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); + if (info.GetWeaponMode().IsComboed() && info.GetWeaponMode().GetType() == EWeaponType::Ice) { + Freeze(mgr, zeus::skZero3f, GetTransform().transposeRotate(pos), 1.5f); + } } void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} -void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } +void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x400_24_hitByPlayerProjectile = false; + x989_24_ = false; + } + CPatterned::Patrol(mgr, msg, dt); +} -void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } +void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x989_24_ = true; + x988_28_alert = false; + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + sub_80228634(mgr); + CPatterned::PathFind(mgr, msg, dt); + x7bc_ = x5d8_data.x4_ * mgr.GetActiveRandom()->Float() + x5d8_data.x0_; + if (TooClose(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); + } + } else if (msg == EStateMsg::Update) { + if (x7bc_ > 0.f) { + x7bc_ -= dt; + } + if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { + CPatterned::PathFind(mgr, msg, dt); + } else { + if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f& move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f& aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const zeus::CVector3f& move = aim - GetTranslation(); + if (move.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f)); + } + } + } + } else if (msg == EStateMsg::Deactivate) { + x6f8_boneTracking.SetActive(false); + } +} void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); } -void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Halt(mgr, msg, dt); } +void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); + x989_24_ = false; + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Add( + {EMaterialTypes::Wall, EMaterialTypes::Ceiling, EMaterialTypes::AIBlock, EMaterialTypes::Character}); + SetMaterialFilter(filter); + } else if (msg == EStateMsg::Deactivate) { + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Remove( + {EMaterialTypes::Wall, EMaterialTypes::Ceiling, EMaterialTypes::AIBlock, EMaterialTypes::Character}); + SetMaterialFilter(filter); + } +} -void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Run(mgr, msg, dt); } +void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x988_31_ = true; + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(1.f, 1.f); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + sub_80228634(mgr); + CPatterned::PathFind(mgr, msg, dt); + } else if (msg == EStateMsg::Update) { + if (PathShagged(mgr, 0.f)) { + auto move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f& aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + move = aim - GetTranslation(); + if (move.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f)); + } + } + } else { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Deactivate) { + x988_31_ = false; + x6f8_boneTracking.SetActive(false); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_, x7a4_); + } +} -void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Generate(mgr, msg, dt); } +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { + switch (msg) { + case EStateMsg::Activate: + x568_ = 1; + break; + case EStateMsg::Update: + switch (x568_) { + case 0: + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { + x568_ = 2; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero)); + } + break; + case 1: + if (ShouldTurn(mgr, 0.f)) { + const auto& playerPos = mgr.GetPlayer().GetTranslation(); + if (playerPos.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(zeus::skZero3f, playerPos.normalized(), 1.f)); + } + } else { + x568_ = 0; + } + break; + case 2: + if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_ = 3; + } + break; + } + break; + case EStateMsg::Deactivate: + sub_8022759c(false, mgr); + sub_802289b0(mgr, true); + break; + } +} void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { - CAi::ProjectileAttack(mgr, msg, dt); + if (msg == EStateMsg::Activate) { + x568_ = 0; + } else if (msg == EStateMsg::Update) { + const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); + if (x568_ == 0) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x568_ = 2; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::One, playerPos, false)); + } + } else if (x568_ == 2) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(playerPos - GetTranslation()); + } else { + x568_ = 3; + } + } + } else if (msg == EStateMsg::Deactivate) { + sub_802285c4(mgr); + } } void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } @@ -355,17 +522,31 @@ void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) { bool CElitePirate::TooClose(CStateManager& mgr, float arg) { return CPatterned::TooClose(mgr, arg); } -bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { return CPatterned::InDetectionRange(mgr, arg); } +bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { + if (x988_28_alert) { + return true; + } else { + return CPatterned::InDetectionRange(mgr, arg); + } +} bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return x568_ == 3; } -bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } +bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) { + if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { + return false; + } + return !ShouldTurn(mgr, 0.f); +} -bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } +bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } -bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) { return CAi::ShouldTurn(mgr, arg); } +bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) { + return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), + GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f); +} bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { if (x772_launcherId == kInvalidUniqueId && !PathShagged(mgr, arg)) { @@ -382,7 +563,7 @@ bool CElitePirate::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::Shou bool CElitePirate::ShouldFire(CStateManager& mgr, float arg) { return CAi::ShouldFire(mgr, arg); } -bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return CAi::ShotAt(mgr, arg); } +bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return x988_27_; } bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } @@ -470,7 +651,8 @@ void CElitePirate::AddSphereCollisionList(const SSphereJointInfo* joints, size_t void CElitePirate::SetupCollisionManager(CStateManager& mgr) { constexpr size_t jointInfoCount = skLeftArmJointList.size() + skRightArmJointList.size() + skSphereJointList.size(); - std::vector joints(jointInfoCount); + std::vector joints; + joints.reserve(jointInfoCount); AddCollisionList(skLeftArmJointList.data(), skLeftArmJointList.size(), joints); AddCollisionList(skRightArmJointList.data(), skLeftArmJointList.size(), joints); AddSphereCollisionList(skSphereJointList.data(), skSphereJointList.size(), joints); @@ -606,4 +788,34 @@ 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); } + +bool CElitePirate::sub_80227430(const CDamageInfo& info) const { + return !x400_25_alive || info.GetWeaponMode().IsComboed() || info.GetWeaponMode().GetType() != EWeaponType::Plasma; +} + +void CElitePirate::sub_80228634(CStateManager& mgr) { + x8b4_ = GetTranslation(); + const zeus::CVector3f& dist = GetTranslation() - mgr.GetPlayer().GetTranslation(); + if (dist.canBeNormalized() && dist.magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { + x2e0_destPos = GetTranslation() + (x2fc_minAttackRange * dist.normalized()); + x8b4_ = x2e0_destPos; + } +} + +void CElitePirate::sub_802285c4(CStateManager& mgr) { + if (mgr.GetActiveRandom()->Float() > x5d8_data.x10_) { + x7b8_ = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; + } +} + +zeus::CVector3f CElitePirate::SUnknownStruct::sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { + while (x4_.size()) { + const zeus::CVector3f v = x4_[x4_.size() - 1] - v1; + if (v.dot(v2) > 0.f && v.isMagnitudeSafe()) { + return v.normalized(); + } + x4_.pop_back(); + } + return zeus::skZero3f; +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 63d490828..4e5b04891 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -59,8 +59,9 @@ public: class CElitePirate : public CPatterned { struct SUnknownStruct { float x0_; - s32 x4_ = 0; + rstl::reserved_vector x4_; SUnknownStruct(float f) : x0_(f * f) {} + zeus::CVector3f sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2); }; s32 x568_ = -1; @@ -173,6 +174,9 @@ private: void UpdateHealthInfo(CStateManager& mgr, TUniqueId uid); void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid); zeus::CVector3f sub_80228864(const CActor* actor) const; + bool sub_80227430(const CDamageInfo& info) const; + void sub_80228634(CStateManager& mgr); + void sub_802285c4(CStateManager& mgr); }; } // namespace MP1 } // namespace urde From 4ada5a00cba2ed8d7ce653bb90f8ac6c5e45b82e Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 29 Mar 2020 03:28:14 -0400 Subject: [PATCH 08/26] CElitePirate: Nearly complete implementation --- Runtime/Character/CharacterCommon.hpp | 4 +- Runtime/MP1/World/CElitePirate.cpp | 490 ++++++++++++++++++++----- Runtime/MP1/World/CElitePirate.hpp | 105 +++--- Runtime/MP1/World/CGrenadeLauncher.cpp | 55 ++- Runtime/MP1/World/CGrenadeLauncher.hpp | 68 ++-- 5 files changed, 556 insertions(+), 166 deletions(-) diff --git a/Runtime/Character/CharacterCommon.hpp b/Runtime/Character/CharacterCommon.hpp index 7b0e628c7..51a3d710e 100644 --- a/Runtime/Character/CharacterCommon.hpp +++ b/Runtime/Character/CharacterCommon.hpp @@ -68,7 +68,7 @@ enum class EFallState { Invalid = -1, Zero, One , Two}; enum class EReactionType { Invalid = -1, Zero, One, Two, Three }; -enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout }; +enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout, Four, Five, Six, Seven }; enum class EJumpType { Normal, One, Ambush }; @@ -96,7 +96,7 @@ enum class ELoopState { Invalid = -1, Begin, Loop, End }; enum class ELoopAttackType { Invalid = -1 }; -enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four }; +enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four, Five }; enum class ESlideType { Invalid = -1, Zero = 0 }; diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 23dc1be20..98b5fe985 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -41,8 +41,8 @@ static constexpr std::array skSphereJointList{{ } // namespace CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) -: x0_(in.readFloatBig()) -, x4_(in.readFloatBig()) +: x0_tauntInterval(in.readFloatBig()) +, x4_tauntVariance(in.readFloatBig()) , x8_(in.readFloatBig()) , xc_(in.readFloatBig()) , x10_(in.readFloatBig()) @@ -57,13 +57,13 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , xa0_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xa4_(in) , xa8_(in) -, xc4_(in.readFloatBig()) +, xc4_launcherHp(in.readFloatBig()) , xc8_(in) , xcc_(in) , xd0_(in) , xd4_(in) , xd8_(in) -, xe0_(in.readFloatBig(), in.readFloatBig(), zeus::degToRad(in.readFloatBig()), zeus::degToRad(in.readFloatBig())) +, xe0_trajectoryInfo(in) , xf0_(in) , xf4_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf6_(CSfxManager::TranslateSFXID(in.readUint32Big())) @@ -72,15 +72,15 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , x118_(in) , x11c_(CSfxManager::TranslateSFXID(in.readUint32Big())) , x11e_(in.readBool()) -, x11f_(propCount < 24 ? true : in.readBool()) {} +, x11f_(propCount < 42 ? true : in.readBool()) {} CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - const CElitePirateData& eliteData) + const CElitePirateData& data) : CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) , x56c_vulnerability(pInfo.GetDamageVulnerability()) -, x5d8_data(eliteData) +, x5d8_data(data) , x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) , x738_(GetBoundingBox(), GetMaterialList()) @@ -96,7 +96,7 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn , x988_31_(false) , x989_24_(false) { if (x5d8_data.GetX20().IsValid()) { - x760_ = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()}); + x760_energyAbsorbDesc = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()}); } x460_knockBackController.SetEnableFreeze(false); @@ -109,7 +109,26 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } -void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } +void CElitePirate::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + CPatterned::Think(dt, mgr); + x6f8_boneTracking.Update(dt); + if (sub_802273a8()) { + x730_collisionActorMgr2->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + } + x5d4_collisionActorMgr1->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + if (sub_80229208() && x5d8_data.x11f_) { + x3b4_speed = 2.f * x7a0_; + } else { + x3b4_speed = x7a0_; + } + sub_80228e50(dt); + sub_80228798(); + sub_802289dc(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv); + sub_80228e84(mgr); + x328_31_ = sub_80229208(); + } +} void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { bool shouldPass = true; @@ -149,7 +168,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } const TUniqueId& touchedUid = actor->GetLastTouchedObject(); if (touchedUid != GetUniqueId()) { - if (TCastToPtr projectile = mgr.ObjectById(touchedUid)) { + if (TCastToPtr(mgr.ObjectById(touchedUid))) { sub_8022759c(true, mgr); } break; @@ -207,8 +226,8 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta KnockBack(projectile->GetTranslation() - projectile->GetPreviousPos(), mgr, damageInfo, EKnockBackType::Radius, false, damageInfo.GetKnockBackPower()); CPatterned::AcceptScriptMsg(msg, uid, mgr); - } else if (uid == x79c_ && x760_->IsLoaded()) { - sub_802281d8(mgr, projectile->GetTransform()); + } else if (uid == x79c_ && x760_energyAbsorbDesc->IsLoaded()) { + CreateEnergyAbsorb(mgr, projectile->GetTransform()); } sub_8022759c(true, mgr); } @@ -216,14 +235,13 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta x450_bodyController->GetCommandMgr().DeliverCmd( CBCKnockBackCmd(GetTransform().frontVector(), pas::ESeverity::Eight)); } else { - sub_80227464(mgr, uid); + ApplyDamageToHead(mgr, uid); } break; case EScriptObjectMessage::InvulnDamage: { sub_8022759c(true, mgr); - TCastToPtr actor = mgr.ObjectById(uid); - if (!actor) { - sub_80227464(mgr, uid); + if (!TCastToPtr(mgr.ObjectById(uid))) { + ApplyDamageToHead(mgr, uid); } break; } @@ -269,7 +287,7 @@ zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { return GetLctrTransform("lockon_target_LCTR").origin; } -zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) const { +zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const { std::shared_ptr playerState = mgr.GetPlayerState(); if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { @@ -370,28 +388,28 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { x6f8_boneTracking.SetActive(true); sub_80228634(mgr); CPatterned::PathFind(mgr, msg, dt); - x7bc_ = x5d8_data.x4_ * mgr.GetActiveRandom()->Float() + x5d8_data.x0_; + x7bc_tauntTimer = x5d8_data.x4_tauntVariance * mgr.GetActiveRandom()->Float() + x5d8_data.x0_tauntInterval; if (TooClose(mgr, 0.f)) { x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); } } else if (msg == EStateMsg::Update) { - if (x7bc_ > 0.f) { - x7bc_ -= dt; + if (x7bc_tauntTimer > 0.f) { + x7bc_tauntTimer -= dt; } if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { CPatterned::PathFind(mgr, msg, dt); } else { if (PathShagged(mgr, 0.f)) { - const zeus::CVector3f& move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector()); + const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); if (move != zeus::skZero3f) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); } } else if (ShouldTurn(mgr, 0.f)) { const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); - const zeus::CVector3f& move = aim - GetTranslation(); - if (move.canBeNormalized()) { - x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f)); + const zeus::CVector3f& face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } } @@ -400,9 +418,32 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); } +void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + if (HasPatrolPath(mgr, 0.f)) { + CPatterned::Patrol(mgr, msg, dt); + UpdateDest(mgr); + } else { + SetDestPos(x3a0_latestLeashPosition); + } + x8b4_ = x2e0_destPos; + if (GetSearchPath() != nullptr) { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Update) { + if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f& move = x45c_steeringBehaviors.Arrival(*this, x8b4_, 25.f); + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } else { + CPatterned::PathFind(mgr, msg, dt); + } + } else if (msg == EStateMsg::Deactivate) { + x988_28_alert = false; + } +} -void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) { +void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); x989_24_ = false; @@ -429,15 +470,15 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } else if (msg == EStateMsg::Update) { if (PathShagged(mgr, 0.f)) { - auto move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector()); + auto move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); if (move != zeus::skZero3f) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); } else if (ShouldTurn(mgr, 0.f)) { const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); - move = aim - GetTranslation(); - if (move.canBeNormalized()) { - x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f)); + auto face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } } else { @@ -450,65 +491,104 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) { - switch (msg) { - case EStateMsg::Activate: - x568_ = 1; - break; - case EStateMsg::Update: - switch (x568_) { - case 0: +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_ = EState::One; + } else if (msg == EStateMsg::Update) { + if (x568_ == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { - x568_ = 2; + x568_ = EState::Two; } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero)); } - break; - case 1: + } else if (x568_ == EState::One) { if (ShouldTurn(mgr, 0.f)) { - const auto& playerPos = mgr.GetPlayer().GetTranslation(); - if (playerPos.canBeNormalized()) { - x450_bodyController->GetCommandMgr().DeliverCmd( - CBCLocomotionCmd(zeus::skZero3f, playerPos.normalized(), 1.f)); + const auto& face = mgr.GetPlayer().GetTranslation() - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } else { - x568_ = 0; + x568_ = EState::Zero; } - break; - case 2: - if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { - x568_ = 3; - } - break; + } else if (x568_ == EState::Two && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_ = EState::Over; } - break; - case EStateMsg::Deactivate: + } else if (msg == EStateMsg::Deactivate) { sub_8022759c(false, mgr); sub_802289b0(mgr, true); - break; } } -void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } +void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_ = EState::Zero; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); + if (x64_modelData->GetNumMaterialSets() > 1) { + x7cc_ = 1; + } + } else if (msg == EStateMsg::Update) { + if (x568_ == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + x568_ = EState::One; + x988_25_ = true; + x7c8_currAnimId = x450_bodyController->GetCurrentAnimId(); + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::One)); + } + } else if (x568_ == EState::One) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + if (x7c8_currAnimId == x450_bodyController->GetCurrentAnimId()) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + if (ShouldAttack(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::Two)); + } + } else { + x568_ = EState::Two; + x988_25_ = false; + x988_26_ = true; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); + ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::CVector3f(2.f)); + } + } else { + x568_ = EState::Over; + } + } else if (x568_ == EState::Two) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); + } else { + x568_ = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + sub_802285c4(mgr); + x988_24_ = false; + x988_26_ = false; + x988_25_ = false; + x7c8_currAnimId = -1; + ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); + ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::skZero3f); + x7cc_ = 0; + } +} void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } -void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { +void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = 0; + x568_ = EState::Zero; } else if (msg == EStateMsg::Update) { const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); - if (x568_ == 0) { + if (x568_ == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { - x568_ = 2; + x568_ = EState::Two; } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::One, playerPos, false)); } - } else if (x568_ == 2) { + } else if (x568_ == EState::Two) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { x450_bodyController->GetCommandMgr().DeliverTargetVector(playerPos - GetTranslation()); } else { - x568_ = 3; + x568_ = EState::Over; } } } else if (msg == EStateMsg::Deactivate) { @@ -518,32 +598,105 @@ void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } -void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) { CAi::CallForBackup(mgr, msg, dt); } - -bool CElitePirate::TooClose(CStateManager& mgr, float arg) { return CPatterned::TooClose(mgr, arg); } - -bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { - if (x988_28_alert) { - return true; - } else { - return CPatterned::InDetectionRange(mgr, arg); +void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_ = EState::Zero; + x988_30_ = true; + sub_8022759c(false, mgr); + } else if (msg == EStateMsg::Update) { + if (x568_ == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { + x568_ = EState::Two; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Five, zeus::skZero3f)); + } + } else if (x568_ == EState::Two) { + if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_ = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); } } -bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } +void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); + if (sub_802273a8()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + actor->SetDamageVulnerability(CDamageVulnerability::ImmuneVulnerabilty()); + } + } + x5d4_collisionActorMgr1->SetActive(mgr, true); + x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + x6f8_boneTracking.SetActive(true); + sub_80228634(mgr); + CPatterned::PathFind(mgr, msg, dt); + if (TooClose(mgr, 0.f)) { + x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); + } + } else if (msg == EStateMsg::Update) { + if (x988_27_) { + x7c0_ -= dt; + if (x7c0_ <= 0.f) { + x988_27_ = false; + } + } + x7a8_ = PathShagged(mgr, 0.f) ? x7a8_ + dt : 0.f; + if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { + CPatterned::PathFind(mgr, msg, dt); + } else if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f& aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const zeus::CVector3f& face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); + } + } + sub_80227a90(mgr); + sub_802277e0(mgr, dt); + } else if (msg == EStateMsg::Deactivate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x6f8_boneTracking.SetActive(false); + if (sub_802273a8()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + actor->SetDamageVulnerability(x56c_vulnerability); + } + } + x5d4_collisionActorMgr1->SetActive(mgr, false); + } +} -bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return x568_ == 3; } +bool CElitePirate::TooClose(CStateManager& mgr, float) { + return x2fc_minAttackRange * x2fc_minAttackRange > (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared(); +} -bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) { +bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) { + return x988_28_alert ? true : CPatterned::InDetectionRange(mgr, arg); +} + +bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { + return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg); +} + +bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_ == EState::Over; } + +bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { return false; } return !ShouldTurn(mgr, 0.f); } -bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } +bool CElitePirate::InPosition(CStateManager& mgr, float) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } -bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) { +bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f); } @@ -559,17 +712,29 @@ bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { return false; } -bool CElitePirate::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); } +bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTimer <= 0.f; } -bool CElitePirate::ShouldFire(CStateManager& mgr, float arg) { return CAi::ShouldFire(mgr, arg); } +bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); } -bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return x988_27_; } +bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_; } -bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); } +bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { + if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) { + const zeus::CVector3f& dist = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); + float magSquared = dist.magSquared(); + if (x2fc_minAttackRange * x2fc_minAttackRange <= magSquared && + magSquared <= x300_maxAttackRange * x300_maxAttackRange) { + return std::abs(dist.z()) < 3.f; + } + } + return false; +} -bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return CAi::ShouldCallForBackup(mgr, arg); } +bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) { + return ShouldCallForBackupFromLauncher(mgr, x772_launcherId); +} -CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); } +CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; } void CElitePirate::SetupHealthInfo(CStateManager& mgr) { const CHealthInfo* const health = HealthInfo(mgr); @@ -732,16 +897,17 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { } CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), params.GetInitialAnimation(), true)); - SGrenadeLauncherData transfer{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_, - x5d8_data.xd4_, x5d8_data.xf0_, x5d8_data.xf4_, x5d8_data.xf6_}; - CGrenadeLauncherData launcherData{transfer, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, x5d8_data.xe0_}; + SBouncyGrenadeData grenadeData{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_, + x5d8_data.xd4_, x5d8_data.xf0_, x5d8_data.xf4_, x5d8_data.xf6_}; + CGrenadeLauncherData launcherData{grenadeData, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, + x5d8_data.xe0_trajectoryInfo}; mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), std::move(mData), mData.GetBounds(GetTransform().getRotation()), - CHealthInfo(x5d8_data.xc4_, 10.f), x56c_vulnerability, + CHealthInfo(x5d8_data.xc4_launcherHp, 10.f), x56c_vulnerability, x5d8_data.x28_launcherActParams, GetUniqueId(), launcherData, 0.f)); } -void CElitePirate::sub_80227464(CStateManager& mgr, TUniqueId uid) { +void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) { if (!sub_802273a8()) { return; } @@ -753,14 +919,15 @@ void CElitePirate::sub_80227464(CStateManager& mgr, TUniqueId uid) { } } -void CElitePirate::sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf) { - if (x7ac_ > 0.f) { +void CElitePirate::CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf) { + if (x7ac_energyAbsorbCooldown > 0.f) { return; } - mgr.AddObject(new CExplosion(*x760_, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList}, - "Absorb energy Fx", xf, 0, GetModelData()->GetScale(), zeus::skWhite)); + mgr.AddObject(new CExplosion(*x760_energyAbsorbDesc, mgr.AllocateUniqueId(), true, + {GetAreaIdAlways(), CEntity::NullConnectionList}, "Absorb energy Fx", xf, 0, + GetModelData()->GetScale(), zeus::skWhite)); CSfxManager::AddEmitter(x5d8_data.x24_sfxAbsorb, GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); - x7ac_ = 0.25f; + x7ac_energyAbsorbCooldown = 0.25f; } void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { @@ -768,7 +935,7 @@ void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { if (uid != kInvalidUniqueId) { if (TCastToPtr actor = mgr.ObjectById(uid)) { auto actHealth = actor->HealthInfo(mgr); - actHealth->SetHP(x5d8_data.xc4_); + actHealth->SetHP(x5d8_data.xc4_launcherHp); actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); actor->SetDamageVulnerability(x56c_vulnerability); } @@ -804,11 +971,131 @@ void CElitePirate::sub_80228634(CStateManager& mgr) { void CElitePirate::sub_802285c4(CStateManager& mgr) { if (mgr.GetActiveRandom()->Float() > x5d8_data.x10_) { - x7b8_ = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; + x7b8_attackTimer = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; } } -zeus::CVector3f CElitePirate::SUnknownStruct::sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { +void CElitePirate::sub_80227a90(CStateManager& mgr) { + // TODO +} + +void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { + if (!x988_27_ || x450_bodyController->IsFrozen()) { + return; + } + x7c4_ += dt; + if (x7c4_ < 3.f) { + return; + } + if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Turn && + x450_bodyController->GetBodyStateInfo().GetCurrentState()->IsMoving()) { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCAdditiveReactionCmd(pas::EAdditiveReactionType::Six, 1.f, false)); + } else { + bool b = false; + if (sub_802273a8()) { + if (TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { + float z = actor->GetTranslation().z(); + b = z - 0.5f * (z - GetTranslation().z()) <= mgr.GetPlayer().GetTranslation().z(); + } + } + b = b || TooClose(mgr, 0.f); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCAdditiveReactionCmd(b ? pas::EAdditiveReactionType::Seven : pas::EAdditiveReactionType::Five, 1.f, false)); + } + x7c4_ = 0.f; +} + +bool CElitePirate::sub_80229208() { + if (x450_bodyController->GetLocomotionType() != pas::ELocomotionType::Crouch) { + return false; + } + const pas::EAnimationState state = x450_bodyController->GetCurrentStateId(); + return state == pas::EAnimationState::Locomotion || state == pas::EAnimationState::Turn; +} + +void CElitePirate::sub_80228e50(float dt) { + if (x7b8_attackTimer > 0.f) { + x7b8_attackTimer -= dt; + } + if (x7ac_energyAbsorbCooldown > 0.f) { + x7ac_energyAbsorbCooldown -= dt; + } +} + +void CElitePirate::sub_80228798() { + const zeus::CVector3f& pos = GetTranslation(); + if (x7d0_pathFindSearch.OnPath(pos) == CPathFindSearch::EResult::Success) { + x8c0_.Clear(); + } + x8c0_.AddValue(pos); +} + +void CElitePirate::sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name) { + if (uid == kInvalidUniqueId) { + return; + } + CActor* actor = static_cast(mgr.ObjectById(uid)); + if (actor == nullptr) { + uid = kInvalidUniqueId; + return; + } + actor->SetTransform(GetLctrTransform(name)); +} + +void CElitePirate::sub_80228e84(CStateManager& mgr) { + float hp = HealthInfo(mgr)->GetHP(); + if (sub_802273a8()) { + if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { + float headHp = actor->HealthInfo(mgr)->GetHP(); + HealthInfo(mgr)->SetHP(hp - (hp - headHp)); + *actor->HealthInfo(mgr) = *HealthInfo(mgr); // TODO does this work? + } + } + if (HealthInfo(mgr)->GetHP() <= 0.f) { + Death(mgr, zeus::skZero3f, EScriptObjectState::DeathRattle); + RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr); + } +} + +void CElitePirate::ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec) { + for (const TUniqueId uid : uids) { + if (TCastToPtr actor = mgr.ObjectById(uid)) { + actor->SetExtendedTouchBounds(vec); + } + } +} + +bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId) { + if (x7b8_attackTimer <= 0.f && launcherId != kInvalidUniqueId) { + const CActor* launcher = static_cast(mgr.GetObjectById(launcherId)); + if (launcher != nullptr) { + const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + if (x300_maxAttackRange * x300_maxAttackRange <= (aim - GetTranslation()).magSquared() && !ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f& origin = sub_80228864(launcher); + if (!IsPatternObstructed(mgr, origin, aim)) { + const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr); + float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin, velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; + CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut, + velocityOut); + const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); + return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); + } + } + } + } + return false; +} + +bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { + if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.x11e_) { + return x7a8_ >= 3.f; + } + return false; +} + +zeus::CVector3f CElitePirate::SUnknownStruct::GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { while (x4_.size()) { const zeus::CVector3f v = x4_[x4_.size() - 1] - v1; if (v.dot(v2) > 0.f && v.isMagnitudeSafe()) { @@ -818,4 +1105,17 @@ zeus::CVector3f CElitePirate::SUnknownStruct::sub_802a07f0(const zeus::CVector3f } return zeus::skZero3f; } + +void CElitePirate::SUnknownStruct::AddValue(const zeus::CVector3f& vec) { + if (x4_.size() > 15) { + return; + } + if (x4_.empty()) { + x4_.emplace_back(vec); + return; + } + if (x4_[x4_.size() - 1].magSquared() > x0_) { + x4_.emplace_back(vec); + } +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 4e5b04891..e690b6e2d 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -2,6 +2,7 @@ #include "Runtime/Character/CBoneTracking.hpp" #include "Runtime/Collision/CJointCollisionDescription.hpp" +#include "Runtime/MP1/World/CGrenadeLauncher.hpp" #include "Runtime/MP1/World/CShockWave.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" @@ -14,8 +15,8 @@ class CGenDescription; namespace MP1 { class CElitePirateData { public: - float x0_; - float x4_; + float x0_tauntInterval; + float x4_tauntVariance; float x8_; float xc_; float x10_; @@ -23,20 +24,20 @@ public: float x18_; float x1c_; CAssetId x20_; - s16 x24_sfxAbsorb; + u16 x24_sfxAbsorb; CActorParameters x28_launcherActParams; CAnimationParameters x90_launcherAnimParams; CAssetId x9c_; u16 xa0_; CAssetId xa4_; CDamageInfo xa8_; - float xc4_; + float xc4_launcherHp; CAssetId xc8_; CAssetId xcc_; CAssetId xd0_; CAssetId xd4_; - CHealthInfo xd8_; // FIXME probably wrong type - zeus::CQuaternion xe0_; // FIXME probably wrong type + SGrenadeUnknownStruct xd8_; + SGrenadeTrajectoryInfo xe0_trajectoryInfo; CAssetId xf0_; u16 xf4_; u16 xf6_; @@ -61,10 +62,20 @@ class CElitePirate : public CPatterned { float x0_; rstl::reserved_vector x4_; SUnknownStruct(float f) : x0_(f * f) {} - zeus::CVector3f sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2); + zeus::CVector3f GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2); + void AddValue(const zeus::CVector3f& vec); + void Clear() { x4_.clear(); } }; - s32 x568_ = -1; + enum class EState { + Invalid = -1, + Zero = 0, + One = 1, + Two = 2, + Over = 3, + }; + + EState x568_ = EState::Invalid; CDamageVulnerability x56c_vulnerability; std::unique_ptr x5d4_collisionActorMgr1; CElitePirateData x5d8_data; @@ -72,7 +83,7 @@ class CElitePirate : public CPatterned { std::unique_ptr x730_collisionActorMgr2; s32 x734_; CCollidableAABox x738_; - std::optional> x760_; + std::optional> x760_energyAbsorbDesc; TUniqueId x770_collisionHeadId = kInvalidUniqueId; TUniqueId x772_launcherId = kInvalidUniqueId; rstl::reserved_vector x774_collisionRJointIds; @@ -81,14 +92,14 @@ class CElitePirate : public CPatterned { float x7a0_; float x7a4_ = 1.f; float x7a8_ = 0.f; - float x7ac_ = 0.f; + float x7ac_energyAbsorbCooldown = 0.f; float x7b0_ = 1.f; float x7b4_hp = 0.f; - float x7b8_ = 0.f; - float x7bc_ = 0.f; + float x7b8_attackTimer = 0.f; + float x7bc_tauntTimer = 0.f; float x7c0_ = 0.f; float x7c4_ = 0.f; - s32 x7c8_ = -1; + s32 x7c8_currAnimId = -1; s32 x7cc_ = 0; CPathFindSearch x7d0_pathFindSearch; zeus::CVector3f x8b4_; @@ -121,33 +132,34 @@ public: zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; const CCollisionPrimitive* GetCollisionPrimitive() const override; - void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, - float magnitude) override; + void KnockBack(const zeus::CVector3f&, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; void TakeDamage(const zeus::CVector3f&, float arg) override; - void Patrol(CStateManager&, EStateMsg msg, float dt) override; - void PathFind(CStateManager&, EStateMsg msg, float dt) override; - void TargetPatrol(CStateManager&, EStateMsg msg, float dt) override; - void Halt(CStateManager&, EStateMsg msg, float dt) override; - void Run(CStateManager&, EStateMsg msg, float dt) override; - void Generate(CStateManager&, EStateMsg msg, float dt) override; - void Attack(CStateManager&, EStateMsg msg, float dt) override; - void Taunt(CStateManager&, EStateMsg msg, float dt) override; - void ProjectileAttack(CStateManager&, EStateMsg msg, float dt) override; - void SpecialAttack(CStateManager&, EStateMsg msg, float dt) override; - void CallForBackup(CStateManager&, EStateMsg msg, float dt) override; - bool TooClose(CStateManager&, float arg) override; - bool InDetectionRange(CStateManager&, float arg) override; - bool SpotPlayer(CStateManager&, float arg) override; - bool AnimOver(CStateManager&, float arg) override; - bool ShouldAttack(CStateManager&, float arg) override; - bool InPosition(CStateManager&, float arg) override; - bool ShouldTurn(CStateManager&, float arg) override; - bool AggressionCheck(CStateManager&, float arg) override; - bool ShouldTaunt(CStateManager&, float arg) override; - bool ShouldFire(CStateManager&, float arg) override; - bool ShotAt(CStateManager&, float arg) override; - bool ShouldSpecialAttack(CStateManager&, float arg) override; - bool ShouldCallForBackup(CStateManager&, float arg) override; + void Patrol(CStateManager& mgr, EStateMsg msg, float dt) override; + void PathFind(CStateManager& mgr, EStateMsg msg, float dt) override; + void TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) override; + void Halt(CStateManager& mgr, EStateMsg msg, float dt) override; + void Run(CStateManager& mgr, EStateMsg msg, float dt) override; + void Generate(CStateManager& mgr, EStateMsg msg, float dt) override; + void Attack(CStateManager& mgr, EStateMsg msg, float dt) override; + void Taunt(CStateManager& mgr, EStateMsg msg, float dt) override; + void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) override; + void SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) override; + void CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) override; + void Cover(CStateManager& mgr, EStateMsg msg, float dt) override; + bool TooClose(CStateManager& mgr, float arg) override; + bool InDetectionRange(CStateManager& mgr, float arg) override; + bool SpotPlayer(CStateManager& mgr, float arg) override; + bool AnimOver(CStateManager& mgr, float arg) override; + bool ShouldAttack(CStateManager& mgr, float arg) override; + bool InPosition(CStateManager& mgr, float arg) override; + bool ShouldTurn(CStateManager& mgr, float arg) override; + bool AggressionCheck(CStateManager& mgr, float arg) override; + bool ShouldTaunt(CStateManager& mgr, float arg) override; + bool ShouldFire(CStateManager& mgr, float arg) override; + bool ShotAt(CStateManager& mgr, float arg) override; + bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; + bool ShouldCallForBackup(CStateManager& mgr, float arg) override; CPathFindSearch* GetSearchPath() override; virtual bool sub_802273a8() const { return true; } virtual bool sub_802273b0() const { return true; } @@ -169,14 +181,25 @@ private: void SetupCollisionActorInfo(CStateManager& mgr); bool IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount); void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); - void sub_80227464(CStateManager& mgr, TUniqueId uid); - void sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf); + void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid); + void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf); void UpdateHealthInfo(CStateManager& mgr, TUniqueId uid); void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid); zeus::CVector3f sub_80228864(const CActor* actor) const; bool sub_80227430(const CDamageInfo& info) const; void sub_80228634(CStateManager& mgr); void sub_802285c4(CStateManager& mgr); + void sub_80227a90(CStateManager& mgr); + void sub_802277e0(CStateManager& mgr, float dt); + bool sub_80229208(); + void sub_80228e50(float dt); + void sub_80228798(); + void sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name); + void sub_80228e84(CStateManager& mgr); + void ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec); + bool ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId); + bool ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid); }; } // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 6f46604e0..ab35701b8 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -1,9 +1,11 @@ #include "Runtime/MP1/World/CGrenadeLauncher.hpp" -#include "Runtime/CSimplePool.hpp" -#include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Character/CPASAnimParm.hpp" #include "Runtime/Character/CPASAnimParmData.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/World/CPlayer.hpp" namespace urde { namespace MP1 { @@ -30,5 +32,54 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C x3c8_animIds[i] = result.second; } } + +zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) { + const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 1.f); + if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) { + return aim - zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()}; + } + return aim; +} + +void CGrenadeLauncher::CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, + const SGrenadeTrajectoryInfo& info, float& angleOut, + float& velocityOut) { + float angle = info.x8_angleMin; + float velocity = info.x0_; + float delta = std::max(0.01f, 0.1f * (info.xc_angleMax - info.x8_angleMin)); + zeus::CVector3f dist = target - origin; + float distXYMag = dist.toVec2f().magnitude(); + float qwSq = info.x0_ * info.x0_; + float qxSq = info.x4_ * info.x4_; + float gravAdj = distXYMag * ((0.5f * CPhysicsActor::GravityConstant()) * distXYMag); + float currAngle = info.x8_angleMin; + float leastResult = FLT_MAX; + while (info.xc_angleMax >= currAngle) { + float cos = std::cos(currAngle); + float sin = std::sin(currAngle); + float result = (distXYMag * (cos * sin) - (dist.z() * (cos * cos))); + if (result > FLT_EPSILON) { + float div = gravAdj / result; + if (qwSq <= result && result <= qxSq) { + angle = currAngle; + velocity = std::sqrt(div); + break; + } + if (result <= qxSq) { + result = qwSq - result; + } else { + result = result - qxSq; + } + if (result < leastResult) { + angle = currAngle; + velocity = std::sqrt(div); + leastResult = result; + } + } + currAngle += delta; + } + angleOut = angle; + velocityOut = velocity; +} } // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index e7ee730cf..c3fb317f2 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -22,8 +22,28 @@ namespace urde { namespace MP1 { -struct SGrenadeLauncherData { - CHealthInfo x0_healthInfo; +struct SGrenadeTrajectoryInfo { + float x0_; + float x4_; + float x8_angleMin; + float xc_angleMax; + + SGrenadeTrajectoryInfo(CInputStream& in) + : x0_(in.readFloatBig()) + , x4_(in.readFloatBig()) + , x8_angleMin(zeus::degToRad(in.readFloatBig())) + , xc_angleMax(zeus::degToRad(in.readFloatBig())) {} +}; + +struct SGrenadeUnknownStruct { + float x0_mass; + float x4_; + + SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_(in.readFloatBig()) {} +}; + +struct SBouncyGrenadeData { + SGrenadeUnknownStruct x0_; CDamageInfo x8_damageInfo; CAssetId x24_; CAssetId x28_; @@ -33,30 +53,22 @@ struct SGrenadeLauncherData { u16 x38_; u16 x3a_; - SGrenadeLauncherData(const CHealthInfo& healthInfo, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, - CAssetId w3, CAssetId w4, CAssetId w5, u16 s1, u16 s2) - : x0_healthInfo(healthInfo) - , x8_damageInfo(damageInfo) - , x24_(w1) - , x28_(w2) - , x2c_(w3) - , x30_(w4) - , x34_(w5) - , x38_(s1) - , x3a_(s2){}; + SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, + CAssetId w3, CAssetId w4, CAssetId w5, u16 s1, u16 s2) + : x0_(unkStruct), x8_damageInfo(damageInfo), x24_(w1), x28_(w2), x2c_(w3), x30_(w4), x34_(w5), x38_(s1), x3a_(s2){}; }; class CGrenadeLauncherData { public: - SGrenadeLauncherData x0_; + SBouncyGrenadeData x0_; CAssetId x3c_; CAssetId x40_; u16 x44_sfx; - zeus::CQuaternion x48_quat; + SGrenadeTrajectoryInfo x48_trajectoryInfo; - CGrenadeLauncherData(const SGrenadeLauncherData& data, CAssetId w1, CAssetId w2, u16 sfx, - const zeus::CQuaternion& quat) - : x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_quat(quat){}; + CGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, + const SGrenadeTrajectoryInfo& trajectoryInfo) + : x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_trajectoryInfo(trajectoryInfo){}; }; class CGrenadeLauncher : public CPhysicsActor { @@ -92,16 +104,20 @@ public: const CGrenadeLauncherData& data, float f1); void Accept(IVisitor& visitor) override { visitor.Visit(this); } - void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + // void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + // void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } - std::optional GetTouchBounds() const override; - CHealthInfo* HealthInfo(CStateManager& mgr) override; - void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void Render(const CStateManager& mgr) const override; - void Think(float dt, CStateManager& mgr) override; - void Touch(CActor& act, CStateManager& mgr) override; + // std::optional GetTouchBounds() const override; + // CHealthInfo* HealthInfo(CStateManager& mgr) override; + // void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + // void Render(const CStateManager& mgr) const override; + // void Think(float dt, CStateManager& mgr) override; + // void Touch(CActor& act, CStateManager& mgr) override; + + static zeus::CVector3f GrenadeTarget(const CStateManager& mgr); + static void CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, + const SGrenadeTrajectoryInfo& info, float& angleOut, float& velocityOut); protected: void UpdateCollision(); From fbbd73db48ef7b0ed6e83953c5dce6464121f743 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 29 Mar 2020 23:45:55 -0400 Subject: [PATCH 09/26] CGrenadeLauncher implementation --- Runtime/MP1/World/CElitePirate.cpp | 44 ++--- Runtime/MP1/World/CElitePirate.hpp | 2 +- Runtime/MP1/World/CGrenadeLauncher.cpp | 225 ++++++++++++++++++++++++- Runtime/MP1/World/CGrenadeLauncher.hpp | 44 ++--- 4 files changed, 261 insertions(+), 54 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 98b5fe985..0fc0e7b6f 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -173,7 +173,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } break; } - if (!x988_31_) { // TODO is this right? + if (x988_31_) { if (x420_curDamageRemTime <= 0.f) { CDamageInfo info = GetContactDamage(); info.SetDamage(0.5f * info.GetDamage()); @@ -783,16 +783,13 @@ bool CElitePirate::IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector< void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count, std::vector& outJoints) const { const CAnimData* animData = GetModelData()->GetAnimationData(); - for (size_t i = 0; i < count; ++i) { const auto& joint = joints[i]; const CSegId from = animData->GetLocatorSegId(joint.from); const CSegId to = animData->GetLocatorSegId(joint.to); - if (to.IsInvalid() || from.IsInvalid()) { continue; } - outJoints.emplace_back(CJointCollisionDescription::SphereSubdivideCollision( to, from, joint.radius, joint.separation, CJointCollisionDescription::EOrientationType::One, joint.from, 10.f)); } @@ -801,15 +798,12 @@ void CElitePirate::AddCollisionList(const SJointInfo* joints, size_t count, void CElitePirate::AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, std::vector& outJoints) const { const CAnimData* animData = GetModelData()->GetAnimationData(); - for (size_t i = 0; i < count; ++i) { const auto& joint = joints[i]; const CSegId seg = animData->GetLocatorSegId(joint.name); - if (seg.IsInvalid()) { continue; } - outJoints.emplace_back(CJointCollisionDescription::SphereCollision(seg, joint.radius, joint.name, 10.f)); } } @@ -891,7 +885,7 @@ bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view loc } void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { - CAnimationParameters& params = x5d8_data.x90_launcherAnimParams; + const CAnimationParameters& params = x5d8_data.x90_launcherAnimParams; if (!params.GetACSFile().IsValid()) { return; } @@ -1068,24 +1062,22 @@ void CElitePirate::ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_ve } bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId) { - if (x7b8_attackTimer <= 0.f && launcherId != kInvalidUniqueId) { - const CActor* launcher = static_cast(mgr.GetObjectById(launcherId)); - if (launcher != nullptr) { - const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f); - if (x300_maxAttackRange * x300_maxAttackRange <= (aim - GetTranslation()).magSquared() && !ShouldTurn(mgr, 0.f)) { - const zeus::CVector3f& origin = sub_80228864(launcher); - if (!IsPatternObstructed(mgr, origin, aim)) { - const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr); - float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin, velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; - CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut, - velocityOut); - const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); - return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); - } - } - } - } - return false; + if (x7b8_attackTimer > 0.f || launcherId == kInvalidUniqueId) + return false; + const CActor* launcher = static_cast(mgr.GetObjectById(launcherId)); + if (launcher == nullptr) + return false; + const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + if (x300_maxAttackRange * x300_maxAttackRange > (aim - GetTranslation()).magSquared() || ShouldTurn(mgr, 0.f)) + return false; + const zeus::CVector3f& origin = sub_80228864(launcher); + if (IsPatternObstructed(mgr, origin, aim)) + return false; + const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr); + float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin, velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; + CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut, velocityOut); + const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); + return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); } bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index e690b6e2d..dabc59e2d 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -144,9 +144,9 @@ public: void Attack(CStateManager& mgr, EStateMsg msg, float dt) override; void Taunt(CStateManager& mgr, EStateMsg msg, float dt) override; void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) override; + void Cover(CStateManager& mgr, EStateMsg msg, float dt) override; void SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) override; void CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) override; - void Cover(CStateManager& mgr, EStateMsg msg, float dt) override; bool TooClose(CStateManager& mgr, float arg) override; bool InDetectionRange(CStateManager& mgr, float arg) override; bool SpotPlayer(CStateManager& mgr, float arg) override; diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index ab35701b8..19bb10589 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -5,6 +5,9 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" +#include "Runtime/World/CExplosion.hpp" +#include "Runtime/World/CPatterned.hpp" #include "Runtime/World/CPlayer.hpp" namespace urde { @@ -12,19 +15,21 @@ namespace MP1 { CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, - const CActorParameters& actParams, TUniqueId otherId, + const CActorParameters& actParams, TUniqueId parentId, const CGrenadeLauncherData& data, float f1) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Character, EMaterialTypes::Solid}, bounds, {1000.f}, actParams, 0.3f, 0.1f) -, x25c_(healthInfo) +, x25c_healthInfo(healthInfo) , x264_vulnerability(vulnerability) -, x2cc_otherId(otherId) +, x2cc_parentId(parentId) , x2d0_data(data) , x328_cSphere({{}, mData.GetScale().z()}, {EMaterialTypes::Character, EMaterialTypes::Solid}) , x350_actParms(actParams) -, x3c0_particleGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.x40_})) -, x3d8_(actParams.GetThermalMag()) +, x3e8_thermalMag(actParams.GetThermalMag()) , x3f8_(f1) { + if (data.x40_.IsValid()) { + x3b8_particleGenDesc = g_SimplePool->GetObj({SBIG('PART'), data.x40_}); + } GetModelData()->EnableLooping(true); const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); for (int i = 0; i < 4; i++) { @@ -81,5 +86,215 @@ void CGrenadeLauncher::CalculateGrenadeTrajectory(const zeus::CVector3f& target, angleOut = angle; velocityOut = velocity; } + +void CGrenadeLauncher::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, uid, mgr); + switch (msg) { + case EScriptObjectMessage::Start: + if (x2cc_parentId == uid && x258_started != 1) { + x258_started = 1; + sub_80230438(); + } + break; + case EScriptObjectMessage::Stop: + if (x2cc_parentId == uid && x258_started != 0) { + x258_started = 0; + sub_80230438(); + } + break; + case EScriptObjectMessage::Action: + if (x2cc_parentId == uid && x258_started == 1) { + x3fc_launchGrenade = true; + } + break; + case EScriptObjectMessage::Registered: + sub_80230438(); + break; + case EScriptObjectMessage::Damage: + x3ec_damageTimer = 0.33f; + break; + default: + break; + } +} + +void CGrenadeLauncher::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + CActor::AddToRenderer(frustum, mgr); +} + +std::optional CGrenadeLauncher::GetTouchBounds() const { + return x328_cSphere.CalculateAABox(GetTransform()); +} + +void CGrenadeLauncher::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + if (x3f4_color3.a() == 1.f) { + xb4_drawFlags = {2, 0, 3, {x3f4_color3, 1.f}}; + } else { + xb4_drawFlags = {5, 0, 3, x3f4_color3}; + } + CActor::PreRender(mgr, frustum); +} + +void CGrenadeLauncher::Render(const CStateManager& mgr) const { + if (x3fd_visible) { + CPhysicsActor::Render(mgr); + } +} + +void CGrenadeLauncher::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + if (x3fc_launchGrenade) { + LaunchGrenade(mgr); + x3fc_launchGrenade = false; + } + + UpdateCollision(); + UpdateColor(dt); + sub_8022f9e0(mgr, dt); + sub_8022f69c(dt); + + const SAdvancementDeltas& deltas = CActor::UpdateAnimation(dt, mgr, true); + MoveToOR(deltas.x0_posDelta, dt); + RotateToOR(deltas.xc_rotDelta, dt); + + TCastToPtr parent = mgr.ObjectById(x2cc_parentId); + if (parent == nullptr || !parent->IsAlive() || parent->HealthInfo(mgr)->GetHP() <= 0.f) { + mgr.SendScriptMsg(parent, GetUniqueId(), EScriptObjectMessage::Damage); + CreateExplosion(mgr); + mgr.FreeScriptObject(GetUniqueId()); + } + } +} + +void CGrenadeLauncher::Touch(CActor& act, CStateManager& mgr) { + if (TCastToPtr projectile = act) { + if (projectile->GetOwnerId() == mgr.GetPlayer().GetUniqueId() && + GetDamageVulnerability()->WeaponHurts(CWeaponMode{projectile->GetType()}, false)) { + x348_shotTimer = 0.5f; + CEntity* parent = mgr.ObjectById(x2cc_parentId); + if (parent != nullptr) { + mgr.SendScriptMsg(parent, GetUniqueId(), EScriptObjectMessage::Touched); + } + } + } +} + +void CGrenadeLauncher::UpdateCollision() { + x328_cSphere.SetSphereCenter(GetLocatorTransform("lockon_target_LCTR"sv).origin); +} + +void CGrenadeLauncher::UpdateColor(float arg) { + if (x348_shotTimer > 0.f) { + x348_shotTimer = std::max(0.f, x348_shotTimer - arg); + x34c_color1 = zeus::CColor::lerp(zeus::skWhite, zeus::skRed, x348_shotTimer); + } +} + +void CGrenadeLauncher::sub_8022f69c(float arg) { + if (x3ec_damageTimer <= 0.f) { + xd0_damageMag = x3e8_thermalMag; + } else { + x3ec_damageTimer = std::max(0.f, x3ec_damageTimer - arg); + x3f4_color3 = zeus::CColor::lerp(zeus::skBlack, x3f0_color2, std::clamp(x3ec_damageTimer / 0.33f, 0.f, 1.f)); + xd0_damageMag = 5.f * x3ec_damageTimer + x3e8_thermalMag; + } +} + +void CGrenadeLauncher::CreateExplosion(CStateManager& mgr) { + if (!x3b8_particleGenDesc) + return; + mgr.AddObject(new CExplosion(*x3b8_particleGenDesc, mgr.AllocateUniqueId(), true, + {GetAreaIdAlways(), CEntity::NullConnectionList}, "Grenade Launcher Explode Fx"sv, + GetTransform(), 0, GetModelData()->GetScale(), zeus::skWhite)); + CSfxManager::SfxStart(x2d0_data.x44_launcherExplodeSfx, 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); +} + +void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { + CModelData* modelData = GetModelData(); + CAnimData* animData; + + if (modelData != nullptr && (animData = modelData->GetAnimationData()) != nullptr && x258_started == 1 && x3fe_) { + const zeus::CVector3f& target = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); + const zeus::CVector3f& rot = GetTransform().rotate({target.x(), target.y(), 0.f}); // TODO double check + + if (rot.canBeNormalized()) { + constexpr float p36d = zeus::degToRad(36.476f); + constexpr float n45d = zeus::degToRad(-45.f); + constexpr float p45d = zeus::degToRad(45.f); + + float l84 = p36d * std::clamp(std::atan2(rot.x(), rot.y()), n45d, p45d); + float l88 = std::clamp((0.25f * (l84 - x3d8_)) / dt, -3.f, 3.f); + float l8c = std::clamp((l88 - x3dc_) / dt, -10.f, 10.f); + x3dc_ += dt * l8c; + + float l90 = p36d * std::clamp(std::atan2(rot.z(), rot.toVec2f().magnitude()), n45d, p45d); + l88 = std::clamp((0.25f * (l90 - x3e0_)) / dt, -3.f, 3.f); + l8c = std::clamp((l88 - x3e4_) / dt, -10.f, 10.f); + x3e4_ += dt * l8c; + + float dVar7 = std::clamp(dt * x3dc_ + x3d8_, -0.5f, 0.5f); + float dVar8 = std::clamp(dt * x3e4_ + x3e0_, -0.5f, 0.5f); + + if (dVar7 != x3d8_) { + if (std::abs(x3d8_) > 0.f && x3d8_ * dVar7 <= 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + } + float weight = std::abs(dVar7); + if (weight > 0.f) { + animData->AddAdditiveAnimation(x3c8_animIds[dVar7 >= 0.f ? 1 : 0], weight, false, false); + } + } + if (dVar8 != x3e0_) { + if (std::abs(x3e0_) > 0.f && x3e0_ * dVar8 <= 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + } + float weight = std::abs(dVar8); + if (weight > 0.f) { + animData->AddAdditiveAnimation(x3c8_animIds[dVar8 <= 0.f ? 3 : 2], weight, false, false); + } + } + x3d8_ = dVar7; + x3e0_ = dVar8; + } + } else { + if (x3d8_ != 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + x3d8_ = 0.f; + } + if (x3e0_ != 0.f) { + animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + x3e0_ = 0.f; + } + } +} + +void CGrenadeLauncher::sub_80230438() { + CModelData* modelData = GetModelData(); + CAnimData* animData; + if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr || x258_started <= -1 || + x258_started >= 2) + return; + + constexpr std::array arr = {0, 3}; + const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation( + {5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(arr[x258_started])}, -1); + if (anim.first > 0.f) { + animData->SetAnimation({anim.second, -1, 1.f, true}, false); + modelData->EnableLooping(true); + } +} + +void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { + CModelData* modelData = GetModelData(); + CAnimData* animData; + if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr) + return; + + const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({24}, -1); + if (anim.first > 0.f) { + animData->AddAdditiveAnimation(anim.second, 1.f, false, true); + // TODO + } +} } // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index c3fb317f2..b961a393f 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -63,57 +63,56 @@ public: SBouncyGrenadeData x0_; CAssetId x3c_; CAssetId x40_; - u16 x44_sfx; + u16 x44_launcherExplodeSfx; SGrenadeTrajectoryInfo x48_trajectoryInfo; CGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, const SGrenadeTrajectoryInfo& trajectoryInfo) - : x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_trajectoryInfo(trajectoryInfo){}; + : x0_(data), x3c_(w1), x40_(w2), x44_launcherExplodeSfx(sfx), x48_trajectoryInfo(trajectoryInfo){}; }; class CGrenadeLauncher : public CPhysicsActor { public: - int x258_ = 0; - CHealthInfo x25c_; + int x258_started = 0; + CHealthInfo x25c_healthInfo; CDamageVulnerability x264_vulnerability; - TUniqueId x2cc_otherId; + TUniqueId x2cc_parentId; CGrenadeLauncherData x2d0_data; CCollidableSphere x328_cSphere; - float x348_ = -1.f; + float x348_shotTimer = -1.f; zeus::CColor x34c_color1{1.f}; CActorParameters x350_actParms; - // was TToken - TLockedToken x3c0_particleGenDesc; + std::optional> x3b8_particleGenDesc; std::array x3c8_animIds; float x3d8_ = 0.f; float x3dc_ = 0.f; float x3e0_ = 0.f; float x3e4_ = 0.f; float x3e8_thermalMag; - float x3ec_ = 0.f; + float x3ec_damageTimer = 0.f; zeus::CColor x3f0_color2{0.5f, 0.f, 0.f}; zeus::CColor x3f4_color3{0.f}; float x3f8_; - bool x3fc_ = false; - bool x3fd_ = true; + bool x3fc_launchGrenade = false; + bool x3fd_visible = true; bool x3fe_ = true; CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, - const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId otherId, + const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId parentId, const CGrenadeLauncherData& data, float f1); void Accept(IVisitor& visitor) override { visitor.Visit(this); } - // void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; - // void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } - // std::optional GetTouchBounds() const override; - // CHealthInfo* HealthInfo(CStateManager& mgr) override; - // void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - // void Render(const CStateManager& mgr) const override; - // void Think(float dt, CStateManager& mgr) override; - // void Touch(CActor& act, CStateManager& mgr) override; + std::optional GetTouchBounds() const override; + CHealthInfo* HealthInfo(CStateManager& mgr) override { return &x25c_healthInfo; } + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void Render(const CStateManager& mgr) const override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& act, CStateManager& mgr) override; static zeus::CVector3f GrenadeTarget(const CStateManager& mgr); static void CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, @@ -123,9 +122,10 @@ protected: void UpdateCollision(); void UpdateColor(float arg); void sub_8022f69c(float arg); - void sub_8022f770(CStateManager& mgr); - void sub_8022f9e0(CStateManager& mgr, float arg); + void CreateExplosion(CStateManager& mgr); + void sub_8022f9e0(CStateManager& mgr, float dt); void sub_80230438(); + void LaunchGrenade(CStateManager& mgr); }; } // namespace MP1 } // namespace urde From bc08792523b2742a4607c725e3c7aa8f2c11e4c2 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 03:05:16 -0400 Subject: [PATCH 10/26] CBouncyGrenade implementation --- Runtime/MP1/World/CBouncyGrenade.cpp | 203 +++++++++++++++++++++++++ Runtime/MP1/World/CBouncyGrenade.hpp | 73 +++++++++ Runtime/MP1/World/CElitePirate.cpp | 4 +- Runtime/MP1/World/CElitePirate.hpp | 2 +- Runtime/MP1/World/CGrenadeLauncher.cpp | 38 ++++- Runtime/MP1/World/CGrenadeLauncher.hpp | 46 ++---- Runtime/MP1/World/CMakeLists.txt | 1 + Runtime/World/CPhysicsActor.hpp | 1 + 8 files changed, 324 insertions(+), 44 deletions(-) create mode 100644 Runtime/MP1/World/CBouncyGrenade.cpp create mode 100644 Runtime/MP1/World/CBouncyGrenade.hpp diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp new file mode 100644 index 000000000..6448858de --- /dev/null +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -0,0 +1,203 @@ +#include "Runtime/MP1/World/CBouncyGrenade.hpp" + +#include "Runtime/CPlayerState.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/Collision/CCollisionActor.hpp" + +namespace urde::MP1 { +CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParams, + TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, + float explodePlayerDistance) +: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, {}, + {data.x0_.x0_mass}, actParams, 0.3f, 0.1f) +, x258_data(data) +, x294_numBounces(data.x34_numBounces) +, x298_parentId(parentId) +, x2a0_elementGen1(std::make_unique(g_SimplePool->GetObj({'PART', data.x24_elementGenId1}))) +, x2a4_elementGen2(std::make_unique(g_SimplePool->GetObj({'PART', data.x28_elementGenId2}))) +, x2a8_elementGen3(std::make_unique(g_SimplePool->GetObj({'PART', data.x2c_elementGenId3}))) +, x2ac_elementGen4(std::make_unique(g_SimplePool->GetObj({'PART', data.x30_elementGenId4}))) +, x2b0_explodePlayerDistance(explodePlayerDistance) +, x2b4_24_exploded(false) +, x2b4_25_(false) { + SetMomentumWR({0.f, 0.f, -GravityConstant() * GetMass()}); + SetVelocityWR(velocity * xf.frontVector()); + x2a0_elementGen1->SetParticleEmission(false); + x2a4_elementGen2->SetParticleEmission(false); + x2a8_elementGen3->SetParticleEmission(false); + x2ac_elementGen4->SetParticleEmission(true); + CMaterialFilter filter = GetMaterialFilter(); + filter.ExcludeList().Add(EMaterialTypes::Character); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(filter.IncludeList(), filter.ExcludeList())); +} + +void CBouncyGrenade::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + CActor::AddToRenderer(frustum, mgr); + if (!x2b4_24_exploded) { + g_Renderer->AddParticleGen(*x2ac_elementGen4); + return; + } + const auto visor = mgr.GetPlayerState()->GetActiveVisor(mgr); + if (visor == CPlayerState::EPlayerVisor::Combat || visor == CPlayerState::EPlayerVisor::Scan) { + g_Renderer->AddParticleGen(*x2a0_elementGen1); + } else if (visor == CPlayerState::EPlayerVisor::XRay || visor == CPlayerState::EPlayerVisor::Thermal) { + g_Renderer->AddParticleGen(*x2a8_elementGen3); + } +} + +void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) { + constexpr auto matList = CMaterialList{ + EMaterialTypes::Solid, + EMaterialTypes::Ceiling, + EMaterialTypes::Floor, + EMaterialTypes::Character, + }; + + bool shouldExplode = false; + if (x298_parentId != id) { + const CEntity* const entity = mgr.GetObjectById(id); + if (entity != nullptr) { + if (TCastToConstPtr actor = entity) { + shouldExplode = actor->GetOwnerId() != x298_parentId; + } else { + shouldExplode = true; + } + } + } + if (shouldExplode) { + Explode(mgr, id); + } else { + for (const auto& info : list) { + if (info.GetMaterialLeft().SharesMaterials(matList)) { + if (x294_numBounces == 0) { + Explode(mgr, kInvalidUniqueId); + } else { + const zeus::CVector3f* normal = &info.GetNormalLeft(); + if (GetVelocity().dot(info.GetNormalLeft()) > 0.f) { + normal = &info.GetNormalRight(); + } + const zeus::CVector3f impulse = (x258_data.x0_.x4_ * GetConstantForce().magnitude()) * *normal; + const zeus::CVector3f angle = -x258_data.x0_.x4_ * GetAngularMomentum(); + ApplyImpulseWR(impulse, angle); + CSfxManager::AddEmitter(x258_data.x38_bounceSfx, GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); + x294_numBounces--; + } + break; + } + } + } + CPhysicsActor::CollidedWith(id, list, mgr); +} + +std::optional CBouncyGrenade::GetTouchBounds() const { return GetModelData()->GetBounds(GetTransform()); } + +void CBouncyGrenade::Render(const CStateManager& mgr) const { + if (!x2b4_24_exploded) { + GetModelData()->Render(mgr, GetTransform(), nullptr, {0, 0, 3, zeus::skWhite}); + } else if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + x2a4_elementGen2->Render(); + mgr.SetupFogForArea(GetAreaIdAlways()); + } +} + +void CBouncyGrenade::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + const zeus::CTransform& orientation = GetTransform().getRotation(); + const zeus::CVector3f& translation = GetTranslation(); + const zeus::CVector3f& scale = GetModelData()->GetScale(); + auto UpdateElementGen = [ orientation, translation, scale, dt ](CElementGen & gen) constexpr { + gen.SetOrientation(orientation); + gen.SetGlobalTranslation(translation); + gen.SetGlobalScale(scale); + gen.Update(dt); + }; + if (x2b4_24_exploded) { + Stop(); + UpdateElementGen(*x2a0_elementGen1); + UpdateElementGen(*x2a4_elementGen2); + UpdateElementGen(*x2a8_elementGen3); + } else { + UpdateElementGen(*x2ac_elementGen4); + } + x29c_ += dt; + if (x29c_ > 0.3f) { + x2b4_25_ = true; + } + const zeus::CVector3f& playerDistance = mgr.GetPlayer().GetTranslation() + + zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()} - + translation; + if (playerDistance.magSquared() < x2b0_explodePlayerDistance * x2b0_explodePlayerDistance) { + Explode(mgr, kInvalidUniqueId); + } + } + if (x2a0_elementGen1->IsSystemDeletable() && x2a4_elementGen2->IsSystemDeletable() && + x2a8_elementGen3->IsSystemDeletable()) { + mgr.FreeScriptObject(GetUniqueId()); + } +} + +void CBouncyGrenade::Touch(CActor& act, CStateManager& mgr) { CActor::Touch(act, mgr); } + +void CBouncyGrenade::Explode(CStateManager& mgr, TUniqueId uid) { + if (x2b4_24_exploded) + return; + + x2b4_24_exploded = true; + CSfxManager::AddEmitter(x258_data.x3a_explodeSfx, GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); + x2a0_elementGen1->SetParticleEmission(true); + x2a4_elementGen2->SetParticleEmission(true); + x2a8_elementGen3->SetParticleEmission(true); + x2ac_elementGen4->SetParticleEmission(false); + + const CDamageInfo& dInfo = x258_data.x8_damageInfo; + { + bool isParent = x298_parentId == uid; + if (TCastToConstPtr actor = mgr.GetObjectById(uid)) { + isParent = x298_parentId == actor->GetOwnerId(); + } + if (uid != kInvalidUniqueId && !isParent) { + mgr.ApplyDamage(GetUniqueId(), uid, GetUniqueId(), dInfo, CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), + zeus::skZero3f); + } + } + + const float radius = dInfo.GetRadius(); + if (radius > 1.f) { + const zeus::CVector3f& pos = GetTranslation(); + const CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Player, EMaterialTypes::Character}); + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, {pos - radius, pos + radius}, filter, nullptr); + + for (const auto& id : nearList) { + bool isParent = x298_parentId == id; + if (TCastToConstPtr cActor = mgr.GetObjectById(id)) { + isParent = x298_parentId == cActor->GetOwnerId(); + } + if (isParent) + continue; + + const CActor* actor = static_cast(mgr.GetObjectById(id)); + if (actor == nullptr) + continue; + + const float magnitude = (actor->GetTranslation() - GetTranslation()).magnitude(); + if (radius <= magnitude) + continue; + + float scale = (radius - magnitude) / radius; + const CDamageInfo info{dInfo.GetWeaponMode(), scale * dInfo.GetDamage(), radius, + scale * dInfo.GetKnockBackPower()}; + mgr.ApplyDamage(GetUniqueId(), id, GetUniqueId(), info, CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), + zeus::skZero3f); + } + } +} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CBouncyGrenade.hpp b/Runtime/MP1/World/CBouncyGrenade.hpp new file mode 100644 index 000000000..0fd2e1cd7 --- /dev/null +++ b/Runtime/MP1/World/CBouncyGrenade.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include "Runtime/World/CPhysicsActor.hpp" +#include "Runtime/World/CDamageInfo.hpp" +#include "Runtime/Particle/CElementGen.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +#include + +namespace urde::MP1 { +struct SGrenadeUnknownStruct { + float x0_mass; + float x4_; // speed? + + SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_(in.readFloatBig()) {} +}; + +struct SBouncyGrenadeData { + SGrenadeUnknownStruct x0_; + CDamageInfo x8_damageInfo; + CAssetId x24_elementGenId1; + CAssetId x28_elementGenId2; + CAssetId x2c_elementGenId3; + CAssetId x30_elementGenId4; + u32 x34_numBounces; + u16 x38_bounceSfx; + u16 x3a_explodeSfx; + + SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, + CAssetId w3, CAssetId w4, u32 w5, u16 s1, u16 s2) + : x0_(unkStruct) + , x8_damageInfo(damageInfo) + , x24_elementGenId1(w1) + , x28_elementGenId2(w2) + , x2c_elementGenId3(w3) + , x30_elementGenId4(w4) + , x34_numBounces(w5) + , x38_bounceSfx(s1) + , x3a_explodeSfx(s2){}; +}; + +class CBouncyGrenade : public CPhysicsActor { +private: + SBouncyGrenadeData x258_data; + u32 x294_numBounces; + TUniqueId x298_parentId; + float x29c_ = 0.f; + std::unique_ptr x2a0_elementGen1; + std::unique_ptr x2a4_elementGen2; + std::unique_ptr x2a8_elementGen3; + std::unique_ptr x2ac_elementGen4; + float x2b0_explodePlayerDistance; + bool x2b4_24_exploded : 1; + bool x2b4_25_ : 1; + +public: + CBouncyGrenade(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& actParams, TUniqueId parentId, + const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance); + + void Accept(IVisitor& visitor) override { visitor.Visit(this); } + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void CollidedWith(TUniqueId id, const CCollisionInfoList &list, CStateManager &mgr) override; + std::optional GetTouchBounds() const override; + void Render(const CStateManager& mgr) const override; + void Think(float dt, CStateManager& mgr) override; + void Touch(CActor& act, CStateManager& mgr) override; + +private: + void Explode(CStateManager& mgr, TUniqueId uid); +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 0fc0e7b6f..ae2ab3f5a 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -64,7 +64,7 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , xd4_(in) , xd8_(in) , xe0_trajectoryInfo(in) -, xf0_(in) +, xf0_grenadeNumBounces(in.readUint32Big()) , xf4_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf6_(CSfxManager::TranslateSFXID(in.readUint32Big())) , xf8_(in) @@ -892,7 +892,7 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), params.GetInitialAnimation(), true)); SBouncyGrenadeData grenadeData{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_, - x5d8_data.xd4_, x5d8_data.xf0_, x5d8_data.xf4_, x5d8_data.xf6_}; + x5d8_data.xd4_, x5d8_data.xf0_grenadeNumBounces, x5d8_data.xf4_, x5d8_data.xf6_}; CGrenadeLauncherData launcherData{grenadeData, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, x5d8_data.xe0_trajectoryInfo}; mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index dabc59e2d..12b2be580 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -38,7 +38,7 @@ public: CAssetId xd4_; SGrenadeUnknownStruct xd8_; SGrenadeTrajectoryInfo xe0_trajectoryInfo; - CAssetId xf0_; + u32 xf0_grenadeNumBounces; u16 xf4_; u16 xf6_; CAssetId xf8_; diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 19bb10589..5bff3f2cc 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -10,8 +10,7 @@ #include "Runtime/World/CPatterned.hpp" #include "Runtime/World/CPlayer.hpp" -namespace urde { -namespace MP1 { +namespace urde::MP1 { CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, @@ -24,9 +23,9 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C , x2cc_parentId(parentId) , x2d0_data(data) , x328_cSphere({{}, mData.GetScale().z()}, {EMaterialTypes::Character, EMaterialTypes::Solid}) -, x350_actParms(actParams) +, x350_grenadeActorParams(actParams) , x3e8_thermalMag(actParams.GetThermalMag()) -, x3f8_(f1) { +, x3f8_explodePlayerDistance(f1) { if (data.x40_.IsValid()) { x3b8_particleGenDesc = g_SimplePool->GetObj({SBIG('PART'), data.x40_}); } @@ -293,8 +292,33 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({24}, -1); if (anim.first > 0.f) { animData->AddAdditiveAnimation(anim.second, 1.f, false, true); - // TODO + const zeus::CVector3f& origin = + GetTranslation() + GetTransform().rotate(GetLocatorTransform("grenade_LCTR"sv).origin); + const zeus::CVector3f& target = GrenadeTarget(mgr); + float angleOut = x2d0_data.x48_trajectoryInfo.x8_angleMin, velocityOut = x2d0_data.x48_trajectoryInfo.x0_; + CalculateGrenadeTrajectory(target, origin, x2d0_data.x48_trajectoryInfo, angleOut, velocityOut); + + zeus::CVector3f dist = target - origin; + dist.z() = 0.f; + const zeus::CVector3f& front = GetTransform().frontVector(); + if (dist.canBeNormalized()) { + dist.normalize(); + } else { + dist = front; + } + + constexpr float maxAngle = zeus::degToRad(45.f); + if (zeus::CVector3f::getAngleDiff(front, dist) > maxAngle) { + dist = zeus::CVector3f::slerp(front, dist, maxAngle); + } + + const zeus::CVector3f& look = zeus::CVector3f::slerp(dist, zeus::skUp, angleOut); + const zeus::CTransform& xf = zeus::lookAt(origin, origin + look, zeus::skUp); + CModelData mData{CStaticRes{x2d0_data.x3c_grenadeCmdl, GetModelData()->GetScale()}}; + mgr.AddObject(new CBouncyGrenade(mgr.AllocateUniqueId(), "Bouncy Grenade"sv, + {GetAreaIdAlways(), CEntity::NullConnectionList}, xf, std::move(mData), + x350_grenadeActorParams, x2cc_parentId, x2d0_data.x0_grenadeData, velocityOut, + x3f8_explodePlayerDistance)); } } -} // namespace MP1 -} // namespace urde +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index b961a393f..11f3bf4b1 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -2,15 +2,14 @@ #include "Runtime/Character/CModelData.hpp" #include "Runtime/Collision/CCollidableSphere.hpp" +#include "Runtime/MP1/World/CBouncyGrenade.hpp" #include "Runtime/Particle/CGenDescription.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CDamageInfo.hpp" #include "Runtime/World/CDamageVulnerability.hpp" #include "Runtime/World/CEntityInfo.hpp" #include "Runtime/World/CHealthInfo.hpp" #include "Runtime/World/CPhysicsActor.hpp" -#include "Runtime/World/CPhysicsActor.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -20,8 +19,7 @@ #include #include -namespace urde { -namespace MP1 { +namespace urde::MP1 { struct SGrenadeTrajectoryInfo { float x0_; float x4_; @@ -35,40 +33,21 @@ struct SGrenadeTrajectoryInfo { , xc_angleMax(zeus::degToRad(in.readFloatBig())) {} }; -struct SGrenadeUnknownStruct { - float x0_mass; - float x4_; - - SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_(in.readFloatBig()) {} -}; - -struct SBouncyGrenadeData { - SGrenadeUnknownStruct x0_; - CDamageInfo x8_damageInfo; - CAssetId x24_; - CAssetId x28_; - CAssetId x2c_; - CAssetId x30_; - CAssetId x34_; - u16 x38_; - u16 x3a_; - - SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, - CAssetId w3, CAssetId w4, CAssetId w5, u16 s1, u16 s2) - : x0_(unkStruct), x8_damageInfo(damageInfo), x24_(w1), x28_(w2), x2c_(w3), x30_(w4), x34_(w5), x38_(s1), x3a_(s2){}; -}; - class CGrenadeLauncherData { public: - SBouncyGrenadeData x0_; - CAssetId x3c_; + SBouncyGrenadeData x0_grenadeData; + CAssetId x3c_grenadeCmdl; CAssetId x40_; u16 x44_launcherExplodeSfx; SGrenadeTrajectoryInfo x48_trajectoryInfo; CGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, const SGrenadeTrajectoryInfo& trajectoryInfo) - : x0_(data), x3c_(w1), x40_(w2), x44_launcherExplodeSfx(sfx), x48_trajectoryInfo(trajectoryInfo){}; + : x0_grenadeData(data) + , x3c_grenadeCmdl(w1) + , x40_(w2) + , x44_launcherExplodeSfx(sfx) + , x48_trajectoryInfo(trajectoryInfo){}; }; class CGrenadeLauncher : public CPhysicsActor { @@ -81,7 +60,7 @@ public: CCollidableSphere x328_cSphere; float x348_shotTimer = -1.f; zeus::CColor x34c_color1{1.f}; - CActorParameters x350_actParms; + CActorParameters x350_grenadeActorParams; std::optional> x3b8_particleGenDesc; std::array x3c8_animIds; float x3d8_ = 0.f; @@ -92,7 +71,7 @@ public: float x3ec_damageTimer = 0.f; zeus::CColor x3f0_color2{0.5f, 0.f, 0.f}; zeus::CColor x3f4_color3{0.f}; - float x3f8_; + float x3f8_explodePlayerDistance; bool x3fc_launchGrenade = false; bool x3fd_visible = true; bool x3fe_ = true; @@ -127,5 +106,4 @@ protected: void sub_80230438(); void LaunchGrenade(CStateManager& mgr); }; -} // namespace MP1 -} // namespace urde +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 53e5ac55e..782deee69 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -5,6 +5,7 @@ set(MP1_WORLD_SOURCES CBabygoth.hpp CBabygoth.cpp CBeetle.hpp CBeetle.cpp CBloodFlower.hpp CBloodFlower.cpp + CBouncyGrenade.hpp CBouncyGrenade.cpp CBurrower.hpp CBurrower.cpp CChozoGhost.hpp CChozoGhost.cpp CElitePirate.hpp CElitePirate.cpp diff --git a/Runtime/World/CPhysicsActor.hpp b/Runtime/World/CPhysicsActor.hpp index fd683477c..fab806ccf 100644 --- a/Runtime/World/CPhysicsActor.hpp +++ b/Runtime/World/CPhysicsActor.hpp @@ -161,6 +161,7 @@ public: void SetMomentumWR(const zeus::CVector3f& momentum) { x150_momentum = momentum; } const zeus::CVector3f& GetConstantForce() const { return xfc_constantForce; } void SetConstantForce(const zeus::CVector3f& force) { xfc_constantForce = force; } + const zeus::CVector3f& GetAngularMomentum() const { return x108_angularMomentum; } void SetAngularMomentum(const zeus::CAxisAngle& momentum) { x108_angularMomentum = momentum; } const zeus::CVector3f& GetMomentum() const { return x150_momentum; } const zeus::CVector3f& GetVelocity() const { return x138_velocity; } From bc1135f0cf7ce3dbacecf8e48bb87a0d28a5a329 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 03:14:33 -0400 Subject: [PATCH 11/26] CBouncyGrenade: Use explicit SMoverData constructor --- Runtime/MP1/World/CBouncyGrenade.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index 6448858de..cb44954ec 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -14,7 +14,7 @@ CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEnti TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, {}, - {data.x0_.x0_mass}, actParams, 0.3f, 0.1f) + SMoverData(data.x0_.x0_mass), actParams, 0.3f, 0.1f) , x258_data(data) , x294_numBounces(data.x34_numBounces) , x298_parentId(parentId) From 571050245d419fb1d6558d0359d631b8675a25a4 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 19:31:14 -0400 Subject: [PATCH 12/26] Add .clang-tidy and apply fixes --- .clang-tidy | 1 + Runtime/MP1/World/CBouncyGrenade.cpp | 18 +++-- Runtime/MP1/World/CElitePirate.cpp | 103 +++++++++++++++---------- Runtime/MP1/World/CElitePirate.hpp | 4 +- Runtime/MP1/World/CGrenadeLauncher.cpp | 28 ++++--- Runtime/MP1/World/CGrenadeLauncher.hpp | 12 +-- 6 files changed, 101 insertions(+), 65 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..6473e7034 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +Checks: '*,-modernize-use-trailing-return-type,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-*,-google-runtime-references' diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index cb44954ec..813de2a75 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -95,7 +95,9 @@ void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CPhysicsActor::CollidedWith(id, list, mgr); } -std::optional CBouncyGrenade::GetTouchBounds() const { return GetModelData()->GetBounds(GetTransform()); } +auto CBouncyGrenade::GetTouchBounds() const -> std::optional { + return GetModelData()->GetBounds(GetTransform()); +} void CBouncyGrenade::Render(const CStateManager& mgr) const { if (!x2b4_24_exploded) { @@ -146,8 +148,9 @@ void CBouncyGrenade::Think(float dt, CStateManager& mgr) { void CBouncyGrenade::Touch(CActor& act, CStateManager& mgr) { CActor::Touch(act, mgr); } void CBouncyGrenade::Explode(CStateManager& mgr, TUniqueId uid) { - if (x2b4_24_exploded) + if (x2b4_24_exploded) { return; + } x2b4_24_exploded = true; CSfxManager::AddEmitter(x258_data.x3a_explodeSfx, GetTranslation(), zeus::skUp, false, false, 0x7f, @@ -181,16 +184,19 @@ void CBouncyGrenade::Explode(CStateManager& mgr, TUniqueId uid) { if (TCastToConstPtr cActor = mgr.GetObjectById(id)) { isParent = x298_parentId == cActor->GetOwnerId(); } - if (isParent) + if (isParent) { continue; + } - const CActor* actor = static_cast(mgr.GetObjectById(id)); - if (actor == nullptr) + const auto* actor = static_cast(mgr.GetObjectById(id)); + if (actor == nullptr) { continue; + } const float magnitude = (actor->GetTranslation() - GetTranslation()).magnitude(); - if (radius <= magnitude) + if (radius <= magnitude) { continue; + } float scale = (radius - magnitude) / radius; const CDamageInfo info{dInfo.GetWeaponMode(), scale * dInfo.GetDamage(), radius, diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index ae2ab3f5a..65bcdae26 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -1,5 +1,7 @@ #include "Runtime/MP1/World/CElitePirate.hpp" +#include + #include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/CSimplePool.hpp" @@ -17,19 +19,19 @@ namespace urde::MP1 { namespace { -static constexpr std::array skLeftArmJointList{{ +constexpr std::array skLeftArmJointList{{ {"L_shoulder", "L_elbow", 1.f, 1.5f}, {"L_wrist", "L_elbow", 0.9f, 1.3f}, {"L_knee", "L_ankle", 0.9f, 1.3f}, }}; -static constexpr std::array skRightArmJointList{{ +constexpr std::array skRightArmJointList{{ {"R_shoulder", "R_elbow", 1.f, 1.5f}, {"R_wrist", "R_elbow", 0.9f, 1.3f}, {"R_knee", "R_ankle", 0.9f, 1.3f}, }}; -static constexpr std::array skSphereJointList{{ +constexpr std::array skSphereJointList{{ {"Head_1", 1.2f}, {"L_Palm_LCTR", 1.5f}, {"R_Palm_LCTR", 1.5f}, @@ -76,11 +78,11 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - const CElitePirateData& data) + CElitePirateData data) : CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large) , x56c_vulnerability(pInfo.GetDamageVulnerability()) -, x5d8_data(data) +, x5d8_data(std::move(data)) , x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) , x738_(GetBoundingBox(), GetMaterialList()) @@ -157,8 +159,9 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta x988_28_alert = true; break; case EScriptObjectMessage::Touched: { - if (HealthInfo(mgr)->GetHP() <= 0.f) + if (HealthInfo(mgr)->GetHP() <= 0.f) { break; + } TCastToPtr actor = mgr.ObjectById(uid); if (!actor) { if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { @@ -263,19 +266,19 @@ void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_ ? numMaterialSets - 1 : x7cc_; } -const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { +auto CElitePirate::GetDamageVulnerability() const -> const CDamageVulnerability* { return &CDamageVulnerability::PassThroughVulnerabilty(); } -const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, - const CDamageInfo& dInfo) const { +auto CElitePirate::GetDamageVulnerability(const zeus::CVector3f& /*pos*/, const zeus::CVector3f& /*dir*/, + const CDamageInfo& /*dInfo*/) const -> const CDamageVulnerability* { return &CDamageVulnerability::PassThroughVulnerabilty(); } -zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { +auto CElitePirate::GetOrbitPosition(const CStateManager& mgr) const -> zeus::CVector3f { if (x772_launcherId != kInvalidUniqueId && mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { - if (const CActor* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { + if (const auto* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { return sub_80228864(actor); } } @@ -287,8 +290,8 @@ zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { return GetLctrTransform("lockon_target_LCTR").origin; } -zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const { - std::shared_ptr playerState = mgr.GetPlayerState(); +auto CElitePirate::GetAimPosition(const CStateManager& mgr, float /*unused*/) const -> zeus::CVector3f { + const std::shared_ptr& playerState = mgr.GetPlayerState(); if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { if (TCastToConstPtr actor = mgr.GetObjectById(x79c_)) { @@ -355,7 +358,7 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node } } -const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } +auto CElitePirate::GetCollisionPrimitive() const -> const CCollisionPrimitive* { return &x738_; } void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { @@ -368,7 +371,7 @@ void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, con } } -void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} +void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float /*arg*/) {} void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { @@ -443,7 +446,7 @@ void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { +void CElitePirate::Halt(CStateManager& /*mgr*/, EStateMsg msg, float /*unused*/) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); x989_24_ = false; @@ -491,7 +494,7 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float /*unused*/) { if (msg == EStateMsg::Activate) { x568_ = EState::One; } else if (msg == EStateMsg::Update) { @@ -519,7 +522,7 @@ void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { } } -void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { +void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float /*unused*/) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); @@ -573,7 +576,7 @@ void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } -void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { +void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float /*unused*/) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; } else if (msg == EStateMsg::Update) { @@ -598,7 +601,7 @@ void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } -void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { +void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float /*unused*/) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; x988_30_ = true; @@ -673,7 +676,7 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { } } -bool CElitePirate::TooClose(CStateManager& mgr, float) { +bool CElitePirate::TooClose(CStateManager& mgr, float /*arg*/) { return x2fc_minAttackRange * x2fc_minAttackRange > (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared(); } @@ -685,18 +688,20 @@ bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg); } -bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_ == EState::Over; } +bool CElitePirate::AnimOver(CStateManager& /*mgr*/, float /*arg*/) { return x568_ == EState::Over; } -bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { +bool CElitePirate::ShouldAttack(CStateManager& mgr, float /*unused*/) { if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { return false; } return !ShouldTurn(mgr, 0.f); } -bool CElitePirate::InPosition(CStateManager& mgr, float) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } +bool CElitePirate::InPosition(CStateManager& /*mgr*/, float /*arg*/) { + return (x8b4_ - GetTranslation()).magSquared() < 25.f; +} -bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { +bool CElitePirate::ShouldTurn(CStateManager& mgr, float /*unused*/) { return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f); } @@ -712,13 +717,15 @@ bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { return false; } -bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTimer <= 0.f; } +bool CElitePirate::ShouldTaunt(CStateManager& /*mgr*/, float /*unused*/) { return x7bc_tauntTimer <= 0.f; } -bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); } +bool CElitePirate::ShouldFire(CStateManager& mgr, float /*unused*/) { + return ShouldFireFromLauncher(mgr, x772_launcherId); +} -bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_; } +bool CElitePirate::ShotAt(CStateManager& /*mgr*/, float /*unused*/) { return x988_27_; } -bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { +bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float /*unused*/) { if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) { const zeus::CVector3f& dist = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); float magSquared = dist.magSquared(); @@ -730,11 +737,11 @@ bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { return false; } -bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) { +bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float /*unused*/) { return ShouldCallForBackupFromLauncher(mgr, x772_launcherId); } -CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; } +auto CElitePirate::GetSearchPath() -> CPathFindSearch* { return &x7d0_pathFindSearch; } void CElitePirate::SetupHealthInfo(CStateManager& mgr) { const CHealthInfo* const health = HealthInfo(mgr); @@ -891,8 +898,15 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { } CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), params.GetInitialAnimation(), true)); - SBouncyGrenadeData grenadeData{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_, - x5d8_data.xd4_, x5d8_data.xf0_grenadeNumBounces, x5d8_data.xf4_, x5d8_data.xf6_}; + SBouncyGrenadeData grenadeData{x5d8_data.xd8_, + x5d8_data.xa8_, + x5d8_data.xc8_, + x5d8_data.xcc_, + x5d8_data.xd0_, + x5d8_data.xd4_, + x5d8_data.xf0_grenadeNumBounces, + x5d8_data.xf4_, + x5d8_data.xf6_}; CGrenadeLauncherData launcherData{grenadeData, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, x5d8_data.xe0_trajectoryInfo}; mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, @@ -1029,7 +1043,7 @@ void CElitePirate::sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_ if (uid == kInvalidUniqueId) { return; } - CActor* actor = static_cast(mgr.ObjectById(uid)); + auto* actor = static_cast(mgr.ObjectById(uid)); if (actor == nullptr) { uid = kInvalidUniqueId; return; @@ -1062,25 +1076,30 @@ void CElitePirate::ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_ve } bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId) { - if (x7b8_attackTimer > 0.f || launcherId == kInvalidUniqueId) + if (x7b8_attackTimer > 0.f || launcherId == kInvalidUniqueId) { return false; - const CActor* launcher = static_cast(mgr.GetObjectById(launcherId)); - if (launcher == nullptr) + } + const auto* launcher = static_cast(mgr.GetObjectById(launcherId)); + if (launcher == nullptr) { return false; + } const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f); - if (x300_maxAttackRange * x300_maxAttackRange > (aim - GetTranslation()).magSquared() || ShouldTurn(mgr, 0.f)) + if (x300_maxAttackRange * x300_maxAttackRange > (aim - GetTranslation()).magSquared() || ShouldTurn(mgr, 0.f)) { return false; + } const zeus::CVector3f& origin = sub_80228864(launcher); - if (IsPatternObstructed(mgr, origin, aim)) + if (IsPatternObstructed(mgr, origin, aim)) { return false; + } const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr); - float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin, velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; + float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin; + float velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut, velocityOut); const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); } -bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { +bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& /*mgr*/, TUniqueId uid) { if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.x11e_) { return x7a8_ >= 3.f; } @@ -1088,7 +1107,7 @@ bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId } zeus::CVector3f CElitePirate::SUnknownStruct::GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { - while (x4_.size()) { + while (!x4_.empty()) { const zeus::CVector3f v = x4_[x4_.size() - 1] - v1; if (v.dot(v2) > 0.f && v.isMagnitudeSafe()) { return v.normalized(); diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 12b2be580..ae85a5a6e 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -61,7 +61,7 @@ class CElitePirate : public CPatterned { struct SUnknownStruct { float x0_; rstl::reserved_vector x4_; - SUnknownStruct(float f) : x0_(f * f) {} + explicit SUnknownStruct(float f) : x0_(f * f) {} zeus::CVector3f GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2); void AddValue(const zeus::CVector3f& vec); void Clear() { x4_.clear(); } @@ -119,7 +119,7 @@ public: CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - const CElitePirateData& data); + CElitePirateData data); void Accept(IVisitor& visitor) override; void Think(float dt, CStateManager& mgr) override; diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 5bff3f2cc..868773441 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -31,13 +31,13 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C } GetModelData()->EnableLooping(true); const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < x3c8_animIds.size(); i++) { const auto result = pasDatabase.FindBestAnimation({22, CPASAnimParm::FromEnum(i)}, -1); x3c8_animIds[i] = result.second; } } -zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) { +auto CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) -> zeus::CVector3f { const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 1.f); if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) { return aim - zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()}; @@ -121,7 +121,7 @@ void CGrenadeLauncher::AddToRenderer(const zeus::CFrustum& frustum, const CState CActor::AddToRenderer(frustum, mgr); } -std::optional CGrenadeLauncher::GetTouchBounds() const { +auto CGrenadeLauncher::GetTouchBounds() const -> std::optional { return x328_cSphere.CalculateAABox(GetTransform()); } @@ -200,8 +200,9 @@ void CGrenadeLauncher::sub_8022f69c(float arg) { } void CGrenadeLauncher::CreateExplosion(CStateManager& mgr) { - if (!x3b8_particleGenDesc) + if (!x3b8_particleGenDesc) { return; + } mgr.AddObject(new CExplosion(*x3b8_particleGenDesc, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList}, "Grenade Launcher Explode Fx"sv, GetTransform(), 0, GetModelData()->GetScale(), zeus::skWhite)); @@ -210,7 +211,7 @@ void CGrenadeLauncher::CreateExplosion(CStateManager& mgr) { void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { CModelData* modelData = GetModelData(); - CAnimData* animData; + CAnimData* animData = nullptr; if (modelData != nullptr && (animData = modelData->GetAnimationData()) != nullptr && x258_started == 1 && x3fe_) { const zeus::CVector3f& target = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); @@ -257,11 +258,15 @@ void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { } } else { if (x3d8_ != 0.f) { - animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + if (animData != nullptr) { // Original code does not check + animData->DelAdditiveAnimation(x3c8_animIds[x3d8_ >= 0.f ? 1 : 0]); + } x3d8_ = 0.f; } if (x3e0_ != 0.f) { - animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + if (animData != nullptr) { // Original code does not check + animData->DelAdditiveAnimation(x3c8_animIds[x3e0_ <= 0.f ? 3 : 2]); + } x3e0_ = 0.f; } } @@ -271,8 +276,9 @@ void CGrenadeLauncher::sub_80230438() { CModelData* modelData = GetModelData(); CAnimData* animData; if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr || x258_started <= -1 || - x258_started >= 2) + x258_started >= 2) { return; + } constexpr std::array arr = {0, 3}; const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation( @@ -286,8 +292,9 @@ void CGrenadeLauncher::sub_80230438() { void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { CModelData* modelData = GetModelData(); CAnimData* animData; - if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr) + if (modelData == nullptr || (animData = modelData->GetAnimationData()) == nullptr) { return; + } const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({24}, -1); if (anim.first > 0.f) { @@ -295,7 +302,8 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { const zeus::CVector3f& origin = GetTranslation() + GetTransform().rotate(GetLocatorTransform("grenade_LCTR"sv).origin); const zeus::CVector3f& target = GrenadeTarget(mgr); - float angleOut = x2d0_data.x48_trajectoryInfo.x8_angleMin, velocityOut = x2d0_data.x48_trajectoryInfo.x0_; + float angleOut = x2d0_data.x48_trajectoryInfo.x8_angleMin; + float velocityOut = x2d0_data.x48_trajectoryInfo.x0_; CalculateGrenadeTrajectory(target, origin, x2d0_data.x48_trajectoryInfo, angleOut, velocityOut); zeus::CVector3f dist = target - origin; diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index 11f3bf4b1..ed28d6824 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -26,7 +26,7 @@ struct SGrenadeTrajectoryInfo { float x8_angleMin; float xc_angleMax; - SGrenadeTrajectoryInfo(CInputStream& in) + explicit SGrenadeTrajectoryInfo(CInputStream& in) : x0_(in.readFloatBig()) , x4_(in.readFloatBig()) , x8_angleMin(zeus::degToRad(in.readFloatBig())) @@ -84,10 +84,12 @@ public: void Accept(IVisitor& visitor) override { visitor.Visit(this); } void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } - const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } - std::optional GetTouchBounds() const override; - CHealthInfo* HealthInfo(CStateManager& mgr) override { return &x25c_healthInfo; } + [[nodiscard]] auto GetCollisionPrimitive() const -> const CCollisionPrimitive* override { return &x328_cSphere; } + [[nodiscard]] auto GetDamageVulnerability() const -> const CDamageVulnerability* override { + return &x264_vulnerability; + } + [[nodiscard]] auto GetTouchBounds() const -> std::optional override; + auto HealthInfo(CStateManager & /*mgr*/) -> CHealthInfo* override { return &x25c_healthInfo; } void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; void Render(const CStateManager& mgr) const override; void Think(float dt, CStateManager& mgr) override; From ed254b460e6153905e913310f80d0ed3209d4f34 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 19:42:11 -0400 Subject: [PATCH 13/26] Revert some clang-tidy changes --- .clang-tidy | 2 +- Runtime/MP1/World/CBouncyGrenade.cpp | 2 +- Runtime/MP1/World/CBouncyGrenade.hpp | 2 +- Runtime/MP1/World/CElitePirate.cpp | 46 +++++++++++--------------- Runtime/MP1/World/CGrenadeLauncher.cpp | 4 +-- Runtime/MP1/World/CGrenadeLauncher.hpp | 10 +++--- 6 files changed, 29 insertions(+), 37 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 6473e7034..915f3de09 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1 +1 @@ -Checks: '*,-modernize-use-trailing-return-type,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-*,-google-runtime-references' +Checks: '*,-misc-unused-parameters,-modernize-use-trailing-return-type,-readability-named-parameter,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-*,-google-runtime-references' diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index 813de2a75..1c227609e 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -95,7 +95,7 @@ void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CPhysicsActor::CollidedWith(id, list, mgr); } -auto CBouncyGrenade::GetTouchBounds() const -> std::optional { +std::optional CBouncyGrenade::GetTouchBounds() const { return GetModelData()->GetBounds(GetTransform()); } diff --git a/Runtime/MP1/World/CBouncyGrenade.hpp b/Runtime/MP1/World/CBouncyGrenade.hpp index 0fd2e1cd7..5fac45c64 100644 --- a/Runtime/MP1/World/CBouncyGrenade.hpp +++ b/Runtime/MP1/World/CBouncyGrenade.hpp @@ -62,7 +62,7 @@ public: void Accept(IVisitor& visitor) override { visitor.Visit(this); } void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; void CollidedWith(TUniqueId id, const CCollisionInfoList &list, CStateManager &mgr) override; - std::optional GetTouchBounds() const override; + [[nodiscard]] std::optional GetTouchBounds() const override; void Render(const CStateManager& mgr) const override; void Think(float dt, CStateManager& mgr) override; void Touch(CActor& act, CStateManager& mgr) override; diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 65bcdae26..be2b2f3ae 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -1,7 +1,5 @@ #include "Runtime/MP1/World/CElitePirate.hpp" -#include - #include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/CSimplePool.hpp" @@ -270,8 +268,8 @@ auto CElitePirate::GetDamageVulnerability() const -> const CDamageVulnerability* return &CDamageVulnerability::PassThroughVulnerabilty(); } -auto CElitePirate::GetDamageVulnerability(const zeus::CVector3f& /*pos*/, const zeus::CVector3f& /*dir*/, - const CDamageInfo& /*dInfo*/) const -> const CDamageVulnerability* { +auto CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const -> const CDamageVulnerability* { return &CDamageVulnerability::PassThroughVulnerabilty(); } @@ -290,7 +288,7 @@ auto CElitePirate::GetOrbitPosition(const CStateManager& mgr) const -> zeus::CVe return GetLctrTransform("lockon_target_LCTR").origin; } -auto CElitePirate::GetAimPosition(const CStateManager& mgr, float /*unused*/) const -> zeus::CVector3f { +auto CElitePirate::GetAimPosition(const CStateManager& mgr, float) const -> zeus::CVector3f { const std::shared_ptr& playerState = mgr.GetPlayerState(); if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { @@ -371,7 +369,7 @@ void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, con } } -void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float /*arg*/) {} +void CElitePirate::TakeDamage(const zeus::CVector3f& pos, float) {} void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { @@ -446,7 +444,7 @@ void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::Halt(CStateManager& /*mgr*/, EStateMsg msg, float /*unused*/) { +void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); x989_24_ = false; @@ -494,7 +492,7 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { } } -void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float /*unused*/) { +void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x568_ = EState::One; } else if (msg == EStateMsg::Update) { @@ -522,7 +520,7 @@ void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float /*unused*/) } } -void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float /*unused*/) { +void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); @@ -576,7 +574,7 @@ void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float /*unused*/) { void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); } -void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float /*unused*/) { +void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; } else if (msg == EStateMsg::Update) { @@ -601,7 +599,7 @@ void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float /*u void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } -void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float /*unused*/) { +void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; x988_30_ = true; @@ -676,7 +674,7 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { } } -bool CElitePirate::TooClose(CStateManager& mgr, float /*arg*/) { +bool CElitePirate::TooClose(CStateManager& mgr, float) { return x2fc_minAttackRange * x2fc_minAttackRange > (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared(); } @@ -688,20 +686,18 @@ bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg); } -bool CElitePirate::AnimOver(CStateManager& /*mgr*/, float /*arg*/) { return x568_ == EState::Over; } +bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_ == EState::Over; } -bool CElitePirate::ShouldAttack(CStateManager& mgr, float /*unused*/) { +bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { return false; } return !ShouldTurn(mgr, 0.f); } -bool CElitePirate::InPosition(CStateManager& /*mgr*/, float /*arg*/) { - return (x8b4_ - GetTranslation()).magSquared() < 25.f; -} +bool CElitePirate::InPosition(CStateManager& mgr, float) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } -bool CElitePirate::ShouldTurn(CStateManager& mgr, float /*unused*/) { +bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f); } @@ -717,15 +713,13 @@ bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { return false; } -bool CElitePirate::ShouldTaunt(CStateManager& /*mgr*/, float /*unused*/) { return x7bc_tauntTimer <= 0.f; } +bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTimer <= 0.f; } -bool CElitePirate::ShouldFire(CStateManager& mgr, float /*unused*/) { - return ShouldFireFromLauncher(mgr, x772_launcherId); -} +bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); } -bool CElitePirate::ShotAt(CStateManager& /*mgr*/, float /*unused*/) { return x988_27_; } +bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_; } -bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float /*unused*/) { +bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) { const zeus::CVector3f& dist = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); float magSquared = dist.magSquared(); @@ -737,7 +731,7 @@ bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float /*unused*/) { return false; } -bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float /*unused*/) { +bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) { return ShouldCallForBackupFromLauncher(mgr, x772_launcherId); } @@ -1099,7 +1093,7 @@ bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcher return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); } -bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& /*mgr*/, TUniqueId uid) { +bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.x11e_) { return x7a8_ >= 3.f; } diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 868773441..a934df0f8 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -37,7 +37,7 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C } } -auto CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) -> zeus::CVector3f { +zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) { const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 1.f); if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) { return aim - zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()}; @@ -121,7 +121,7 @@ void CGrenadeLauncher::AddToRenderer(const zeus::CFrustum& frustum, const CState CActor::AddToRenderer(frustum, mgr); } -auto CGrenadeLauncher::GetTouchBounds() const -> std::optional { +std::optional CGrenadeLauncher::GetTouchBounds() const { return x328_cSphere.CalculateAABox(GetTransform()); } diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index ed28d6824..5fd1913c7 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -84,12 +84,10 @@ public: void Accept(IVisitor& visitor) override { visitor.Visit(this); } void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - [[nodiscard]] auto GetCollisionPrimitive() const -> const CCollisionPrimitive* override { return &x328_cSphere; } - [[nodiscard]] auto GetDamageVulnerability() const -> const CDamageVulnerability* override { - return &x264_vulnerability; - } - [[nodiscard]] auto GetTouchBounds() const -> std::optional override; - auto HealthInfo(CStateManager & /*mgr*/) -> CHealthInfo* override { return &x25c_healthInfo; } + [[nodiscard]] const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; } + [[nodiscard]] const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; } + [[nodiscard]] std::optional GetTouchBounds() const override; + CHealthInfo* HealthInfo(CStateManager& mgr) override { return &x25c_healthInfo; } void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; void Render(const CStateManager& mgr) const override; void Think(float dt, CStateManager& mgr) override; From 684bbd5903834ad06f8bde00629239430bdda552 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 20:40:38 -0400 Subject: [PATCH 14/26] CElitePirate: Bug fixes, make member variables private, cleanup --- .clang-tidy | 2 +- Runtime/MP1/World/CBouncyGrenade.cpp | 27 ++++---- Runtime/MP1/World/CBouncyGrenade.hpp | 23 ++++++- Runtime/MP1/World/CElitePirate.cpp | 93 ++++++++++++-------------- Runtime/MP1/World/CElitePirate.hpp | 52 ++++++++++---- Runtime/MP1/World/CGrenadeLauncher.cpp | 40 +++++------ Runtime/MP1/World/CGrenadeLauncher.hpp | 43 ++++++++---- Runtime/World/CPatterned.hpp | 2 +- 8 files changed, 165 insertions(+), 117 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 915f3de09..a3c98d4fa 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1 +1 @@ -Checks: '*,-misc-unused-parameters,-modernize-use-trailing-return-type,-readability-named-parameter,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-fuchsia-*,-google-runtime-references' +Checks: '*,-misc-unused-parameters,-modernize-use-trailing-return-type,-readability-named-parameter,-readability-convert-member-functions-to-static,-readability-uppercase-literal-suffix,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-hicpp-signed-bitwise,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-non-private-member-variables-in-classes,-fuchsia-*,-google-runtime-references' diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index 1c227609e..04ce5b5e6 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -14,14 +14,14 @@ CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEnti TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, {}, - SMoverData(data.x0_.x0_mass), actParams, 0.3f, 0.1f) + SMoverData(data.GetUnkStruct().GetMass()), actParams, 0.3f, 0.1f) , x258_data(data) -, x294_numBounces(data.x34_numBounces) +, x294_numBounces(data.GetNumBounces()) , x298_parentId(parentId) -, x2a0_elementGen1(std::make_unique(g_SimplePool->GetObj({'PART', data.x24_elementGenId1}))) -, x2a4_elementGen2(std::make_unique(g_SimplePool->GetObj({'PART', data.x28_elementGenId2}))) -, x2a8_elementGen3(std::make_unique(g_SimplePool->GetObj({'PART', data.x2c_elementGenId3}))) -, x2ac_elementGen4(std::make_unique(g_SimplePool->GetObj({'PART', data.x30_elementGenId4}))) +, x2a0_elementGen1(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId1()}))) +, x2a4_elementGen2(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId2()}))) +, x2a8_elementGen3(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId3()}))) +, x2ac_elementGen4(std::make_unique(g_SimplePool->GetObj({'PART', data.GetElementGenId4()}))) , x2b0_explodePlayerDistance(explodePlayerDistance) , x2b4_24_exploded(false) , x2b4_25_(false) { @@ -81,10 +81,11 @@ void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, if (GetVelocity().dot(info.GetNormalLeft()) > 0.f) { normal = &info.GetNormalRight(); } - const zeus::CVector3f impulse = (x258_data.x0_.x4_ * GetConstantForce().magnitude()) * *normal; - const zeus::CVector3f angle = -x258_data.x0_.x4_ * GetAngularMomentum(); + const zeus::CVector3f impulse = + (x258_data.GetUnkStruct().GetSpeed() * GetConstantForce().magnitude()) * *normal; + const zeus::CVector3f angle = -x258_data.GetUnkStruct().GetSpeed() * GetAngularMomentum(); ApplyImpulseWR(impulse, angle); - CSfxManager::AddEmitter(x258_data.x38_bounceSfx, GetTranslation(), zeus::skUp, false, false, 0x7f, + CSfxManager::AddEmitter(x258_data.GetBounceSfx(), GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); x294_numBounces--; } @@ -95,9 +96,7 @@ void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, CPhysicsActor::CollidedWith(id, list, mgr); } -std::optional CBouncyGrenade::GetTouchBounds() const { - return GetModelData()->GetBounds(GetTransform()); -} +std::optional CBouncyGrenade::GetTouchBounds() const { return GetModelData()->GetBounds(GetTransform()); } void CBouncyGrenade::Render(const CStateManager& mgr) const { if (!x2b4_24_exploded) { @@ -153,14 +152,14 @@ void CBouncyGrenade::Explode(CStateManager& mgr, TUniqueId uid) { } x2b4_24_exploded = true; - CSfxManager::AddEmitter(x258_data.x3a_explodeSfx, GetTranslation(), zeus::skUp, false, false, 0x7f, + CSfxManager::AddEmitter(x258_data.GetExplodeSfx(), GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); x2a0_elementGen1->SetParticleEmission(true); x2a4_elementGen2->SetParticleEmission(true); x2a8_elementGen3->SetParticleEmission(true); x2ac_elementGen4->SetParticleEmission(false); - const CDamageInfo& dInfo = x258_data.x8_damageInfo; + const CDamageInfo& dInfo = x258_data.GetDamageInfo(); { bool isParent = x298_parentId == uid; if (TCastToConstPtr actor = mgr.GetObjectById(uid)) { diff --git a/Runtime/MP1/World/CBouncyGrenade.hpp b/Runtime/MP1/World/CBouncyGrenade.hpp index 5fac45c64..1ea0f9533 100644 --- a/Runtime/MP1/World/CBouncyGrenade.hpp +++ b/Runtime/MP1/World/CBouncyGrenade.hpp @@ -10,13 +10,19 @@ namespace urde::MP1 { struct SGrenadeUnknownStruct { +private: float x0_mass; - float x4_; // speed? + float x4_speed; // wrong name probably - SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_(in.readFloatBig()) {} +public: + explicit SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_speed(in.readFloatBig()) {} + + [[nodiscard]] float GetMass() const { return x0_mass; } + [[nodiscard]] float GetSpeed() const { return x4_speed; } }; struct SBouncyGrenadeData { +private: SGrenadeUnknownStruct x0_; CDamageInfo x8_damageInfo; CAssetId x24_elementGenId1; @@ -27,6 +33,7 @@ struct SBouncyGrenadeData { u16 x38_bounceSfx; u16 x3a_explodeSfx; +public: SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2, CAssetId w3, CAssetId w4, u32 w5, u16 s1, u16 s2) : x0_(unkStruct) @@ -38,6 +45,16 @@ struct SBouncyGrenadeData { , x34_numBounces(w5) , x38_bounceSfx(s1) , x3a_explodeSfx(s2){}; + + [[nodiscard]] const SGrenadeUnknownStruct& GetUnkStruct() const { return x0_; } + [[nodiscard]] const CDamageInfo& GetDamageInfo() const { return x8_damageInfo; } + [[nodiscard]] CAssetId GetElementGenId1() const { return x24_elementGenId1; } + [[nodiscard]] CAssetId GetElementGenId2() const { return x28_elementGenId2; } + [[nodiscard]] CAssetId GetElementGenId3() const { return x2c_elementGenId3; } + [[nodiscard]] CAssetId GetElementGenId4() const { return x30_elementGenId4; } + [[nodiscard]] u32 GetNumBounces() const { return x34_numBounces; } + [[nodiscard]] u16 GetBounceSfx() const { return x38_bounceSfx; } + [[nodiscard]] u16 GetExplodeSfx() const { return x3a_explodeSfx; } }; class CBouncyGrenade : public CPhysicsActor { @@ -61,7 +78,7 @@ public: void Accept(IVisitor& visitor) override { visitor.Visit(this); } void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - void CollidedWith(TUniqueId id, const CCollisionInfoList &list, CStateManager &mgr) override; + void CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr) override; [[nodiscard]] std::optional GetTouchBounds() const override; void Render(const CStateManager& mgr) const override; void Think(float dt, CStateManager& mgr) override; diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index be2b2f3ae..477eca7e1 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -45,9 +45,9 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount) , x4_tauntVariance(in.readFloatBig()) , x8_(in.readFloatBig()) , xc_(in.readFloatBig()) -, x10_(in.readFloatBig()) -, x14_(in.readFloatBig()) -, x18_(in.readFloatBig()) +, x10_attackChance(in.readFloatBig()) +, x14_shotAtTime(in.readFloatBig()) +, x18_shotAtTimeVariance(in.readFloatBig()) , x1c_(in.readFloatBig()) , x20_(in) , x24_sfxAbsorb(CSfxManager::TranslateSFXID(in.readUint32Big())) @@ -84,12 +84,13 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn , x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) , x738_(GetBoundingBox(), GetMaterialList()) +, x7a0_initialSpeed(x3b4_speed) , x7d0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) , x8c0_(5.f) , x988_24_(false) , x988_25_(false) , x988_26_(false) -, x988_27_(false) +, x988_27_shotAt(false) , x988_28_alert(false) , x988_29_(false) , x988_30_(false) @@ -117,10 +118,10 @@ void CElitePirate::Think(float dt, CStateManager& mgr) { x730_collisionActorMgr2->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); } x5d4_collisionActorMgr1->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); - if (sub_80229208() && x5d8_data.x11f_) { - x3b4_speed = 2.f * x7a0_; + if (sub_80229208() && x5d8_data.GetX11F()) { + x3b4_speed = 2.f * x7a0_initialSpeed; } else { - x3b4_speed = x7a0_; + x3b4_speed = x7a0_initialSpeed; } sub_80228e50(dt); sub_80228798(); @@ -163,14 +164,14 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta TCastToPtr actor = mgr.ObjectById(uid); if (!actor) { if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { - sub_8022759c(true, mgr); + SetShotAt(true, mgr); } break; } const TUniqueId& touchedUid = actor->GetLastTouchedObject(); if (touchedUid != GetUniqueId()) { if (TCastToPtr(mgr.ObjectById(touchedUid))) { - sub_8022759c(true, mgr); + SetShotAt(true, mgr); } break; } @@ -230,7 +231,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } else if (uid == x79c_ && x760_energyAbsorbDesc->IsLoaded()) { CreateEnergyAbsorb(mgr, projectile->GetTransform()); } - sub_8022759c(true, mgr); + SetShotAt(true, mgr); } } else if (uid == x772_launcherId && x772_launcherId != kInvalidUniqueId) { x450_bodyController->GetCommandMgr().DeliverCmd( @@ -240,7 +241,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } break; case EScriptObjectMessage::InvulnDamage: { - sub_8022759c(true, mgr); + SetShotAt(true, mgr); if (!TCastToPtr(mgr.ObjectById(uid))) { ApplyDamageToHead(mgr, uid); } @@ -389,7 +390,7 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { x6f8_boneTracking.SetActive(true); sub_80228634(mgr); CPatterned::PathFind(mgr, msg, dt); - x7bc_tauntTimer = x5d8_data.x4_tauntVariance * mgr.GetActiveRandom()->Float() + x5d8_data.x0_tauntInterval; + x7bc_tauntTimer = x5d8_data.GetTauntVariance() * mgr.GetActiveRandom()->Float() + x5d8_data.GetTauntInterval(); if (TooClose(mgr, 0.f)) { x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); } @@ -515,7 +516,7 @@ void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { x568_ = EState::Over; } } else if (msg == EStateMsg::Deactivate) { - sub_8022759c(false, mgr); + SetShotAt(false, mgr); sub_802289b0(mgr, true); } } @@ -603,7 +604,7 @@ void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x568_ = EState::Zero; x988_30_ = true; - sub_8022759c(false, mgr); + SetShotAt(false, mgr); } else if (msg == EStateMsg::Update) { if (x568_ == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { @@ -638,10 +639,10 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); } } else if (msg == EStateMsg::Update) { - if (x988_27_) { - x7c0_ -= dt; - if (x7c0_ <= 0.f) { - x988_27_ = false; + if (x988_27_shotAt) { + x7c0_shotAtTimer -= dt; + if (x7c0_shotAtTimer <= 0.f) { + x988_27_shotAt = false; } } x7a8_ = PathShagged(mgr, 0.f) ? x7a8_ + dt : 0.f; @@ -717,7 +718,7 @@ bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTim bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); } -bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_; } +bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_shotAt; } bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) { if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) { @@ -763,17 +764,18 @@ void CElitePirate::sub_80229248() { x7d0_pathFindSearch.SetCharacterHeight(3.f * scale); } -void CElitePirate::sub_8022759c(bool param_1, CStateManager& mgr) { - if (!sub_802273b0() || x7b4_hp <= 0.f || !param_1) { - x988_27_ = param_1; +// TODO rename +void CElitePirate::SetShotAt(bool val, CStateManager& mgr) { + if (!sub_802273b0() || x7b4_hp <= 0.f || !val) { + x988_27_shotAt = val; } else if (HealthInfo(mgr)->GetHP() / x7b4_hp <= x7b0_) { x7b0_ -= 0.2f; - x988_27_ = true; + x988_27_shotAt = true; } - if (x988_27_) { - x7c0_ = mgr.GetActiveRandom()->Float() * x5d8_data.x18_ + x5d8_data.x14_; + if (x988_27_shotAt) { + x7c0_shotAtTimer = mgr.GetActiveRandom()->Float() * x5d8_data.GetShotAtTimeVariance() + x5d8_data.GetShotAtTime(); } else { - x7c0_ = 0.f; + x7c0_shotAtTimer = 0.f; } } @@ -886,27 +888,16 @@ bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view loc } void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { - const CAnimationParameters& params = x5d8_data.x90_launcherAnimParams; + const CAnimationParameters& params = x5d8_data.GetLauncherAnimParams(); if (!params.GetACSFile().IsValid()) { return; } CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), params.GetInitialAnimation(), true)); - SBouncyGrenadeData grenadeData{x5d8_data.xd8_, - x5d8_data.xa8_, - x5d8_data.xc8_, - x5d8_data.xcc_, - x5d8_data.xd0_, - x5d8_data.xd4_, - x5d8_data.xf0_grenadeNumBounces, - x5d8_data.xf4_, - x5d8_data.xf6_}; - CGrenadeLauncherData launcherData{grenadeData, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, - x5d8_data.xe0_trajectoryInfo}; - mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, - GetTransform(), std::move(mData), mData.GetBounds(GetTransform().getRotation()), - CHealthInfo(x5d8_data.xc4_launcherHp, 10.f), x56c_vulnerability, - x5d8_data.x28_launcherActParams, GetUniqueId(), launcherData, 0.f)); + mgr.AddObject(new CGrenadeLauncher( + uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), std::move(mData), + mData.GetBounds(GetTransform().getRotation()), CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability, + x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f)); } void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) { @@ -928,7 +919,8 @@ void CElitePirate::CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform mgr.AddObject(new CExplosion(*x760_energyAbsorbDesc, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList}, "Absorb energy Fx", xf, 0, GetModelData()->GetScale(), zeus::skWhite)); - CSfxManager::AddEmitter(x5d8_data.x24_sfxAbsorb, GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); + CSfxManager::AddEmitter(x5d8_data.GetSFXAbsorb(), GetTranslation(), zeus::skUp, false, false, 0x7f, + GetAreaIdAlways()); x7ac_energyAbsorbCooldown = 0.25f; } @@ -937,7 +929,7 @@ void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { if (uid != kInvalidUniqueId) { if (TCastToPtr actor = mgr.ObjectById(uid)) { auto actHealth = actor->HealthInfo(mgr); - actHealth->SetHP(x5d8_data.xc4_launcherHp); + actHealth->SetHP(x5d8_data.GetLauncherHP()); actHealth->SetKnockbackResistance(health->GetKnockbackResistance()); actor->SetDamageVulnerability(x56c_vulnerability); } @@ -972,7 +964,7 @@ void CElitePirate::sub_80228634(CStateManager& mgr) { } void CElitePirate::sub_802285c4(CStateManager& mgr) { - if (mgr.GetActiveRandom()->Float() > x5d8_data.x10_) { + if (mgr.GetActiveRandom()->Float() > x5d8_data.GetAttackChance()) { x7b8_attackTimer = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; } } @@ -982,7 +974,7 @@ void CElitePirate::sub_80227a90(CStateManager& mgr) { } void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { - if (!x988_27_ || x450_bodyController->IsFrozen()) { + if (!x988_27_shotAt || x450_bodyController->IsFrozen()) { return; } x7c4_ += dt; @@ -1086,15 +1078,16 @@ bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcher return false; } const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr); - float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin; - float velocityOut = x5d8_data.xe0_trajectoryInfo.x0_; - CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut, velocityOut); + float angleOut = x5d8_data.GetGrenadeTrajectoryInfo().GetAngleMin(); + float velocityOut = x5d8_data.GetGrenadeTrajectoryInfo().GetVelocityMin(); + CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.GetGrenadeTrajectoryInfo(), angleOut, + velocityOut); const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)}); return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); } bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { - if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.x11e_) { + if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.GetX11E()) { return x7a8_ >= 3.f; } return false; diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index ae85a5a6e..811f15980 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -14,14 +14,14 @@ class CCollisionActorManager; class CGenDescription; namespace MP1 { class CElitePirateData { -public: +private: float x0_tauntInterval; float x4_tauntVariance; float x8_; float xc_; - float x10_; - float x14_; - float x18_; + float x10_attackChance; + float x14_shotAtTime; + float x18_shotAtTimeVariance; float x1c_; CAssetId x20_; u16 x24_sfxAbsorb; @@ -48,19 +48,43 @@ public: bool x11e_; bool x11f_; +public: CElitePirateData(CInputStream&, u32 propCount); - CAssetId GetX20() const { return x20_; } - CAssetId GetXF8() const { return xf8_; } - const CDamageInfo& GetXFC() const { return xfc_; } - CAssetId GetX118() const { return x118_; } - s16 GetX11C() const { return x11c_; } + [[nodiscard]] float GetTauntInterval() const { return x0_tauntInterval; } + [[nodiscard]] float GetTauntVariance() const { return x4_tauntVariance; } + [[nodiscard]] float GetAttackChance() const { return x10_attackChance; } + [[nodiscard]] float GetShotAtTime() const { return x14_shotAtTime; } + [[nodiscard]] float GetShotAtTimeVariance() const { return x18_shotAtTimeVariance; } + [[nodiscard]] CAssetId GetX20() const { return x20_; } + [[nodiscard]] u16 GetSFXAbsorb() const { return x24_sfxAbsorb; } + [[nodiscard]] const CActorParameters& GetLauncherActParams() const { return x28_launcherActParams; } + [[nodiscard]] const CAnimationParameters& GetLauncherAnimParams() const { return x90_launcherAnimParams; } + [[nodiscard]] float GetLauncherHP() const { return xc4_launcherHp; } + [[nodiscard]] const SGrenadeTrajectoryInfo& GetGrenadeTrajectoryInfo() const { return xe0_trajectoryInfo; } + [[nodiscard]] CAssetId GetXF8() const { return xf8_; } + [[nodiscard]] const CDamageInfo& GetXFC() const { return xfc_; } + [[nodiscard]] CAssetId GetX118() const { return x118_; } + [[nodiscard]] s16 GetX11C() const { return x11c_; } + [[nodiscard]] bool GetX11E() const { return x11e_; } + [[nodiscard]] bool GetX11F() const { return x11f_; } + + [[nodiscard]] SBouncyGrenadeData GetBouncyGrenadeData() const { + return {xd8_, xa8_, xc8_, xcc_, xd0_, xd4_, xf0_grenadeNumBounces, xf4_, xf6_}; + } + [[nodiscard]] SGrenadeLauncherData GetGrenadeLauncherData() const { + return {GetBouncyGrenadeData(), xa4_, x9c_, xa0_, xe0_trajectoryInfo}; + } }; class CElitePirate : public CPatterned { +private: struct SUnknownStruct { + private: float x0_; rstl::reserved_vector x4_; + + public: explicit SUnknownStruct(float f) : x0_(f * f) {} zeus::CVector3f GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2); void AddValue(const zeus::CVector3f& vec); @@ -81,7 +105,7 @@ class CElitePirate : public CPatterned { CElitePirateData x5d8_data; CBoneTracking x6f8_boneTracking; std::unique_ptr x730_collisionActorMgr2; - s32 x734_; + // s32 x734_; CCollidableAABox x738_; std::optional> x760_energyAbsorbDesc; TUniqueId x770_collisionHeadId = kInvalidUniqueId; @@ -89,7 +113,7 @@ class CElitePirate : public CPatterned { rstl::reserved_vector x774_collisionRJointIds; rstl::reserved_vector x788_collisionLJointIds; TUniqueId x79c_ = kInvalidUniqueId; - float x7a0_; + float x7a0_initialSpeed; float x7a4_ = 1.f; float x7a8_ = 0.f; float x7ac_energyAbsorbCooldown = 0.f; @@ -97,7 +121,7 @@ class CElitePirate : public CPatterned { float x7b4_hp = 0.f; float x7b8_attackTimer = 0.f; float x7bc_tauntTimer = 0.f; - float x7c0_ = 0.f; + float x7c0_shotAtTimer = 0.f; float x7c4_ = 0.f; s32 x7c8_currAnimId = -1; s32 x7cc_ = 0; @@ -107,7 +131,7 @@ class CElitePirate : public CPatterned { bool x988_24_ : 1; bool x988_25_ : 1; bool x988_26_ : 1; - bool x988_27_ : 1; + bool x988_27_shotAt : 1; bool x988_28_alert : 1; bool x988_29_ : 1; bool x988_30_ : 1; @@ -171,7 +195,7 @@ public: private: void sub_80229248(); - void sub_8022759c(bool param_1, CStateManager& mgr); + void SetShotAt(bool val, CStateManager& mgr); bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const; void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, std::vector& outJoints) const; diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index a934df0f8..65463bce0 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -15,7 +15,7 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId parentId, - const CGrenadeLauncherData& data, float f1) + const SGrenadeLauncherData& data, float f1) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Character, EMaterialTypes::Solid}, bounds, {1000.f}, actParams, 0.3f, 0.1f) , x25c_healthInfo(healthInfo) @@ -26,8 +26,8 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C , x350_grenadeActorParams(actParams) , x3e8_thermalMag(actParams.GetThermalMag()) , x3f8_explodePlayerDistance(f1) { - if (data.x40_.IsValid()) { - x3b8_particleGenDesc = g_SimplePool->GetObj({SBIG('PART'), data.x40_}); + if (data.GetExplosionGenDescId().IsValid()) { + x3b8_particleGenDesc = g_SimplePool->GetObj({SBIG('PART'), data.GetExplosionGenDescId()}); } GetModelData()->EnableLooping(true); const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); @@ -48,31 +48,31 @@ zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) { void CGrenadeLauncher::CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, const SGrenadeTrajectoryInfo& info, float& angleOut, float& velocityOut) { - float angle = info.x8_angleMin; - float velocity = info.x0_; - float delta = std::max(0.01f, 0.1f * (info.xc_angleMax - info.x8_angleMin)); + float angle = info.GetAngleMin(); + float velocity = info.GetVelocityMin(); + float delta = std::max(0.01f, 0.1f * (info.GetAngleMax() - info.GetAngleMin())); zeus::CVector3f dist = target - origin; float distXYMag = dist.toVec2f().magnitude(); - float qwSq = info.x0_ * info.x0_; - float qxSq = info.x4_ * info.x4_; + float velocityMinSq = info.GetVelocityMin() * info.GetVelocityMin(); + float velocityMaxSq = info.GetVelocityMax() * info.GetVelocityMax(); float gravAdj = distXYMag * ((0.5f * CPhysicsActor::GravityConstant()) * distXYMag); - float currAngle = info.x8_angleMin; + float currAngle = info.GetAngleMin(); float leastResult = FLT_MAX; - while (info.xc_angleMax >= currAngle) { + while (info.GetAngleMax() >= currAngle) { float cos = std::cos(currAngle); float sin = std::sin(currAngle); float result = (distXYMag * (cos * sin) - (dist.z() * (cos * cos))); if (result > FLT_EPSILON) { float div = gravAdj / result; - if (qwSq <= result && result <= qxSq) { + if (velocityMinSq <= result && result <= velocityMaxSq) { angle = currAngle; velocity = std::sqrt(div); break; } - if (result <= qxSq) { - result = qwSq - result; + if (result <= velocityMaxSq) { + result = velocityMinSq - result; } else { - result = result - qxSq; + result = result - velocityMaxSq; } if (result < leastResult) { angle = currAngle; @@ -206,7 +206,7 @@ void CGrenadeLauncher::CreateExplosion(CStateManager& mgr) { mgr.AddObject(new CExplosion(*x3b8_particleGenDesc, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList}, "Grenade Launcher Explode Fx"sv, GetTransform(), 0, GetModelData()->GetScale(), zeus::skWhite)); - CSfxManager::SfxStart(x2d0_data.x44_launcherExplodeSfx, 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); + CSfxManager::SfxStart(x2d0_data.GetExplosionSfx(), 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); } void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { @@ -302,9 +302,9 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { const zeus::CVector3f& origin = GetTranslation() + GetTransform().rotate(GetLocatorTransform("grenade_LCTR"sv).origin); const zeus::CVector3f& target = GrenadeTarget(mgr); - float angleOut = x2d0_data.x48_trajectoryInfo.x8_angleMin; - float velocityOut = x2d0_data.x48_trajectoryInfo.x0_; - CalculateGrenadeTrajectory(target, origin, x2d0_data.x48_trajectoryInfo, angleOut, velocityOut); + float angleOut = x2d0_data.GetGrenadeTrajectoryInfo().GetAngleMin(); + float velocityOut = x2d0_data.GetGrenadeTrajectoryInfo().GetVelocityMin(); + CalculateGrenadeTrajectory(target, origin, x2d0_data.GetGrenadeTrajectoryInfo(), angleOut, velocityOut); zeus::CVector3f dist = target - origin; dist.z() = 0.f; @@ -322,10 +322,10 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { const zeus::CVector3f& look = zeus::CVector3f::slerp(dist, zeus::skUp, angleOut); const zeus::CTransform& xf = zeus::lookAt(origin, origin + look, zeus::skUp); - CModelData mData{CStaticRes{x2d0_data.x3c_grenadeCmdl, GetModelData()->GetScale()}}; + CModelData mData{CStaticRes{x2d0_data.GetGrenadeModelId(), GetModelData()->GetScale()}}; mgr.AddObject(new CBouncyGrenade(mgr.AllocateUniqueId(), "Bouncy Grenade"sv, {GetAreaIdAlways(), CEntity::NullConnectionList}, xf, std::move(mData), - x350_grenadeActorParams, x2cc_parentId, x2d0_data.x0_grenadeData, velocityOut, + x350_grenadeActorParams, x2cc_parentId, x2d0_data.GetGrenadeData(), velocityOut, x3f8_explodePlayerDistance)); } } diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index 5fd1913c7..cb07cf1e5 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -21,48 +21,62 @@ namespace urde::MP1 { struct SGrenadeTrajectoryInfo { - float x0_; - float x4_; +private: + float x0_velocityMin; + float x4_velocityMax; float x8_angleMin; float xc_angleMax; +public: explicit SGrenadeTrajectoryInfo(CInputStream& in) - : x0_(in.readFloatBig()) - , x4_(in.readFloatBig()) + : x0_velocityMin(in.readFloatBig()) + , x4_velocityMax(in.readFloatBig()) , x8_angleMin(zeus::degToRad(in.readFloatBig())) , xc_angleMax(zeus::degToRad(in.readFloatBig())) {} + + [[nodiscard]] float GetVelocityMin() const { return x0_velocityMin; } + [[nodiscard]] float GetVelocityMax() const { return x4_velocityMax; } + [[nodiscard]] float GetAngleMin() const { return x8_angleMin; } + [[nodiscard]] float GetAngleMax() const { return xc_angleMax; } }; -class CGrenadeLauncherData { -public: +struct SGrenadeLauncherData { +private: SBouncyGrenadeData x0_grenadeData; CAssetId x3c_grenadeCmdl; - CAssetId x40_; + CAssetId x40_launcherExplodeGenDesc; u16 x44_launcherExplodeSfx; SGrenadeTrajectoryInfo x48_trajectoryInfo; - CGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, +public: + SGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx, const SGrenadeTrajectoryInfo& trajectoryInfo) : x0_grenadeData(data) , x3c_grenadeCmdl(w1) - , x40_(w2) + , x40_launcherExplodeGenDesc(w2) , x44_launcherExplodeSfx(sfx) , x48_trajectoryInfo(trajectoryInfo){}; + + [[nodiscard]] const SBouncyGrenadeData& GetGrenadeData() const { return x0_grenadeData; } + [[nodiscard]] CAssetId GetGrenadeModelId() const { return x3c_grenadeCmdl; } + [[nodiscard]] CAssetId GetExplosionGenDescId() const { return x40_launcherExplodeGenDesc; } + [[nodiscard]] u16 GetExplosionSfx() const { return x44_launcherExplodeSfx; } + [[nodiscard]] const SGrenadeTrajectoryInfo& GetGrenadeTrajectoryInfo() const { return x48_trajectoryInfo; } }; class CGrenadeLauncher : public CPhysicsActor { -public: +private: int x258_started = 0; CHealthInfo x25c_healthInfo; CDamageVulnerability x264_vulnerability; TUniqueId x2cc_parentId; - CGrenadeLauncherData x2d0_data; + SGrenadeLauncherData x2d0_data; CCollidableSphere x328_cSphere; float x348_shotTimer = -1.f; zeus::CColor x34c_color1{1.f}; CActorParameters x350_grenadeActorParams; std::optional> x3b8_particleGenDesc; - std::array x3c8_animIds; + std::array x3c8_animIds{}; float x3d8_ = 0.f; float x3dc_ = 0.f; float x3e0_ = 0.f; @@ -76,10 +90,11 @@ public: bool x3fd_visible = true; bool x3fe_ = true; +public: CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& bounds, const CHealthInfo& healthInfo, const CDamageVulnerability& vulnerability, const CActorParameters& actParams, TUniqueId parentId, - const CGrenadeLauncherData& data, float f1); + const SGrenadeLauncherData& data, float f1); void Accept(IVisitor& visitor) override { visitor.Visit(this); } void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; @@ -97,7 +112,7 @@ public: static void CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin, const SGrenadeTrajectoryInfo& info, float& angleOut, float& velocityOut); -protected: +private: void UpdateCollision(); void UpdateColor(float arg); void sub_8022f69c(float arg); diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index 840ed78c8..2d6ad2859 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -26,7 +26,7 @@ namespace urde { class CPatternedInfo; class CProjectileInfo; class CPathFindSearch; -typedef void (CPatterned::*CPatternedTryFunc)(CStateManager&, int); +using CPatternedTryFunc = void (CPatterned::*)(CStateManager&, int); class CPatterned : public CAi { public: From 2e3d1c980b2646c1c6ed3c73492881c6e32b13a6 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 23:10:51 -0400 Subject: [PATCH 15/26] CElitePirate: Implement AttractProjectiles; fix CGameProjectile material list --- Runtime/MP1/World/CElitePirate.cpp | 149 +++++++++++++++++++++-------- Runtime/MP1/World/CElitePirate.hpp | 17 ++-- Runtime/Weapon/CGameProjectile.cpp | 3 +- Runtime/World/CPatterned.hpp | 3 +- 4 files changed, 123 insertions(+), 49 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 477eca7e1..6a9232867 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -118,16 +118,16 @@ void CElitePirate::Think(float dt, CStateManager& mgr) { x730_collisionActorMgr2->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); } x5d4_collisionActorMgr1->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); - if (sub_80229208() && x5d8_data.GetX11F()) { + if (IsAttractingEnergy() && x5d8_data.GetX11F()) { x3b4_speed = 2.f * x7a0_initialSpeed; } else { x3b4_speed = x7a0_initialSpeed; } - sub_80228e50(dt); + UpdateTimers(dt); sub_80228798(); - sub_802289dc(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv); + UpdateActorTransform(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv); sub_80228e84(mgr); - x328_31_ = sub_80229208(); + x328_31_energyAttractor = IsAttractingEnergy(); } } @@ -265,16 +265,16 @@ void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_ ? numMaterialSets - 1 : x7cc_; } -auto CElitePirate::GetDamageVulnerability() const -> const CDamageVulnerability* { +const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { return &CDamageVulnerability::PassThroughVulnerabilty(); } -auto CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, - const CDamageInfo& dInfo) const -> const CDamageVulnerability* { +const CDamageVulnerability* CElitePirate::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CDamageInfo& dInfo) const { return &CDamageVulnerability::PassThroughVulnerabilty(); } -auto CElitePirate::GetOrbitPosition(const CStateManager& mgr) const -> zeus::CVector3f { +zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { if (x772_launcherId != kInvalidUniqueId && mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { if (const auto* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { @@ -289,7 +289,7 @@ auto CElitePirate::GetOrbitPosition(const CStateManager& mgr) const -> zeus::CVe return GetLctrTransform("lockon_target_LCTR").origin; } -auto CElitePirate::GetAimPosition(const CStateManager& mgr, float) const -> zeus::CVector3f { +zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const { const std::shared_ptr& playerState = mgr.GetPlayerState(); if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { @@ -357,7 +357,7 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node } } -auto CElitePirate::GetCollisionPrimitive() const -> const CCollisionPrimitive* { return &x738_; } +const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { @@ -400,19 +400,17 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { } if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { CPatterned::PathFind(mgr, msg, dt); - } else { - if (PathShagged(mgr, 0.f)) { - const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); - if (move != zeus::skZero3f) { - x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); - } - } else if (ShouldTurn(mgr, 0.f)) { - const zeus::CVector3f& aim = - mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); - const zeus::CVector3f& face = aim - GetTranslation(); - if (face.canBeNormalized()) { - x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); - } + } else if (PathShagged(mgr, 0.f)) { + const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector()); + if (move != zeus::skZero3f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); + } + } else if (ShouldTurn(mgr, 0.f)) { + const zeus::CVector3f& aim = + mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale()); + const zeus::CVector3f& face = aim - GetTranslation(); + if (face.canBeNormalized()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } } else if (msg == EStateMsg::Deactivate) { @@ -661,7 +659,7 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } - sub_80227a90(mgr); + AttractProjectiles(mgr); sub_802277e0(mgr, dt); } else if (msg == EStateMsg::Deactivate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); @@ -736,7 +734,7 @@ bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) { return ShouldCallForBackupFromLauncher(mgr, x772_launcherId); } -auto CElitePirate::GetSearchPath() -> CPathFindSearch* { return &x7d0_pathFindSearch; } +CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; } void CElitePirate::SetupHealthInfo(CStateManager& mgr) { const CHealthInfo* const health = HealthInfo(mgr); @@ -764,7 +762,7 @@ void CElitePirate::sub_80229248() { x7d0_pathFindSearch.SetCharacterHeight(3.f * scale); } -// TODO rename +// TODO rename? void CElitePirate::SetShotAt(bool val, CStateManager& mgr) { if (!sub_802273b0() || x7b4_hp <= 0.f || !val) { x988_27_shotAt = val; @@ -956,9 +954,10 @@ bool CElitePirate::sub_80227430(const CDamageInfo& info) const { void CElitePirate::sub_80228634(CStateManager& mgr) { x8b4_ = GetTranslation(); - const zeus::CVector3f& dist = GetTranslation() - mgr.GetPlayer().GetTranslation(); + const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); + const zeus::CVector3f& dist = GetTranslation() - playerPos; if (dist.canBeNormalized() && dist.magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { - x2e0_destPos = GetTranslation() + (x2fc_minAttackRange * dist.normalized()); + x2e0_destPos = playerPos + (x2fc_minAttackRange * dist.normalized()); x8b4_ = x2e0_destPos; } } @@ -969,8 +968,63 @@ void CElitePirate::sub_802285c4(CStateManager& mgr) { } } -void CElitePirate::sub_80227a90(CStateManager& mgr) { - // TODO +void CElitePirate::AttractProjectiles(CStateManager& mgr) { + if (!IsAlive()) { + return; + } + TCastToConstPtr actor = mgr.GetObjectById(x79c_); + if (!actor) { + return; + } + + float radius = x5d8_data.GetX1C(); + const zeus::CVector3f& actorPos = actor->GetTranslation(); + const zeus::CVector3f& pos = GetTranslation(); + rstl::reserved_vector projNearList; + zeus::CAABox aabb{pos - radius, pos + radius}; + mgr.BuildNearList(projNearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Projectile}), nullptr); + if (projNearList.empty()) { + return; + } + + rstl::reserved_vector charNearList; + mgr.BuildNearList(charNearList, aabb, CMaterialFilter::MakeInclude({EMaterialTypes::Character}), nullptr); + for (const TUniqueId projId : projNearList) { + TCastToPtr projectile = mgr.ObjectById(projId); + if (!projectile || projectile->GetType() == EWeaponType::Missile || + projectile->GetOwnerId() != mgr.GetPlayer().GetUniqueId() || + projectile->GetAreaIdAlways() != GetAreaIdAlways()) { + continue; + } + + const zeus::CVector3f& projectilePos = projectile->GetTranslation(); + const zeus::CVector3f actorProjDist = actorPos - projectilePos; + if (GetTransform().frontVector().dot(actorProjDist) < 0.f) { + const zeus::CVector3f projectileDir = projectilePos - projectile->GetPreviousPos(); + if (projectileDir.canBeNormalized() && IsClosestEnergyAttractor(mgr, charNearList, projectilePos)) { + float actorProjMag = actorProjDist.magnitude(); + const zeus::CVector3f b = projectilePos + ((0.5f * actorProjMag) * projectileDir.normalized()); + const zeus::CVector3f c = actorPos + zeus::CVector3f{0.f, 0.f, 0.4f * 0.4f * actorProjMag}; + const zeus::CVector3f p1 = zeus::getBezierPoint(projectilePos, b, c, actorPos, 0.333f); + const zeus::CVector3f p2 = zeus::getBezierPoint(projectilePos, b, c, actorPos, 0.666f); + + float magAdd = (p2 - p1).magnitude() + (p1 - projectilePos).magnitude() + (actorPos - p2).magnitude(); + const zeus::CVector3f p3 = + zeus::getBezierPoint(projectilePos, b, c, actorPos, projectileDir.magnitude() / magAdd); + + const zeus::CVector3f look = p3 - projectilePos; + if (look.canBeNormalized()) { + zeus::CTransform xf = zeus::lookAt(zeus::skZero3f, look); + xf.orthonormalize(); + CProjectileWeapon& weapon = projectile->ProjectileWeapon(); + weapon.SetWorldSpaceOrientation(xf); + const zeus::CVector3f scaledVelocity = 0.8f * weapon.GetVelocity().normalized(); + weapon.SetVelocity(weapon.GetVelocity() * 0.39999998f + (scaledVelocity * 0.6f)); + } + } + } + SetShotAt(true, mgr); + } } void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { @@ -1000,15 +1054,15 @@ void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { x7c4_ = 0.f; } -bool CElitePirate::sub_80229208() { - if (x450_bodyController->GetLocomotionType() != pas::ELocomotionType::Crouch) { - return false; +bool CElitePirate::IsAttractingEnergy() { + if (x450_bodyController->GetLocomotionType() == pas::ELocomotionType::Crouch) { + const auto state = x450_bodyController->GetCurrentStateId(); + return state == pas::EAnimationState::Locomotion || state == pas::EAnimationState::Turn; } - const pas::EAnimationState state = x450_bodyController->GetCurrentStateId(); - return state == pas::EAnimationState::Locomotion || state == pas::EAnimationState::Turn; + return false; } -void CElitePirate::sub_80228e50(float dt) { +void CElitePirate::UpdateTimers(float dt) { if (x7b8_attackTimer > 0.f) { x7b8_attackTimer -= dt; } @@ -1025,7 +1079,7 @@ void CElitePirate::sub_80228798() { x8c0_.AddValue(pos); } -void CElitePirate::sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name) { +void CElitePirate::UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std::string_view name) { if (uid == kInvalidUniqueId) { return; } @@ -1052,8 +1106,8 @@ void CElitePirate::sub_80228e84(CStateManager& mgr) { } } -void CElitePirate::ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector& uids, - const zeus::CVector3f& vec) { +void CElitePirate::ExtendTouchBounds(const CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec) const { for (const TUniqueId uid : uids) { if (TCastToPtr actor = mgr.ObjectById(uid)) { actor->SetExtendedTouchBounds(vec); @@ -1086,13 +1140,28 @@ bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcher return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot)); } -bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) { +bool CElitePirate::ShouldCallForBackupFromLauncher(const CStateManager& mgr, TUniqueId uid) const { if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.GetX11E()) { return x7a8_ >= 3.f; } return false; } +bool CElitePirate::IsClosestEnergyAttractor(const CStateManager& mgr, + const rstl::reserved_vector& charNearList, + const zeus::CVector3f& projectilePos) const { + float distance = (projectilePos - GetTranslation()).magSquared(); + for (const auto id : charNearList) { + if (TCastToConstPtr actor = mgr.GetObjectById(id)) { + if (actor->GetUniqueId() != GetUniqueId() && actor->IsEnergyAttractor() && + (projectilePos - actor->GetTranslation()).magSquared() < distance) { + return false; + } + } + } + return true; +} + zeus::CVector3f CElitePirate::SUnknownStruct::GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2) { while (!x4_.empty()) { const zeus::CVector3f v = x4_[x4_.size() - 1] - v1; diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 811f15980..6033df77b 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -56,6 +56,7 @@ public: [[nodiscard]] float GetAttackChance() const { return x10_attackChance; } [[nodiscard]] float GetShotAtTime() const { return x14_shotAtTime; } [[nodiscard]] float GetShotAtTimeVariance() const { return x18_shotAtTimeVariance; } + [[nodiscard]] float GetX1C() const { return x1c_; } [[nodiscard]] CAssetId GetX20() const { return x20_; } [[nodiscard]] u16 GetSFXAbsorb() const { return x24_sfxAbsorb; } [[nodiscard]] const CActorParameters& GetLauncherActParams() const { return x28_launcherActParams; } @@ -213,17 +214,19 @@ private: bool sub_80227430(const CDamageInfo& info) const; void sub_80228634(CStateManager& mgr); void sub_802285c4(CStateManager& mgr); - void sub_80227a90(CStateManager& mgr); + void AttractProjectiles(CStateManager& mgr); void sub_802277e0(CStateManager& mgr, float dt); - bool sub_80229208(); - void sub_80228e50(float dt); + bool IsAttractingEnergy(); + void UpdateTimers(float dt); void sub_80228798(); - void sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name); + void UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std::string_view name); void sub_80228e84(CStateManager& mgr); - void ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector& uids, - const zeus::CVector3f& vec); + void ExtendTouchBounds(const CStateManager& mgr, const rstl::reserved_vector& uids, + const zeus::CVector3f& vec) const; bool ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId); - bool ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid); + bool ShouldCallForBackupFromLauncher(const CStateManager& mgr, TUniqueId uid) const; + bool IsClosestEnergyAttractor(const CStateManager& mgr, const rstl::reserved_vector& charNearList, + const zeus::CVector3f& projectilePos) const; }; } // namespace MP1 } // namespace urde diff --git a/Runtime/Weapon/CGameProjectile.cpp b/Runtime/Weapon/CGameProjectile.cpp index 62a8affdd..851054cef 100644 --- a/Runtime/Weapon/CGameProjectile.cpp +++ b/Runtime/Weapon/CGameProjectile.cpp @@ -25,7 +25,8 @@ CGameProjectile::CGameProjectile(bool active, const TToken& CMaterialFilter::MakeIncludeExclude( {EMaterialTypes::Solid, EMaterialTypes::NonSolidDamageable}, {EMaterialTypes::Projectile, EMaterialTypes::ProjectilePassthrough, excludeMat}), - CMaterialList(), dInfo, attribs | GetBeamAttribType(wType), CModelData::CModelDataNull()) + CMaterialList(EMaterialTypes::Projectile), dInfo, attribs | GetBeamAttribType(wType), + CModelData::CModelDataNull()) , x158_visorParticle(visorParticle) , x168_visorSfx(visorSfx) , x170_projectile(wDesc, xf.origin, xf.basis, scale, diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index 2d6ad2859..5ad14341d 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -133,7 +133,7 @@ protected: bool x328_28_prevOnGround : 1; bool x328_29_noPatternShagging : 1; bool x328_30_lookAtDeathDir : 1; - bool x328_31_ : 1; + bool x328_31_energyAttractor : 1; bool x329_24_ : 1; }; u32 _dummy = 0; @@ -366,6 +366,7 @@ public: } float GetDamageDuration() const { return x504_damageDur; } zeus::CVector3f GetGunEyePos() const; + bool IsEnergyAttractor() const { return x328_31_energyAttractor; } bool IsAlive() const { return x400_25_alive; } void BuildBodyController(EBodyType); From 782a13c0a4f8af80be832aedcc22fa172ba6d22d Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 23:31:46 -0400 Subject: [PATCH 16/26] CGrenadeLauncher: Fix CModelFlags assignment --- Runtime/MP1/World/CGrenadeLauncher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 65463bce0..1d16203bd 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -127,9 +127,9 @@ std::optional CGrenadeLauncher::GetTouchBounds() const { void CGrenadeLauncher::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { if (x3f4_color3.a() == 1.f) { - xb4_drawFlags = {2, 0, 3, {x3f4_color3, 1.f}}; + xb4_drawFlags = CModelFlags{2, 0, 3, zeus::CColor{x3f4_color3, 1.f}}; } else { - xb4_drawFlags = {5, 0, 3, x3f4_color3}; + xb4_drawFlags = CModelFlags{5, 0, 3, x3f4_color3}; } CActor::PreRender(mgr, frustum); } From f0927d937aabbc5abe03fdfe2284f143a87a1a31 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 30 Mar 2020 23:39:41 -0400 Subject: [PATCH 17/26] CGrenadeLauncher: Remove redundant CColor --- Runtime/MP1/World/CGrenadeLauncher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 1d16203bd..7273c84a9 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -127,7 +127,8 @@ std::optional CGrenadeLauncher::GetTouchBounds() const { void CGrenadeLauncher::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { if (x3f4_color3.a() == 1.f) { - xb4_drawFlags = CModelFlags{2, 0, 3, zeus::CColor{x3f4_color3, 1.f}}; + // Original code redundantly sets a() = 1.f + xb4_drawFlags = CModelFlags{2, 0, 3, x3f4_color3}; } else { xb4_drawFlags = CModelFlags{5, 0, 3, x3f4_color3}; } From b43d4eaddc0f75a513a420cc166f7f5bf1aa58ed Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 31 Mar 2020 03:29:00 -0400 Subject: [PATCH 18/26] CElitePirate: Implement SpecialAttack, CShockWave --- Runtime/MP1/World/CElitePirate.cpp | 25 ++++++++++- Runtime/MP1/World/CShockWave.cpp | 70 ++++++++++++++++++++++++++---- Runtime/MP1/World/CShockWave.hpp | 13 +++--- 3 files changed, 91 insertions(+), 17 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 6a9232867..431592b8b 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -596,7 +596,30 @@ void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { } } -void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } +void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_ = EState::Zero; + } else if (msg == EStateMsg::Update) { + if (x568_ == EState::Zero) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x568_ = EState::Two; + x988_29_ = true; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCProjectileAttackCmd(pas::ESeverity::Two, mgr.GetPlayer().GetTranslation(), false)); + } + } else if (x568_ == EState::Two) { + if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { + x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation()); + } else { + x568_ = EState::Over; + } + } + } else if (msg == EStateMsg::Deactivate) { + sub_802285c4(mgr); + x988_29_ = false; + } +} void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp index 4d55b753f..96e040da5 100644 --- a/Runtime/MP1/World/CShockWave.cpp +++ b/Runtime/MP1/World/CShockWave.cpp @@ -1,15 +1,16 @@ #include "Runtime/MP1/World/CShockWave.hpp" +#include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CBooRenderer.hpp" #include "Runtime/World/CActorParameters.hpp" +#include "Runtime/World/CGameLight.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path -namespace urde { -namespace MP1 { +namespace urde::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}, @@ -35,8 +36,19 @@ CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& void CShockWave::Accept(IVisitor& visitor) { visitor.Visit(this); } void CShockWave::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { - // TODO + if (msg == EScriptObjectMessage::Registered) { + if (x110_elementGen->SystemHasLight()) { + x980_id2 = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(x980_id2, GetAreaIdAlways(), GetActive(), "ShockWaveLight_" + x10_name, + GetTransform(), GetUniqueId(), x110_elementGen->GetLight(), + x114_data.x4_particleDesc.Value(), 1, 0.f)); + } + } else if (msg == EScriptObjectMessage::Deleted) { + mgr.FreeScriptObject(x980_id2); + x980_id2 = kInvalidUniqueId; + } CActor::AcceptScriptMsg(msg, uid, mgr); + mgr.SendScriptMsgAlways(x980_id2, uid, msg); } void CShockWave::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { @@ -45,8 +57,10 @@ void CShockWave::AddToRenderer(const zeus::CFrustum& frustum, const CStateManage } std::optional CShockWave::GetTouchBounds() const { - // TODO - return CActor::GetTouchBounds(); + if (x150_ <= 0.f) { + return std::nullopt; + } + return zeus::CAABox({-x150_, -x150_, 0.f}, {x150_, x150_, 1.f}).getTransformedAABox(GetTransform()); } void CShockWave::Render(const CStateManager& mgr) const { @@ -55,11 +69,49 @@ void CShockWave::Render(const CStateManager& mgr) const { } void CShockWave::Think(float dt, CStateManager& mgr) { - // TODO + if (GetActive()) { + x110_elementGen->Update(dt); + x158_ += dt; + x150_ += x154_ * dt; + x154_ += dt * x114_data.x30_; + x110_elementGen->SetExternalVar(0, x150_); + for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); i++) { + auto& particle = static_cast(x110_elementGen->GetActiveChildParticle(i)); + if (particle.Get4CharId() == SBIG('PART')) { + particle.SetExternalVar(0, x150_); + } + } + if (x16c_) { + x164_ += dt; + x16c_ = false; + } + if (x16d_) { + x168_ += dt; + x16d_ = false; + } + } + if (x110_elementGen->IsSystemDeletable() && x15c_ > 0.f && x158_ >= x15c_) { + mgr.FreeScriptObject(GetUniqueId()); + } else if (x980_id2 != kInvalidUniqueId) { + if (TCastToPtr light = mgr.ObjectById(x980_id2)) { + if (light->GetActive()) { + light->SetLight(x110_elementGen->GetLight()); + } + } + } } void CShockWave::Touch(CActor& actor, CStateManager& mgr) { - // TODO + if (x158_ >= x15c_) { + return; + } + + bool isParent = xe8_id1 == actor.GetUniqueId(); + if (TCastToConstPtr cactor = mgr.GetObjectById(actor.GetUniqueId())) { + isParent = xe8_id1 == cactor->GetOwnerId(); + } + if (!isParent) { + // TODO + } } -} // namespace MP1 -} // namespace urde +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CShockWave.hpp b/Runtime/MP1/World/CShockWave.hpp index 19e3e479a..f5a8d2336 100644 --- a/Runtime/MP1/World/CShockWave.hpp +++ b/Runtime/MP1/World/CShockWave.hpp @@ -4,8 +4,7 @@ #include "Runtime/World/CDamageInfo.hpp" #include "Runtime/Particle/CElementGen.hpp" -namespace urde { -namespace MP1 { +namespace urde::MP1 { struct SShockWaveData { u32 x0_ = 8; CAssetId x4_particleDesc; @@ -22,7 +21,7 @@ struct SShockWaveData { }; class CShockWave : public CActor { -public: +private: TUniqueId xe8_id1; CDamageInfo xec_damageInfo; TToken x108_elementGenDesc; @@ -35,22 +34,22 @@ public: float x160_; float x164_ = 0.f; float x168_ = 0.f; - char x16c_flags1; - char x16d_flags2; + bool x16c_ = false; + bool x16d_ = false; // x368 => very large reserved_vector of ? std::optional> x974_electricDesc; TUniqueId x980_id2 = kInvalidUniqueId; +public: 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; + [[nodiscard]] 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 From ffd94d11061e9d87a7bd13079a45878a760c6649 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 31 Mar 2020 14:17:47 -0400 Subject: [PATCH 19/26] COmegaPirate: Stub --- Runtime/MP1/World/CElitePirate.hpp | 7 ++----- Runtime/MP1/World/CMakeLists.txt | 1 + Runtime/MP1/World/COmegaPirate.cpp | 12 ++++++++++++ Runtime/MP1/World/COmegaPirate.hpp | 24 +++++++++++++++++++++++ Runtime/World/ScriptLoader.cpp | 31 +++++++++++++++++++++++++++++- 5 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 Runtime/MP1/World/COmegaPirate.cpp create mode 100644 Runtime/MP1/World/COmegaPirate.hpp diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 6033df77b..09db287af 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -1,6 +1,7 @@ #pragma once #include "Runtime/Character/CBoneTracking.hpp" +#include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/Collision/CJointCollisionDescription.hpp" #include "Runtime/MP1/World/CGrenadeLauncher.hpp" #include "Runtime/MP1/World/CShockWave.hpp" @@ -9,10 +10,7 @@ #include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CPatterned.hpp" -namespace urde { -class CCollisionActorManager; -class CGenDescription; -namespace MP1 { +namespace urde::MP1 { class CElitePirateData { private: float x0_tauntInterval; @@ -228,5 +226,4 @@ private: bool IsClosestEnergyAttractor(const CStateManager& mgr, const rstl::reserved_vector& charNearList, const zeus::CVector3f& projectilePos) const; }; -} // namespace MP1 } // namespace urde diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 782deee69..e0c88ce2e 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -27,6 +27,7 @@ set(MP1_WORLD_SOURCES CMetroidPrimeProjectile.hpp CMetroidPrimeProjectile.cpp CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp CNewIntroBoss.hpp CNewIntroBoss.cpp + COmegaPirate.hpp COmegaPirate.cpp CParasite.hpp CParasite.cpp CPuddleSpore.hpp CPuddleSpore.cpp CPuddleToadGamma.hpp CPuddleToadGamma.cpp diff --git a/Runtime/MP1/World/COmegaPirate.cpp b/Runtime/MP1/World/COmegaPirate.cpp new file mode 100644 index 000000000..16f462ec6 --- /dev/null +++ b/Runtime/MP1/World/COmegaPirate.cpp @@ -0,0 +1,12 @@ +#include "Runtime/MP1/World/COmegaPirate.hpp" + +namespace urde::MP1 { +COmegaPirate::CFlash::CFlash(TUniqueId uid, const CEntityInfo& info, const zeus::CVector3f& pos, CToken& p4, float p5) +: CActor(uid, true, "Omega Pirate Flash", info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), {}, + CActorParameters::None(), kInvalidUniqueId) {} + +COmegaPirate::COmegaPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, + CElitePirateData data, CAssetId w1, CAssetId w2, CAssetId w3) +: CElitePirate(uid, name, info, xf, std::move(mData), pInfo, actParms, data) {} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/COmegaPirate.hpp b/Runtime/MP1/World/COmegaPirate.hpp new file mode 100644 index 000000000..369393aa5 --- /dev/null +++ b/Runtime/MP1/World/COmegaPirate.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "Runtime/MP1/World/CElitePirate.hpp" + +namespace urde::MP1 { +class COmegaPirate : public CElitePirate { +private: + class CFlash : public CActor { + private: + CToken xe8_; + int xf0_; + float xf4_; + float xf8_; + float xfc_; + + CFlash(TUniqueId uid, const CEntityInfo& info, const zeus::CVector3f& pos, CToken& p4, float p5); + }; + +public: + COmegaPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, CElitePirateData data, + CAssetId w1, CAssetId w2, CAssetId w3); +}; +} // namespace urde::MP1 diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 060122f19..463435c9b 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -31,6 +31,7 @@ #include "Runtime/MP1/World/CMetroidBeta.hpp" #include "Runtime/MP1/World/CMetroidPrimeRelay.hpp" #include "Runtime/MP1/World/CNewIntroBoss.hpp" +#include "Runtime/MP1/World/COmegaPirate.hpp" #include "Runtime/MP1/World/CParasite.hpp" #include "Runtime/MP1/World/CPuddleSpore.hpp" #include "Runtime/MP1/World/CPuddleToadGamma.hpp" @@ -127,6 +128,8 @@ static logvisor::Module Log("urde::ScriptLoader"); constexpr SObjectTag MorphballDoorANCS = {FOURCC('ANCS'), 0x1F9DA858}; +constexpr int skElitePiratePropCount = 41; + static bool EnsurePropertyCount(int count, int expected, const char* structName) { if (count < expected) { Log.report(logvisor::Warning, fmt("Insufficient number of props ({}/{}) for {} entity"), count, expected, @@ -1383,7 +1386,7 @@ CEntity* ScriptLoader::LoadFlyingPirate(CStateManager& mgr, CInputStream& in, in } CEntity* ScriptLoader::LoadElitePirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - if (!EnsurePropertyCount(propCount, 41, "ElitePirate")) + if (!EnsurePropertyCount(propCount, skElitePiratePropCount, "ElitePirate")) return nullptr; SScaledActorHead actHead = LoadScaledActorHead(in, mgr); @@ -3622,7 +3625,33 @@ CEntity* ScriptLoader::LoadMazeNode(CStateManager& mgr, CInputStream& in, int pr } CEntity* ScriptLoader::LoadOmegaPirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { + if (!EnsurePropertyCount(propCount, skElitePiratePropCount + 1, "OmegaPirate")) { + return nullptr; + } + +#if 0 + SScaledActorHead actHead = LoadScaledActorHead(in, mgr); + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (!pair.first) { + return nullptr; + } + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + MP1::CElitePirateData elitePirateData(in, propCount); + + if (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) { + return nullptr; + } + + CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(), + actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true)); + + return new MP1::COmegaPirate(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData), + pInfo, actParms, elitePirateData, CAssetId(in), CAssetId(in), CAssetId(in)); +#else return nullptr; +#endif } CEntity* ScriptLoader::LoadPhazonPool(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { From deba91bfc0fd74151cf24565935bd2170f5ba319 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 31 Mar 2020 21:29:14 -0400 Subject: [PATCH 20/26] CGrenadeLauncher: Fix rendering --- Runtime/MP1/World/CGrenadeLauncher.cpp | 12 +++++++----- Runtime/MP1/World/CGrenadeLauncher.hpp | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 7273c84a9..abcb3764d 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -127,10 +127,12 @@ std::optional CGrenadeLauncher::GetTouchBounds() const { void CGrenadeLauncher::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { if (x3f4_color3.a() == 1.f) { + xb4_drawFlags = CModelFlags{2, 0, 3, zeus::skWhite}; // Original code redundantly sets a() = 1.f - xb4_drawFlags = CModelFlags{2, 0, 3, x3f4_color3}; + xb4_drawFlags.addColor = x3f4_color3; } else { - xb4_drawFlags = CModelFlags{5, 0, 3, x3f4_color3}; + xb4_drawFlags = CModelFlags{5, 0, 3, zeus::skWhite}; + xb4_drawFlags.addColor = x3f4_color3; } CActor::PreRender(mgr, frustum); } @@ -151,7 +153,7 @@ void CGrenadeLauncher::Think(float dt, CStateManager& mgr) { UpdateCollision(); UpdateColor(dt); sub_8022f9e0(mgr, dt); - sub_8022f69c(dt); + UpdateDamageTime(dt); const SAdvancementDeltas& deltas = CActor::UpdateAnimation(dt, mgr, true); MoveToOR(deltas.x0_posDelta, dt); @@ -190,7 +192,7 @@ void CGrenadeLauncher::UpdateColor(float arg) { } } -void CGrenadeLauncher::sub_8022f69c(float arg) { +void CGrenadeLauncher::UpdateDamageTime(float arg) { if (x3ec_damageTimer <= 0.f) { xd0_damageMag = x3e8_thermalMag; } else { @@ -297,7 +299,7 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { return; } - const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({24}, -1); + const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({23}, -1); if (anim.first > 0.f) { animData->AddAdditiveAnimation(anim.second, 1.f, false, true); const zeus::CVector3f& origin = diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index cb07cf1e5..ad865e7f2 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -115,7 +115,7 @@ public: private: void UpdateCollision(); void UpdateColor(float arg); - void sub_8022f69c(float arg); + void UpdateDamageTime(float arg); void CreateExplosion(CStateManager& mgr); void sub_8022f9e0(CStateManager& mgr, float dt); void sub_80230438(); From 6e5c32abfd1e8dabec25d1d4aa2863609f9a68df Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 01:38:48 -0400 Subject: [PATCH 21/26] CBouncyGrenade: Pass bounding box to CPhysicsActor --- Runtime/MP1/World/CBouncyGrenade.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index 04ce5b5e6..a749bcd61 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -13,8 +13,8 @@ CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEnti const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParams, TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance) -: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, {}, - SMoverData(data.GetUnkStruct().GetMass()), actParams, 0.3f, 0.1f) +: CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, + mData.GetBounds(), SMoverData(data.GetUnkStruct().GetMass()), actParams, 0.3f, 0.1f) , x258_data(data) , x294_numBounces(data.GetNumBounces()) , x298_parentId(parentId) From d4ff239f91d46432b85cbf48c9f0121bc4bd570d Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 02:41:31 -0400 Subject: [PATCH 22/26] CShockWave: Implement Touch --- Runtime/MP1/World/CElitePirate.cpp | 9 +-- Runtime/MP1/World/CElitePirate.hpp | 4 +- Runtime/MP1/World/CShockWave.cpp | 92 ++++++++++++++++++++++++------ Runtime/MP1/World/CShockWave.hpp | 32 ++++++++--- 4 files changed, 106 insertions(+), 31 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 431592b8b..fb9c88f0e 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -915,10 +915,11 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { } CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(), params.GetInitialAnimation(), true)); - mgr.AddObject(new CGrenadeLauncher( - uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), std::move(mData), - mData.GetBounds(GetTransform().getRotation()), CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability, - x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f)); + const zeus::CAABox bounds = mData.GetBounds(GetTransform().getRotation()); + mgr.AddObject( + new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), + std::move(mData), bounds, CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability, + x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f)); } void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) { diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 09db287af..1b4c53423 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -42,7 +42,7 @@ private: CAssetId xf8_; CDamageInfo xfc_; CAssetId x118_; - s16 x11c_; + u16 x11c_; bool x11e_; bool x11f_; @@ -64,7 +64,7 @@ public: [[nodiscard]] CAssetId GetXF8() const { return xf8_; } [[nodiscard]] const CDamageInfo& GetXFC() const { return xfc_; } [[nodiscard]] CAssetId GetX118() const { return x118_; } - [[nodiscard]] s16 GetX11C() const { return x11c_; } + [[nodiscard]] u16 GetX11C() const { return x11c_; } [[nodiscard]] bool GetX11E() const { return x11e_; } [[nodiscard]] bool GetX11F() const { return x11f_; } diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp index 96e040da5..b7126f15f 100644 --- a/Runtime/MP1/World/CShockWave.cpp +++ b/Runtime/MP1/World/CShockWave.cpp @@ -7,6 +7,8 @@ #include "Runtime/Graphics/CBooRenderer.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CGameLight.hpp" +#include "Runtime/World/CHUDBillboardEffect.hpp" +#include "Runtime/World/CPlayer.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -16,16 +18,16 @@ CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& : 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})) +, xec_damageInfo(data.GetDamageInfo()) +, x108_elementGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.GetParticleDescId()})) , x110_elementGen(std::make_unique(x108_elementGenDesc)) , x114_data(data) -, x150_(data.x24_) -, x154_(data.x2c_) +, x150_(data.GetX24()) +, x154_(data.GetX2C()) , x15c_(f1) , x160_(f2) { - if (data.x34_weaponDesc.IsValid()) { - x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.x34_weaponDesc}); + if (data.GetWeaponDescId().IsValid()) { + x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.GetWeaponDescId()}); } x110_elementGen->SetParticleEmission(true); x110_elementGen->SetOrientation(GetTransform().getRotation()); @@ -41,7 +43,7 @@ void CShockWave::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState x980_id2 = mgr.AllocateUniqueId(); mgr.AddObject(new CGameLight(x980_id2, GetAreaIdAlways(), GetActive(), "ShockWaveLight_" + x10_name, GetTransform(), GetUniqueId(), x110_elementGen->GetLight(), - x114_data.x4_particleDesc.Value(), 1, 0.f)); + x114_data.GetParticleDescId().Value(), 1, 0.f)); } } else if (msg == EScriptObjectMessage::Deleted) { mgr.FreeScriptObject(x980_id2); @@ -73,7 +75,7 @@ void CShockWave::Think(float dt, CStateManager& mgr) { x110_elementGen->Update(dt); x158_ += dt; x150_ += x154_ * dt; - x154_ += dt * x114_data.x30_; + x154_ += dt * x114_data.GetX30(); x110_elementGen->SetExternalVar(0, x150_); for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); i++) { auto& particle = static_cast(x110_elementGen->GetActiveChildParticle(i)); @@ -81,13 +83,13 @@ void CShockWave::Think(float dt, CStateManager& mgr) { particle.SetExternalVar(0, x150_); } } - if (x16c_) { - x164_ += dt; - x16c_ = false; + if (x16c_hitPlayerInAir) { + x164_timeSinceHitPlayerInAir += dt; + x16c_hitPlayerInAir = false; } - if (x16d_) { - x168_ += dt; - x16d_ = false; + if (x16d_hitPlayer) { + x168_timeSinceHitPlayer += dt; + x16d_hitPlayer = false; } } if (x110_elementGen->IsSystemDeletable() && x15c_ > 0.f && x158_ >= x15c_) { @@ -110,8 +112,66 @@ void CShockWave::Touch(CActor& actor, CStateManager& mgr) { if (TCastToConstPtr cactor = mgr.GetObjectById(actor.GetUniqueId())) { isParent = xe8_id1 == cactor->GetOwnerId(); } - if (!isParent) { - // TODO + if (isParent) { + return; + } + + float mmax = x150_ * x150_; + float mmin = mmax * x114_data.GetX28() * x114_data.GetX28(); + zeus::CVector3f dist = actor.GetTranslation() - GetTranslation(); + CDamageInfo damageInfo = xec_damageInfo; + float knockBackScale = std::max(0.f, 1.f - x160_ * x158_); + bool isPlayer = mgr.GetPlayer().GetUniqueId() == actor.GetUniqueId(); + bool isPlayerInAir = isPlayer && mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround; + float distXYMag = dist.toVec2f().magSquared(); + if (distXYMag < mmin || distXYMag > mmax) { + return; + } + + if (isPlayer) { + if (mgr.GetPlayer().GetPlayerMovementState() == CPlayer::EPlayerMovementState::OnGround) { + const zeus::CTransform& playerTransform = mgr.GetPlayer().GetTransform(); + zeus::CVector3f playerDir = GetTranslation() - playerTransform.origin; + if (playerDir.canBeNormalized()) { + playerDir.normalize(); + float dot = std::abs(playerDir.dot(playerTransform.frontVector())); + knockBackScale = std::max(0.12f, 0.88f * dot * dot); + } + } + if (mgr.GetPlayer().GetVelocity().magnitude() > 40.f) { + x168_timeSinceHitPlayer = 0.2666f; + } + } + damageInfo.SetKnockBackPower(knockBackScale * damageInfo.GetKnockBackPower()); + + if (isPlayer && (x164_timeSinceHitPlayerInAir >= 0.1333f || x168_timeSinceHitPlayer >= 0.2666f)) { + return; + } + if (!IsHit(actor.GetUniqueId())) { + mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + if (isPlayer && x974_electricDesc) { + mgr.AddObject(new CHUDBillboardEffect(std::nullopt, x974_electricDesc, mgr.AllocateUniqueId(), true, + "VisorElectricFx", CHUDBillboardEffect::GetNearClipDistance(mgr), + CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f, + zeus::skZero3f)); + CSfxManager::SfxStart(x114_data.GetElectrocuteSfx(), 1.f, 1.f, false, 0x7f, false, kInvalidAreaId); + } + x170_hitIds.push_back(actor.GetUniqueId()); + } else { + damageInfo.SetDamage(0.f); + mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); + } + if (isPlayerInAir) { + x16c_hitPlayerInAir = true; + } + if (isPlayer) { + x16d_hitPlayer = true; } } + +bool CShockWave::IsHit(TUniqueId id) const { + return std::find(x170_hitIds.begin(), x170_hitIds.end(), id) != x170_hitIds.end(); +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CShockWave.hpp b/Runtime/MP1/World/CShockWave.hpp index f5a8d2336..25a90c4f8 100644 --- a/Runtime/MP1/World/CShockWave.hpp +++ b/Runtime/MP1/World/CShockWave.hpp @@ -6,6 +6,7 @@ namespace urde::MP1 { struct SShockWaveData { +private: u32 x0_ = 8; CAssetId x4_particleDesc; CDamageInfo x8_damageInfo; @@ -14,10 +15,20 @@ struct SShockWaveData { float x2c_ = 16.5217f; float x30_ = 0.f; CAssetId x34_weaponDesc; - s16 x38_sfx; + u16 x38_electrocuteSfx; - SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, s16 sfx) - : x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_sfx(sfx) {} +public: + SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, u16 sfx) + : x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_electrocuteSfx(sfx) {} + + [[nodiscard]] CAssetId GetParticleDescId() const { return x4_particleDesc; } + [[nodiscard]] const CDamageInfo& GetDamageInfo() const { return x8_damageInfo; } + [[nodiscard]] float GetX24() const { return x24_; } + [[nodiscard]] float GetX28() const { return x28_; } + [[nodiscard]] float GetX2C() const { return x2c_; } + [[nodiscard]] float GetX30() const { return x30_; } + [[nodiscard]] CAssetId GetWeaponDescId() const { return x34_weaponDesc; } + [[nodiscard]] u16 GetElectrocuteSfx() const { return x38_electrocuteSfx; } }; class CShockWave : public CActor { @@ -32,11 +43,11 @@ private: float x158_ = 0.f; float x15c_; float x160_; - float x164_ = 0.f; - float x168_ = 0.f; - bool x16c_ = false; - bool x16d_ = false; - // x368 => very large reserved_vector of ? + float x164_timeSinceHitPlayerInAir = 0.f; + float x168_timeSinceHitPlayer = 0.f; + bool x16c_hitPlayerInAir = false; + bool x16d_hitPlayer = false; + rstl::reserved_vector x170_hitIds; std::optional> x974_electricDesc; TUniqueId x980_id2 = kInvalidUniqueId; @@ -51,5 +62,8 @@ public: void Render(const CStateManager& mgr) const override; void Think(float dt, CStateManager& mgr) override; void Touch(CActor& actor, CStateManager& mgr) override; + +private: + [[nodiscard]] bool IsHit(TUniqueId id) const; }; -} // namespace urde +} // namespace urde::MP1 From 162b23297998976e760755cc2b4d1322bdfd5500 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 03:39:05 -0400 Subject: [PATCH 23/26] CElitePirate: Fix melee & contact damage --- Runtime/MP1/World/CElitePirate.cpp | 20 ++++++++++---------- Runtime/MP1/World/CElitePirate.hpp | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index fb9c88f0e..1699cef47 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -87,7 +87,7 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn , x7a0_initialSpeed(x3b4_speed) , x7d0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) , x8c0_(5.f) -, x988_24_(false) +, x988_24_damageOn(false) , x988_25_(false) , x988_26_(false) , x988_27_shotAt(false) @@ -169,13 +169,13 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta break; } const TUniqueId& touchedUid = actor->GetLastTouchedObject(); - if (touchedUid != GetUniqueId()) { + if (touchedUid != mgr.GetPlayer().GetUniqueId()) { if (TCastToPtr(mgr.ObjectById(touchedUid))) { SetShotAt(true, mgr); } break; } - if (x988_31_) { + if (!x988_24_damageOn) { if (x420_curDamageRemTime <= 0.f) { CDamageInfo info = GetContactDamage(); info.SetDamage(0.5f * info.GetDamage()); @@ -192,7 +192,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f); x420_curDamageRemTime = x424_damageWaitTime; - x988_24_ = false; + x988_24_damageOn = false; break; } case EScriptObjectMessage::Registered: { @@ -262,7 +262,7 @@ void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) x6f8_boneTracking.PreRender(mgr, *modelData->GetAnimationData(), GetTransform(), modelData->GetScale(), *x450_bodyController); auto numMaterialSets = modelData->GetNumMaterialSets(); - xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_ ? numMaterialSets - 1 : x7cc_; + xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_activeMaterialSet ? numMaterialSets - 1 : x7cc_activeMaterialSet; } const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { @@ -312,11 +312,11 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node break; case EUserEventType::DamageOn: handled = true; - x988_24_ = true; + x988_24_damageOn = true; break; case EUserEventType::DamageOff: handled = true; - x988_24_ = false; + x988_24_damageOn = false; break; case EUserEventType::ScreenShake: sub_802273a8(); @@ -524,7 +524,7 @@ void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { x568_ = EState::Zero; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); if (x64_modelData->GetNumMaterialSets() > 1) { - x7cc_ = 1; + x7cc_activeMaterialSet = 1; } } else if (msg == EStateMsg::Update) { if (x568_ == EState::Zero) { @@ -561,13 +561,13 @@ void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { } } else if (msg == EStateMsg::Deactivate) { sub_802285c4(mgr); - x988_24_ = false; + x988_24_damageOn = false; x988_26_ = false; x988_25_ = false; x7c8_currAnimId = -1; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::skZero3f); - x7cc_ = 0; + x7cc_activeMaterialSet = 0; } } diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index 1b4c53423..b7faf6ed5 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -123,11 +123,11 @@ private: float x7c0_shotAtTimer = 0.f; float x7c4_ = 0.f; s32 x7c8_currAnimId = -1; - s32 x7cc_ = 0; + u32 x7cc_activeMaterialSet = 0; CPathFindSearch x7d0_pathFindSearch; zeus::CVector3f x8b4_; SUnknownStruct x8c0_; - bool x988_24_ : 1; + bool x988_24_damageOn : 1; bool x988_25_ : 1; bool x988_26_ : 1; bool x988_27_shotAt : 1; From bb7699be4632a6f6a4575d8ca379e91d776bb4e0 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 14:54:01 -0400 Subject: [PATCH 24/26] CElitePirate/CShockWave: Renaming --- Runtime/MP1/World/CElitePirate.cpp | 288 +++++++++++++++-------------- Runtime/MP1/World/CElitePirate.hpp | 54 +++--- Runtime/MP1/World/CShockWave.cpp | 14 +- Runtime/MP1/World/CShockWave.hpp | 8 +- 4 files changed, 183 insertions(+), 181 deletions(-) diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 1699cef47..23bcc515c 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -83,19 +83,19 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn , x5d8_data(std::move(data)) , x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) -, x738_(GetBoundingBox(), GetMaterialList()) +, x738_collisionAabb(GetBoundingBox(), GetMaterialList()) , x7a0_initialSpeed(x3b4_speed) , x7d0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) , x8c0_(5.f) , x988_24_damageOn(false) -, x988_25_(false) -, x988_26_(false) +, x988_25_attackingRightClaw(false) +, x988_26_attackingLeftClaw(false) , x988_27_shotAt(false) , x988_28_alert(false) -, x988_29_(false) -, x988_30_(false) -, x988_31_(false) -, x989_24_(false) { +, x988_29_shockWaveAnim(false) +, x988_30_calledForBackup(false) +, x988_31_running(false) +, x989_24_onPath(false) { if (x5d8_data.GetX20().IsValid()) { x760_energyAbsorbDesc = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()}); } @@ -105,7 +105,7 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn x460_knockBackController.SetEnableBurn(false); x460_knockBackController.SetEnableExplodeDeath(false); x460_knockBackController.SetEnableLaggedBurnDeath(false); - sub_80229248(); + SetupPathFindSearch(); } void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); } @@ -114,19 +114,19 @@ void CElitePirate::Think(float dt, CStateManager& mgr) { if (GetActive()) { CPatterned::Think(dt, mgr); x6f8_boneTracking.Update(dt); - if (sub_802273a8()) { - x730_collisionActorMgr2->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); } - x5d4_collisionActorMgr1->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + x5d4_collisionActorMgr->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); if (IsAttractingEnergy() && x5d8_data.GetX11F()) { x3b4_speed = 2.f * x7a0_initialSpeed; } else { x3b4_speed = x7a0_initialSpeed; } UpdateTimers(dt); - sub_80228798(); + UpdatePositionHistory(); UpdateActorTransform(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv); - sub_80228e84(mgr); + UpdateHealthInfo(mgr); x328_31_energyAttractor = IsAttractingEnergy(); } } @@ -136,8 +136,8 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta switch (msg) { case EScriptObjectMessage::Activate: { - if (sub_802273a8()) { - x730_collisionActorMgr2->SetActive(mgr, true); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->SetActive(mgr, true); } if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { ent->SetActive(true); @@ -145,10 +145,10 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta break; } case EScriptObjectMessage::Deactivate: { - if (sub_802273a8()) { - x730_collisionActorMgr2->SetActive(mgr, false); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->SetActive(mgr, false); } - x5d4_collisionActorMgr1->SetActive(mgr, false); + x5d4_collisionActorMgr->SetActive(mgr, false); if (CEntity* ent = mgr.ObjectById(x772_launcherId)) { ent->SetActive(false); } @@ -185,8 +185,8 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta } break; } - if ((!x988_25_ || !IsArmClawCollider(uid, x774_collisionRJointIds)) && - (!x988_26_ || !IsArmClawCollider(uid, x788_collisionLJointIds))) { + if ((!x988_25_attackingRightClaw || !IsArmClawCollider(uid, x774_collisionRJointIds)) && + (!x988_26_attackingLeftClaw || !IsArmClawCollider(uid, x788_collisionLJointIds))) { break; } mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetContactDamage(), @@ -202,17 +202,17 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta CreateGrenadeLauncher(mgr, x772_launcherId); const auto& bodyStateInfo = x450_bodyController->GetBodyStateInfo(); if (bodyStateInfo.GetMaxSpeed() > 0.f) { - x7a4_ = (0.99f * bodyStateInfo.GetLocomotionSpeed(pas::ELocomotionAnim::Walk)) / bodyStateInfo.GetMaxSpeed(); + x7a4_steeringSpeed = (0.99f * bodyStateInfo.GetLocomotionSpeed(pas::ELocomotionAnim::Walk)) / bodyStateInfo.GetMaxSpeed(); } x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); - x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_, x7a4_); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_steeringSpeed, x7a4_steeringSpeed); break; } case EScriptObjectMessage::Deleted: - if (sub_802273a8()) { - x730_collisionActorMgr2->Destroy(mgr); + if (HasWeakPointHead()) { + x730_collisionActorMgrHead->Destroy(mgr); } - x5d4_collisionActorMgr1->Destroy(mgr); + x5d4_collisionActorMgr->Destroy(mgr); mgr.FreeScriptObject(x772_launcherId); break; case EScriptObjectMessage::InitializedInArea: @@ -262,7 +262,8 @@ void CElitePirate::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) x6f8_boneTracking.PreRender(mgr, *modelData->GetAnimationData(), GetTransform(), modelData->GetScale(), *x450_bodyController); auto numMaterialSets = modelData->GetNumMaterialSets(); - xb4_drawFlags.x1_matSetIdx = numMaterialSets - 1 < x7cc_activeMaterialSet ? numMaterialSets - 1 : x7cc_activeMaterialSet; + xb4_drawFlags.x1_matSetIdx = + numMaterialSets - 1 < x7cc_activeMaterialSet ? numMaterialSets - 1 : x7cc_activeMaterialSet; } const CDamageVulnerability* CElitePirate::GetDamageVulnerability() const { @@ -278,10 +279,10 @@ zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { if (x772_launcherId != kInvalidUniqueId && mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { if (const auto* actor = static_cast(mgr.GetObjectById(x772_launcherId))) { - return sub_80228864(actor); + return GetLockOnPosition(actor); } } - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { return actor->GetTranslation(); } @@ -291,7 +292,7 @@ zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const { zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const { const std::shared_ptr& playerState = mgr.GetPlayerState(); - if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() && + if (x5d4_collisionActorMgr->GetActive() && playerState->IsFiringComboBeam() && playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) { if (TCastToConstPtr actor = mgr.GetObjectById(x79c_)) { return actor->GetTranslation(); @@ -319,7 +320,7 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node x988_24_damageOn = false; break; case EUserEventType::ScreenShake: - sub_802273a8(); + HasWeakPointHead(); handled = true; break; case EUserEventType::BeginAction: { @@ -332,16 +333,16 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node origin.z(), }); 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)); + xf, GetUniqueId(), GetShockWaveData(), IsElitePirate() ? 2.f : 1.3f, + IsElitePirate() ? 0.4f : 0.5f)); handled = true; break; } case EUserEventType::BecomeShootThrough: - if (sub_802273a8()) { - u32 numCollisionActors = x730_collisionActorMgr2->GetNumCollisionActors(); + if (HasWeakPointHead()) { + u32 numCollisionActors = x730_collisionActorMgrHead->GetNumCollisionActors(); for (u32 i = 0; i < numCollisionActors; i++) { - const auto& description = x730_collisionActorMgr2->GetCollisionDescFromIndex(i); + const auto& description = x730_collisionActorMgrHead->GetCollisionDescFromIndex(i); if (TCastToPtr actor = mgr.ObjectById(description.GetCollisionActorId())) { actor->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); } @@ -357,11 +358,11 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node } } -const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_; } +const CCollisionPrimitive* CElitePirate::GetCollisionPrimitive() const { return &x738_collisionAabb; } void CElitePirate::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { - if (!sub_80227430(info)) { + if (!CanKnockBack(info)) { return; } CPatterned::KnockBack(pos, mgr, info, type, inDeferred, magnitude); @@ -376,19 +377,19 @@ void CElitePirate::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); x400_24_hitByPlayerProjectile = false; - x989_24_ = false; + x989_24_onPath = false; } CPatterned::Patrol(mgr, msg, dt); } void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { - x989_24_ = true; + x989_24_onPath = true; x988_28_alert = false; x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); x6f8_boneTracking.SetActive(true); - sub_80228634(mgr); + UpdateDestPos(mgr); CPatterned::PathFind(mgr, msg, dt); x7bc_tauntTimer = x5d8_data.GetTauntVariance() * mgr.GetActiveRandom()->Float() + x5d8_data.GetTauntInterval(); if (TooClose(mgr, 0.f)) { @@ -427,13 +428,13 @@ void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { } else { SetDestPos(x3a0_latestLeashPosition); } - x8b4_ = x2e0_destPos; + x8b4_targetDestPos = x2e0_destPos; if (GetSearchPath() != nullptr) { CPatterned::PathFind(mgr, msg, dt); } } else if (msg == EStateMsg::Update) { if (PathShagged(mgr, 0.f)) { - const zeus::CVector3f& move = x45c_steeringBehaviors.Arrival(*this, x8b4_, 25.f); + const zeus::CVector3f& move = x45c_steeringBehaviors.Arrival(*this, x8b4_targetDestPos, 25.f); x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f)); } else { CPatterned::PathFind(mgr, msg, dt); @@ -446,7 +447,7 @@ void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); - x989_24_ = false; + x989_24_onPath = false; CMaterialFilter filter = GetMaterialFilter(); filter.ExcludeList().Add( {EMaterialTypes::Wall, EMaterialTypes::Ceiling, EMaterialTypes::AIBlock, EMaterialTypes::Character}); @@ -461,12 +462,12 @@ void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) { void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { - x988_31_ = true; + x988_31_running = true; x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(1.f, 1.f); x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); x6f8_boneTracking.SetActive(true); - sub_80228634(mgr); + UpdateDestPos(mgr); CPatterned::PathFind(mgr, msg, dt); } else if (msg == EStateMsg::Update) { if (PathShagged(mgr, 0.f)) { @@ -485,57 +486,57 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } } else if (msg == EStateMsg::Deactivate) { - x988_31_ = false; + x988_31_running = false; x6f8_boneTracking.SetActive(false); - x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_, x7a4_); + x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(x7a4_steeringSpeed, x7a4_steeringSpeed); } } void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = EState::One; + x568_state = EState::One; } else if (msg == EStateMsg::Update) { - if (x568_ == EState::Zero) { + if (x568_state == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { - x568_ = EState::Two; + x568_state = EState::Two; } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero)); } - } else if (x568_ == EState::One) { + } else if (x568_state == EState::One) { if (ShouldTurn(mgr, 0.f)) { const auto& face = mgr.GetPlayer().GetTranslation() - GetTranslation(); if (face.canBeNormalized()) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f)); } } else { - x568_ = EState::Zero; + x568_state = EState::Zero; } - } else if (x568_ == EState::Two && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { - x568_ = EState::Over; + } else if (x568_state == EState::Two && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { + x568_state = EState::Over; } } else if (msg == EStateMsg::Deactivate) { SetShotAt(false, mgr); - sub_802289b0(mgr, true); + SetLaunchersActive(mgr, true); } } void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = EState::Zero; + x568_state = EState::Zero; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f)); if (x64_modelData->GetNumMaterialSets() > 1) { x7cc_activeMaterialSet = 1; } } else if (msg == EStateMsg::Update) { - if (x568_ == EState::Zero) { + if (x568_state == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { - x568_ = EState::One; - x988_25_ = true; + x568_state = EState::One; + x988_25_attackingRightClaw = true; x7c8_currAnimId = x450_bodyController->GetCurrentAnimId(); } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::One)); } - } else if (x568_ == EState::One) { + } else if (x568_state == EState::One) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { if (x7c8_currAnimId == x450_bodyController->GetCurrentAnimId()) { x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); @@ -543,27 +544,27 @@ void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::Two)); } } else { - x568_ = EState::Two; - x988_25_ = false; - x988_26_ = true; + x568_state = EState::Two; + x988_25_attackingRightClaw = false; + x988_26_attackingLeftClaw = true; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::CVector3f(2.f)); } } else { - x568_ = EState::Over; + x568_state = EState::Over; } - } else if (x568_ == EState::Two) { + } else if (x568_state == EState::Two) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) { x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation()); } else { - x568_ = EState::Over; + x568_state = EState::Over; } } } else if (msg == EStateMsg::Deactivate) { - sub_802285c4(mgr); + CheckAttackChance(mgr); x988_24_damageOn = false; - x988_26_ = false; - x988_25_ = false; + x988_26_attackingLeftClaw = false; + x988_25_attackingRightClaw = false; x7c8_currAnimId = -1; ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f); ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::skZero3f); @@ -575,67 +576,67 @@ void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Tau void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = EState::Zero; + x568_state = EState::Zero; } else if (msg == EStateMsg::Update) { const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); - if (x568_ == EState::Zero) { + if (x568_state == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { - x568_ = EState::Two; + x568_state = EState::Two; } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::One, playerPos, false)); } - } else if (x568_ == EState::Two) { + } else if (x568_state == EState::Two) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { x450_bodyController->GetCommandMgr().DeliverTargetVector(playerPos - GetTranslation()); } else { - x568_ = EState::Over; + x568_state = EState::Over; } } } else if (msg == EStateMsg::Deactivate) { - sub_802285c4(mgr); + CheckAttackChance(mgr); } } void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = EState::Zero; + x568_state = EState::Zero; } else if (msg == EStateMsg::Update) { - if (x568_ == EState::Zero) { + if (x568_state == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { - x568_ = EState::Two; - x988_29_ = true; + x568_state = EState::Two; + x988_29_shockWaveAnim = true; } else { x450_bodyController->GetCommandMgr().DeliverCmd( CBCProjectileAttackCmd(pas::ESeverity::Two, mgr.GetPlayer().GetTranslation(), false)); } - } else if (x568_ == EState::Two) { + } else if (x568_state == EState::Two) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) { x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation()); } else { - x568_ = EState::Over; + x568_state = EState::Over; } } } else if (msg == EStateMsg::Deactivate) { - sub_802285c4(mgr); - x988_29_ = false; + CheckAttackChance(mgr); + x988_29_shockWaveAnim = false; } } void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { if (msg == EStateMsg::Activate) { - x568_ = EState::Zero; - x988_30_ = true; + x568_state = EState::Zero; + x988_30_calledForBackup = true; SetShotAt(false, mgr); } else if (msg == EStateMsg::Update) { - if (x568_ == EState::Zero) { + if (x568_state == EState::Zero) { if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) { - x568_ = EState::Two; + x568_state = EState::Two; } else { x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Five, zeus::skZero3f)); } - } else if (x568_ == EState::Two) { + } else if (x568_state == EState::Two) { if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) { - x568_ = EState::Over; + x568_state = EState::Over; } } } else if (msg == EStateMsg::Deactivate) { @@ -646,15 +647,15 @@ void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) { void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { actor->SetDamageVulnerability(CDamageVulnerability::ImmuneVulnerabilty()); } } - x5d4_collisionActorMgr1->SetActive(mgr, true); + x5d4_collisionActorMgr->SetActive(mgr, true); x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); x6f8_boneTracking.SetActive(true); - sub_80228634(mgr); + UpdateDestPos(mgr); CPatterned::PathFind(mgr, msg, dt); if (TooClose(mgr, 0.f)) { x450_bodyController->GetCommandMgr().ClearLocomotionCmds(); @@ -666,7 +667,7 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { x988_27_shotAt = false; } } - x7a8_ = PathShagged(mgr, 0.f) ? x7a8_ + dt : 0.f; + x7a8_pathShaggedTime = PathShagged(mgr, 0.f) ? x7a8_pathShaggedTime + dt : 0.f; if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) { CPatterned::PathFind(mgr, msg, dt); } else if (PathShagged(mgr, 0.f)) { @@ -683,16 +684,16 @@ void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) { } } AttractProjectiles(mgr); - sub_802277e0(mgr, dt); + UpdateAbsorbBodyState(mgr, dt); } else if (msg == EStateMsg::Deactivate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); x6f8_boneTracking.SetActive(false); - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { actor->SetDamageVulnerability(x56c_vulnerability); } } - x5d4_collisionActorMgr1->SetActive(mgr, false); + x5d4_collisionActorMgr->SetActive(mgr, false); } } @@ -708,7 +709,7 @@ bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg); } -bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_ == EState::Over; } +bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_state == EState::Over; } bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { @@ -717,7 +718,9 @@ bool CElitePirate::ShouldAttack(CStateManager& mgr, float) { return !ShouldTurn(mgr, 0.f); } -bool CElitePirate::InPosition(CStateManager& mgr, float) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; } +bool CElitePirate::InPosition(CStateManager& mgr, float) { + return (x8b4_targetDestPos - GetTranslation()).magSquared() < 25.f; +} bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(), @@ -726,11 +729,11 @@ bool CElitePirate::ShouldTurn(CStateManager& mgr, float) { bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) { if (x772_launcherId == kInvalidUniqueId && !PathShagged(mgr, arg)) { - if (!x988_31_) { - return 4.f * x300_maxAttackRange * x300_maxAttackRange < - (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); + if (x988_31_running) { + return true; } - return true; + return 4.f * x300_maxAttackRange * x300_maxAttackRange < + (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); } return false; } @@ -762,7 +765,7 @@ CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; } void CElitePirate::SetupHealthInfo(CStateManager& mgr) { const CHealthInfo* const health = HealthInfo(mgr); x7b4_hp = health->GetHP(); - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { auto actHealth = actor->HealthInfo(mgr); actHealth->SetHP(health->GetHP()); @@ -770,24 +773,23 @@ void CElitePirate::SetupHealthInfo(CStateManager& mgr) { actor->SetDamageVulnerability(x56c_vulnerability); } } - UpdateHealthInfo(mgr, x772_launcherId); + SetupLauncherHealthInfo(mgr, x772_launcherId); } -void CElitePirate::sub_802289b0(CStateManager& mgr, bool b) { sub_80228920(mgr, b, x772_launcherId); } +void CElitePirate::SetLaunchersActive(CStateManager& mgr, bool val) { SetLauncherActive(mgr, val, x772_launcherId); } -void CElitePirate::sub_80229248() { +void CElitePirate::SetupPathFindSearch() { float scale = 1.5f * GetModelData()->GetScale().y(); - float fVar1 = sub_802273b0() ? 5.f : 1.f; + float fVar1 = IsElitePirate() ? 5.f : 1.f; zeus::CAABox box{{-scale, -scale, 0.f}, {scale, scale, fVar1 * scale}}; SetBoundingBox(box); - x738_.SetBox(box); + x738_collisionAabb.SetBox(box); x7d0_pathFindSearch.SetCharacterRadius(scale); x7d0_pathFindSearch.SetCharacterHeight(3.f * scale); } -// TODO rename? void CElitePirate::SetShotAt(bool val, CStateManager& mgr) { - if (!sub_802273b0() || x7b4_hp <= 0.f || !val) { + if (!IsElitePirate() || x7b4_hp <= 0.f || !val) { x988_27_shotAt = val; } else if (HealthInfo(mgr)->GetHP() / x7b4_hp <= x7b0_) { x7b0_ -= 0.2f; @@ -839,10 +841,10 @@ void CElitePirate::SetupCollisionManager(CStateManager& mgr) { AddCollisionList(skLeftArmJointList.data(), skLeftArmJointList.size(), joints); AddCollisionList(skRightArmJointList.data(), skLeftArmJointList.size(), joints); AddSphereCollisionList(skSphereJointList.data(), skSphereJointList.size(), joints); - if (sub_802273a8()) { - x730_collisionActorMgr2 = + if (HasWeakPointHead()) { + x730_collisionActorMgrHead = std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, true); - x730_collisionActorMgr2->SetActive(mgr, GetActive()); + x730_collisionActorMgrHead->SetActive(mgr, GetActive()); } x774_collisionRJointIds.clear(); x788_collisionLJointIds.clear(); @@ -851,7 +853,7 @@ void CElitePirate::SetupCollisionManager(CStateManager& mgr) { constexpr zeus::CVector3f bounds{4.f, 4.f, 2.f}; joints.emplace_back(CJointCollisionDescription::OBBCollision(animData->GetLocatorSegId("L_Palm_LCTR"sv), bounds, zeus::skZero3f, "Shield"sv, 10.f)); - x5d4_collisionActorMgr1 = + x5d4_collisionActorMgr = std::make_unique(mgr, GetUniqueId(), GetAreaIdAlways(), joints, false); SetupCollisionActorInfo(mgr); @@ -864,9 +866,9 @@ void CElitePirate::SetupCollisionManager(CStateManager& mgr) { } void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) { - if (sub_802273a8()) { - for (size_t i = 0; i < x730_collisionActorMgr2->GetNumCollisionActors(); ++i) { - const auto& colDesc = x730_collisionActorMgr2->GetCollisionDescFromIndex(i); + if (HasWeakPointHead()) { + for (size_t i = 0; i < x730_collisionActorMgrHead->GetNumCollisionActors(); ++i) { + const auto& colDesc = x730_collisionActorMgrHead->GetCollisionDescFromIndex(i); const TUniqueId& uid = colDesc.GetCollisionActorId(); if (TCastToPtr act = mgr.ObjectById(uid)) { if (colDesc.GetName() == "Head_1"sv) { @@ -883,16 +885,16 @@ void CElitePirate::SetupCollisionActorInfo(CStateManager& mgr) { } } } - x730_collisionActorMgr2->AddMaterial( + x730_collisionActorMgrHead->AddMaterial( mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough, EMaterialTypes::Immovable}); } - const CJointCollisionDescription& description = x5d4_collisionActorMgr1->GetCollisionDescFromIndex(0); + const CJointCollisionDescription& description = x5d4_collisionActorMgr->GetCollisionDescFromIndex(0); x79c_ = description.GetCollisionActorId(); if (TCastToPtr act = mgr.ObjectById(x79c_)) { act->SetWeaponCollisionResponseType(EWeaponCollisionResponseTypes::None); } - x5d4_collisionActorMgr1->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough}); + x5d4_collisionActorMgr->AddMaterial(mgr, {EMaterialTypes::AIJoint, EMaterialTypes::CameraPassthrough}); } bool CElitePirate::IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, @@ -923,7 +925,7 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) { } void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) { - if (!sub_802273a8()) { + if (!HasWeakPointHead()) { return; } if (TCastToPtr weapon = mgr.ObjectById(uid)) { @@ -946,7 +948,7 @@ void CElitePirate::CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform x7ac_energyAbsorbCooldown = 0.25f; } -void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { +void CElitePirate::SetupLauncherHealthInfo(CStateManager& mgr, TUniqueId uid) { const CHealthInfo* const health = HealthInfo(mgr); if (uid != kInvalidUniqueId) { if (TCastToPtr actor = mgr.ObjectById(uid)) { @@ -958,35 +960,35 @@ void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) { } } -void CElitePirate::sub_80228920(CStateManager& mgr, bool b, TUniqueId uid) { +void CElitePirate::SetLauncherActive(CStateManager& mgr, bool val, TUniqueId uid) { if (uid == kInvalidUniqueId) { return; } if (auto entity = mgr.ObjectById(uid)) { - mgr.SendScriptMsg(entity, GetUniqueId(), b ? EScriptObjectMessage::Start : EScriptObjectMessage::Stop); + mgr.SendScriptMsg(entity, GetUniqueId(), val ? EScriptObjectMessage::Start : EScriptObjectMessage::Stop); } } -zeus::CVector3f CElitePirate::sub_80228864(const CActor* actor) const { - const zeus::CTransform& targetTransform = actor->GetLocatorTransform("lockon_target_LCTR"); +zeus::CVector3f CElitePirate::GetLockOnPosition(const CActor* actor) const { + const zeus::CTransform& targetTransform = actor->GetLocatorTransform("lockon_target_LCTR"sv); return actor->GetTranslation() + actor->GetTransform().rotate(targetTransform.origin); } -bool CElitePirate::sub_80227430(const CDamageInfo& info) const { +bool CElitePirate::CanKnockBack(const CDamageInfo& info) const { return !x400_25_alive || info.GetWeaponMode().IsComboed() || info.GetWeaponMode().GetType() != EWeaponType::Plasma; } -void CElitePirate::sub_80228634(CStateManager& mgr) { - x8b4_ = GetTranslation(); +void CElitePirate::UpdateDestPos(CStateManager& mgr) { + x8b4_targetDestPos = GetTranslation(); const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation(); const zeus::CVector3f& dist = GetTranslation() - playerPos; if (dist.canBeNormalized() && dist.magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) { x2e0_destPos = playerPos + (x2fc_minAttackRange * dist.normalized()); - x8b4_ = x2e0_destPos; + x8b4_targetDestPos = x2e0_destPos; } } -void CElitePirate::sub_802285c4(CStateManager& mgr) { +void CElitePirate::CheckAttackChance(CStateManager& mgr) { if (mgr.GetActiveRandom()->Float() > x5d8_data.GetAttackChance()) { x7b8_attackTimer = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime; } @@ -1051,12 +1053,12 @@ void CElitePirate::AttractProjectiles(CStateManager& mgr) { } } -void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { +void CElitePirate::UpdateAbsorbBodyState(CStateManager& mgr, float dt) { if (!x988_27_shotAt || x450_bodyController->IsFrozen()) { return; } - x7c4_ += dt; - if (x7c4_ < 3.f) { + x7c4_absorbUpdateTimer += dt; + if (x7c4_absorbUpdateTimer < 3.f) { return; } if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Turn && @@ -1065,7 +1067,7 @@ void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { CBCAdditiveReactionCmd(pas::EAdditiveReactionType::Six, 1.f, false)); } else { bool b = false; - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToConstPtr actor = mgr.GetObjectById(x770_collisionHeadId)) { float z = actor->GetTranslation().z(); b = z - 0.5f * (z - GetTranslation().z()) <= mgr.GetPlayer().GetTranslation().z(); @@ -1075,7 +1077,7 @@ void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) { x450_bodyController->GetCommandMgr().DeliverCmd( CBCAdditiveReactionCmd(b ? pas::EAdditiveReactionType::Seven : pas::EAdditiveReactionType::Five, 1.f, false)); } - x7c4_ = 0.f; + x7c4_absorbUpdateTimer = 0.f; } bool CElitePirate::IsAttractingEnergy() { @@ -1095,7 +1097,7 @@ void CElitePirate::UpdateTimers(float dt) { } } -void CElitePirate::sub_80228798() { +void CElitePirate::UpdatePositionHistory() { const zeus::CVector3f& pos = GetTranslation(); if (x7d0_pathFindSearch.OnPath(pos) == CPathFindSearch::EResult::Success) { x8c0_.Clear(); @@ -1115,9 +1117,9 @@ void CElitePirate::UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std: actor->SetTransform(GetLctrTransform(name)); } -void CElitePirate::sub_80228e84(CStateManager& mgr) { +void CElitePirate::UpdateHealthInfo(CStateManager& mgr) { float hp = HealthInfo(mgr)->GetHP(); - if (sub_802273a8()) { + if (HasWeakPointHead()) { if (TCastToPtr actor = mgr.ObjectById(x770_collisionHeadId)) { float headHp = actor->HealthInfo(mgr)->GetHP(); HealthInfo(mgr)->SetHP(hp - (hp - headHp)); @@ -1151,7 +1153,7 @@ bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcher if (x300_maxAttackRange * x300_maxAttackRange > (aim - GetTranslation()).magSquared() || ShouldTurn(mgr, 0.f)) { return false; } - const zeus::CVector3f& origin = sub_80228864(launcher); + const zeus::CVector3f& origin = GetLockOnPosition(launcher); if (IsPatternObstructed(mgr, origin, aim)) { return false; } @@ -1165,10 +1167,10 @@ bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcher } bool CElitePirate::ShouldCallForBackupFromLauncher(const CStateManager& mgr, TUniqueId uid) const { - if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.GetX11E()) { - return x7a8_ >= 3.f; + if (x988_30_calledForBackup || uid != kInvalidUniqueId || !x5d8_data.GetX11E()) { + return false; } - return false; + return x7a8_pathShaggedTime >= 3.f; } bool CElitePirate::IsClosestEnergyAttractor(const CStateManager& mgr, diff --git a/Runtime/MP1/World/CElitePirate.hpp b/Runtime/MP1/World/CElitePirate.hpp index b7faf6ed5..4761a68b3 100644 --- a/Runtime/MP1/World/CElitePirate.hpp +++ b/Runtime/MP1/World/CElitePirate.hpp @@ -98,14 +98,14 @@ private: Over = 3, }; - EState x568_ = EState::Invalid; + EState x568_state = EState::Invalid; CDamageVulnerability x56c_vulnerability; - std::unique_ptr x5d4_collisionActorMgr1; + std::unique_ptr x5d4_collisionActorMgr; CElitePirateData x5d8_data; CBoneTracking x6f8_boneTracking; - std::unique_ptr x730_collisionActorMgr2; + std::unique_ptr x730_collisionActorMgrHead; // s32 x734_; - CCollidableAABox x738_; + CCollidableAABox x738_collisionAabb; std::optional> x760_energyAbsorbDesc; TUniqueId x770_collisionHeadId = kInvalidUniqueId; TUniqueId x772_launcherId = kInvalidUniqueId; @@ -113,29 +113,29 @@ private: rstl::reserved_vector x788_collisionLJointIds; TUniqueId x79c_ = kInvalidUniqueId; float x7a0_initialSpeed; - float x7a4_ = 1.f; - float x7a8_ = 0.f; + float x7a4_steeringSpeed = 1.f; + float x7a8_pathShaggedTime = 0.f; float x7ac_energyAbsorbCooldown = 0.f; float x7b0_ = 1.f; float x7b4_hp = 0.f; float x7b8_attackTimer = 0.f; float x7bc_tauntTimer = 0.f; float x7c0_shotAtTimer = 0.f; - float x7c4_ = 0.f; + float x7c4_absorbUpdateTimer = 0.f; s32 x7c8_currAnimId = -1; u32 x7cc_activeMaterialSet = 0; CPathFindSearch x7d0_pathFindSearch; - zeus::CVector3f x8b4_; + zeus::CVector3f x8b4_targetDestPos; SUnknownStruct x8c0_; bool x988_24_damageOn : 1; - bool x988_25_ : 1; - bool x988_26_ : 1; + bool x988_25_attackingRightClaw : 1; + bool x988_26_attackingLeftClaw : 1; bool x988_27_shotAt : 1; bool x988_28_alert : 1; - bool x988_29_ : 1; - bool x988_30_ : 1; - bool x988_31_ : 1; - bool x989_24_ : 1; + bool x988_29_shockWaveAnim : 1; + bool x988_30_calledForBackup : 1; + bool x988_31_running : 1; + bool x989_24_onPath : 1; public: DEFINE_PATTERNED(ElitePirate) @@ -184,16 +184,16 @@ public: bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; bool ShouldCallForBackup(CStateManager& mgr, float arg) override; CPathFindSearch* GetSearchPath() override; - virtual bool sub_802273a8() const { return true; } - virtual bool sub_802273b0() const { return true; } + virtual bool HasWeakPointHead() const { return true; } + virtual bool IsElitePirate() const { return true; } virtual void SetupHealthInfo(CStateManager& mgr); - virtual void sub_802289b0(CStateManager& mgr, bool b); + virtual void SetLaunchersActive(CStateManager& mgr, bool val); virtual SShockWaveData GetShockWaveData() const { return {x5d8_data.GetXF8(), x5d8_data.GetXFC(), x5d8_data.GetX118(), x5d8_data.GetX11C()}; } private: - void sub_80229248(); + void SetupPathFindSearch(); void SetShotAt(bool val, CStateManager& mgr); bool IsArmClawCollider(TUniqueId uid, const rstl::reserved_vector& vec) const; void AddSphereCollisionList(const SSphereJointInfo* joints, size_t count, @@ -206,19 +206,19 @@ private: void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid); void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid); void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf); - void UpdateHealthInfo(CStateManager& mgr, TUniqueId uid); - void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid); - zeus::CVector3f sub_80228864(const CActor* actor) const; - bool sub_80227430(const CDamageInfo& info) const; - void sub_80228634(CStateManager& mgr); - void sub_802285c4(CStateManager& mgr); + void SetupLauncherHealthInfo(CStateManager& mgr, TUniqueId uid); + void SetLauncherActive(CStateManager& mgr, bool val, TUniqueId uid); + zeus::CVector3f GetLockOnPosition(const CActor* actor) const; + bool CanKnockBack(const CDamageInfo& info) const; + void UpdateDestPos(CStateManager& mgr); + void CheckAttackChance(CStateManager& mgr); void AttractProjectiles(CStateManager& mgr); - void sub_802277e0(CStateManager& mgr, float dt); + void UpdateAbsorbBodyState(CStateManager& mgr, float dt); bool IsAttractingEnergy(); void UpdateTimers(float dt); - void sub_80228798(); + void UpdatePositionHistory(); void UpdateActorTransform(CStateManager& mgr, TUniqueId& uid, std::string_view name); - void sub_80228e84(CStateManager& mgr); + void UpdateHealthInfo(CStateManager& mgr); void ExtendTouchBounds(const CStateManager& mgr, const rstl::reserved_vector& uids, const zeus::CVector3f& vec) const; bool ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId); diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp index b7126f15f..32958ea8d 100644 --- a/Runtime/MP1/World/CShockWave.cpp +++ b/Runtime/MP1/World/CShockWave.cpp @@ -14,7 +14,7 @@ namespace urde::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) + TUniqueId parent, const SShockWaveData& data, float minActiveTime, float knockback) : CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), {EMaterialTypes::Projectile}, CActorParameters::None(), kInvalidUniqueId) , xe8_id1(parent) @@ -24,8 +24,8 @@ CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& , x114_data(data) , x150_(data.GetX24()) , x154_(data.GetX2C()) -, x15c_(f1) -, x160_(f2) { +, x15c_minActiveTime(minActiveTime) +, x160_knockback(knockback) { if (data.GetWeaponDescId().IsValid()) { x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.GetWeaponDescId()}); } @@ -73,7 +73,7 @@ void CShockWave::Render(const CStateManager& mgr) const { void CShockWave::Think(float dt, CStateManager& mgr) { if (GetActive()) { x110_elementGen->Update(dt); - x158_ += dt; + x158_activeTime += dt; x150_ += x154_ * dt; x154_ += dt * x114_data.GetX30(); x110_elementGen->SetExternalVar(0, x150_); @@ -92,7 +92,7 @@ void CShockWave::Think(float dt, CStateManager& mgr) { x16d_hitPlayer = false; } } - if (x110_elementGen->IsSystemDeletable() && x15c_ > 0.f && x158_ >= x15c_) { + if (x110_elementGen->IsSystemDeletable() && x15c_minActiveTime > 0.f && x158_activeTime >= x15c_minActiveTime) { mgr.FreeScriptObject(GetUniqueId()); } else if (x980_id2 != kInvalidUniqueId) { if (TCastToPtr light = mgr.ObjectById(x980_id2)) { @@ -104,7 +104,7 @@ void CShockWave::Think(float dt, CStateManager& mgr) { } void CShockWave::Touch(CActor& actor, CStateManager& mgr) { - if (x158_ >= x15c_) { + if (x158_activeTime >= x15c_minActiveTime) { return; } @@ -120,7 +120,7 @@ void CShockWave::Touch(CActor& actor, CStateManager& mgr) { float mmin = mmax * x114_data.GetX28() * x114_data.GetX28(); zeus::CVector3f dist = actor.GetTranslation() - GetTranslation(); CDamageInfo damageInfo = xec_damageInfo; - float knockBackScale = std::max(0.f, 1.f - x160_ * x158_); + float knockBackScale = std::max(0.f, 1.f - x160_knockback * x158_activeTime); bool isPlayer = mgr.GetPlayer().GetUniqueId() == actor.GetUniqueId(); bool isPlayerInAir = isPlayer && mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround; float distXYMag = dist.toVec2f().magSquared(); diff --git a/Runtime/MP1/World/CShockWave.hpp b/Runtime/MP1/World/CShockWave.hpp index 25a90c4f8..6947cbf73 100644 --- a/Runtime/MP1/World/CShockWave.hpp +++ b/Runtime/MP1/World/CShockWave.hpp @@ -40,9 +40,9 @@ private: SShockWaveData x114_data; float x150_; float x154_; - float x158_ = 0.f; - float x15c_; - float x160_; + float x158_activeTime = 0.f; + float x15c_minActiveTime; + float x160_knockback; float x164_timeSinceHitPlayerInAir = 0.f; float x168_timeSinceHitPlayer = 0.f; bool x16c_hitPlayerInAir = false; @@ -53,7 +53,7 @@ private: public: CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, - TUniqueId parent, const SShockWaveData& data, float f1, float f2); + TUniqueId parent, const SShockWaveData& data, float minActiveTime, float knockback); void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; From 0c1f4fa738fdb45acf9a2f43b94e1a2dc1ffbda8 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 15:01:44 -0400 Subject: [PATCH 25/26] CElitePirate/etc: Use prefix increment/decrement --- Runtime/MP1/World/CBouncyGrenade.cpp | 2 +- Runtime/MP1/World/CElitePirate.cpp | 2 +- Runtime/MP1/World/CGrenadeLauncher.cpp | 2 +- Runtime/MP1/World/CShockWave.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index a749bcd61..178eb1d2d 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -87,7 +87,7 @@ void CBouncyGrenade::CollidedWith(TUniqueId id, const CCollisionInfoList& list, ApplyImpulseWR(impulse, angle); CSfxManager::AddEmitter(x258_data.GetBounceSfx(), GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways()); - x294_numBounces--; + --x294_numBounces; } break; } diff --git a/Runtime/MP1/World/CElitePirate.cpp b/Runtime/MP1/World/CElitePirate.cpp index 23bcc515c..a7cc4272f 100644 --- a/Runtime/MP1/World/CElitePirate.cpp +++ b/Runtime/MP1/World/CElitePirate.cpp @@ -341,7 +341,7 @@ void CElitePirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node case EUserEventType::BecomeShootThrough: if (HasWeakPointHead()) { u32 numCollisionActors = x730_collisionActorMgrHead->GetNumCollisionActors(); - for (u32 i = 0; i < numCollisionActors; i++) { + for (u32 i = 0; i < numCollisionActors; ++i) { const auto& description = x730_collisionActorMgrHead->GetCollisionDescFromIndex(i); if (TCastToPtr actor = mgr.ObjectById(description.GetCollisionActorId())) { actor->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index abcb3764d..26f184cb4 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -31,7 +31,7 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C } GetModelData()->EnableLooping(true); const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); - for (int i = 0; i < x3c8_animIds.size(); i++) { + for (int i = 0; i < x3c8_animIds.size(); ++i) { const auto result = pasDatabase.FindBestAnimation({22, CPASAnimParm::FromEnum(i)}, -1); x3c8_animIds[i] = result.second; } diff --git a/Runtime/MP1/World/CShockWave.cpp b/Runtime/MP1/World/CShockWave.cpp index 32958ea8d..a61cbd53a 100644 --- a/Runtime/MP1/World/CShockWave.cpp +++ b/Runtime/MP1/World/CShockWave.cpp @@ -77,7 +77,7 @@ void CShockWave::Think(float dt, CStateManager& mgr) { x150_ += x154_ * dt; x154_ += dt * x114_data.GetX30(); x110_elementGen->SetExternalVar(0, x150_); - for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); i++) { + for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); ++i) { auto& particle = static_cast(x110_elementGen->GetActiveChildParticle(i)); if (particle.Get4CharId() == SBIG('PART')) { particle.SetExternalVar(0, x150_); From 62e58553c55dadb38635ea6a7b3d737725368dd6 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 1 Apr 2020 15:32:38 -0400 Subject: [PATCH 26/26] CBouncyGrenade/CGrenadeLauncher: Explicit constructor fixes --- Runtime/MP1/World/CBouncyGrenade.cpp | 2 +- Runtime/MP1/World/CGrenadeLauncher.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Runtime/MP1/World/CBouncyGrenade.cpp b/Runtime/MP1/World/CBouncyGrenade.cpp index 178eb1d2d..05fe40b0f 100644 --- a/Runtime/MP1/World/CBouncyGrenade.cpp +++ b/Runtime/MP1/World/CBouncyGrenade.cpp @@ -14,7 +14,7 @@ CBouncyGrenade::CBouncyGrenade(TUniqueId uid, std::string_view name, const CEnti TUniqueId parentId, const SBouncyGrenadeData& data, float velocity, float explodePlayerDistance) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Projectile, EMaterialTypes::Solid}, - mData.GetBounds(), SMoverData(data.GetUnkStruct().GetMass()), actParams, 0.3f, 0.1f) + mData.GetBounds(), SMoverData{data.GetUnkStruct().GetMass()}, actParams, 0.3f, 0.1f) , x258_data(data) , x294_numBounces(data.GetNumBounces()) , x298_parentId(parentId) diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 26f184cb4..6f88fbd3e 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -17,7 +17,7 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C const CActorParameters& actParams, TUniqueId parentId, const SGrenadeLauncherData& data, float f1) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), {EMaterialTypes::Character, EMaterialTypes::Solid}, bounds, - {1000.f}, actParams, 0.3f, 0.1f) + SMoverData{1000.f}, actParams, 0.3f, 0.1f) , x25c_healthInfo(healthInfo) , x264_vulnerability(vulnerability) , x2cc_parentId(parentId) @@ -32,7 +32,7 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C GetModelData()->EnableLooping(true); const CPASDatabase& pasDatabase = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase(); for (int i = 0; i < x3c8_animIds.size(); ++i) { - const auto result = pasDatabase.FindBestAnimation({22, CPASAnimParm::FromEnum(i)}, -1); + const auto result = pasDatabase.FindBestAnimation(CPASAnimParmData{22, CPASAnimParm::FromEnum(i)}, -1); x3c8_animIds[i] = result.second; } } @@ -285,7 +285,7 @@ void CGrenadeLauncher::sub_80230438() { constexpr std::array arr = {0, 3}; const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation( - {5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(arr[x258_started])}, -1); + CPASAnimParmData{5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(arr[x258_started])}, -1); if (anim.first > 0.f) { animData->SetAnimation({anim.second, -1, 1.f, true}, false); modelData->EnableLooping(true); @@ -299,7 +299,7 @@ void CGrenadeLauncher::LaunchGrenade(CStateManager& mgr) { return; } - const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation({23}, -1); + const auto& anim = animData->GetCharacterInfo().GetPASDatabase().FindBestAnimation(CPASAnimParmData{23}, -1); if (anim.first > 0.f) { animData->AddAdditiveAnimation(anim.second, 1.f, false, true); const zeus::CVector3f& origin =