diff --git a/src/KingSystem/Physics/System/physRayCast.cpp b/src/KingSystem/Physics/System/physRayCast.cpp index 34a03926..0983d15f 100644 --- a/src/KingSystem/Physics/System/physRayCast.cpp +++ b/src/KingSystem/Physics/System/physRayCast.cpp @@ -267,9 +267,7 @@ void RayCast::worldRayCastImpl(hkpWorldRayCastOutput* output, ContactLayerType l hkpWorldRayCastInput input; fillCastInput(input, layer_type); - System::instance()->lockWorld(layer_type, "raycast", 0, OnlyLockIfNeeded::Yes); - auto world_guard = sead::makeScopeGuard( - [&] { System::instance()->unlockWorld(layer_type, "raycast", 0, OnlyLockIfNeeded::Yes); }); + ScopedWorldLock lock{layer_type, "raycast", 0, OnlyLockIfNeeded::Yes}; if (mNormalCheckingMode == NormalCheckingMode::DoNotCheck) { if (mIgnoredGroups.size() > 0 || int(mIgnoredGroundHit) != GroundHit::Ignore) { diff --git a/src/KingSystem/Physics/System/physShapeCast.cpp b/src/KingSystem/Physics/System/physShapeCast.cpp index 024cb395..3b9904c7 100644 --- a/src/KingSystem/Physics/System/physShapeCast.cpp +++ b/src/KingSystem/Physics/System/physShapeCast.cpp @@ -86,22 +86,22 @@ bool ShapeCast::doExecuteQuery(hkpCdPointCollector& cast_collector, OnlyLockIfNeeded only_lock_if_needed) { const auto layer_type = mBody->getLayerType(); - System::instance()->lockWorld(layer_type, "shape_cast", 0, only_lock_if_needed); + { + ScopedWorldLock lock{layer_type, "shape_cast", 0, only_lock_if_needed}; - hkpLinearCastInput input; - loadFromVec3(&input.m_to, mTo); + hkpLinearCastInput input; + loadFromVec3(&input.m_to, mTo); - // Reset internal state. - cast_collector.reset(); - if (_44 == 1) - reset(); + // Reset internal state. + cast_collector.reset(); + if (_44 == 1) + reset(); - System::instance()->getHavokWorld(layer_type)->m_collisionInput->m_weldClosestPoints = - bool(weld_closest_points); + System::instance()->getHavokWorld(layer_type)->m_collisionInput->m_weldClosestPoints = + bool(weld_closest_points); - doCast(input, cast_collector, start_collector); - - System::instance()->unlockWorld(layer_type, "shape_cast", 0, only_lock_if_needed); + doCast(input, cast_collector, start_collector); + } // Register every point that is in start_collector. auto* body = mBody; diff --git a/src/KingSystem/Physics/System/physSystem.h b/src/KingSystem/Physics/System/physSystem.h index 6b130476..1f9647c1 100644 --- a/src/KingSystem/Physics/System/physSystem.h +++ b/src/KingSystem/Physics/System/physSystem.h @@ -86,8 +86,11 @@ public: void removeSystemGroupHandler(SystemGroupHandler* handler); hkpWorld* getHavokWorld(ContactLayerType type) const; + + // 0x0000007101215754 void lockWorld(ContactLayerType type, const char* description = nullptr, int b = 0, OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No); + // 0x0000007101215784 void unlockWorld(ContactLayerType type, const char* description = nullptr, int b = 0, OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No); @@ -146,4 +149,27 @@ private: }; KSYS_CHECK_SIZE_NX150(System, 0x480); +class ScopedWorldLock { +public: + explicit ScopedWorldLock(ContactLayerType type, const char* description = nullptr, int unk = 0, + OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No) + : mType(type), mDescription(description), mUnk(unk), + mOnlyLockIfNeeded(only_lock_if_needed) { + System::instance()->lockWorld(mType, mDescription, mUnk, mOnlyLockIfNeeded); + } + + ~ScopedWorldLock() { + System::instance()->unlockWorld(mType, mDescription, mUnk, mOnlyLockIfNeeded); + } + + ScopedWorldLock(const ScopedWorldLock&) = delete; + auto operator=(const ScopedWorldLock&) = delete; + +private: + ContactLayerType mType; + const char* mDescription; + int mUnk; + OnlyLockIfNeeded mOnlyLockIfNeeded; +}; + } // namespace ksys::phys