diff --git a/Runtime/MP1/World/CFlyingPirate.cpp b/Runtime/MP1/World/CFlyingPirate.cpp index 727d71c0d..ddb5dfa8c 100644 --- a/Runtime/MP1/World/CFlyingPirate.cpp +++ b/Runtime/MP1/World/CFlyingPirate.cpp @@ -7,7 +7,7 @@ namespace urde::MP1 { namespace { -constexpr std::array skBurst1{{ +constexpr std::array skBurst1{{ {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}, @@ -16,7 +16,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 skBurst2{{ {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}, @@ -25,7 +25,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 skBurst3{{ {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}, @@ -33,7 +33,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 skBurst4{{ {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}, @@ -41,10 +41,16 @@ constexpr std::array skBurst4{{ {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000}, }}; -constexpr std::array skBursts{ +constexpr std::array skBursts{ skBurst1.data(), skBurst2.data(), skBurst3.data(), skBurst4.data(), nullptr, }; + +constexpr std::array skParts{ + "s_Head", "s_R_shoulder", "s_R_elbow", "s_R_wrist", "s_L_shoulder", "s_L_elbow", "s_L_wrist", + "s_R_hip", "s_R_knee", "s_R_ankle", "s_L_hip", "s_L_knee", "s_L_ankle", "s_rocket_LCTR", +}; } // namespace + CFlyingPirate::CFlyingPirateData::CFlyingPirateData(CInputStream& in, u32 propCount) : x0_(in.readFloatBig()) , x4_(in.readFloatBig()) @@ -78,6 +84,73 @@ CFlyingPirate::CFlyingPirateData::CFlyingPirateData(CInputStream& in, u32 propCo x60_projInfo3.Token().Lock(); } +CFlyingPirate::CFlyingPirateRagDoll::CFlyingPirateRagDoll(CStateManager& mgr, CFlyingPirate* actor, u16 w1, u16 w2) +: CRagDoll(-actor->GetGravityConstant(), 3.f, 8.f, 0) +, x88_(w1) +, x9c_(w2) +, xa4_(actor->GetDestPos() - actor->GetTranslation()) { + actor->RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::AIBlock, EMaterialTypes::GroundCollider, mgr); + actor->HealthInfo(mgr)->SetHP(-1.f); + SetNumParticles(15); + SetNumLengthConstraints(45); + SetNumJointConstraints(4); + CAnimData* animData = actor->GetModelData()->GetAnimationData(); + animData->BuildPose(); + const zeus::CVector3f& center = actor->GetBoundingBox().center(); + for (const auto& part : skParts) { + const CSegId& id = animData->GetLocatorSegId(part); + AddParticle(id, center, center * animData->GetPose().GetOffset(id), 0.45f * center.z()); + } + SatisfyWorldConstraintsOnConstruction(mgr); + AddLengthConstraint(0, 1); + AddLengthConstraint(0, 2); + AddLengthConstraint(0, 8); + AddLengthConstraint(0, 11); + AddLengthConstraint(0, 5); + AddLengthConstraint(2, 3); + AddLengthConstraint(3, 4); + AddLengthConstraint(5, 6); + AddLengthConstraint(6, 7); + AddLengthConstraint(2, 5); + AddLengthConstraint(2, 11); + AddLengthConstraint(5, 8); + AddLengthConstraint(5, 11); + AddLengthConstraint(8, 11); + AddLengthConstraint(8, 9); + AddLengthConstraint(9, 10); + AddLengthConstraint(11, 12); + AddLengthConstraint(12, 13); + AddLengthConstraint(14, 0); + AddLengthConstraint(14, 2); + AddLengthConstraint(14, 5); + AddLengthConstraint(14, 8); + AddLengthConstraint(14, 11); + AddMinLengthConstraint(1, 8, x14_lengthConstraints[2].GetLength()); + AddMinLengthConstraint(1, 11, x14_lengthConstraints[3].GetLength()); + AddMinLengthConstraint(4, 2, x14_lengthConstraints[5].GetLength()); + AddMinLengthConstraint(7, 5, x14_lengthConstraints[7].GetLength()); + AddMinLengthConstraint(3, 5, 0.5f * x14_lengthConstraints[5].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(6, 2, 0.5f * x14_lengthConstraints[7].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(4, 5, 0.5f * x14_lengthConstraints[5].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(7, 2, 0.5f * x14_lengthConstraints[7].GetLength() + x14_lengthConstraints[9].GetLength()); + AddMinLengthConstraint(10, 8, x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(11, 11, x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(9, 2, 0.707f * x14_lengthConstraints[15].GetLength() + x14_lengthConstraints[10].GetLength()); + AddMinLengthConstraint(12, 5, 0.707f * x14_lengthConstraints[17].GetLength() + x14_lengthConstraints[13].GetLength()); + AddMinLengthConstraint(9, 11, x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(12, 8, x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(10, 0, x14_lengthConstraints[2].GetLength() + x14_lengthConstraints[15].GetLength()); + AddMinLengthConstraint(13, 0, x14_lengthConstraints[3].GetLength() + x14_lengthConstraints[17].GetLength()); + AddMinLengthConstraint(9, 12, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(10, 12, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(13, 9, 0.5f * x14_lengthConstraints[14].GetLength()); + AddMinLengthConstraint(10, 13, 0.5f * x14_lengthConstraints[14].GetLength()); + AddJointConstraint(8, 2, 5, 8, 9, 10); + AddJointConstraint(11, 2, 5, 11, 12, 13); + AddJointConstraint(2, 11, 5, 2, 3, 4); + AddJointConstraint(5, 2, 8, 5, 6, 7); +} + CFlyingPirate::CFlyingPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CInputStream& in, u32 propCount) @@ -88,8 +161,8 @@ CFlyingPirate::CFlyingPirate(TUniqueId uid, std::string_view name, const CEntity , x7a0_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) , x7ec_burstFire(skBursts.data(), 0) { - CModelData* modelData = GetModelData(); - CAnimData* animData = modelData->GetAnimationData(); + const CModelData* modelData = GetModelData(); + const CAnimData* animData = modelData->GetAnimationData(); x798_ = animData->GetLocatorSegId("Head_1"); x7e0_ = animData->GetLocatorSegId("L_gun_LCTR"); x864_missileSegments.push_back(animData->GetLocatorSegId("L_Missile_LCTR")); diff --git a/Runtime/MP1/World/CFlyingPirate.hpp b/Runtime/MP1/World/CFlyingPirate.hpp index 24aaf422b..ba7398eb6 100644 --- a/Runtime/MP1/World/CFlyingPirate.hpp +++ b/Runtime/MP1/World/CFlyingPirate.hpp @@ -1,9 +1,11 @@ #pragma once #include "Runtime/Character/CBoneTracking.hpp" +#include "Runtime/Character/CRagDoll.hpp" #include "Runtime/Particle/CElementGen.hpp" #include "Runtime/Weapon/CBurstFire.hpp" #include "Runtime/Weapon/CProjectileInfo.hpp" +#include "Runtime/World/CAi.hpp" #include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CPatterned.hpp" @@ -48,10 +50,91 @@ private: CFlyingPirateData(CInputStream& in, u32 propCount); }; + class CFlyingPirateRagDoll : CRagDoll { + private: + CFlyingPirate* x6c_actor; + float x70_ = 0.f; + zeus::CVector3f x74_ = zeus::skUp; + float x80_ = 0.f; + float x84_ = 5.f; + u16 x88_; + float x8c_ = 0.f; + zeus::CVector3f x90_ = zeus::skZero3f; + u16 x9c_; + int xa0_ = 0; + zeus::CVector3f xa4_; + char xb0_; // TODO flags + + public: + CFlyingPirateRagDoll(CStateManager& mgr, CFlyingPirate* actor, u16 w1, u16 w2); + + void PreRender(const zeus::CVector3f& pos, CModelData& mData) override; + void Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData) override; + void Update(CStateManager& mgr, float dt, float waterTop) override; + }; + public: CFlyingPirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CActorParameters&, const CPatternedInfo&, CInputStream&, u32); + 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; + bool AnimOver(CStateManager& mgr, float arg) override; + void CalculateRenderBounds() override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + void MassiveDeath(CStateManager& mgr) override; + float GetGravityConstant() const override { return 50.f; /* TODO check flags */ } + CPathFindSearch* GetSearchPath() override { return &x6a8_pathFindSearch; } + bool IsListening() const override { return true; } + bool KnockbackWhenFrozen() const override { return false; } + bool Listen(const zeus::CVector3f& pos, EListenNoiseType type) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + CProjectileInfo* GetProjectileInfo() override { return &x568_data.xc_projInfo1; } + void Think(float dt, CStateManager& mgr) override; + + void Attack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Bounce(CStateManager& mgr, EStateMsg msg, float arg) override; + void Deactivate(CStateManager& mgr, EStateMsg msg, float arg) override; + void Dead(CStateManager& mgr, EStateMsg msg, float arg) override; + void Dodge(CStateManager& mgr, EStateMsg msg, float arg) override; + void Enraged(CStateManager& mgr, EStateMsg msg, float arg) override; + void Explode(CStateManager& mgr, EStateMsg msg, float arg) override; + void GetUp(CStateManager& mgr, EStateMsg msg, float arg) override; + void Jump(CStateManager& mgr, EStateMsg msg, float arg) override; + void KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; + void Land(CStateManager& mgr, EStateMsg msg, float arg) override; + void Lurk(CStateManager& mgr, EStateMsg msg, float arg) override; + void PathFind(CStateManager& mgr, EStateMsg msg, float arg) override; + void Patrol(CStateManager& mgr, EStateMsg msg, float arg) override; + void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Retreat(CStateManager& mgr, EStateMsg msg, float arg) override; + void TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) override; + void Taunt(CStateManager& mgr, EStateMsg msg, float arg) override; + void TurnAround(CStateManager& mgr, EStateMsg msg, float arg) override; + void Walk(CStateManager& mgr, EStateMsg msg, float arg) override; + + bool AggressionCheck(CStateManager& mgr, float arg) override; + bool Attacked(CStateManager& mgr, float arg) override; + bool CoverCheck(CStateManager& mgr, float arg) override; + bool CoverFind(CStateManager& mgr, float arg) override; + bool HearPlayer(CStateManager& mgr, float arg) override; + bool HearShot(CStateManager& mgr, float arg) override; + bool InPosition(CStateManager& mgr, float arg) override; + bool InRange(CStateManager& mgr, float arg) override; + bool Landed(CStateManager& mgr, float arg) override; + bool LineOfSight(CStateManager& mgr, float arg) override; + bool PatternOver(CStateManager& mgr, float arg) override; + bool ShotAt(CStateManager& mgr, float arg) override; + bool ShouldAttack(CStateManager& mgr, float arg) override; + bool ShouldDodge(CStateManager& mgr, float arg) override; + bool ShouldMove(CStateManager& mgr, float arg) override; + bool ShouldRetreat(CStateManager& mgr, float arg) override; + bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; + bool SpotPlayer(CStateManager& mgr, float arg) override; + bool Stuck(CStateManager& mgr, float arg) override; + private: CFlyingPirateData x568_data; rstl::reserved_vector, 4> x65c_particleGenDescs; @@ -88,8 +171,20 @@ private: TUniqueId x890_ = kInvalidUniqueId; float x894_ = 1.f; float x898_ = 1.f; -// CFlyingPirateRagDoll x89c_ragDoll; TODO + std::unique_ptr x89c_ragDoll; TUniqueId x8a0_ = kInvalidUniqueId; float x8a4_ = 0.f; + + zeus::CVector3f AvoidActors(CStateManager& mgr); + bool CanFireMissiles(CStateManager& mgr); + bool CheckForProjectiles(CStateManager& mgr); + void FireProjectile(CStateManager& mgr, const zeus::CVector3f& pos); + pas::EStepDirection GetDodgeDirection(CStateManager& mgr, float arg); + zeus::CVector3f GetTargetPos(CStateManager& mgr); + bool LineOfSightTest(CStateManager& mgr, zeus::CVector3f& pos, zeus::CVector3f& dir, CMaterialList materials); + void UpdateLandingSmoke(CStateManager& mgr, bool active); + void UpdateParticleEffects(CStateManager& mgr, float f1, bool b1); + void DeliverGetUp(); + void UpdateCantSeePlayer(CStateManager& mgr); }; } // namespace urde::MP1 diff --git a/Runtime/World/CAi.hpp b/Runtime/World/CAi.hpp index 0f739769c..6ba2be1ca 100644 --- a/Runtime/World/CAi.hpp +++ b/Runtime/World/CAi.hpp @@ -55,7 +55,7 @@ public: virtual void TakeDamage(const zeus::CVector3f& direction, float magnitude) {} virtual bool CanBeShot(const CStateManager&, int) { return true; } virtual bool IsListening() const { return false; } - virtual bool Listen(const zeus::CVector3f&, EListenNoiseType) { return 0; } + virtual bool Listen(const zeus::CVector3f&, EListenNoiseType) { return false; } virtual zeus::CVector3f GetOrigin(const CStateManager& mgr, const CTeamAiRole& role, const zeus::CVector3f& aimPos) const { diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index 612eec1be..840ed78c8 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -379,6 +379,7 @@ public: bool sendCollideMsg, const zeus::CVector3f& scale); void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const zeus::CVector3f& GetDestPos() const { return x2e0_destPos; } void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; } void UpdateAlphaDelta(float dt, CStateManager& mgr); void SetModelAlpha(float a) { x42c_color.a() = a; }