diff --git a/Runtime/MP1/World/CGrenadeLauncher.cpp b/Runtime/MP1/World/CGrenadeLauncher.cpp index 08f556b7e..1611e26b4 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.cpp +++ b/Runtime/MP1/World/CGrenadeLauncher.cpp @@ -216,7 +216,8 @@ void CGrenadeLauncher::sub_8022f9e0(CStateManager& mgr, float dt) { CModelData* modelData = GetModelData(); CAnimData* animData = nullptr; - if (modelData != nullptr && (animData = modelData->GetAnimationData()) != nullptr && x258_started == 1 && x3fe_) { + if (modelData != nullptr && (animData = modelData->GetAnimationData()) != nullptr && x258_started == 1 && + x3fe_followPlayer) { 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 diff --git a/Runtime/MP1/World/CGrenadeLauncher.hpp b/Runtime/MP1/World/CGrenadeLauncher.hpp index ad865e7f2..c0cd93b1e 100644 --- a/Runtime/MP1/World/CGrenadeLauncher.hpp +++ b/Runtime/MP1/World/CGrenadeLauncher.hpp @@ -88,7 +88,7 @@ private: float x3f8_explodePlayerDistance; bool x3fc_launchGrenade = false; bool x3fd_visible = true; - bool x3fe_ = true; + bool x3fe_followPlayer = true; public: CGrenadeLauncher(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, @@ -108,6 +108,8 @@ public: void Think(float dt, CStateManager& mgr) override; void Touch(CActor& act, CStateManager& mgr) override; + void SetFollowPlayer(bool val) { x3fe_followPlayer = val; } + 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); diff --git a/Runtime/MP1/World/COmegaPirate.cpp b/Runtime/MP1/World/COmegaPirate.cpp index 26bfdb7e4..1320c5c76 100644 --- a/Runtime/MP1/World/COmegaPirate.cpp +++ b/Runtime/MP1/World/COmegaPirate.cpp @@ -284,7 +284,45 @@ void COmegaPirate::Dizzy(CStateManager& mgr, EStateMsg msg, float dt) { } void COmegaPirate::DoubleSnap(CStateManager& mgr, EStateMsg msg, float dt) { - // TODO + if (msg == EStateMsg::Activate) { + SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None); + SetShotAt(false, mgr); + SetState(CElitePirate::EState::Zero); + xa44_ = false; + xa4a_ = false; + xa88_ = false; + xa8c_ = 3.f; + for (auto& entry : x9dc_scriptPlatforms) { + if (auto platform = static_cast(mgr.ObjectById(entry.first))) { + platform->SetActive(true); + platform->SetDamageVulnerability(xae4_platformVuln); + platform->AddMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr); + platform->SetDisableXRayAlpha(false); + platform->SetXRayFog(true); + } + } + xb64_ = 17.f; + AddMaterial(EMaterialTypes::Scannable, mgr); + } else if (msg == EStateMsg::Update) { + if (GetState() == CElitePirate::EState::Zero) { + if (GetBodyController()->GetCurrentStateId() == pas::EAnimationState::Step) { + SetState(CElitePirate::EState::Two); + } else { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCStepCmd(pas::EStepDirection::Backward, pas::EStepType::BreakDodge)); + } + } else if (GetState() == CElitePirate::EState::Two && + GetBodyController()->GetCurrentStateId() != pas::EAnimationState::Step) { + SetState(CElitePirate::EState::Over); + } + } else if (msg == EStateMsg::Deactivate) { + if (auto launcher = static_cast(mgr.ObjectById(GetLauncherId()))) { + launcher->SetFollowPlayer(true); + } + if (auto launcher = static_cast(mgr.ObjectById(x990_launcherId2))) { + launcher->SetFollowPlayer(true); + } + } } void COmegaPirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { @@ -306,7 +344,23 @@ void COmegaPirate::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node } break; case EUserEventType::ObjectPickUp: - // TODO + xab4_.clear(); + xac8_ = 0; + ++xacc_; + if (xac4_ == 0) { + sub_8028cbec(2, mgr); + } else if (xac4_ == 1) { + sub_8028cbec(1, mgr); + sub_8028cbec(1, mgr); + } else if (xac4_ == 2) { + sub_8028cbec(2, mgr); + sub_8028cbec(1, mgr); + } else if (xac4_ == 3) { + sub_8028cbec(1, mgr); + sub_8028cbec(1, mgr); + sub_8028cbec(1, mgr); + } + SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None); break; case EUserEventType::Projectile: case EUserEventType::DamageOn: @@ -691,4 +745,17 @@ void COmegaPirate::SetupCollisionActorInfo2(const std::unique_ptr arr{0, 0, 0, 0}; + for (const auto i : xab4_) { + arr[i]++; + } + u8 ret = 0; + for (size_t i = 0; i < arr.size(); ++i) { + if (xb7c_[i] != 0 || arr[i] != 0) { + ret++; + } + } + return ret; +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/COmegaPirate.hpp b/Runtime/MP1/World/COmegaPirate.hpp index 5c7a6d256..8bf0bcdc9 100644 --- a/Runtime/MP1/World/COmegaPirate.hpp +++ b/Runtime/MP1/World/COmegaPirate.hpp @@ -56,7 +56,7 @@ private: std::unique_ptr xa9c_collisionActorMgr2; std::vector> xaa0_scriptSounds; float xab0_ = 0.f; - std::vector xab4_; // TODO type + std::vector xab4_; int xac4_ = 0; int xac8_ = 0; int xacc_ = 0; @@ -143,5 +143,9 @@ private: std::vector& outJoints) const; void SetupCollisionActorInfo1(const std::unique_ptr& actMgr, CStateManager& mgr); void SetupCollisionActorInfo2(const std::unique_ptr& actMgr, CStateManager& mgr); + + void sub_8028cbec(u32 arg, CStateManager& mgr); + int sub_8028c230() const; + u8 sub_8028bfac() const; }; } // namespace urde::MP1 diff --git a/Runtime/World/CScriptPlatform.hpp b/Runtime/World/CScriptPlatform.hpp index d2dcdcfa8..caaf4a352 100644 --- a/Runtime/World/CScriptPlatform.hpp +++ b/Runtime/World/CScriptPlatform.hpp @@ -83,8 +83,8 @@ public: CModelData&& mData, const CActorParameters& actParms, const zeus::CAABox& aabb, float speed, bool detectCollision, float xrayAlpha, bool active, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, - const std::optional>& dcln, - bool rainSplashes, u32 maxRainSplashes, u32 rainGenRate); + const std::optional>& dcln, bool rainSplashes, + u32 maxRainSplashes, u32 rainGenRate); void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; @@ -112,8 +112,11 @@ public: TUniqueId GetWaypoint(CStateManager&); const CDamageVulnerability* GetDamageVulnerability() const override { return &x29c_damageVuln; } + void SetDamageVulnerability(const CDamageVulnerability& vuln) { x29c_damageVuln = vuln; } CHealthInfo* HealthInfo(CStateManager&) override { return &x294_health; } void SetControlledAnimation(bool controlled) { x356_25_controlledAnimation = controlled; } + void SetDisableXRayAlpha(bool val) { x356_30_disableXrayAlpha = val; } + void SetXRayFog(bool val) { x356_31_xrayFog = val; } virtual void SplashThink(const zeus::CAABox&, const CFluidPlane&, float, CStateManager&) const; virtual zeus::CQuaternion Move(float, CStateManager&);