From 841996a872322993e7cef2df88f96ad49865fc93 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 5 Jan 2020 20:24:54 -0800 Subject: [PATCH] More work on CThardus --- Runtime/Character/CParticleData.hpp | 2 + Runtime/MP1/World/CThardus.cpp | 340 ++++++++++++++++++++++------ Runtime/MP1/World/CThardus.hpp | 79 ++++--- Runtime/World/CDestroyableRock.cpp | 53 ++++- Runtime/World/CDestroyableRock.hpp | 49 +++- 5 files changed, 416 insertions(+), 107 deletions(-) diff --git a/Runtime/Character/CParticleData.hpp b/Runtime/Character/CParticleData.hpp index e79a01866..907f406d4 100644 --- a/Runtime/Character/CParticleData.hpp +++ b/Runtime/Character/CParticleData.hpp @@ -37,6 +37,8 @@ class CAuxiliaryParticleData { float x18_scale = 1.f; public: + CAuxiliaryParticleData(u32 duration, const SObjectTag& particle, const zeus::CVector3f& translation, float scale) + : x0_duration(duration), x4_particle(particle), xc_translation(translation), x18_scale(scale) {} u32 GetDuration() const { return x0_duration; } const SObjectTag& GetTag() const { return x4_particle; } const zeus::CVector3f& GetTranslation() const { return xc_translation; } diff --git a/Runtime/MP1/World/CThardus.cpp b/Runtime/MP1/World/CThardus.cpp index 42f673507..67003f8a1 100644 --- a/Runtime/MP1/World/CThardus.cpp +++ b/Runtime/MP1/World/CThardus.cpp @@ -1,5 +1,7 @@ #include "Runtime/MP1/World/CThardus.hpp" +#include "Runtime/Camera/CCameraManager.hpp" +#include "Runtime/Camera/CFirstPersonCamera.hpp" #include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/CStateManager.hpp" @@ -11,6 +13,7 @@ #include "Runtime/World/CPlayer.hpp" #include "Runtime/World/CScriptWaypoint.hpp" #include "Runtime/World/CWorld.hpp" +#include "Runtime/MP1/CSamusHud.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -46,6 +49,10 @@ constexpr std::array skSearchJointNames = { "L_Back_Rock_Collision_LCTR"sv, "Head_Collision_LCTR"sv, }; + +constexpr std::array skRockJoints = { + "R_knee"sv, "R_forearm"sv, "L_elbow"sv, "L_hip"sv, "R_collar_BigRock_SDK"sv, "collar_rock4_SDK"sv, "Neck_1"sv, +}; } // namespace CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, @@ -80,7 +87,7 @@ CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info , x758_(sfxId2) , x75c_(sfxId3) , x760_(sfxId4) -, x7f0_(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) { +, x7f0_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f) { CMaterialList exclude = GetMaterialFilter().GetExcludeList(); CMaterialList include = GetMaterialFilter().GetIncludeList(); exclude.Add(EMaterialTypes::Player); @@ -98,35 +105,54 @@ CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info GetModelData()->GetAnimationData()->GetParticleDB().CacheParticleDesc( CCharacterInfo::CParticleResData(gens, {}, {}, {})); x798_.reserve(6); - x7a8_.reserve(16); + x7a8_timers.reserve(16); UpdateThermalFrozenState(true); xd0_damageMag = 0.f; x50c_baseDamageMag = 0.f; - x8f4_.reserve(16); + x8f4_waypoints.reserve(16); x91c_.Lock(); x403_26_stateControlledMassiveDeath = false; x460_knockBackController.SetAutoResetImpulse(false); SetMass(100000.f); } -void CThardus::Think(float dt, CStateManager& mgr) { -// if (!x7c8_) { -// float fVar2 = 10.f * GetModelData()->GetScale().x(); -// zeus::CVector3f diff = mgr.GetPlayer().GetTranslation() - GetTranslation(); -// if (diff.magSquared() < fVar2 * fVar2) { -// mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), -// CDamageInfo(CWeaponMode(EWeaponType::AI), 0.f, 0.f, 10.f), CMaterialFilter::skPassEverything, -// diff.normalized()); -// x688_ = true; -// x7c8_ = false; -// x7cc_.zeroOut(); -// } -// } +void CThardus::sub801dbf34(float dt, CStateManager& mgr) {} +void CThardus::sub801dd608(CStateManager& mgr) { + zeus::CVector3f scale = GetModelData()->GetScale(); + CAnimData* animData = GetModelData()->GetAnimationData(); + for (size_t i = 0; i < x610_destroyableRocks.size(); ++i) { + zeus::CTransform xf = + GetTransform() * (zeus::CTransform::Scale(scale) * animData->GetLocatorTransform(skRockJoints[i], nullptr)); + if (TCastToPtr act = mgr.ObjectById(x610_destroyableRocks[i])) + act->SetTransform(xf); + if (TCastToPtr gl = mgr.ObjectById(x6c0_rockLights[i])) + gl->SetTransform(xf); + } +} +void CThardus::sub801dcfa4(CStateManager& mgr) {} + +void CThardus::Think(float dt, CStateManager& mgr) { + if (!GetActive() && x450_bodyController->GetActive()) { + x91c_.Lock(); + } + + if (x7c8_) { + float fVar2 = 10.f * GetModelData()->GetScale().x(); + zeus::CVector3f diff = mgr.GetPlayer().GetTranslation() - GetTranslation(); + if (diff.magSquared() < fVar2 * fVar2) { + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), + CDamageInfo(CWeaponMode(EWeaponType::AI), 0.f, 0.f, 10.f), CMaterialFilter::skPassEverything, + diff.normalized()); + x688_ = true; + x7c8_ = false; + x7cc_.zeroOut(); + } + } + + sub801dbf34(dt, mgr); - //sub801dbf34(dt, mgr); - /* if (!sub801dc2c8()) { - if (x648_ < x610_destroyableRocks.size() - 2) + if (x648_currentRock < x610_destroyableRocks.size() - 2) x690_ = 1.f; else x690_ = 1.f; @@ -134,8 +160,7 @@ void CThardus::Think(float dt, CStateManager& mgr) { x690_ = 1.f; SendScriptMsgs(EScriptObjectState::DeactivateState, mgr, EScriptObjectMessage::None); } -*/ - /* + if (!x93c_) { x3b4_speed = x690_; x402_28_isMakingBigStrike = false; @@ -144,21 +169,92 @@ void CThardus::Think(float dt, CStateManager& mgr) { x3b4_speed = x690_; x402_28_isMakingBigStrike = true; x504_damageDur = 1.f; - } */ + } CPatterned::Think(dt, mgr); - if (x648_ > 2 && !x689_) { - //sub801dc878(mgr); + if (x648_currentRock > 2 && !x689_) { + _DoSuckState(mgr); } - x5f0_->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + x5f0_rockColliders->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); x5f4_->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); x5f8_->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); - //sub801dd608(mgr); - //sub801dcfa4(mgr); + sub801dd608(mgr); + sub801dcfa4(mgr); + if (x610_destroyableRocks.size() <= x648_currentRock) + Death(mgr, zeus::skZero3f, EScriptObjectState::DeathRattle); + + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { + for (size_t i = 0; i < x610_destroyableRocks.size(); ++i) { + if (CActor* act = static_cast(mgr.ObjectById(x610_destroyableRocks[i]))) { + if (x648_currentRock == i && !x688_ && !x93c_ && !x909_ && !x93d_) { + act->AddMaterial(EMaterialTypes::Orbit, mgr); + act->AddMaterial(EMaterialTypes::Target, mgr); + } else { + RemoveMaterial(EMaterialTypes::Orbit, mgr); + RemoveMaterial(EMaterialTypes::Target, mgr); + } + } + } + if (x688_) + x688_ = false; + + } else { + UpdateNonDestroyableCollisionActorMaterials(EUpdateMaterialMode::Remove, EMaterialTypes::ProjectilePassthrough, mgr); + for (size_t i = 0; i < x610_destroyableRocks.size(); ++i) { + if (CActor* act = static_cast(mgr.ObjectById(x610_destroyableRocks[i]))) { + if (!x688_ && !x93c_ && !x909_ && !x93d_) { + bool found = act->GetName().find("Neck_1"sv) != std::string::npos; + if (!found || !x6b0_[x648_currentRock] || x648_currentRock == x610_destroyableRocks.size() - 1) { + if (!x6b0_[i]) { + if (!found || x6b0_[i]) { + act->RemoveMaterial(EMaterialTypes::Orbit, mgr); + act->RemoveMaterial(EMaterialTypes::Target, mgr); + } + } else { + act->AddMaterial(EMaterialTypes::Orbit, mgr); + act->AddMaterial(EMaterialTypes::Target, mgr); + } + } else { + act->RemoveMaterial(EMaterialTypes::Orbit, mgr); + act->RemoveMaterial(EMaterialTypes::Target, mgr); + } + } else { + x688_ = false; + act->RemoveMaterial(EMaterialTypes::Orbit, mgr); + act->RemoveMaterial(EMaterialTypes::Target, mgr); + } + } + } + } + if (x644_ == 1) { + UpdateExcludeList(x5f0_rockColliders, EUpdateMaterialMode::Add, EMaterialTypes::Player, mgr); + UpdateExcludeList(x5f4_, EUpdateMaterialMode::Add, EMaterialTypes::Player, mgr); + UpdateExcludeList(x5f8_, EUpdateMaterialMode::Add, EMaterialTypes::Player, mgr); + CCameraManager* cameraManager = mgr.GetCameraManager(); + if (x93c_) { + if (x6f8_ < 0.3f) { + x6f8_ += dt; + } else { + if (cameraManager->GetFirstPersonCamera()->GetUniqueId() == cameraManager->GetCurrentCameraId()) { + cameraManager->AddCameraShaker( + CCameraShakeData::BuildMissileCameraShake(0.25f, 0.75f, 125.f, GetTranslation()), true); + } + x6f8_ = 0.f; + } + + if (cameraManager->GetCurrentCameraId() != cameraManager->GetFirstPersonCamera()->GetUniqueId() && x95d_ == 0) { + CSamusHud::DisplayHudMemo(g_MainStringTable->GetString(104), CHUDMemoParms(5.f, true, false, false)); + } + } + } else { + UpdateExcludeList(x5f0_rockColliders, EUpdateMaterialMode::Remove, EMaterialTypes::Player, mgr); + UpdateExcludeList(x5f4_, EUpdateMaterialMode::Remove, EMaterialTypes::Player, mgr); + UpdateExcludeList(x5f8_, EUpdateMaterialMode::Remove, EMaterialTypes::Player, mgr); + } } void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, uid, mgr); @@ -172,11 +268,11 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa break; } case EScriptObjectMessage::SetToMax: { - for (size_t i = x648_; i < x610_destroyableRocks.size() - 1; ++i) { + for (size_t i = x648_currentRock; i < x610_destroyableRocks.size() - 1; ++i) { if (CEntity* ent = mgr.ObjectById(x610_destroyableRocks[i])) { ent->SetActive(false); } - ++x648_; + ++x648_currentRock; } break; } @@ -213,10 +309,8 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa x644_ == 1 ? knockBack : zeus::skZero3f); x420_curDamageRemTime = x424_damageWaitTime; } else if (TCastToConstPtr(mgr.GetObjectById(colAct->GetLastTouchedObject()))) { -#if 0 if (x644_ == 1 && x93c_) - sub801dae2c(mgr, x648_); -#endif + sub801dae2c(mgr, x648_currentRock); } } @@ -231,7 +325,6 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa float health = (i == x5cc_.size() - 1) ? 2.f * x6a8_ : x6a8_; TUniqueId rockId = mgr.AllocateUniqueId(); CModelData mData1(x5cc_[i]); - CModelData mData2(x5dc_[i]); mgr.AddObject(new CDestroyableRock( rockId, true, "", CEntityInfo(GetAreaIdAlways(), NullConnectionList), {}, std::move(mData1), 0.f, CHealthInfo(health, 0.f), @@ -242,16 +335,18 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::One), GetMaterialList(), x630_, CActorParameters(CLightParameters(false, 0.f, CLightParameters::EShadowTesselation::Invalid, 0.f, 0.f, - zeus::skWhite, false, CLightParameters::EWorldLightingOptions::NoShadowCast, + zeus::skWhite, true, CLightParameters::EWorldLightingOptions::NoShadowCast, CLightParameters::ELightRecalculationOptions::LargeFrameCount, zeus::skZero3f, -1, -1, 0, 0), {}, {}, {}, {}, true, true, false, false, 0.f, 0.f, 1.f), - std::move(mData2), 0)); + x5dc_[i], 0)); x610_destroyableRocks.push_back(rockId); x6b0_.push_back(false); TUniqueId lightId = mgr.AllocateUniqueId(); - mgr.AddObject(new CGameLight(lightId, GetAreaIdAlways(), false, ""sv, {}, GetUniqueId(), - CLight::BuildPoint({}, zeus::skBlue), 0, 0, 0.f)); + CGameLight* gl = new CGameLight(lightId, GetAreaIdAlways(), false, ""sv, {}, GetUniqueId(), + CLight::BuildPoint({}, zeus::skBlue), 0, 0, 0.f); + gl->SetActive(false); + mgr.AddObject(gl); x6c0_rockLights.push_back(lightId); x90c_.push_back(health); } @@ -270,10 +365,10 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa break; } case EScriptObjectMessage::Deleted: { - x5f0_->Destroy(mgr); + x5f0_rockColliders->Destroy(mgr); x5f4_->Destroy(mgr); x5f8_->Destroy(mgr); - mgr.FreeScriptObject(x64c_); + mgr.FreeScriptObject(x64c_fog); for (const auto& id : x610_destroyableRocks) { mgr.FreeScriptObject(id); } @@ -284,10 +379,10 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa break; } case EScriptObjectMessage::InitializedInArea: { - if (x94c_) + if (x94c_initialized) break; - x94c_ = true; - x764_ = GetTransform(); + x94c_initialized = true; + x764_startTransform = GetTransform(); for (const SConnection& conn : GetConnectionList()) { TUniqueId connId = mgr.GetIdForScript(conn.x8_objId); @@ -299,27 +394,27 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa rstl::reserved_vector wpIds; GatherWaypoints(wp, mgr, wpIds); for (const auto& id : wpIds) - x570_.push_back(id); + x570_waypoints.push_back(id); } else if (CPatterned* p = CPatterned::CastTo(mgr.ObjectById(connId))) { - x5fc_ = connId; - x60c_ = conn.x8_objId; + x5fc_projectileId = connId; + x60c_projectileEditorId = conn.x8_objId; p->SetActive(false); } else if (TCastToConstPtr(mgr.GetObjectById(connId))) { - x660_.push_back(connId); + x660_repulsors.push_back(connId); } else if (TCastToConstPtr(mgr.GetObjectById(connId))) { - x64c_ = connId; + x64c_fog = connId; } } else if (conn.x0_state == EScriptObjectState::Zero) { if (TCastToPtr wp = mgr.ObjectById(connId)) { - x8f4_.push_back(connId); + x8f4_waypoints.push_back(connId); wp->SetActive(false); } } else if (conn.x0_state == EScriptObjectState::Dead) { if (TCastToConstPtr(mgr.GetObjectById(connId))) - x7a8_.push_back(connId); + x7a8_timers.push_back(connId); } } - x7f0_.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); + x7f0_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); break; } case EScriptObjectMessage::Damage: { @@ -330,7 +425,14 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa } } -void CThardus::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } +void CThardus::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CPatterned::PreRender(mgr, frustum); + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal) { + xb4_drawFlags = CModelFlags(0, 0, 1, zeus::skWhite); + } else { + xb4_drawFlags = CModelFlags(0, 0, 3, zeus::skWhite); + } +} void CThardus::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal && x7c4_ != 0) { @@ -350,8 +452,30 @@ zeus::CAABox CThardus::GetSortingBounds(const CStateManager& mgr) const { void CThardus::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { CPatterned::DoUserAnimEvent(mgr, node, type, dt); } -void CThardus::Patrol(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::Patrol(mgr, msg, arg); } -void CThardus::Dead(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::Dead(mgr, msg, arg); } +void CThardus::Patrol(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x658_ = -1; + x950_ = GetTranslation(); + } else if (msg == EStateMsg::Update) { + if (!ShouldTurn(mgr, 0.f)) + return; + + zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation(); + zeus::CQuaternion q = zeus::CQuaternion::lookAt(x950_, plPos.normalized(), zeus::degToRad(360.f)); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(zeus::skZero3f, q.toTransform() * (plPos - GetTranslation()).normalized(), 1.f)); + x950_ = plPos; + } else if (msg == EStateMsg::Deactivate) { + sub80deadc(mgr); + x94d_ = false; + } +} +void CThardus::Dead(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + SetTransform(x764_startTransform); + } + CPatterned::Dead(mgr, msg, arg); +} void CThardus::PathFind(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::PathFind(mgr, msg, arg); } void CThardus::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) { if (msg == EStateMsg::Activate) { @@ -424,10 +548,13 @@ void CThardus::Cover(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Cover( void CThardus::Enraged(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Enraged(mgr, msg, arg); } void CThardus::Growth(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Growth(mgr, msg, arg); } void CThardus::Faint(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Faint(mgr, msg, arg); } -bool CThardus::PathFound(CStateManager& mgr, float arg) { return CPatterned::PathFound(mgr, arg); } -bool CThardus::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } -bool CThardus::PatternOver(CStateManager& mgr, float arg) { return CPatterned::PatternOver(mgr, arg); } -bool CThardus::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } +bool CThardus::PathFound(CStateManager& mgr, float arg) { return x8d4_; } +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 !x570_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); } @@ -485,8 +612,8 @@ void CThardus::_SetupCollisionActorMaterials(const std::unique_ptr list; _BuildSphereJointList(skDamageableSphereJointInfoList1, 7, list); - x5f0_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); - _SetupCollisionActorMaterials(x5f0_, mgr); + x5f0_rockColliders.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); + _SetupCollisionActorMaterials(x5f0_rockColliders, mgr); list.clear(); _BuildSphereJointList(skDamageableSphereJointInfoList2, 5, list); x5f4_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); @@ -496,11 +623,12 @@ void CThardus::_SetupCollisionManagers(CStateManager& mgr) { x5f8_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); _SetupCollisionActorMaterials(x5f8_, mgr); list.clear(); - x634_.reserve(x5f4_->GetNumCollisionActors() + x5f0_->GetNumCollisionActors() + x5f8_->GetNumCollisionActors()); + x634_nonDestroyableActors.reserve(x5f4_->GetNumCollisionActors() + x5f0_rockColliders->GetNumCollisionActors() + + x5f8_->GetNumCollisionActors()); sub801dd4fc(x5f4_); sub801dd4fc(x5f8_); - for (size_t i = 0; i < x5f0_->GetNumCollisionActors(); ++i) { - const auto& colDesc = x5f0_->GetCollisionDescFromIndex(i); + for (size_t i = 0; i < x5f0_rockColliders->GetNumCollisionActors(); ++i) { + const auto& colDesc = x5f0_rockColliders->GetCollisionDescFromIndex(i); if (TCastToPtr colAct = mgr.ObjectById(colDesc.GetCollisionActorId())) { if (CDestroyableRock* rock = static_cast(mgr.ObjectById(x610_destroyableRocks[i]))) { if (i == 0) { @@ -530,8 +658,92 @@ void CThardus::sub801dd4fc(const std::unique_ptr& colMgr } if (!foundBone) - x634_.push_back(uid); + x634_nonDestroyableActors.push_back(uid); } } -} \ No newline at end of file +void CThardus::sub801dae2c(CStateManager& mgr, u32 rockIndex) { + TCastToPtr rockCol = + mgr.ObjectById(x5f0_rockColliders->GetCollisionDescFromIndex(rockIndex).GetCollisionActorId()); + if (TCastToPtr rock = mgr.ObjectById(x610_destroyableRocks[rockIndex])) { + if (!rock->IsUsingPhazonModel()) { + rock->UsePhazonModel(); + float hp = rockIndex == x5f0_rockColliders->GetNumCollisionActors() - 1 ? 2.f * x6a4_ : x6a4_; + CHealthInfo* hInfo = rock->HealthInfo(mgr); + hInfo->SetHP(hp); + hInfo->SetKnockbackResistance(2.f); + hInfo = rockCol->HealthInfo(mgr); + hInfo->SetHP(hp); + hInfo->SetKnockbackResistance(2.f); + CGameLight* light = static_cast(mgr.ObjectById(x6c0_rockLights[rockIndex])); + light->SetActive(true); + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal || + (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Thermal && x7c4_ != 3)) { + sub801dc444(mgr, GetTranslation(), x6d4_); + } + sub801dbc5c(mgr, rock); + ProcessSoundEvent(x760_, 1.f, 0, 0.1f, 1000.f, 0.16f, 1.f, zeus::skZero3f, GetTranslation(), mgr.GetNextAreaId(), + mgr, true); + } + } +} + +void CThardus::sub801dc444(CStateManager& mgr, const zeus::CVector3f& pos, CAssetId particle) { + u32 w = x6f4_; + ++x6f4_; + std::string particleName = fmt::format(fmt("ROCK_EFFECT{}-{}"), particle.Value(), w); + GetModelData()->GetAnimationData()->GetParticleDB().AddAuxiliaryParticleEffect( + particleName, 0x40, CAuxiliaryParticleData(0, {FOURCC('PART'), particle}, pos, 1.f), + 2.f * GetModelData()->GetScale(), mgr, GetAreaIdAlways(), 0); +} + +void CThardus::sub801dbc5c(CStateManager& mgr, CDestroyableRock* rock) { + if (!x938_) { + x938_ = true; + x939_ = false; + sub801dbbdc(mgr, rock); + } +} + +void CThardus::sub801dbbdc(CStateManager& mgr, CDestroyableRock* rock) { + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) + x688_ = true; + + if (x7c4_ == 0 || x7c4_ == 2) { + x7c4_ = 1; + x7b8_ = 0.f; + } + + x928_currentRockId = rock->GetUniqueId(); + x92c_currentRockPos = rock->GetTranslation(); +} + +void CThardus::UpdateNonDestroyableCollisionActorMaterials(EUpdateMaterialMode mode, EMaterialTypes mat, urde::CStateManager& mgr) { + for (const auto& uid : x634_nonDestroyableActors) { + if (TCastToPtr col = mgr.ObjectById(uid)) { + if (mode == EUpdateMaterialMode::Remove) + col->RemoveMaterial(mat, mgr); + else if (mode == EUpdateMaterialMode::Add) + col->AddMaterial(mat, mgr); + + *col->HealthInfo(mgr) = CHealthInfo(1000000.0, 10.f); + } + } +} + +void CThardus::UpdateExcludeList(const std::unique_ptr& colMgr, EUpdateMaterialMode mode, EMaterialTypes w2, + CStateManager& mgr) { + for (size_t i = 0; i < colMgr->GetNumCollisionActors(); ++i) { + if (TCastToPtr colAct = mgr.ObjectById(colMgr->GetCollisionDescFromIndex(i).GetCollisionActorId())) { + CMaterialList exclude = colAct->GetMaterialFilter().GetExcludeList(); + if (mode == EUpdateMaterialMode::Remove) + exclude.Remove(w2); + else if (mode == EUpdateMaterialMode::Add) + exclude.Add(w2); + + colAct->SetMaterialFilter( + CMaterialFilter::MakeIncludeExclude(colAct->GetMaterialFilter().GetIncludeList(), exclude)); + } + } +} +} // namespace urde::MP1 \ No newline at end of file diff --git a/Runtime/MP1/World/CThardus.hpp b/Runtime/MP1/World/CThardus.hpp index b1749fc95..4a8e9391f 100644 --- a/Runtime/MP1/World/CThardus.hpp +++ b/Runtime/MP1/World/CThardus.hpp @@ -8,6 +8,9 @@ namespace urde { class CCollisionActorManager; namespace MP1 { class CThardus : public CPatterned { + + enum class EUpdateMaterialMode { Add, Remove }; + class CThardusSomething { TUniqueId x0_ = kInvalidUniqueId; zeus::CVector3f x4_; @@ -18,7 +21,7 @@ class CThardus : public CPatterned { }; u32 x568_; TUniqueId x56c_ = kInvalidUniqueId; - std::vector x570_; + std::vector x570_waypoints; u32 x5c4_ = 1; bool x5c8_heardPlayer = false; /* NOTE(phil) These two vectors used to vectors of CModelData, They have been converted to vectors of CStaticRes due @@ -26,27 +29,27 @@ class CThardus : public CPatterned { std::vector x5cc_; std::vector x5dc_; s32 x5ec_ = -1; - std::unique_ptr x5f0_; + std::unique_ptr x5f0_rockColliders; std::unique_ptr x5f4_; std::unique_ptr x5f8_; - TUniqueId x5fc_ = kInvalidUniqueId; + TUniqueId x5fc_projectileId = kInvalidUniqueId; CAssetId x600_; CAssetId x604_; CAssetId x608_; - TEditorId x60c_ = kInvalidEditorId; + TEditorId x60c_projectileEditorId = kInvalidEditorId; std::vector x610_destroyableRocks; u32 x624_; u32 x628_; u32 x62c_; CAssetId x630_; - std::vector x634_; + std::vector x634_nonDestroyableActors; s32 x644_ = -1; - u32 x648_ = 0; - TUniqueId x64c_ = kInvalidUniqueId; + u32 x648_currentRock = 0; + TUniqueId x64c_fog = kInvalidUniqueId; zeus::CVector2f x650_ = zeus::CVector2f(0.f, 1.f); s32 x658_ = -1; s32 x65c_ = -1; - std::vector x660_; + std::vector x660_repulsors; bool x688_ = false; bool x689_ = false; u32 x68c_ = 0; @@ -76,10 +79,10 @@ class CThardus : public CPatterned { s32 x758_; s32 x75c_; s32 x760_; - zeus::CTransform x764_; + zeus::CTransform x764_startTransform; u32 x794_ = 0; std::vector x798_; - std::vector x7a8_; + std::vector x7a8_timers; float x7b8_ = 0.f; float x7bc_ = 10.f; u32 x7c0_; @@ -88,18 +91,19 @@ class CThardus : public CPatterned { zeus::CVector3f x7cc_; zeus::CVector3f x7d8_; zeus::CVector3f x7e4_; - CPathFindSearch x7f0_; + CPathFindSearch x7f0_pathFindSearch; bool x8d4_ = false; zeus::CVector3f x8d8_; zeus::CVector3f x8e4_; bool x8f0_ = false; - std::vector x8f4_; + std::vector x8f4_waypoints; u32 x904_ = 0; bool x908_ = false; + bool x909_ = false; std::vector x90c_; TLockedToken x91c_; - TUniqueId x928_; - zeus::CVector3f x92c_; + TUniqueId x928_currentRockId; + zeus::CVector3f x92c_currentRockPos; bool x938_ = false; bool x939_ = false; bool x93a_ = false; @@ -109,11 +113,11 @@ class CThardus : public CPatterned { u32 x940_ = 0; float x944_ = 0.3f; u32 x948_; - bool x94c_ = false; + bool x94c_initialized = false; bool x94d_ = false; zeus::CVector3f x950_; bool x95c_doCodeTrigger = false; - bool x95d_ = false; + u8 x95d_ = 0; bool x95e_ = false; void SetState(s32 state, CStateManager& mgr) { @@ -127,6 +131,29 @@ class CThardus : public CPatterned { void GatherWaypoints(CScriptWaypoint* wp, CStateManager& mgr, rstl::reserved_vector& uids); void sub801dec80() { x68c_ = 20000; } void sub801dd4fc(const std::unique_ptr& colMgr); + void sub801dbf34(float dt, CStateManager& mgr); + bool sub801dc2c8() const { return (x610_destroyableRocks.size() - 1) == x648_currentRock; } + void _DoSuckState(CStateManager& mgr) { x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Suck"sv); } + void sub801de9f8(CStateManager& mgr){}; + void sub801dd608(CStateManager& mgr); + void sub801dcfa4(CStateManager& mgr); + void sub80deadc(CStateManager& mgr) { + if (x570_waypoints.empty()) { + sub801de9f8(mgr); + } else { + if (sub801dc2c8() || x5c4_ != 0 || x944_ <= 0.f) + sub801de9f8(mgr); + else + x944_ = 0.f; + } + } + 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); + void UpdateNonDestroyableCollisionActorMaterials(EUpdateMaterialMode mode, EMaterialTypes mat, CStateManager& mgr); + void UpdateExcludeList(const std::unique_ptr& colMgr, EUpdateMaterialMode mode, + EMaterialTypes mat, CStateManager& mgr); void _SetupCollisionActorMaterials(const std::unique_ptr& colMgr, CStateManager& mgr); void _SetupCollisionManagers(CStateManager& mgr); void _BuildSphereJointList(const SSphereJointInfo* arr, int count, std::vector& list); @@ -176,29 +203,23 @@ public: bool PathFound(CStateManager& mgr, float arg) override; bool InRange(CStateManager& mgr, float arg) override; bool PatternOver(CStateManager& mgr, float arg) override; - bool HasAttackPattern(CStateManager& mgr, float arg) override { - return x5c4_ == 1 && !ShouldMove(mgr, 0.f); - } + bool HasAttackPattern(CStateManager& mgr, float arg) override { return x5c4_ == 1 && !ShouldMove(mgr, 0.f); } bool AnimOver(CStateManager& mgr, float arg) override; bool InPosition(CStateManager& mgr, float arg) override; bool ShouldTurn(CStateManager& mgr, float arg) override; bool HitSomething(CStateManager& mgr, float arg) override; bool HearPlayer(CStateManager& mgr, float arg) override { return x5c8_heardPlayer; } - bool CoverBlown(CStateManager& mgr, float arg) override { - return x5c4_ == 2 && !ShouldMove(mgr, 0.f); - } - bool CoveringFire(CStateManager& mgr, float arg) override { - return x5c4_ == 0 && !ShouldMove(mgr, 0.f); - } + bool CoverBlown(CStateManager& mgr, float arg) override { return x5c4_ == 2 && !ShouldMove(mgr, 0.f); } + bool CoveringFire(CStateManager& mgr, float arg) override { return x5c4_ == 0 && !ShouldMove(mgr, 0.f); } bool AggressionCheck(CStateManager& mgr, float arg) override { return x330_stateMachineState.GetTime() > 0.1f; } bool AttackOver(CStateManager& mgr, float arg) override { return true; } - bool ShouldTaunt(CStateManager& mgr, float arg) override { return false;} - bool ShouldMove(CStateManager& mgr, float arg) override { return x68c_ < x570_.size() || x93b_; } - bool CodeTrigger(CStateManager& mgr, float arg) override { return x95c_doCodeTrigger;} + bool ShouldTaunt(CStateManager& mgr, float arg) override { return false; } + bool ShouldMove(CStateManager& mgr, float arg) override { return x68c_ < x570_waypoints.size() || x93b_; } + bool CodeTrigger(CStateManager& mgr, float arg) override { return x95c_doCodeTrigger; } bool IsDizzy(CStateManager& mgr, float arg) override { return x330_stateMachineState.GetTime() > 4.f; } bool ShouldCallForBackup(CStateManager& mgr, float arg) override { return x330_stateMachineState.GetTime() > .5f; } - CPathFindSearch* GetSearchPath() override { return &x7f0_; } + CPathFindSearch* GetSearchPath() override { return &x7f0_pathFindSearch; } }; } // namespace MP1 } // namespace urde diff --git a/Runtime/World/CDestroyableRock.cpp b/Runtime/World/CDestroyableRock.cpp index c9b91c2f1..c9a08668a 100644 --- a/Runtime/World/CDestroyableRock.cpp +++ b/Runtime/World/CDestroyableRock.cpp @@ -1,5 +1,7 @@ #include "Runtime/World/CDestroyableRock.hpp" - +#include "Runtime/World/CActorParameters.hpp" +#include "Runtime/CPlayerState.hpp" +#include "Runtime/CStateManager.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde { @@ -7,14 +9,47 @@ CDestroyableRock::CDestroyableRock(TUniqueId id, bool active, std::string_view n const zeus::CTransform& xf, CModelData&& modelData, float mass, const CHealthInfo& health, const CDamageVulnerability& vulnerability, const CMaterialList& matList, CAssetId fsm, const CActorParameters& actParams, - const CModelData& modelData2, s32) + const CStaticRes& phazonModel, s32 w1) : CAi(id, active, name, info, xf, std::move(modelData), modelData.GetBounds(), mass, health, vulnerability, matList, - fsm, actParams, 0.3f, 0.8f) {} - -void CDestroyableRock::Accept(urde::IVisitor& visitor) { - visitor.Visit(this); + fsm, actParams, 0.3f, 0.8f) +, x2d8_phazonModel(phazonModel) +, x32c_thermalMag(actParams.GetThermalMag()) +, x338_healthInfo(health) +, x341_(w1 != 0) { + /* This is now in UsePhazonModel + x2d8_phazonModel->SetSortThermal(true); + */ + CreateShadow(false); +} + +void CDestroyableRock::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } +void CDestroyableRock::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + if (GetActive()) { + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal) { + xb4_drawFlags = CModelFlags(0, 0, 1, zeus::skWhite); + } else { + if (x330_.r() >= 1.f && x330_.g() >= 1.f && x330_.b() >= 1.f) { + xb4_drawFlags = CModelFlags(0, 0, 3, zeus::skWhite); + } else { + x330_.a() = 1.f; + xb4_drawFlags = CModelFlags(0, 0, 3, x330_); + } + } + } + + CActor::PreRender(mgr, frustum); +} +void CDestroyableRock::Think(float dt, CStateManager& mgr) { + if (!GetActive()) + return; + + float damageMag = x32c_thermalMag; + if (x324_ > 0.f) { + x324_ = zeus::max(0.f, x324_ - dt); + x330_ = zeus::CColor::lerp(zeus::skBlack, zeus::CColor(0.5, 0.f, 0.f, 1.f), x324_); + damageMag = ((x335_usePhazonModel ? 0.5f : 0.25f) * x324_) + damageMag; + } + xd0_damageMag = damageMag; + CEntity::Think(dt, mgr); } -void CDestroyableRock::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) {} -void CDestroyableRock::KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, - bool inDeferred, float magnitude) {} } // namespace urde diff --git a/Runtime/World/CDestroyableRock.hpp b/Runtime/World/CDestroyableRock.hpp index ca186abe0..5e0710b56 100644 --- a/Runtime/World/CDestroyableRock.hpp +++ b/Runtime/World/CDestroyableRock.hpp @@ -8,19 +8,58 @@ namespace urde { class CDestroyableRock : public CAi { - float x32c_; + /* Used to be a CModelData */ + CStaticRes x2d8_phazonModel; + float x324_ = 0.f; + float x328_ = 0.f; + float x32c_thermalMag; + zeus::CColor x330_ = zeus::skWhite; + bool x334_isCold = false; + bool x335_usePhazonModel = false; + CHealthInfo x338_healthInfo; + bool x341_; + public: CDestroyableRock(TUniqueId id, bool active, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& modelData, float mass, const CHealthInfo& health, const CDamageVulnerability& vulnerability, const CMaterialList& matList, CAssetId fsm, - const CActorParameters& actParams, const CModelData& modelData2, s32); + const CActorParameters& actParams, const CStaticRes& phazonModel, s32); void Accept(IVisitor& visitor) override; - void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override { + CAi::AcceptScriptMsg(msg, uid, mgr); + if (msg == EScriptObjectMessage::Registered) { + AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); + AddMaterial(EMaterialTypes::CameraPassthrough, mgr); + } + } + void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override { + x334_isCold = true; + } void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, - float magnitude) override; + float magnitude) override {} - void Set_x32c(float val) { x32c_ = val; } + zeus::CVector3f GetAimPosition(const CStateManager&, float) const override { return GetTranslation(); } + zeus::CVector3f GetOrbitPosition(const CStateManager&) const override { return GetTranslation(); } + std::optional GetTouchBounds() const override { return GetModelData()->GetBounds(GetTransform()); } + bool CanRenderUnsorted(const CStateManager&) const override { return true; } + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void TakeDamage(const zeus::CVector3f&, float) override { + x324_ = 1.f; + x328_ = 2.f; + } + + void Think(float dt, CStateManager& mgr) override; + + void Set_x32c(float val) { x32c_thermalMag = val; } + void SetIsCold(bool v) { x334_isCold = v; } + bool IsUsingPhazonModel() const { return x335_usePhazonModel; } + void UsePhazonModel() { + SetModelData(std::make_unique(x2d8_phazonModel)); + x335_usePhazonModel = true; + /* This used to be in the constructor, since we can't store CModelData directly in the class we must set it here */ + GetModelData()->SetSortThermal(true); + } }; } // namespace urde