diff --git a/Runtime/MP1/World/CThardus.cpp b/Runtime/MP1/World/CThardus.cpp index c081a6e37..21336b431 100644 --- a/Runtime/MP1/World/CThardus.cpp +++ b/Runtime/MP1/World/CThardus.cpp @@ -10,6 +10,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/MP1/CSamusHud.hpp" #include "Runtime/MP1/World/CThardusRockProjectile.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CDestroyableRock.hpp" #include "Runtime/World/CGameLight.hpp" @@ -22,6 +23,7 @@ #include "TCastTo.hpp" // Generated file, do not modify include path #include +#include namespace urde::MP1 { namespace { constexpr std::array skDamageableSphereJointInfoList1{{ @@ -428,6 +430,44 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa break; } case EScriptObjectMessage::Damage: { + if (TCastToPtr colAct = mgr.ObjectById(uid)) { + TUniqueId lastTouchedObj = colAct->GetLastTouchedObject(); + TUniqueId targetRock = kInvalidUniqueId; + + for (size_t i = 0; i < x5f0_rockColliders->GetNumCollisionActors(); ++i) { + const CJointCollisionDescription& desc = x5f0_rockColliders->GetCollisionDescFromIndex(i); + if (desc.GetCollisionActorId() == uid) { + targetRock = x610_destroyableRocks[i]; + } + } + + if (targetRock == kInvalidUniqueId) { + break; + } + if (CDestroyableRock* rock = static_cast(mgr.ObjectById(targetRock))) { + if (TCastToConstPtr proj = mgr.GetObjectById(lastTouchedObj)) { + if (GetBodyController()->GetBodyStateInfo().GetCurrentAdditiveStateId() != + pas::EAnimationState::AdditiveReaction && + rock->Get_x324() <= 0.f) { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCAdditiveReactionCmd(pas::EAdditiveReactionType::Five, 1.f, false)); + } + + rock->TakeDamage(zeus::skZero3f, 0.f); + const bool thermalInactive = mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Thermal; + if (thermalInactive || (!thermalInactive && x7c4_ != 3)) { + sub801dc444(mgr, proj->GetTranslation(), x6d0_); + } + if (!rock->IsUsingPhazonModel()) { + ProcessSoundEvent(x75c_, 1.f, 0, 0.1f, 1000.f, 0.16f, 1.f, zeus::skZero3f, rock->GetTranslation(), + mgr.GetNextAreaId(), mgr, true); + } else { + ProcessSoundEvent(SFXsfx0AC0, 1.f, 0, 0.1f, 1000.f, 0.16f, 1.f, zeus::skZero3f, rock->GetTranslation(), + mgr.GetNextAreaId(), mgr, false); + } + } + } + } break; } default: @@ -559,8 +599,8 @@ void CThardus::Attack(CStateManager& mgr, EStateMsg msg, float arg) { } } void CThardus::LoopedAttack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::LoopedAttack(mgr, msg, arg); } -void CThardus::DoubleSnap(CStateManager& mgr, EStateMsg msg, float arg) { } -void CThardus::Shuffle(CStateManager& mgr, EStateMsg msg, float arg) { } +void CThardus::DoubleSnap(CStateManager& mgr, EStateMsg msg, float arg) {} +void CThardus::Shuffle(CStateManager& mgr, EStateMsg msg, float arg) {} void CThardus::GetUp(CStateManager& mgr, EStateMsg msg, float arg) { if (msg != EStateMsg::Activate) return; @@ -611,6 +651,7 @@ void CThardus::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float arg) { } } } + void CThardus::Flinch(CStateManager& mgr, EStateMsg msg, float arg) { if (msg == EStateMsg::Activate) { for (TUniqueId uid : x798_) { @@ -782,11 +823,16 @@ bool CThardus::InRange(CStateManager& mgr, float arg) { return (mgr.GetPlayer().GetTranslation().toVec2f() - GetTranslation().toVec2f()).magnitude() < 10.f * GetModelData()->GetScale().x(); } + bool CThardus::PatternOver(CStateManager& mgr, float arg) { return !x574_waypoints.empty() || x93b_; } bool CThardus::AnimOver(CStateManager& mgr, float arg) { return x5ec_ == 3; } -bool CThardus::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } -bool CThardus::ShouldTurn(CStateManager& mgr, float arg) { return CAi::ShouldTurn(mgr, arg); } -bool CThardus::HitSomething(CStateManager& mgr, float arg) { return CAi::HitSomething(mgr, arg); } +bool CThardus::InPosition(CStateManager& mgr, float arg) { return x660_repulsors.size() > 3; } +bool CThardus::ShouldTurn(CStateManager& mgr, float arg) { + return std::fabs(zeus::CVector2f::getAngleDiff(GetTransform().frontVector().toVec2f(), + mgr.GetPlayer().GetTranslation().toVec2f() - + GetTranslation().toVec2f())) > zeus::degToRad(30.f); +} +bool CThardus::HitSomething(CStateManager& mgr, float arg) { return mgr.GetPlayer().GetFrozenState(); } void CThardus::GatherWaypoints(urde::CScriptWaypoint* wp, urde::CStateManager& mgr, rstl::reserved_vector& uids) { diff --git a/Runtime/MP1/World/CThardus.hpp b/Runtime/MP1/World/CThardus.hpp index e83e82f7c..19a4d86e2 100644 --- a/Runtime/MP1/World/CThardus.hpp +++ b/Runtime/MP1/World/CThardus.hpp @@ -149,9 +149,11 @@ class CThardus : public CPatterned { } } void sub801dae2c(CStateManager& mgr, u32 rockIndex); + void sub801dc444(CStateManager& mgr, const zeus::CVector3f& pos, CAssetId particle); void sub801dbc5c(CStateManager& mgr, CDestroyableRock* rock); void sub801dbbdc(CStateManager& mgr, CDestroyableRock* rock); + bool sub801dc2c8() { return (x610_destroyableRocks.size() - 1) > x648_currentRock; } void UpdateNonDestroyableCollisionActorMaterials(EUpdateMaterialMode mode, EMaterialTypes mat, CStateManager& mgr); void UpdateExcludeList(const std::unique_ptr& colMgr, EUpdateMaterialMode mode, EMaterialTypes mat, CStateManager& mgr); @@ -165,6 +167,10 @@ class CThardus : public CPatterned { std::optional m_flareFilter; + void DoDoubleSnap(CStateManager& mgr) { + x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "DoubleSnap"sv); + } + public: DEFINE_PATTERNED(Thardus); CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, diff --git a/Runtime/World/CDestroyableRock.hpp b/Runtime/World/CDestroyableRock.hpp index 5e0710b56..cd4a79d25 100644 --- a/Runtime/World/CDestroyableRock.hpp +++ b/Runtime/World/CDestroyableRock.hpp @@ -51,6 +51,7 @@ public: void Think(float dt, CStateManager& mgr) override; + float Get_x324() const { return x324_; } void Set_x32c(float val) { x32c_thermalMag = val; } void SetIsCold(bool v) { x334_isCold = v; } bool IsUsingPhazonModel() const { return x335_usePhazonModel; }