From 6c5581b83ecfad1dba02fc3a3fe96753f1acbf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valdir=20da=20Costa=20J=C3=BAnior?= <24408289+JuniorDjjr@users.noreply.github.com> Date: Sun, 19 Jun 2022 03:25:59 -0300 Subject: [PATCH] v1.1.0 --- CLEOPlus/CLEOPlus.cpp | 64 ++++++++++------------------- CLEOPlus/CLEOPlus.vcxproj | 4 +- CLEOPlus/Events.cpp | 47 ++++++++++++++++++--- CLEOPlus/ExtendedEntityVars.cpp | 18 ++++----- CLEOPlus/List.cpp | 65 ++++++++++++++++++++---------- CLEOPlus/MathRelated.cpp | 8 ++-- CLEOPlus/Misc.cpp | 61 +++++++++++++++++----------- CLEOPlus/Patches.cpp | 21 ++++++++++ CLEOPlus/RadarBlip.cpp | 10 +++-- CLEOPlus/TextDrawer/TextDrawer.cpp | 5 ++- 10 files changed, 188 insertions(+), 115 deletions(-) diff --git a/CLEOPlus/CLEOPlus.cpp b/CLEOPlus/CLEOPlus.cpp index a00b582..6d6fed9 100644 --- a/CLEOPlus/CLEOPlus.cpp +++ b/CLEOPlus/CLEOPlus.cpp @@ -18,7 +18,7 @@ #include "rw/rpworld.h" #include -constexpr uint32_t CLEOPLUS_VERSION_INT = 0x01000900; +constexpr uint32_t CLEOPLUS_VERSION_INT = 0x01010000; using namespace plugin; using namespace std; @@ -55,6 +55,7 @@ bool disableCamControl = false; bool disabledCamControlLastFrame = false; bool controllerMode = false; bool pausedLastFrame = true; +bool isBuildingProcessPatched = false; CSprite2d *radarBlipSprites; bool keysPressedLastFrame[0xFF] = { false }; bool buttonsPressedLastFrame[2][20] = { false }; @@ -481,7 +482,7 @@ class CLEOPlus } else sampfuncsInstalled = false; - if (GetModuleHandleA("V_HUD_by_DK22Pac.asi")) { + if (GetModuleHandleA("V_HUD_by_DK22Pac.asi") || GetModuleHandleA("VHud.asi")) { gtavhudInstalled = true; } else gtavhudInstalled = false; @@ -713,7 +714,7 @@ class CLEOPlus CLEO_RegisterOpcode(0xEF8, GET_MODEL_INFO); // 0xEF8=2,get_model_info %1d% store_to %2d% CLEO_RegisterOpcode(0xEF9, GET_CAR_ANIMGROUP); // 0xEF9=2,get_car_animgroup %1d% store_to %2d% CLEO_RegisterOpcode(0xEFA, GET_CHAR_FEAR); // 0xEFA=2,get_char_fear %1d% store_to %2d% - CLEO_RegisterOpcode(0xEFB, IS_CAR_CONVERTIBLE); // 0xEFB=1,is_car_double_convertible %1d% + CLEO_RegisterOpcode(0xEFB, IS_CAR_CONVERTIBLE); // 0xEFB=1,is_car_convertible %1d% CLEO_RegisterOpcode(0xEFC, GET_CAR_VALUE); // 0xEFC=2,get_car_value %1d% store_to %2d% CLEO_RegisterOpcode(0xEFD, GET_CAR_PEDALS); // 0xEFD=3,get_car_pedals %1d% gas_to %2d% break_to %3d% CLEO_RegisterOpcode(0xEFE, GET_LOADED_LIBRARY); // 0xEFE=2,get_loaded_library %1d% store_to %2d% @@ -752,10 +753,10 @@ class CLEOPlus CLEO_RegisterOpcode(0xE1F, EASE); // 0E1F=4,ease %1d% mode %2d% way %3d% to %4d% CLEO_RegisterOpcode(0xE27, GET_ANGLE_FROM_TWO_COORDS); // 0E27=5,get_angle_from_two_coords %1d% %2d% and %3d% %4d% to %5d% CLEO_RegisterOpcode(0xE03, PERLIN_NOISE); // 0E03=2,perlin_noise %1d% store_to %2d% - CLEO_RegisterOpcode(0xE29, PERLIN_NOISE_FRACTAL); // 0E29=7,perlin_noise %1d% octaves %2d% frequency %3d% amplitude %4d% lacunarity %5d% persistence %6d% store_to %7d% + CLEO_RegisterOpcode(0xE29, PERLIN_NOISE_FRACTAL); // 0E29=6,perlin_noise %1d% frequency %2d% amplitude %3d% lacunarity %4d% persistence %5d% store_to %6d% CLEO_RegisterOpcode(0xEF0, GET_COORD_FROM_ANGLED_DISTANCE); // 0EF0=6,get_coord_from_angled_distance %1d% %2d% angle %3d% dist %4d% store_to %5d% %6d% - CLEO_RegisterOpcode(0xEF1, PERLIN_NOISE_FRACTAL_2D); // 0EF1=8,perlin_noise_fractal_2d x %1d% y %2d% octaves %3d% frequency %4d% amplitude %5d% lacunarity %6d% persistence %7d% store_to %8d% - CLEO_RegisterOpcode(0xEF2, PERLIN_NOISE_FRACTAL_3D); // 0EF2=9,perlin_noise_fractal_3d x %1d% y %2d% z %3d% octaves %4d% frequency %5d% amplitude %6d% lacunarity %7d% persistence %8d% store_to %9d% + CLEO_RegisterOpcode(0xEF1, PERLIN_NOISE_FRACTAL_2D); // 0xEF1=7,perlin_noise_fractal_2d %1d% %2d% frequency %3d% amplitude %4d% lacunarity %5d% persistence %6d% store_to %7d% + CLEO_RegisterOpcode(0xEF2, PERLIN_NOISE_FRACTAL_3D); // 0xEF2=8,perlin_noise_fractal_3d %1d% %2d% %3d% frequency %4d% amplitude %5d% lacunarity %6d% persistence %7d% store_to %8d% CLEO_RegisterOpcode(0xEF4, CLAMP_FLOAT); // 0EF4=4,clamp_float %1d% min %2d% max %3d% store_to %4d% CLEO_RegisterOpcode(0xEF7, CLAMP_INT); // 0EF7=4,clamp_int %1d% min %2d% max %3d% store_to %4d% CLEO_RegisterOpcode(0xEB3, CONVERT_DIRECTION_TO_QUAT); // 0xEB3=4,convert_direction_to_quat %1d% dir %2d% %3d% %4d% @@ -889,7 +890,7 @@ class CLEOPlus { // Reset ped data per frame auto& pedsPool = CPools::ms_pPedPool; - for (int index = 0; index < pedsPool->m_nSize; ++index) + for (unsigned int index = 0; index < pedsPool->m_nSize; ++index) { if (CPed* ped = pedsPool->GetAt(index)) { @@ -912,7 +913,7 @@ class CLEOPlus if (ped->m_pIntelligence) { CTaskManager* taskMgr = &ped->m_pIntelligence->m_TaskMgr; - for (int i = 0; i < 5; i++) + for (unsigned int i = 0; i < 5; i++) { CTask* task = taskMgr->m_aPrimaryTasks[i]; while (task) @@ -922,7 +923,7 @@ class CLEOPlus } } - for (int i = 0; i < 5; i++) + for (unsigned int i = 0; i < 5; i++) { CTask* task = taskMgr->m_aSecondaryTasks[i]; while (task) @@ -943,7 +944,7 @@ class CLEOPlus { // Reset ped data per frame auto &pedsPool = CPools::ms_pPedPool; - for (int index = 0; index < pedsPool->m_nSize; ++index) + for (unsigned int index = 0; index < pedsPool->m_nSize; ++index) { if (CPed* ped = pedsPool->GetAt(index)) { @@ -959,7 +960,7 @@ class CLEOPlus } // Reset vehicle data per frame auto& vehsPool = CPools::ms_pVehiclePool; - for (int index = 0; index < vehsPool->m_nSize; ++index) + for (unsigned int index = 0; index < vehsPool->m_nSize; ++index) { if (CVehicle* vehicle = vehsPool->GetAt(index)) { @@ -986,7 +987,7 @@ class CLEOPlus if (disableCamControl) { // Disables it each frame to make it compatible with GTA V Hud. - for (int i = 0; i < 14; ++i) + for (unsigned int i = 0; i < 14; ++i) { patch::SetPointer(disableCamMoveAddresses[i], &fZero); } @@ -995,7 +996,7 @@ class CLEOPlus else if (disabledCamControlLastFrame) { // Get using address (to make it compatible with other mods) - for (int i = 0; i < 14; ++i) + for (unsigned int i = 0; i < 14; ++i) { patch::SetInt(disableCamMoveAddresses[i], (i > 4) ? defaultMouseAccelHorizontalAddress : defaultMouseAccelVerticalAddress); } @@ -1003,29 +1004,8 @@ class CLEOPlus } }; - // EntityPreRender (caution, this is called A LOT) - injector::MakeInline<0x535FBE, 0x535FBE + 5>([](injector::reg_pack& regs) - { - CEntity *entity = (CEntity *)regs.esi; - if (entity->m_nType == eEntityType::ENTITY_TYPE_BUILDING) - { - if (scriptEvents[ScriptEvent::List::BuildingProcess].size() > 0) - { - for (auto scriptEvent : scriptEvents[ScriptEvent::List::BuildingProcess]) scriptEvent->RunScriptEvent((DWORD)entity); - } - } - else if (entity->m_nType == eEntityType::ENTITY_TYPE_OBJECT) - { - if (scriptEvents[ScriptEvent::List::ObjectProcess].size() > 0) - { - CObject *object = reinterpret_cast(entity); - int ref = CPools::GetObjectRef(object); - for (auto scriptEvent : scriptEvents[ScriptEvent::List::ObjectProcess]) scriptEvent->RunScriptEvent(ref); - } - } - regs.ebx = regs.eax; //mov ebx, eax - regs.eax = *(uint8_t*)(regs.edi + 0xD); //mov al, [edi+0Dh] - }); + // EntityPreRender + // PATCH MOVED TO: PatchBuildingProcessIfNeeded Events.cpp // VehiclePreRender vehiclePreRenderEvent +=[](CVehicle *vehicle) @@ -1127,7 +1107,7 @@ class CLEOPlus // Fixes corrupted old saves with deleted LOD objects loadingEventAfterPoolsLoaded.before += [] { - for (int i = 0; i < sizeScriptConnectLodsObjects; ++i) + for (unsigned int i = 0; i < sizeScriptConnectLodsObjects; ++i) { if (CTheScripts__ScriptConnectLodsObjects[i] != -1) { @@ -1164,7 +1144,7 @@ class CLEOPlus CStreaming::RemoveModel(id); } //specialCharacterModelsUsed.clear(); // don't clear it, we use this list to reuse IDs in GET_MODEL_DOESNT_EXIST_IN_RANGE - for (int i = 0; i < DrawEvent::TOTAL_DRAW_EVENT; ++i) { + for (unsigned int i = 0; i < DrawEvent::TOTAL_DRAW_EVENT; ++i) { ClearMySprites(sprites[i]); textDrawer[i].ClearAll(); } @@ -1228,7 +1208,7 @@ class CLEOPlus if (scriptEvents[ScriptEvent::List::ObjectDelete].size() > 0) { for (auto scriptEvent : scriptEvents[ScriptEvent::List::ObjectDelete]) scriptEvent->RunScriptEvent(ref); } - for (int i = 0; i < sizeScriptConnectLodsObjects; ++i) + for (unsigned int i = 0; i < sizeScriptConnectLodsObjects; ++i) { if (CTheScripts__ScriptConnectLodsObjects[i] == ref) CTheScripts__ScriptConnectLodsObjects[i] = -1; } @@ -1446,16 +1426,16 @@ class CLEOPlus // Update keys pressed memset(keysPressedLastFrame, 0, sizeof(keysPressedLastFrame)); - for (int vk = 0x01; vk < 0xFF; ++vk) + for (unsigned int vk = 0x01; vk < 0xFF; ++vk) { keysPressedLastFrame[vk] = ((GetKeyState(vk) & 0x8000) != 0); } // Update buttons pressed, and control disable memset(buttonsPressedLastFrame, 0, sizeof(buttonsPressedLastFrame)); - for (int pad = 0; pad < 2; ++pad) + for (unsigned int pad = 0; pad < 2; ++pad) { - for (int id = 0; id < 20; ++id) + for (unsigned int id = 0; id < 20; ++id) { // There is old state, but isn't array, and also this function may be changed by some crazy script buttonsPressedLastFrame[pad][id] = reinterpret_cast(0)->GetPadState(pad, id); diff --git a/CLEOPlus/CLEOPlus.vcxproj b/CLEOPlus/CLEOPlus.vcxproj index 3518db5..5553cee 100644 --- a/CLEOPlus/CLEOPlus.vcxproj +++ b/CLEOPlus/CLEOPlus.vcxproj @@ -96,14 +96,14 @@ - G:\GTA SA The Modded Edition\CLEO\ + G:\GTA SA\cleo\ $(ProjectDir).obj\GTASA\Release\ CLEO+ .cleo $(VC_IncludePath);$(WindowsSDK_IncludePath);E:\Documents\Para GTA\plugin-sdk-2020\shared;E:\Documents\Para GTA\plugin-sdk-2020\plugin_sa\game_sa - G:\GTA SA The Modded Edition\CLEO\ + G:\GTA SA\cleo\ $(ProjectDir).obj\GTASA\Debug\ CLEO+ .cleo diff --git a/CLEOPlus/Events.cpp b/CLEOPlus/Events.cpp index feca386..c613dbe 100644 --- a/CLEOPlus/Events.cpp +++ b/CLEOPlus/Events.cpp @@ -1,13 +1,15 @@ #include "OpcodesCommon.h" #include "Events.h" #include "CMenuManager.h" +#include "..\injector\assembly.hpp" vector scriptEvents[ScriptEvent::TOTAL_SCRIPT_EVENTS]; extern bool pausedLastFrame; +extern bool isBuildingProcessPatched; void ScriptEvent::ClearAllForScript(CRunningScript* script) { - for (int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) + for (unsigned int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) { for (vector::iterator it = scriptEvents[i].begin(); it != scriptEvents[i].end();) { @@ -30,7 +32,7 @@ void ScriptEvent::ClearForScriptLabelAndVar(vector &scriptEvents, if (scriptEvent->script == script && scriptEvent->eventScriptIP == label) { bool ok = true; - for (int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 4; ++i) { if (scriptEvent->varPointer[i] == 0) break; if (scriptEvent->varPointer[i] != varPointer[i]) @@ -51,11 +53,11 @@ void ScriptEvent::ClearForScriptLabelAndVar(vector &scriptEvents, void ScriptEvent::ClearAllScriptEvents() { - for (int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) + for (unsigned int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) { for (auto& scriptEvent : scriptEvents[i]) delete scriptEvent; } - for (int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) + for (unsigned int i = 0; i < ScriptEvent::TOTAL_SCRIPT_EVENTS; ++i) { scriptEvents[i].clear(); } @@ -108,7 +110,7 @@ void AddEvent(CScriptThread* thread, vector &scriptEventList, int eventStruct->script = reinterpret_cast(thread); eventStruct->eventScriptIP = label; - for (int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 4; ++i) { uintptr_t pointer = 0; if (i < args) @@ -123,7 +125,7 @@ void AddEvent(CScriptThread* thread, vector &scriptEventList, int else { uintptr_t vars[4]; - for (int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 4; ++i) { uintptr_t pointer = 0; if (i < args) @@ -138,6 +140,37 @@ void AddEvent(CScriptThread* thread, vector &scriptEventList, int return; } +// This is called A LOT, so patch if only if needed. Note: this will also be called when turning off the event, it's fine. +void PatchBuildingProcessIfNeeded() +{ + if (!isBuildingProcessPatched) + { + injector::MakeInline<0x535FBE, 0x535FBE + 5>([](injector::reg_pack& regs) + { + CEntity* entity = (CEntity*)regs.esi; + if (entity->m_nType == eEntityType::ENTITY_TYPE_BUILDING) + { + if (scriptEvents[ScriptEvent::List::BuildingProcess].size() > 0) + { + for (auto scriptEvent : scriptEvents[ScriptEvent::List::BuildingProcess]) scriptEvent->RunScriptEvent((DWORD)entity); + } + } + else if (entity->m_nType == eEntityType::ENTITY_TYPE_OBJECT) + { + if (scriptEvents[ScriptEvent::List::ObjectProcess].size() > 0) + { + CObject* object = reinterpret_cast(entity); + int ref = CPools::GetObjectRef(object); + for (auto scriptEvent : scriptEvents[ScriptEvent::List::ObjectProcess]) scriptEvent->RunScriptEvent(ref); + } + } + regs.ebx = regs.eax; //mov ebx, eax + regs.eax = *(uint8_t*)(regs.edi + 0xD); //mov al, [edi+0Dh] + }); + isBuildingProcessPatched = true; + } +} + OpcodeResult WINAPI RETURN_SCRIPT_EVENT(CScriptThread* thread) { return OR_INTERRUPT; @@ -206,12 +239,14 @@ OpcodeResult WINAPI SET_SCRIPT_EVENT_CAR_PROCESS(CScriptThread* thread) OpcodeResult WINAPI SET_SCRIPT_EVENT_OBJECT_PROCESS(CScriptThread* thread) { AddEvent(thread, scriptEvents[ScriptEvent::List::ObjectProcess]); + PatchBuildingProcessIfNeeded(); return OR_CONTINUE; } OpcodeResult WINAPI SET_SCRIPT_EVENT_BUILDING_PROCESS(CScriptThread* thread) { AddEvent(thread, scriptEvents[ScriptEvent::List::BuildingProcess]); + PatchBuildingProcessIfNeeded(); return OR_CONTINUE; } diff --git a/CLEOPlus/ExtendedEntityVars.cpp b/CLEOPlus/ExtendedEntityVars.cpp index e6d223d..a3c7ae6 100644 --- a/CLEOPlus/ExtendedEntityVars.cpp +++ b/CLEOPlus/ExtendedEntityVars.cpp @@ -115,7 +115,7 @@ OpcodeResult WINAPI INIT_EXTENDED_CHAR_VARS(CScriptThread* thread) if (&xdata != nullptr && totalVars > 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -146,7 +146,7 @@ OpcodeResult WINAPI SET_EXTENDED_CHAR_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -173,7 +173,7 @@ OpcodeResult WINAPI GET_EXTENDED_CHAR_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -203,7 +203,7 @@ OpcodeResult WINAPI INIT_EXTENDED_CAR_VARS(CScriptThread* thread) if (&xdata != nullptr && totalVars > 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -234,7 +234,7 @@ OpcodeResult WINAPI SET_EXTENDED_CAR_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -261,7 +261,7 @@ OpcodeResult WINAPI GET_EXTENDED_CAR_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -292,7 +292,7 @@ OpcodeResult WINAPI INIT_EXTENDED_OBJECT_VARS(CScriptThread* thread) if (&xdata != nullptr && totalVars > 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -323,7 +323,7 @@ OpcodeResult WINAPI SET_EXTENDED_OBJECT_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) @@ -351,7 +351,7 @@ OpcodeResult WINAPI GET_EXTENDED_OBJECT_VAR(CScriptThread* thread) if (&xdata && varId >= 0) { if (findId == 2949658545) // "AUTO" - findId = (int)thread; + findId = (uint32_t)thread; ExtendedVars *extVars = FindExtendedVarsFromId(xdata.extendedVarsList, findId); if (extVars) diff --git a/CLEOPlus/List.cpp b/CLEOPlus/List.cpp index 68c51cc..b70f530 100644 --- a/CLEOPlus/List.cpp +++ b/CLEOPlus/List.cpp @@ -143,30 +143,36 @@ OpcodeResult WINAPI LIST_REMOVE_STRING_VALUE(CScriptThread* thread) OpcodeResult WINAPI LIST_REMOVE_INDEX(CScriptThread* thread) { ScriptList *scriptList = (ScriptList*)CLEO_GetIntOpcodeParam(thread); - int index = CLEO_GetIntOpcodeParam(thread); + unsigned int index = CLEO_GetIntOpcodeParam(thread); if (scriptList->type == 0) // int { list *l = (list*)scriptList->listPointer; - list::iterator it; - it = l->begin(); - advance(it, index); - l->erase(it); + if (index < l->size()) { + list::iterator it; + it = l->begin(); + advance(it, index); + l->erase(it); + } } else if (scriptList->type == 1) // float { list *l = (list*)scriptList->listPointer; - list::iterator it; - it = l->begin(); - advance(it, index); - l->erase(it); + if (index < l->size()) { + list::iterator it; + it = l->begin(); + advance(it, index); + l->erase(it); + } } else if (scriptList->type == 2) // string { list *l = (list*)scriptList->listPointer; - list::iterator it; - it = l->begin(); - advance(it, index); - l->erase(it); + if (index < l->size()) { + list::iterator it; + it = l->begin(); + advance(it, index); + l->erase(it); + } } return OR_CONTINUE; } @@ -238,22 +244,32 @@ OpcodeResult WINAPI GET_LIST_SIZE(CScriptThread* thread) OpcodeResult WINAPI GET_LIST_VALUE_BY_INDEX(CScriptThread* thread) { ScriptList *scriptList = (ScriptList*)CLEO_GetIntOpcodeParam(thread); - int index = CLEO_GetIntOpcodeParam(thread); + unsigned int index = CLEO_GetIntOpcodeParam(thread); if (scriptList->type == 0) // int { list *l = (list*)scriptList->listPointer; list::iterator it; it = l->begin(); - advance(it, index); - CLEO_SetIntOpcodeParam(thread, *it); + if (index >= l->size()) { + CLEO_SetIntOpcodeParam(thread, 0); + } + else { + advance(it, index); + CLEO_SetIntOpcodeParam(thread, *it); + } } else if (scriptList->type == 1) // float { list *l = (list*)scriptList->listPointer; list::iterator it; it = l->begin(); - advance(it, index); - CLEO_SetFloatOpcodeParam(thread, *it); + if (index >= l->size()) { + CLEO_SetIntOpcodeParam(thread, 0); + } + else { + advance(it, index); + CLEO_SetFloatOpcodeParam(thread, *it); + } } return OR_CONTINUE; } @@ -261,15 +277,20 @@ OpcodeResult WINAPI GET_LIST_VALUE_BY_INDEX(CScriptThread* thread) OpcodeResult WINAPI GET_LIST_STRING_VALUE_BY_INDEX(CScriptThread* thread) { ScriptList *scriptList = (ScriptList*)CLEO_GetIntOpcodeParam(thread); - int index = CLEO_GetIntOpcodeParam(thread); + unsigned int index = CLEO_GetIntOpcodeParam(thread); if (scriptList->type == 2) // string { list *l = (list*)scriptList->listPointer; list::iterator it; it = l->begin(); - advance(it, index); - string str = *it; - CLEO_WriteStringOpcodeParam(thread, &str[0]); + if (index >= l->size()) { + CLEO_WriteStringOpcodeParam(thread, ""); + } + else { + advance(it, index); + string str = *it; + CLEO_WriteStringOpcodeParam(thread, &str[0]); + } } return OR_CONTINUE; } diff --git a/CLEOPlus/MathRelated.cpp b/CLEOPlus/MathRelated.cpp index 3e27135..1f0b34e 100644 --- a/CLEOPlus/MathRelated.cpp +++ b/CLEOPlus/MathRelated.cpp @@ -331,7 +331,7 @@ OpcodeResult WINAPI EASE(CScriptThread* thread) return OR_CONTINUE; } -// 0xE03=2,perlin_noise %1d% store_to %2d% +// 0E03=2,perlin_noise %1d% store_to %2d% OpcodeResult WINAPI PERLIN_NOISE(CScriptThread* thread) { float result = SimplexNoise::noise(CLEO_GetFloatOpcodeParam(thread)); @@ -339,7 +339,7 @@ OpcodeResult WINAPI PERLIN_NOISE(CScriptThread* thread) return OR_CONTINUE; } -// 0xE29=7,perlin_noise %1d% octaves %2d% frequency %3d% amplitude %4d% lacunarity %5d% persistence %6d% store_to %7d% +// 0E29=7,perlin_noise %1d% octaves %2d% frequency %3d% amplitude %4d% lacunarity %5d% persistence %6d% store_to %7d% OpcodeResult WINAPI PERLIN_NOISE_FRACTAL(CScriptThread* thread) { float f = CLEO_GetFloatOpcodeParam(thread); @@ -357,7 +357,7 @@ OpcodeResult WINAPI PERLIN_NOISE_FRACTAL(CScriptThread* thread) return OR_CONTINUE; } -// 0xEF1=8,perlin_noise_fractal_2d x %1d% y %2d% octaves %3d% frequency %4d% amplitude %5d% lacunarity %6d% persistence %7d% store_to %8d% +// 0EF1=8,perlin_noise_fractal_2d x %1d% y %2d% octaves %3d% frequency %4d% amplitude %5d% lacunarity %6d% persistence %7d% store_to %8d% OpcodeResult WINAPI PERLIN_NOISE_FRACTAL_2D(CScriptThread* thread) { float x = CLEO_GetFloatOpcodeParam(thread); @@ -376,7 +376,7 @@ OpcodeResult WINAPI PERLIN_NOISE_FRACTAL_2D(CScriptThread* thread) return OR_CONTINUE; } -// 0xEF2=9,perlin_noise_fractal_3d x %1d% y %2d% z %3d% octaves %4d% frequency %5d% amplitude %6d% lacunarity %7d% persistence %8d% store_to %9d% +// 0EF2=9,perlin_noise_fractal_3d x %1d% y %2d% z %3d% octaves %4d% frequency %5d% amplitude %6d% lacunarity %7d% persistence %8d% store_to %9d% OpcodeResult WINAPI PERLIN_NOISE_FRACTAL_3D(CScriptThread* thread) { float x = CLEO_GetFloatOpcodeParam(thread); diff --git a/CLEOPlus/Misc.cpp b/CLEOPlus/Misc.cpp index 691ef00..4806dd2 100644 --- a/CLEOPlus/Misc.cpp +++ b/CLEOPlus/Misc.cpp @@ -263,17 +263,23 @@ OpcodeResult WINAPI CHANGE_PLAYER_MONEY(CScriptThread* thread) int player = CLEO_GetIntOpcodeParam(thread); int mode = CLEO_GetIntOpcodeParam(thread); int value = CLEO_GetIntOpcodeParam(thread); - switch (mode) { - case 0: - CWorld::Players[player].m_nMoney = value; - CWorld::Players[player].m_nDisplayMoney = value; - break; - case 1: - CWorld::Players[player].m_nMoney += value; - break; - case 2: - CWorld::Players[player].m_nMoney -= value; - break; + CPlayerPed* playerPed = FindPlayerPed(player); + if (playerPed) { + CPlayerInfo *playerInfo = playerPed->GetPlayerInfoForThisPlayerPed(); + if (playerInfo) { + switch (mode) { + case 0: + playerInfo->m_nMoney = value; + playerInfo->m_nDisplayMoney = value; + break; + case 1: + playerInfo->m_nMoney += value; + break; + case 2: + playerInfo->m_nMoney -= value; + break; + } + } } return OR_CONTINUE; } @@ -282,8 +288,10 @@ OpcodeResult WINAPI CHANGE_PLAYER_MONEY(CScriptThread* thread) OpcodeResult WINAPI CAR_HORN(CScriptThread* thread) { CVehicle *vehicle = CPools::GetVehicle(CLEO_GetIntOpcodeParam(thread)); - vehicle->m_nHornCounter = 1; - vehicle->PlayCarHorn(); + if (vehicle) { + vehicle->m_nHornCounter = 1; + vehicle->PlayCarHorn(); + } return OR_CONTINUE; } @@ -553,11 +561,13 @@ OpcodeResult WINAPI GET_OBJECT_CENTRE_OF_MASS_TO_BASE_OF_MODEL(CScriptThread* th OpcodeResult WINAPI GET_MODEL_TYPE(CScriptThread* thread) { int modelId = CLEO_GetIntOpcodeParam(thread); - CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelId); + CBaseModelInfo* modelInfo; int type = -1; - if (modelInfo) - { - type = modelInfo->GetModelType(); + if (modelId >= 0) { + modelInfo = CModelInfo::GetModelInfo(modelId); + if (modelInfo) { + type = modelInfo->GetModelType(); + } } CLEO_SetIntOpcodeParam(thread, type); return OR_CONTINUE; @@ -603,7 +613,7 @@ OpcodeResult WINAPI IS_STRING_COMMENT(CScriptThread* thread) bool bResult = false; LPSTR string = CLEO_ReadStringPointerOpcodeParam(thread, bufferA, 128); - int i = 0; + unsigned int i = 0; while (string[i] == ' ' && i <= 127) ++i; if (string[i] == '#' || string[i] == ';' || (string[i] == '/' && string[i + 1] == '/')) bResult = true; @@ -928,7 +938,7 @@ OpcodeResult WINAPI GET_CLOSEST_COP_NEAR_CHAR(CScriptThread* thread) auto& pool = CPools::ms_pPedPool; CPed *closestCop = nullptr; - for (int index = 0; index < pool->m_nSize; ++index) + for (unsigned int index = 0; index < pool->m_nSize; ++index) { if (auto obj = pool->GetAt(index)) { @@ -993,7 +1003,7 @@ OpcodeResult WINAPI GET_CLOSEST_COP_NEAR_POS(CScriptThread* thread) auto& pool = CPools::ms_pPedPool; CPed *closestCop = nullptr; - for (int index = 0; index < pool->m_nSize; ++index) + for (unsigned int index = 0; index < pool->m_nSize; ++index) { if (auto obj = pool->GetAt(index)) { @@ -1045,7 +1055,7 @@ OpcodeResult WINAPI GET_ANY_CHAR_NO_SAVE_RECURSIVE(CScriptThread* thread) auto& pool = CPools::ms_pPedPool; CPed *objFound = nullptr; - for (int index = progress; index < pool->m_nSize; ++index) + for (unsigned int index = progress; index < pool->m_nSize; ++index) { if (auto obj = pool->GetAt(index)) { @@ -1076,7 +1086,7 @@ OpcodeResult WINAPI GET_ANY_CAR_NO_SAVE_RECURSIVE(CScriptThread* thread) auto& pool = CPools::ms_pVehiclePool; CVehicle *objFound = nullptr; - for (int index = progress; index < pool->m_nSize; ++index) + for (unsigned int index = progress; index < pool->m_nSize; ++index) { if (auto obj = pool->GetAt(index)) { @@ -1107,7 +1117,7 @@ OpcodeResult WINAPI GET_ANY_OBJECT_NO_SAVE_RECURSIVE(CScriptThread* thread) auto& pool = CPools::ms_pObjectPool; CObject *objFound = nullptr; - for (int index = progress; index < pool->m_nSize; ++index) + for (unsigned int index = progress; index < pool->m_nSize; ++index) { if (auto obj = pool->GetAt(index)) { @@ -1789,7 +1799,10 @@ OpcodeResult WINAPI GET_MODEL_INFO(CScriptThread* thread) { bool bResult = false; int model = CLEO_GetIntOpcodeParam(thread); - CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(model); + CBaseModelInfo* modelInfo = nullptr; + if (model >= 0) { + modelInfo = CModelInfo::GetModelInfo(model); + } if (modelInfo) bResult = true; CLEO_SetIntOpcodeParam(thread, (DWORD)modelInfo); reinterpret_cast(thread)->UpdateCompareFlag(bResult); diff --git a/CLEOPlus/Patches.cpp b/CLEOPlus/Patches.cpp index 6609de5..ba765f5 100644 --- a/CLEOPlus/Patches.cpp +++ b/CLEOPlus/Patches.cpp @@ -45,6 +45,27 @@ void ApplyPatches() patch::RedirectCall(0x6AD9E1, GetSimplestActiveTask_CarAnimFix, true); patch::RedirectCall(0x6AD9F9, GetSimplestActiveTask_CarAnimFix, true); + // Fix IS_CHAR_DEAD returning false even if health is 0.0 (wtf? why? this caused my script and Bullet Physics Ragdoll to not work correctly) + struct IsCharDeadFix + { + void operator()(reg_pack& regs) + { + CPed* ped = (CPed*)(regs.eax); + if (ped->m_fHealth <= 0.0f) { + regs.eax = ePedState::PEDSTATE_DEAD; + } + else { + regs.eax = ped->m_nPedState; //original code + } + } + }; + if (GetGameVersion() == GAME_10US_HOODLUM) { + MakeInline(0x156E7B4, 0x156E7B4 + 6); + } + else { + MakeInline(0x464D74, 0x464D74 + 6); + } + if (!coopOpcodesInstalled) PatchCoop(); RadarBlip::Patch(); } diff --git a/CLEOPlus/RadarBlip.cpp b/CLEOPlus/RadarBlip.cpp index 721e081..84e4560 100644 --- a/CLEOPlus/RadarBlip.cpp +++ b/CLEOPlus/RadarBlip.cpp @@ -38,6 +38,7 @@ namespace RadarBlip color.g = g; color.b = b; color.a = a; + angle = 0.0f; } }; @@ -137,18 +138,19 @@ using namespace RadarBlip; OpcodeResult WINAPI ADD_CLEO_BLIP(CScriptThread* thread) { int spriteId = CLEO_GetIntOpcodeParam(thread); + unsigned int spriteIdUnsigned = (unsigned int)spriteId; CSprite2d *sprite = new CSprite2d(); - if (spriteId < 0) { + if (spriteId < 0 && spriteId > -10000) { sprite->m_pTexture = (RwTexture*)CLEO_GetScriptTextureById(thread, (spriteId * -1)); spriteId = -1; } else { - if (spriteId > 0x00100000) { - sprite->m_pTexture = (RwTexture*)spriteId; + if (spriteIdUnsigned > 0x00010000) { + sprite->m_pTexture = (RwTexture*)spriteIdUnsigned; spriteId = -1; } else { - sprite->m_pTexture = radarBlipSprites[spriteId].m_pTexture; + sprite->m_pTexture = radarBlipSprites[spriteIdUnsigned].m_pTexture; } } float x = CLEO_GetFloatOpcodeParam(thread); diff --git a/CLEOPlus/TextDrawer/TextDrawer.cpp b/CLEOPlus/TextDrawer/TextDrawer.cpp index 7032950..6dc008d 100644 --- a/CLEOPlus/TextDrawer/TextDrawer.cpp +++ b/CLEOPlus/TextDrawer/TextDrawer.cpp @@ -64,9 +64,10 @@ void TextDrawer::DrawPrints() } void TextDrawer::ClearAll() { - for (auto print : m_aPrints) + unsigned int size = m_aPrints.size(); + for (unsigned int i = 0; i < size; ++i) { - delete print; + delete m_aPrints[i]; } m_aPrints.clear(); } \ No newline at end of file