diff --git a/src/game/features/recovery/GiveVehicleReward.cpp b/src/game/features/recovery/GiveVehicleReward.cpp index aa4f8c1..f2ab78d 100644 --- a/src/game/features/recovery/GiveVehicleReward.cpp +++ b/src/game/features/recovery/GiveVehicleReward.cpp @@ -12,43 +12,79 @@ namespace YimMenu bool GiveVehicleReward::IsSafeToRunScript() { - return Self::GetVehicle().IsValid() && *Pointers.IsSessionStarted && SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("AM_MP_VEHICLE_REWARD"_J) > 0; + return Self::GetVehicle().IsValid() && *Pointers.IsSessionStarted; } void GiveVehicleReward::RunScriptImpl() { while (g_Running) { - if (m_ShouldRunScript) + ScriptMgr::Yield(); + + if (!m_ShouldRunScript) + continue; + + if (!IsSafeToRunScript()) { - if (IsSafeToRunScript()) + if (m_StartedByUs && m_Thread) { - if (auto thread = Scripts::FindScriptThread("AM_MP_VEHICLE_REWARD"_J)) - { - if (auto VehicleRewardData = VEHICLE_REWARD_DATA::Get(thread)) - { - auto VehicleMenuData = ScriptLocal(thread, 176).As(); // TO-DO: add struct for this? - if (giveVehicleReward.Call(Self::GetVehicle().GetHandle(), VehicleMenuData, &VehicleRewardData->TransactionStatus, &VehicleRewardData->Garage, &VehicleRewardData->GarageOffset, &VehicleRewardData->ControlStatus, false, true, true, false, 0, -1)) - { - if (VehicleRewardData->ControlStatus != 3) - { - VehicleRewardData->TransactionStatus = 0; - VehicleRewardData->Garage = 0; - VehicleRewardData->GarageOffset = 0; - VehicleRewardData->ControlStatus = 0; - m_ShouldRunScript = false; - } - } - } - } + m_Thread->m_Context.m_State = rage::scrThread::State::KILLED; + m_StartedByUs = false; + } + m_Thread = nullptr; + m_ShouldRunScript = false; + continue; + } + + if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("AM_MP_VEHICLE_REWARD"_J) == 0) + { + SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH("AM_MP_VEHICLE_REWARD"_J); + if (SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED("AM_MP_VEHICLE_REWARD"_J)) + { + int id = BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH("AM_MP_VEHICLE_REWARD"_J, 2050); + m_Thread = Scripts::FindScriptThreadByID(id); + if (m_Thread) + m_Thread->m_Context.m_State = rage::scrThread::State::PAUSED; + SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED("AM_MP_VEHICLE_REWARD"_J); + m_StartedByUs = true; } else { - m_ShouldRunScript = false; + continue; } } + else + { + m_Thread = Scripts::FindScriptThread("AM_MP_VEHICLE_REWARD"_J); + } - ScriptMgr::Yield(); + if (!m_Thread) + { + m_ShouldRunScript = false; + continue; + } + + if (auto VehicleRewardData = VEHICLE_REWARD_DATA::Get(m_Thread)) + { + auto VehicleMenuData = ScriptLocal(m_Thread, 176).As(); // TO-DO: add struct for this? + if (giveVehicleReward.Call(Self::GetVehicle().GetHandle(), VehicleMenuData, &VehicleRewardData->TransactionStatus, &VehicleRewardData->Garage, &VehicleRewardData->GarageOffset, &VehicleRewardData->ControlStatus, false, true, true, false, 0, -1)) + { + if (VehicleRewardData->ControlStatus != 3) + { + VehicleRewardData->TransactionStatus = 0; + VehicleRewardData->Garage = 0; + VehicleRewardData->GarageOffset = 0; + VehicleRewardData->ControlStatus = 0; + if (m_StartedByUs) + { + m_Thread->m_Context.m_State = rage::scrThread::State::KILLED; + m_StartedByUs = false; + } + m_Thread = nullptr; + m_ShouldRunScript = false; + } + } + } } } } \ No newline at end of file diff --git a/src/game/features/recovery/GiveVehicleReward.hpp b/src/game/features/recovery/GiveVehicleReward.hpp index 850e80f..52923b5 100644 --- a/src/game/features/recovery/GiveVehicleReward.hpp +++ b/src/game/features/recovery/GiveVehicleReward.hpp @@ -1,5 +1,10 @@ #pragma once +namespace rage +{ + class scrThread; +} + namespace YimMenu { class GiveVehicleReward @@ -12,7 +17,9 @@ namespace YimMenu void RunScriptImpl(); - bool m_ShouldRunScript = false; + bool m_ShouldRunScript = false; + bool m_StartedByUs = false; + rage::scrThread* m_Thread = nullptr; public: static bool IsSafeToRunScript(); diff --git a/src/game/gta/Scripts.cpp b/src/game/gta/Scripts.cpp index e69c890..7baaf34 100644 --- a/src/game/gta/Scripts.cpp +++ b/src/game/gta/Scripts.cpp @@ -28,6 +28,19 @@ namespace YimMenu::Scripts return nullptr; } + rage::scrThread* FindScriptThreadByID(std::uint32_t id) + { + for (auto& thread : *Pointers.ScriptThreads) + { + if (thread && thread->m_Context.m_ThreadId == id) + { + return thread; + } + } + + return nullptr; + } + rage::scrProgram* FindScriptProgram(joaat_t hash) { for (int i = 0; i < 176; i++) diff --git a/src/game/gta/Scripts.hpp b/src/game/gta/Scripts.hpp index 13b5ada..1bc2499 100644 --- a/src/game/gta/Scripts.hpp +++ b/src/game/gta/Scripts.hpp @@ -12,6 +12,7 @@ class SimplePattern; namespace YimMenu::Scripts { extern rage::scrThread* FindScriptThread(joaat_t hash); + extern rage::scrThread* FindScriptThreadByID(std::uint32_t id); extern rage::scrProgram* FindScriptProgram(joaat_t hash); extern void RunAsScript(rage::scrThread* thread, std::function callback); extern void RunWithSpoofedThreadName(std::uint32_t name, std::function callback); // consider using RunAsScript if possible