diff --git a/Runtime/MP1/World/CIceAttackProjectile.cpp b/Runtime/MP1/World/CIceAttackProjectile.cpp new file mode 100644 index 000000000..292860a51 --- /dev/null +++ b/Runtime/MP1/World/CIceAttackProjectile.cpp @@ -0,0 +1,64 @@ +#include "Runtime/MP1/World/CIceAttackProjectile.hpp" + +#include "Runtime/CStateManager.hpp" +#include "Runtime/World/CActorParameters.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +namespace urde::MP1 { + +CIceAttackProjectile::CIceAttackProjectile(const TToken& gen1, const TToken& gen2, + const TToken& gen3, TUniqueId uid, TAreaId areaId, + TUniqueId owner, bool active, const zeus::CTransform& xf, + const CDamageInfo& dInfo, const zeus::CAABox& bounds, float f1, float f2, + CAssetId unkInt1, u16 unkShort1, u16 unkShort2, CAssetId unkInt2) +: CActor(uid, active, "IceAttackProjectile"sv, CEntityInfo(areaId, NullConnectionList), xf, + CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Projectile, EMaterialTypes::CameraPassthrough), + CActorParameters::None(), kInvalidUniqueId) +, xe8_(gen1) +, xf0_(gen2) +, xf8_(gen3) +, x118_owner(owner) +, x11c_(dInfo) +, x138_(dInfo) +, x154_(bounds) +, x170_(f1) +, x174_(f2) +, x184_(unkInt1) +, x188_(unkShort1) +, x18a_(unkShort2) +, x18c_(unkInt2) { + + zeus::CVector3f m0 = zeus::CVector3f{0.f, 1.f, 0.f}.cross(xf.frontVector()).normalized(); + zeus::CVector3f m1 = m0.cross(zeus::CVector3f{0.f, 0.f, 1.f}).normalized(); + SetTransform(zeus::CTransform(m0, m1, zeus::CVector3f{0.f, 0.f, 1.f}, GetTranslation())); + x100_ = std::make_unique(xf8_, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +void CIceAttackProjectile::Accept(IVisitor& visitor) { + visitor.Visit(this); +} + +void CIceAttackProjectile::Think(float dt, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + if (!x190_) { + } + CEntity::Think(dt, mgr); +} + +void CIceAttackProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, other, mgr); +} + +void CIceAttackProjectile::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { + mgr.AddDrawableActor(*this, -1000.f * CGraphics::g_ViewMatrix.frontVector(), x9c_renderBounds); +} + +void CIceAttackProjectile::Render(CStateManager& mgr) {} + +void CIceAttackProjectile::Touch(CActor& act, CStateManager& mgr) {} +} // namespace urde::MP1 \ No newline at end of file diff --git a/Runtime/MP1/World/CIceAttackProjectile.hpp b/Runtime/MP1/World/CIceAttackProjectile.hpp new file mode 100644 index 000000000..109de5fcd --- /dev/null +++ b/Runtime/MP1/World/CIceAttackProjectile.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "Runtime/World/CActor.hpp" +#include "Runtime/World/CDamageInfo.hpp" + +namespace urde { +class CElementGen; +namespace MP1 { +class CIceAttackProjectile : public CActor { + TToken xe8_; + TToken xf0_; + TToken xf8_; + std::unique_ptr x100_; + std::vector x108_trailObjects; + TUniqueId x118_owner; + CDamageInfo x11c_; + CDamageInfo x138_; + std::optional x154_; + float x170_; + float x174_; + float x178_ = 0.f; + float x17c_ = 0.f; + s32 x180_ = 0; + CAssetId x184_; + u16 x188_; + u16 x18a_; + CAssetId x18c_; + bool x190_ = false; + bool x191_ = false; + bool x192_ = false; + int x194_ = 0; + +public: + CIceAttackProjectile(const TToken& gen1, const TToken& gen2, + const TToken& gen3, TUniqueId uid, TAreaId areaId, TUniqueId owner, bool active, + const zeus::CTransform& xf, const CDamageInfo& dInfo, const zeus::CAABox& bounds, float f1, + float f2, CAssetId unkInt1, u16 unkShort1, u16 unkShort2, CAssetId unkInt2); + + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) override; + void Render(CStateManager& mgr) override; + + [[nodiscard]] std::optional GetTouchBounds() const override { + if (!GetActive()) { + return std::nullopt; + } + return x154_->getTransformedAABox(GetTransform()); + } + + void Touch(CActor& act, CStateManager& mgr) override; +}; +} // namespace MP1 +} // namespace urde diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index c795bd04f..15f231e82 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -51,6 +51,7 @@ set(MP1_WORLD_SOURCES CTryclops.hpp CTryclops.cpp CIceSheegoth.hpp CIceSheegoth.cpp CWarWasp.hpp CWarWasp.cpp + CIceAttackProjectile.hpp CIceAttackProjectile.cpp ) runtime_add_list(World MP1_WORLD_SOURCES) diff --git a/Runtime/MP1/World/CThardus.cpp b/Runtime/MP1/World/CThardus.cpp index 966ac08e3..849cf38cd 100644 --- a/Runtime/MP1/World/CThardus.cpp +++ b/Runtime/MP1/World/CThardus.cpp @@ -2,12 +2,12 @@ #include +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" #include "Runtime/Camera/CCameraManager.hpp" #include "Runtime/Camera/CFirstPersonCamera.hpp" #include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp" -#include "Runtime/CSimplePool.hpp" -#include "Runtime/CStateManager.hpp" #include "Runtime/MP1/CSamusHud.hpp" #include "Runtime/MP1/World/CThardusRockProjectile.hpp" #include "Runtime/Weapon/CGameProjectile.hpp" @@ -16,10 +16,11 @@ #include "Runtime/World/CGameLight.hpp" #include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CRepulsor.hpp" #include "Runtime/World/CScriptDistanceFog.hpp" #include "Runtime/World/CScriptWaypoint.hpp" -#include "Runtime/World/CRepulsor.hpp" #include "Runtime/World/CWorld.hpp" +#include "Runtime/MP1/World/CIceAttackProjectile.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -209,7 +210,16 @@ void CThardus::sub801dbf34(float dt, CStateManager& mgr) { void CThardus::sub801de9f8(CStateManager& mgr) { float dVar5 = mgr.GetActiveRandom()->Float(); if (!sub801dc2c8() || dVar5 >= 0.3f) { - + const float local_28 = std::max(0.f, dVar5 - 0.19999999f); + if (local_28 > 0.8f) { + x5c4_ = 2; + } else if (local_28 >= 0.4f) { + x5c4_ = 1; + } else { + x5c4_ = 0; + } + ++x574_; + x944_ = 0.3f; } else { x93b_ = true; } @@ -221,10 +231,12 @@ void CThardus::sub801dd608(CStateManager& mgr) { 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])) + if (TCastToPtr act = mgr.ObjectById(x610_destroyableRocks[i])) { act->SetTransform(xf); - if (TCastToPtr gl = mgr.ObjectById(x6c0_rockLights[i])) + } + if (TCastToPtr gl = mgr.ObjectById(x6c0_rockLights[i])) { gl->SetTransform(xf); + } } } void CThardus::sub801dcfa4(CStateManager& mgr) { @@ -652,6 +664,16 @@ zeus::CAABox CThardus::GetSortingBounds(const CStateManager& mgr) const { void CThardus::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { switch (type) { case EUserEventType::Projectile: { + zeus::CTransform wristXf = GetLctrTransform("L_wrist"sv); + CRayCastResult res = mgr.RayStaticIntersection(wristXf.origin, zeus::skDown, 100.f, + CMaterialFilter::MakeInclude(EMaterialTypes::Solid)); + zeus::CTransform xf = zeus::lookAt(res.GetPoint() + zeus::CVector3f{0.f, 0.f, 1.f}, GetTranslation()); + xf.rotateLocalZ(zeus::degToRad(mgr.GetActiveRandom()->Range(-5.f, 5.f))); + mgr.AddObject(new CIceAttackProjectile( + g_SimplePool->GetObj({SBIG('PART'), x600_}), g_SimplePool->GetObj({SBIG('PART'), x604_}), + g_SimplePool->GetObj({SBIG('PART'), x608_}), mgr.AllocateUniqueId(), GetAreaIdAlways(), + mgr.GetPlayer().GetUniqueId(), true, xf, CDamageInfo(CWeaponMode::Ice(), 6.f, 0.f, 0.f), zeus::CAABox(0.f, 1.f), + x6ac_, zeus::degToRad(42.f), x6e8_, x6ec_, SFXsfx0AAD, x6f0_)); break; } case EUserEventType::LoopedSoundStop: @@ -1170,8 +1192,8 @@ void CThardus::_SetupCollisionManagers(CStateManager& mgr) { list.clear(); x634_nonDestroyableActors.reserve(x5f4_->GetNumCollisionActors() + x5f0_rockColliders->GetNumCollisionActors() + x5f8_->GetNumCollisionActors()); - sub801dd4fc(x5f4_); - sub801dd4fc(x5f8_); + FindNonDestroyableActors(x5f4_); + FindNonDestroyableActors(x5f8_); for (size_t i = 0; i < x5f0_rockColliders->GetNumCollisionActors(); ++i) { const auto& colDesc = x5f0_rockColliders->GetCollisionDescFromIndex(i); if (TCastToPtr colAct = mgr.ObjectById(colDesc.GetCollisionActorId())) { @@ -1190,7 +1212,7 @@ void CThardus::_SetupCollisionManagers(CStateManager& mgr) { } } -void CThardus::sub801dd4fc(const std::unique_ptr& colMgr) { +void CThardus::FindNonDestroyableActors(const std::unique_ptr& colMgr) { for (size_t i = 0; i < colMgr->GetNumCollisionActors(); ++i) { const auto& colDesc = colMgr->GetCollisionDescFromIndex(i); TUniqueId uid = colDesc.GetCollisionActorId(); @@ -1202,8 +1224,9 @@ void CThardus::sub801dd4fc(const std::unique_ptr& colMgr } } - if (!foundBone) + if (!foundBone) { x634_nonDestroyableActors.push_back(uid); + } } } @@ -1243,16 +1266,19 @@ void CThardus::sub801dc444(CStateManager& mgr, const zeus::CVector3f& pos, CAsse } void CThardus::sub801dbc5c(CStateManager& mgr, CDestroyableRock* rock) { - if (!x938_) { - x938_ = true; - x939_ = false; - sub801dbbdc(mgr, rock); + if (x938_) { + return; } + + x938_ = true; + x939_ = false; + sub801dbbdc(mgr, rock); } void CThardus::sub801dbbdc(CStateManager& mgr, CDestroyableRock* rock) { - if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Thermal) { x688_ = true; + } if (x7c4_ == 0 || x7c4_ == 2) { x7c4_ = 1; @@ -1425,11 +1451,7 @@ zeus::CVector2f CThardus::sub801dac30(CStateManager& mgr) const { } bool CThardus::sub801db5b4(CStateManager& mgr) const { - if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal) { - return !x93a_ || x7c4_ == 0; - } - - return true; + return mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal ? !x93a_ || x7c4_ == 0 : true; } void CThardus::ApplyCameraShake(float magnitude, float sfxDistance, float duration, CStateManager& mgr, @@ -1486,9 +1508,10 @@ void CThardus::sub801dbc40() { x7b8_ = FLT_EPSILON + x7bc_; x938_ = false; } + zeus::CVector2f CThardus::sub801dc60c(float arg, CStateManager& mgr) { zeus::CVector2f ret; - if (GetSearchPath()) { + if (GetSearchPath() != nullptr) { if (GetSearchPath()->GetResult() == CPathFindSearch::EResult::Success) { CPatterned::PathFind(mgr, EStateMsg::Update, arg); ret = GetBodyController()->GetCommandMgr().GetMoveVector().toVec2f(); @@ -1510,4 +1533,5 @@ zeus::CVector2f CThardus::sub801dc60c(float arg, CStateManager& mgr) { return ret; } + } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CThardus.hpp b/Runtime/MP1/World/CThardus.hpp index 160a39dd2..7af2e6e06 100644 --- a/Runtime/MP1/World/CThardus.hpp +++ b/Runtime/MP1/World/CThardus.hpp @@ -135,7 +135,7 @@ 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 FindNonDestroyableActors(const std::unique_ptr& colMgr); void sub801dbf34(float dt, CStateManager& mgr); bool sub801dc2c8() const { return (x610_destroyableRocks.size() - 1) == x648_currentRock; } void sub801de9f8(CStateManager& mgr);