diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 946efb3a5..9ce7b668a 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -2813,4 +2813,9 @@ float CStateManager::IntegrateVisorFog(float f) const { float CStateManager::g_EscapeShakeCountdown; bool CStateManager::g_EscapeShakeCountdownInit = false; + +void CStateManager::sub_80044098(const CCollisionResponseData& colRespData, const CRayCastResult& rayCast, + TUniqueId uid, const CWeaponMode& weaponMode, uint w1, u8 thermalFlags) { + // TODO implement +} } // namespace urde diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 4f30e3b09..43e8dbc71 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -457,6 +457,9 @@ public: static float g_EscapeShakeCountdown; static bool g_EscapeShakeCountdownInit; + void sub_80044098(const CCollisionResponseData& colRespData, const CRayCastResult& rayCast, TUniqueId uid, + const CWeaponMode& weaponMode, uint w1, u8 thermalFlags); + void SetWarping(bool warp) { m_warping = warp; } }; } // namespace urde diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index b6bc51353..975392488 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -962,11 +962,9 @@ void CDrone::RemoveFromTeam(CStateManager& mgr) const { } void CDrone::UpdateLaser(CStateManager& mgr, u32 laserIdx, bool active) { - if (active) { - if (x7d8_[laserIdx] == kInvalidUniqueId) { - x7d8_[laserIdx] = mgr.AllocateUniqueId(); - mgr.AddObject(new CDroneLaser(x7d8_[laserIdx], GetAreaIdAlways(), GetTransform(), x568_laserParticlesId)); - } + if (active && x7d8_[laserIdx] == kInvalidUniqueId) { + x7d8_[laserIdx] = mgr.AllocateUniqueId(); + mgr.AddObject(new CDroneLaser(x7d8_[laserIdx], GetAreaIdAlways(), GetTransform(), x568_laserParticlesId)); } if (CEntity* ent = mgr.ObjectById(x7d8_[laserIdx])) { mgr.SendScriptMsg(ent, GetUniqueId(), active ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); @@ -1061,7 +1059,36 @@ void CDrone::sub_8015f158(float dt) { void CDrone::sub_80165984(CStateManager& mgr, const zeus::CTransform& xf) { /*constexpr*/ float sin60 = std::sqrt(3.f) / 2.f; - // TODO implement + const auto playerAimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + const auto distNorm = (playerAimPos - xf.origin).normalized(); + if (distNorm.dot(xf.frontVector()) <= sin60) { + sub_801656d4(xf, mgr); + } else { + zeus::CVector3f vec; + if (mgr.GetActiveRandom()->Float() > 0.2f) { + const auto lookAt = zeus::lookAt(xf.origin, playerAimPos); + vec = zeus::CQuaternion::fromAxisAngle(lookAt.frontVector(), mgr.GetActiveRandom()->Range(0.f, M_PIF)) + .transform(4.f * lookAt.rightVector()); + } + sub_801656d4(zeus::lookAt(xf.origin, playerAimPos + vec), mgr); + } +} + +void CDrone::sub_801656d4(const zeus::CTransform& xf, CStateManager& mgr) { + constexpr auto matFilter = + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough}); + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, xf.origin, xf.frontVector(), 100000.f, matFilter, this); + TUniqueId id; + const auto result = mgr.RayWorldIntersection(id, xf.origin, xf.frontVector(), 100000.f, matFilter, nearList); + if (result.IsInvalid()) { + return; + } + if (id == mgr.GetPlayer().GetUniqueId()) { + mgr.ApplyDamage(GetUniqueId(), id, GetUniqueId(), x5ac_, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), zeus::skZero3f); + } + mgr.sub_80044098(*x56c_.GetObj(), result, id, x5ac_.GetWeaponMode(), 1, xe6_27_thermalVisorFlags); } } // namespace urde::MP1