diff --git a/CLEOPlus/CLEOPlus.cpp b/CLEOPlus/CLEOPlus.cpp index f0ae3b1..355e4df 100644 --- a/CLEOPlus/CLEOPlus.cpp +++ b/CLEOPlus/CLEOPlus.cpp @@ -17,8 +17,8 @@ #include "CTimer.h" #include "rw/rpworld.h" #include - -constexpr uint32_t CLEOPLUS_VERSION_INT = 0x01000500; + +constexpr uint32_t CLEOPLUS_VERSION_INT = 0x01000600; using namespace plugin; using namespace std; @@ -683,7 +683,7 @@ class CLEOPlus CLEO_RegisterOpcode(0xEC3, SET_STRING_LOWER); // 0xEC3=1,set_string_lower %1s% CLEO_RegisterOpcode(0xEC4, STRING_FIND); // 0xEC4=4,string_find %1d% %2s% %3s% store_to %4d% CLEO_RegisterOpcode(0xEC5, CUT_STRING_AT); // 0xEC5=2,cut_string_at %1d% %2d% - CLEO_RegisterOpcode(0xEC6, IS_STRING_CHARACTER_AT); // 0xEC6=2,is_string_character_at %1d% %2d% + CLEO_RegisterOpcode(0xEC6, IS_STRING_CHARACTER_AT); // 0xEC6=3,is_string_character_at %1d% character %2d% index %2d% CLEO_RegisterOpcode(0xEC8, GET_CHAR_RANDOM_SEED); // 0xEC8=2,get_char_random_seed %1d% store_to %2d% CLEO_RegisterOpcode(0xEC9, GET_CAR_RANDOM_SEED); // 0xEC9=2,get_car_random_seed %1d% store_to %2d% CLEO_RegisterOpcode(0xECA, GET_OBJECT_RANDOM_SEED); // 0xECA=2,get_object_random_seed %1d% store_to %2d% @@ -888,8 +888,6 @@ class CLEOPlus { if (CPed* ped = pedsPool->GetAt(index)) { - PedExtended& xdata = extData.Get(ped); - // Call char process script event if invisible, because our ped render hook will not call it if (ped->m_nPedState == 50) { if (scriptEvents[ScriptEvent::List::CharProcess].size() > 0) { @@ -898,35 +896,39 @@ class CLEOPlus } } - // Reset AI flags - xdata.aiFlagsIntValue = 0; - - // Cache tasks - int activeTaskIndex = 0; - if (ped->m_pIntelligence) + PedExtended& xdata = extData.Get(ped); + if (&xdata != nullptr) { - CTaskManager* taskMgr = &ped->m_pIntelligence->m_TaskMgr; - for (int i = 0; i < 5; i++) + // Reset AI flags + xdata.aiFlagsIntValue = 0; + + // Cache tasks + int activeTaskIndex = 0; + if (ped->m_pIntelligence) { - CTask* task = taskMgr->m_aPrimaryTasks[i]; - while (task) + CTaskManager* taskMgr = &ped->m_pIntelligence->m_TaskMgr; + for (int i = 0; i < 5; i++) { - CacheOnePedTask(ped, xdata, activeTaskIndex, task, false); - task = task->GetSubTask(); + CTask* task = taskMgr->m_aPrimaryTasks[i]; + while (task) + { + CacheOnePedTask(ped, xdata, activeTaskIndex, task, false); + task = task->GetSubTask(); + } } - } - for (int i = 0; i < 5; i++) - { - CTask* task = taskMgr->m_aSecondaryTasks[i]; - while (task) + for (int i = 0; i < 5; i++) { - CacheOnePedTask(ped, xdata, activeTaskIndex, task, true); - task = task->GetSubTask(); + CTask* task = taskMgr->m_aSecondaryTasks[i]; + while (task) + { + CacheOnePedTask(ped, xdata, activeTaskIndex, task, true); + task = task->GetSubTask(); + } } } + if (activeTaskIndex < 31) xdata.activeTasks[activeTaskIndex] = -1; // set terminator } - if (activeTaskIndex < 31) xdata.activeTasks[activeTaskIndex] = -1; // set terminator } } @@ -940,13 +942,14 @@ class CLEOPlus { if (CPed* ped = pedsPool->GetAt(index)) { - PedExtended& xdata = extData.Get(ped); - - // Reset last damage; - xdata.lastDamageEntity = nullptr; - xdata.lastDamageWeapon = 0; - xdata.lastDamagePart = 0; - xdata.lastDamageIntensity = 0.0f; + PedExtended &xdata = extData.Get(ped); + if (&xdata != nullptr) { + // Reset last damage; + xdata.lastDamageEntity = nullptr; + xdata.lastDamageWeapon = 0; + xdata.lastDamagePart = 0; + xdata.lastDamageIntensity = 0.0f; + } } } // Reset vehicle data per frame @@ -955,12 +958,14 @@ class CLEOPlus { if (CVehicle* vehicle = vehsPool->GetAt(index)) { - VehExtended& xdata = vehExtData.Get(vehicle); + VehExtended &xdata = vehExtData.Get(vehicle); - // Reset last damage; - xdata.lastDamagePed = nullptr; - xdata.lastDamageType = 0; - xdata.lastDamageIntensity = 0.0f; + if (&xdata) { + // Reset last damage; + xdata.lastDamagePed = nullptr; + xdata.lastDamageType = 0; + xdata.lastDamageIntensity = 0.0f; + } } } controllerMode = ReadMemory(0x47F399, false); @@ -1044,7 +1049,7 @@ class CLEOPlus // -- Render objects if (ped->m_bIsVisible && ped->m_pRwObject) { - if (xdata.renderObjects.size() > 0) + if (&xdata != nullptr && xdata.renderObjects.size() > 0) { for (RenderObject *renderObject : xdata.renderObjects) { @@ -1159,7 +1164,7 @@ class CLEOPlus Events::pedDtorEvent.before += [](CPed *ped) { PedExtended &data = extData.Get(ped); - if (&data && data.renderObjects.size() > 0) + if (&data != nullptr && data.renderObjects.size() > 0) { DeleteAllRenderObjectsFromChar(data); } @@ -1242,11 +1247,13 @@ class CLEOPlus CPedDamageResponseCalculator *damageCalculator = (CPedDamageResponseCalculator *)regs.ebp; if (damageCalculator->m_fDamageFactor != 0.0f) { CPed* ped = (CPed*)regs.esi; - PedExtended& data = extData.Get(ped); - data.lastDamageEntity = damageCalculator->m_pDamager; - data.lastDamageIntensity = damageCalculator->m_fDamageFactor; - data.lastDamageWeapon = damageCalculator->m_weaponType; - data.lastDamagePart = damageCalculator->m_pedPieceType; + PedExtended &data = extData.Get(ped); + if (&data != nullptr) { + data.lastDamageEntity = damageCalculator->m_pDamager; + data.lastDamageIntensity = damageCalculator->m_fDamageFactor; + data.lastDamageWeapon = damageCalculator->m_weaponType; + data.lastDamagePart = damageCalculator->m_pedPieceType; + } if (scriptEvents[ScriptEvent::List::CharDamage].size() > 0) { int ref = CPools::GetPedRef(ped); @@ -1262,9 +1269,11 @@ class CLEOPlus if (intensity != 0.0f) { CVehicle *vehicle = (CVehicle *)regs.esi; VehExtended &data = vehExtData.Get(vehicle); - data.lastDamagePed = (CEntity *)regs.edi; - data.lastDamageType = regs.ebx; - data.lastDamageIntensity = intensity; + if (&data != nullptr) { + data.lastDamagePed = (CEntity*)regs.edi; + data.lastDamageType = regs.ebx; + data.lastDamageIntensity = intensity; + } if (scriptEvents[ScriptEvent::List::CarWeaponDamage].size() > 0) { int ref = CPools::GetVehicleRef(vehicle); @@ -1281,7 +1290,7 @@ class CLEOPlus regs.ecx = *(uint32_t*)(regs.ebx + 0x534); //mov ecx, [ebx+534h] CPed *ped = (CPed *)regs.ebx; PedExtended &data = extData.Get(ped); - if (data.ignoreDamageAnims) { + if (&data != nullptr && data.ignoreDamageAnims) { *(uintptr_t*)(regs.esp - 0x4) = 0x4B4019; // ret } }); diff --git a/CLEOPlus/Intelligence.cpp b/CLEOPlus/Intelligence.cpp index 87172a3..1a284b7 100644 --- a/CLEOPlus/Intelligence.cpp +++ b/CLEOPlus/Intelligence.cpp @@ -152,15 +152,17 @@ OpcodeResult WINAPI IS_CHAR_DOING_TASK_ID(CScriptThread* thread) PedExtended &data = extData.Get(ped); int taskId = CLEO_GetIntOpcodeParam(thread); - for (int i = 0; i < 32; ++i) { - int activeTaskId = data.activeTasks[i]; - if (activeTaskId != -1) { - if (activeTaskId == taskId) { - bResult = true; - break; + if (&data != nullptr) { + for (int i = 0; i < 32; ++i) { + int activeTaskId = data.activeTasks[i]; + if (activeTaskId != -1) { + if (activeTaskId == taskId) { + bResult = true; + break; + } } + else break; } - else break; } reinterpret_cast(thread)->UpdateCompareFlag(bResult); return OR_CONTINUE; @@ -176,7 +178,7 @@ OpcodeResult WINAPI GET_CHAR_TASK_POINTER_BY_ID(CScriptThread* thread) int activeTaskIndex = 0; CTask* task; - if (ped->m_pIntelligence) + if (ped->m_pIntelligence && &data != nullptr) { CTaskManager* taskMgr = &ped->m_pIntelligence->m_TaskMgr; for (int i = 0; i < 5; i++) @@ -220,7 +222,7 @@ OpcodeResult WINAPI GET_CHAR_KILL_TARGET_CHAR(CScriptThread* thread) CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); CEntity *entity = nullptr; PedExtended &data = extData.Get(ped); - entity = data.killTargetPed; + if (&data != nullptr) entity = data.killTargetPed; if (reinterpret_cast(entity) == -1 && ped->IsPlayer()) { entity = reinterpret_cast(ped)->m_pPlayerTargettedPed; } @@ -238,7 +240,7 @@ OpcodeResult WINAPI IS_CHAR_USING_GUN(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(xdata.aiFlags.bUsingGun); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && xdata.aiFlags.bUsingGun); return OR_CONTINUE; } @@ -247,16 +249,16 @@ OpcodeResult WINAPI IS_CHAR_FIGHTING(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(xdata.aiFlags.bFighting); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && xdata.aiFlags.bFighting); return OR_CONTINUE; } - + // 0E48=1,is_char_fallen_on_ground %1d% OpcodeResult WINAPI IS_CHAR_FALLEN_ON_GROUND(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(xdata.aiFlags.bFallenOnGround); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && xdata.aiFlags.bFallenOnGround); return OR_CONTINUE; } @@ -265,7 +267,7 @@ OpcodeResult WINAPI IS_CHAR_ENTERING_ANY_CAR(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(xdata.aiFlags.bEnteringAnyCar); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && xdata.aiFlags.bEnteringAnyCar); return OR_CONTINUE; } @@ -274,7 +276,7 @@ OpcodeResult WINAPI IS_CHAR_EXITING_ANY_CAR(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(xdata.aiFlags.bExitingAnyCar); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && xdata.aiFlags.bExitingAnyCar); return OR_CONTINUE; } @@ -285,7 +287,7 @@ OpcodeResult WINAPI IS_CHAR_PLAYING_ANY_SCRIPT_ANIMATION(CScriptThread* thread) CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); int includeAnims = CLEO_GetIntOpcodeParam(thread); PedExtended &xdata = extData.Get(ped); - reinterpret_cast(thread)->UpdateCompareFlag(CheckPlayingAnyAnim(xdata, includeAnims)); + reinterpret_cast(thread)->UpdateCompareFlag(&xdata != nullptr && CheckPlayingAnyAnim(xdata, includeAnims)); return OR_CONTINUE; } @@ -296,7 +298,7 @@ OpcodeResult WINAPI IS_CHAR_DOING_ANY_IMPORTANT_TASK(CScriptThread* thread) CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); int includeAnims = CLEO_GetIntOpcodeParam(thread); PedExtended &xdata = extData.Get(ped); - if (xdata.aiFlags.bRootTaskIsntImportant && !xdata.aiFlags.bKillingSomething) { + if (&xdata != nullptr && xdata.aiFlags.bRootTaskIsntImportant && !xdata.aiFlags.bKillingSomething) { bResult = CheckPlayingAnyAnim(xdata, includeAnims); } reinterpret_cast(thread)->UpdateCompareFlag(bResult); diff --git a/CLEOPlus/Misc.cpp b/CLEOPlus/Misc.cpp index 12fd804..523640a 100644 --- a/CLEOPlus/Misc.cpp +++ b/CLEOPlus/Misc.cpp @@ -1260,11 +1260,21 @@ OpcodeResult WINAPI GET_CHAR_DAMAGE_LAST_FRAME(CScriptThread* thread) int ref = CLEO_GetIntOpcodeParam(thread); CPed *ped = CPools::GetPed(ref); PedExtended &data = extData.Get(ped); - CLEO_SetIntOpcodeParam(thread, (DWORD)data.lastDamageEntity); - CLEO_SetIntOpcodeParam(thread, data.lastDamageWeapon); - CLEO_SetIntOpcodeParam(thread, data.lastDamagePart); - CLEO_SetFloatOpcodeParam(thread, data.lastDamageIntensity); - if (data.lastDamageIntensity > 0.0f) bResult = true; + if (&data) + { + CLEO_SetIntOpcodeParam(thread, -1); + CLEO_SetIntOpcodeParam(thread, -1); + CLEO_SetIntOpcodeParam(thread, -1); + CLEO_SetFloatOpcodeParam(thread, 0.0f); + } + else + { + CLEO_SetIntOpcodeParam(thread, (DWORD)data.lastDamageEntity); + CLEO_SetIntOpcodeParam(thread, data.lastDamageWeapon); + CLEO_SetIntOpcodeParam(thread, data.lastDamagePart); + CLEO_SetFloatOpcodeParam(thread, data.lastDamageIntensity); + if (data.lastDamageIntensity > 0.0f) bResult = true; + } reinterpret_cast(thread)->UpdateCompareFlag(bResult); return OR_CONTINUE; } @@ -1277,14 +1287,22 @@ OpcodeResult WINAPI GET_CAR_WEAPON_DAMAGE_LAST_FRAME(CScriptThread* thread) VehExtended &data = vehExtData.Get(vehicle); int pedReturn = -1; - if (data.lastDamagePed) { - pedReturn = CPools::GetPedRef((CPed*)data.lastDamagePed); + + if (&data != nullptr) { + CLEO_SetIntOpcodeParam(thread, pedReturn); + CLEO_SetIntOpcodeParam(thread, -1); + CLEO_SetFloatOpcodeParam(thread, 0.0f); } - if (data.lastDamageIntensity != 0.0f) bResult = true; + else { + if (data.lastDamagePed) { + pedReturn = CPools::GetPedRef((CPed*)data.lastDamagePed); + } + if (data.lastDamageIntensity != 0.0f) bResult = true; - CLEO_SetIntOpcodeParam(thread, pedReturn); - CLEO_SetIntOpcodeParam(thread, data.lastDamageType); - CLEO_SetFloatOpcodeParam(thread, data.lastDamageIntensity); + CLEO_SetIntOpcodeParam(thread, pedReturn); + CLEO_SetIntOpcodeParam(thread, data.lastDamageType); + CLEO_SetFloatOpcodeParam(thread, data.lastDamageIntensity); + } reinterpret_cast(thread)->UpdateCompareFlag(bResult); return OR_CONTINUE; } @@ -1454,7 +1472,7 @@ OpcodeResult WINAPI STRING_FIND(CScriptThread* thread) std::string str = CLEO_ReadStringPointerOpcodeParam(thread, bufferA, 128); std::string strFind = CLEO_ReadStringPointerOpcodeParam(thread, bufferB, 128); - size_t found; + size_t found = 0; if (mode == 0) { @@ -1577,7 +1595,10 @@ OpcodeResult WINAPI SET_CHAR_IGNORE_DAMAGE_ANIMS(CScriptThread* thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); PedExtended &data = extData.Get(ped); - data.ignoreDamageAnims = CLEO_GetIntOpcodeParam(thread) == 1; + bool set = CLEO_GetIntOpcodeParam(thread) == 1; + if (&data != nullptr) { + data.ignoreDamageAnims = set; + } return OR_CONTINUE; } diff --git a/CLEOPlus/RenderObjectOnChar.cpp b/CLEOPlus/RenderObjectOnChar.cpp index 62a4575..7d65101 100644 --- a/CLEOPlus/RenderObjectOnChar.cpp +++ b/CLEOPlus/RenderObjectOnChar.cpp @@ -47,7 +47,9 @@ OpcodeResult WINAPI CREATE_RENDER_OBJECT_TO_CHAR_BONE(CScriptThread* thread) renderObject = new RenderObject(ped, 0, rwFrame, rpAtomic, model, boneId, x, y, z, rx, ry, rz, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); PedExtended &data = extData.Get(ped); - data.renderObjects.push_back(renderObject); + if (&data != nullptr) { + data.renderObjects.push_back(renderObject); + } } } else @@ -61,7 +63,9 @@ OpcodeResult WINAPI CREATE_RENDER_OBJECT_TO_CHAR_BONE(CScriptThread* thread) renderObject = new RenderObject(ped, rpClump, 0, 0, model, boneId, x, y, z, rx, ry, rz, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); PedExtended &data = extData.Get(ped); - data.renderObjects.push_back(renderObject); + if (&data != nullptr) { + data.renderObjects.push_back(renderObject); + } } } @@ -77,7 +81,7 @@ OpcodeResult WINAPI DELETE_RENDER_OBJECT(CScriptThread* thread) if (renderObject) { PedExtended &data = extData.Get((CPed*)renderObject->owner); - if (&data) + if (&data != nullptr) { for (std::vector::iterator iter = data.renderObjects.begin(); iter != data.renderObjects.end(); ++iter) {