From 28310ef8d253769ce55239e1530c4eed465a4b0c Mon Sep 17 00:00:00 2001 From: MiranDMC <11084446+MiranDMC@users.noreply.github.com> Date: Sun, 7 Dec 2025 23:52:02 +0000 Subject: [PATCH 01/13] Update version info: v.1001 --- shared/plugin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/plugin.h b/shared/plugin.h index ca0790ec..07a0cd21 100644 --- a/shared/plugin.h +++ b/shared/plugin.h @@ -9,10 +9,10 @@ #define __TO_STR(x) #x #define TO_STR(x) __TO_STR(x) -#define PLUGIN_SDK_VERSION 1000 +#define PLUGIN_SDK_VERSION 1001 #define PLUGIN_SDK_VERSION_STR TO_STR(PLUGIN_SDK_VERSION) -#define PLUGIN_SDK_DATE 2025-10-28 18:33:25 +#define PLUGIN_SDK_DATE 2025-12-07 23:52:00 #define PLUGIN_SDK_DATE_STR TO_STR(PLUGIN_SDK_DATE) #include "PluginBase.h" From 9f5ec89f323419ee787d80e9dafa4c7c758b0c6b Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 01:08:39 +0100 Subject: [PATCH 02/13] Added missing DEBUG define for debug configurations --- tools/premake/premake5.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/premake/premake5.lua b/tools/premake/premake5.lua index 96b0dba1..7c5d11aa 100644 --- a/tools/premake/premake5.lua +++ b/tools/premake/premake5.lua @@ -193,6 +193,7 @@ function pluginSdkStaticLibProject(projectName, sdkdir, outName, isPluginProject symbols "Off" filter "zDebug" symbols "On" + defines "DEBUG" filter {} if mingw then @@ -764,6 +765,7 @@ function pluginSdkExampleProject(projectDir, projectName, projectType, game2, ga linktimeoptimization "On" filter "Debug" symbols "On" + defines "DEBUG" filter {} setToolset() From 8cd23438291d70f4dfeca96908539162a9b80b16 Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 01:09:27 +0100 Subject: [PATCH 03/13] Added Reset method to CVector --- examples/UnitTests/source/Test_CVector.h | 10 ++++++++++ shared/game/CVector.h | 5 ++++- shared/game/CVectorImplementation.h | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/examples/UnitTests/source/Test_CVector.h b/examples/UnitTests/source/Test_CVector.h index 78c97812..12afebf8 100644 --- a/examples/UnitTests/source/Test_CVector.h +++ b/examples/UnitTests/source/Test_CVector.h @@ -77,6 +77,16 @@ UTEST(CVector, ctor_CVector2D) // assignments +UTEST(CVector, Reset) +{ + auto v = CVector(1.0f, 2.0f, 3.0f); + + v.Reset(); + EXPECT_EQ(v.x, 0.0f); + EXPECT_EQ(v.y, 0.0f); + EXPECT_EQ(v.z, 0.0f); +} + UTEST(CVector, Set_F) { auto v = CVector(); diff --git a/shared/game/CVector.h b/shared/game/CVector.h index adced239..5d22d582 100644 --- a/shared/game/CVector.h +++ b/shared/game/CVector.h @@ -20,7 +20,9 @@ class CVector2D; class CVector { public: - float x, y, z; + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; // constructors CVector() = default; @@ -33,6 +35,7 @@ class CVector explicit CVector(const CVector2D& xy, float z = 0.0f); // assignments + void Reset(); // set to 0 0 0 void Set(float value); // assign value to all components void Set(float x, float y, float z); void operator =(const CVector& src); diff --git a/shared/game/CVectorImplementation.h b/shared/game/CVectorImplementation.h index 82128cba..beffe203 100644 --- a/shared/game/CVectorImplementation.h +++ b/shared/game/CVectorImplementation.h @@ -33,6 +33,10 @@ inline CVector::CVector(const CVector2D& xy, float z) { // assignments +inline void CVector::Reset() { + Set(0.0f); +} + inline void CVector::Set(float value) { Set(value, value, value); } From 8cd7d516015db0ed4ac79b00bc5bb782dd545945 Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 01:44:10 +0100 Subject: [PATCH 04/13] Added CMentalState class --- plugin_sa/game_sa/CMentalState.cpp | 17 ++++++++++++++++ plugin_sa/game_sa/CMentalState.h | 32 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 plugin_sa/game_sa/CMentalState.cpp create mode 100644 plugin_sa/game_sa/CMentalState.h diff --git a/plugin_sa/game_sa/CMentalState.cpp b/plugin_sa/game_sa/CMentalState.cpp new file mode 100644 index 00000000..bb41c605 --- /dev/null +++ b/plugin_sa/game_sa/CMentalState.cpp @@ -0,0 +1,17 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CMentalState.h" + +// 0x421050 +void CMentalState::IncrementAnger(int anger) { + plugin::CallMethod<0x421050, CMentalState*, int>(this, anger); +} + +// 0x6008A0 +void CMentalState::Process() { + plugin::CallMethod<0x6008A0, CMentalState*>(this); +} diff --git a/plugin_sa/game_sa/CMentalState.h b/plugin_sa/game_sa/CMentalState.h new file mode 100644 index 00000000..51996a31 --- /dev/null +++ b/plugin_sa/game_sa/CMentalState.h @@ -0,0 +1,32 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) header file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#pragma once + +#include "PluginBase.h" +#include "CTaskTimer.h" + +class PLUGIN_API CMentalState { +public: + unsigned char m_AngerAtPlayer; + unsigned char m_LastAngerAtPlayer; + + CTaskTimer m_AngerTimer; + + unsigned char m_pedHealth; + unsigned char m_oldPedHealth; + + unsigned char m_vehicleHealth; + unsigned char m_oldVehicleHealth; + +public: + CMentalState() = default; + ~CMentalState() = default; + + void IncrementAnger(int anger); + void Process(); +}; +VALIDATE_SIZE(CMentalState, 0x14); From 90b61407175f7d50f0dfeda5df344402cdb77f60 Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 01:46:33 +0100 Subject: [PATCH 05/13] Added CCollisionEventScanner class --- plugin_sa/game_sa/CCollisionEventScanner.cpp | 12 ++++++++++++ plugin_sa/game_sa/CCollisionEventScanner.h | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 plugin_sa/game_sa/CCollisionEventScanner.cpp create mode 100644 plugin_sa/game_sa/CCollisionEventScanner.h diff --git a/plugin_sa/game_sa/CCollisionEventScanner.cpp b/plugin_sa/game_sa/CCollisionEventScanner.cpp new file mode 100644 index 00000000..d4d93890 --- /dev/null +++ b/plugin_sa/game_sa/CCollisionEventScanner.cpp @@ -0,0 +1,12 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CCollisionEventScanner.h" + +void CCollisionEventScanner::ScanForCollisionEvents(CPed* victim, CEventGroup* eventGroup) +{ + plugin::CallMethod<0x604500, CCollisionEventScanner*, CPed*, CEventGroup*>(this, victim, eventGroup); +} diff --git a/plugin_sa/game_sa/CCollisionEventScanner.h b/plugin_sa/game_sa/CCollisionEventScanner.h new file mode 100644 index 00000000..c113cd95 --- /dev/null +++ b/plugin_sa/game_sa/CCollisionEventScanner.h @@ -0,0 +1,20 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) header file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#pragma once + +#include "PluginBase.h" + +class CPed; +class CEventGroup; + +class PLUGIN_API CCollisionEventScanner { +public: + bool m_bAlreadyHitByCar; + + void ScanForCollisionEvents(CPed* victim, CEventGroup* eventGroup); +}; +VALIDATE_SIZE(CCollisionEventScanner, 0x1); From d527aa4dd1882b8275c7897bc5a33c79e5dcc1be Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 02:15:22 +0100 Subject: [PATCH 06/13] Added CPedStuckChecker class --- plugin_sa/game_sa/CPedStuckChecker.cpp | 12 +++++++++ plugin_sa/game_sa/CPedStuckChecker.h | 36 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 plugin_sa/game_sa/CPedStuckChecker.cpp create mode 100644 plugin_sa/game_sa/CPedStuckChecker.h diff --git a/plugin_sa/game_sa/CPedStuckChecker.cpp b/plugin_sa/game_sa/CPedStuckChecker.cpp new file mode 100644 index 00000000..1a841189 --- /dev/null +++ b/plugin_sa/game_sa/CPedStuckChecker.cpp @@ -0,0 +1,12 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CPedStuckChecker.h" + +bool CPedStuckChecker::TestPedStuck(CPed* ped, CEventGroup* eventGroup) +{ + return plugin::CallMethodAndReturn(this, ped, eventGroup); +} diff --git a/plugin_sa/game_sa/CPedStuckChecker.h b/plugin_sa/game_sa/CPedStuckChecker.h new file mode 100644 index 00000000..7b67b2d4 --- /dev/null +++ b/plugin_sa/game_sa/CPedStuckChecker.h @@ -0,0 +1,36 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#pragma once + +#include "CVector.h" + +class CPed; +class CEventGroup; + +enum PLUGIN_API ePedStuckState : unsigned short { + PED_STUCK_STATE_NONE = 0, + PED_STUCK_STATE_STUCK, + PED_STUCK_STATE_WAS_STUCK +}; + +class PLUGIN_API CPedStuckChecker { +public: + CVector m_lastNonStuckPoint; + unsigned short m_radius; + ePedStuckState m_state; + +public: + CPedStuckChecker() { // inlined 0x607292 + m_radius = 0; + m_state = PED_STUCK_STATE_NONE; + } + + bool TestPedStuck(CPed* ped, CEventGroup* eventGroup); + + auto GetState() const { return m_state; } +}; +VALIDATE_SIZE(CPedStuckChecker, 0x10); From 3f264d9e1a05f30a50ae3665cab41f3fcaae75fb Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 02:19:34 +0100 Subject: [PATCH 07/13] Defined some unknown fields of CPedIntelligence --- plugin_sa/game_sa/CPed.h | 2 +- plugin_sa/game_sa/CPedIntelligence.h | 167 +++++++++++++-------------- 2 files changed, 83 insertions(+), 86 deletions(-) diff --git a/plugin_sa/game_sa/CPed.h b/plugin_sa/game_sa/CPed.h index 7c3c6e24..897b1a04 100644 --- a/plugin_sa/game_sa/CPed.h +++ b/plugin_sa/game_sa/CPed.h @@ -39,7 +39,7 @@ enum PLUGIN_API eMoveState { PEDMOVE_SPRINT }; -enum eFightingStyle +enum PLUGIN_API eFightingStyle { STYLE_STANDARD = 4, STYLE_BOXING, diff --git a/plugin_sa/game_sa/CPedIntelligence.h b/plugin_sa/game_sa/CPedIntelligence.h index d901d330..14575ab0 100644 --- a/plugin_sa/game_sa/CPedIntelligence.h +++ b/plugin_sa/game_sa/CPedIntelligence.h @@ -11,8 +11,10 @@ #include "CEventHandler.h" #include "CEventGroup.h" #include "CEntityScanner.h" -#include "CTaskTimer.h" +#include "CMentalState.h" #include "CEventScanner.h" +#include "CCollisionEventScanner.h" +#include "CPedStuckChecker.h" #include "CTaskSimpleUseGun.h" #include "CTaskSimpleJetpack.h" #include "CTaskSimpleFight.h" @@ -26,91 +28,86 @@ class PLUGIN_API CPedIntelligence { public: - class CPed *m_pPed; - CTaskManager m_TaskMgr; - CEventHandler m_eventHandler; - CEventGroup m_eventGroup; - unsigned int m_nDecisionMakerType; - unsigned int m_nDecisionMakerTypeInGroup; - float m_fHearingRange; - float m_fSeeingRange; - unsigned int m_nDmNumPedsToScan; - float m_fDmRadius; - int field_CC; - char field_D0; - unsigned char m_nEventId; - unsigned char m_nEventPriority; - char field_D3; - CEntityScanner m_vehicleScanner; - CEntityScanner m_pedScanner; - char field_174; - char gap_175[3]; - CTaskTimer field_178; - int field_184; - char field_188; - char gap_189[3]; - CEventScanner m_eventScanner; - char field_260; - char gap_261[3]; - char field_264[16]; - int field_274; - int field_278; - char gap_27C[12]; - class CEntity *m_apInterestingEntities[3]; + class CPed* m_pPed; + CTaskManager m_TaskMgr; + CEventHandler m_eventHandler; + CEventGroup m_eventGroup; + unsigned int m_nDecisionMakerType; + unsigned int m_nDecisionMakerTypeInGroup; + float m_fHearingRange; + float m_fSeeingRange; + unsigned int m_nDmNumPedsToScan; + float m_fDmRadius; + float m_FollowNodeThresholdDistance; + char m_NextEventResponseSequence; + unsigned char m_nEventId; + unsigned char m_nEventPriority; + char field_D3; + CEntityScanner m_vehicleScanner; + CEntityScanner m_pedScanner; + CMentalState m_mentalState; + char field_188; + CEventScanner m_eventScanner; + CCollisionEventScanner m_collisionScanner; + CPedStuckChecker m_pedStuckChecker; + int m_AnotherStaticCounter; + int m_StaticCounter; + CVector m_vecLastPedPosDuringDamageEntity; + class CEntity* m_apInterestingEntities[3]; - void SetPedDecisionMakerType(int newtype); - void SetPedDecisionMakerTypeInGroup(int newtype); - void RestorePedDecisionMakerType(); - void SetHearingRange(float range); - void SetSeeingRange(float range); - bool IsInHearingRange(CVector const& posn); - bool IsInSeeingRange(CVector const& posn); - bool FindRespectedFriendInInformRange(); - bool IsRespondingToEvent(int event); - void AddTaskPhysResponse(CTask* task, bool arg2); - void AddTaskEventResponseTemp(CTask* task, bool arg2); - void AddTaskEventResponseNonTemp(CTask* task, bool arg2); - void AddTaskPrimaryMaybeInGroup(CTask* task, bool arg2); - CTask* FindTaskByType(int type); - CTaskSimpleFight* GetTaskFighting(); - CTaskSimpleUseGun* GetTaskUseGun(); - CTaskSimpleThrowProjectile* GetTaskThrow(); - CTaskSimpleHoldEntity* GetTaskHold(bool arg1); - CTaskSimpleSwim* GetTaskSwim(); - CTaskSimpleDuck* GetTaskDuck(bool arg1); - CTaskSimpleJetPack* GetTaskJetPack(); - CTaskSimpleInAir* GetTaskInAir(); - CTaskSimpleClimb* GetTaskClimb(); - bool GetUsingParachute(); - void SetTaskDuckSecondary(unsigned short arg1); - void ClearTaskDuckSecondary(); - void ClearTasks(bool arg1, bool arg2); - void FlushImmediately(bool arg1); - C2dEffect* GetEffectInUse(); - void SetEffectInUse(C2dEffect* arg1); - void ProcessAfterProcCol(); - void ProcessAfterPreRender(); - void ProcessEventHandler(); - bool IsFriendlyWith(CPed const& ped); - bool IsThreatenedBy(CPed const& ped); - bool Respects(CPed const& ped); - bool IsInACarOrEnteringOne(); - static bool AreFriends(CPed const& ped1, CPed const& ped2); - bool IsPedGoingSomewhereOnFoot(); - int* GetMoveStateFromGoToTask(); - void FlushIntelligence(); - bool TestForStealthKill(CPed* pPed, bool arg2); - void RecordEventForScript(int EventID, int EventPriority); - bool HasInterestingEntites(); - bool IsInterestingEntity(CEntity* pEntity); - void LookAtInterestingEntities(); - void RemoveAllInterestingEntities(); - bool IsPedGoingForCarDoor(); - float CanSeeEntityWithLights(CEntity const* pEntity, bool arg2); - void ProcessStaticCounter(); - void ProcessFirst(); - void Process(); - static void operator delete(void* arg1); + void SetPedDecisionMakerType(int newtype); + void SetPedDecisionMakerTypeInGroup(int newtype); + void RestorePedDecisionMakerType(); + void SetHearingRange(float range); + void SetSeeingRange(float range); + bool IsInHearingRange(CVector const& posn); + bool IsInSeeingRange(CVector const& posn); + bool FindRespectedFriendInInformRange(); + bool IsRespondingToEvent(int event); + void AddTaskPhysResponse(CTask* task, bool arg2); + void AddTaskEventResponseTemp(CTask* task, bool arg2); + void AddTaskEventResponseNonTemp(CTask* task, bool arg2); + void AddTaskPrimaryMaybeInGroup(CTask* task, bool arg2); + CTask* FindTaskByType(int type); + CTaskSimpleFight* GetTaskFighting(); + CTaskSimpleUseGun* GetTaskUseGun(); + CTaskSimpleThrowProjectile* GetTaskThrow(); + CTaskSimpleHoldEntity* GetTaskHold(bool arg1); + CTaskSimpleSwim* GetTaskSwim(); + CTaskSimpleDuck* GetTaskDuck(bool arg1); + CTaskSimpleJetPack* GetTaskJetPack(); + CTaskSimpleInAir* GetTaskInAir(); + CTaskSimpleClimb* GetTaskClimb(); + bool GetUsingParachute(); + void SetTaskDuckSecondary(unsigned short arg1); + void ClearTaskDuckSecondary(); + void ClearTasks(bool arg1, bool arg2); + void FlushImmediately(bool arg1); + C2dEffect* GetEffectInUse(); + void SetEffectInUse(C2dEffect* arg1); + void ProcessAfterProcCol(); + void ProcessAfterPreRender(); + void ProcessEventHandler(); + bool IsFriendlyWith(CPed const& ped); + bool IsThreatenedBy(CPed const& ped); + bool Respects(CPed const& ped); + bool IsInACarOrEnteringOne(); + static bool AreFriends(CPed const& ped1, CPed const& ped2); + bool IsPedGoingSomewhereOnFoot(); + int* GetMoveStateFromGoToTask(); + void FlushIntelligence(); + bool TestForStealthKill(CPed* pPed, bool arg2); + void RecordEventForScript(int EventID, int EventPriority); + bool HasInterestingEntites(); + bool IsInterestingEntity(CEntity* pEntity); + void LookAtInterestingEntities(); + void RemoveAllInterestingEntities(); + bool IsPedGoingForCarDoor(); + float CanSeeEntityWithLights(CEntity const* pEntity, bool arg2); + void ProcessStaticCounter(); + void ProcessFirst(); + void Process(); + static void operator delete(void* arg1); }; VALIDATE_SIZE(CPedIntelligence, 0x294); From ba6c5e6b176f746a0e8821ac0c4fb55036d5acc9 Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 03:01:31 +0100 Subject: [PATCH 08/13] eTaskType formatting fixes --- plugin_sa/game_sa/eTaskType.h | 258 +++++++++++++++++----------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/plugin_sa/game_sa/eTaskType.h b/plugin_sa/game_sa/eTaskType.h index 80e9ed6a..2d2adfe9 100644 --- a/plugin_sa/game_sa/eTaskType.h +++ b/plugin_sa/game_sa/eTaskType.h @@ -38,7 +38,7 @@ enum eTaskType : int TASK_SIMPLE_STAND_STILL, //SCRIPT_DECISION TASK_SIMPLE_SET_STAY_IN_SAME_PLACE, - TASK_SIMPLE_GET_UP, + TASK_SIMPLE_GET_UP, TASK_COMPLEX_GET_UP_AND_STAND_STILL, TASK_SIMPLE_FALL, TASK_COMPLEX_FALL_AND_GET_UP, @@ -63,7 +63,7 @@ enum eTaskType : int TASK_COMPLEX_SIT_DOWN_THEN_IDLE_THEN_STAND_UP, TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS, TASK_COMPLEX_OBSERVE_TRAFFIC_LIGHTS_AND_ACHIEVE_HEADING, - TASK_NOT_USED, + TASK_NOT_USED, TASK_COMPLEX_CROSS_ROAD_LOOK_AND_ACHIEVE_HEADING, TASK_SIMPLE_TURN_180, TASK_SIMPLE_HAIL_TAXI, @@ -71,7 +71,7 @@ enum eTaskType : int TASK_COMPLEX_HIT_BY_GUN_RESPONSE, TASK_UNUSED_SLOT, TASK_COMPLEX_USE_EFFECT, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_WAIT_AT_ATTRACTOR, TASK_COMPLEX_USE_ATTRACTOR, TASK_COMPLEX_WAIT_FOR_DRY_WEATHER, @@ -96,9 +96,9 @@ enum eTaskType : int TASK_SIMPLE_TRIGGER_EVENT, TASK_SIMPLE_RAGDOLL, TASK_SIMPLE_CLIMB, - TASK_SIMPLE_PLAYER_ON_FIRE, - TASK_COMPLEX_PARTNER, - TASK_COMPLEX_STARE_AT_PED, + TASK_SIMPLE_PLAYER_ON_FIRE, + TASK_COMPLEX_PARTNER, + TASK_COMPLEX_STARE_AT_PED, TASK_COMPLEX_USE_CLOSEST_FREE_SCRIPTED_ATTRACTOR, //SCRIPT_DECISION TASK_COMPLEX_USE_EFFECT_RUNNING, @@ -111,8 +111,8 @@ enum eTaskType : int //SCRIPT_DECISION TASK_SIMPLE_CHOKING, TASK_SIMPLE_IK_CHAIN, - TASK_SIMPLE_IK_MANAGER, - TASK_SIMPLE_IK_LOOK_AT, + TASK_SIMPLE_IK_MANAGER, + TASK_SIMPLE_IK_LOOK_AT, TASK_COMPLEX_CLIMB, TASK_COMPLEX_IN_WATER, TASK_SIMPLE_TRIGGER_LOOK_AT, @@ -136,17 +136,17 @@ enum eTaskType : int //SCRIPT_DECISION TASK_SIMPLE_FACIAL, //SCRIPT_DECISION - TASK_COMPLEX_CHAINED_FACIAL, - TASK_COMPLEX_FACIAL, - TASK_SIMPLE_AFFECT_SECONDARY_BEHAVIOUR, - TASK_SIMPLE_HOLD_ENTITY, - TASK_SIMPLE_PICKUP_ENTITY, // these three aren't really secondary tasks - TASK_SIMPLE_PUTDOWN_ENTITY, // but they exist around the secondary hold entity - TASK_COMPLEX_GO_PICKUP_ENTITY, // task at the start and finish + TASK_COMPLEX_CHAINED_FACIAL, + TASK_COMPLEX_FACIAL, + TASK_SIMPLE_AFFECT_SECONDARY_BEHAVIOUR, + TASK_SIMPLE_HOLD_ENTITY, + TASK_SIMPLE_PICKUP_ENTITY, // these three aren't really secondary tasks + TASK_SIMPLE_PUTDOWN_ENTITY, // but they exist around the secondary hold entity + TASK_COMPLEX_GO_PICKUP_ENTITY, // task at the start and finish TASK_SIMPLE_DUCK_WHILE_SHOTS_WHIZZING, //SCRIPT_DECISION - //anims (tasks that are sub-classes of CTaskSimpleRunUnloopedAnim) + //anims (tasks that are sub-classes of CTaskSimpleRunUnloopedAnim) TASK_SIMPLE_ANIM = 400, TASK_SIMPLE_NAMED_ANIM, TASK_SIMPLE_TIMED_ANIM, @@ -185,13 +185,13 @@ enum eTaskType : int //collision response tasks TASK_SIMPLE_HIT_HEAD = 500, - TASK_SIMPLE_EVASIVE_STEP, - TASK_COMPLEX_EVASIVE_STEP, - TASK_SIMPLE_EVASIVE_DIVE, + TASK_SIMPLE_EVASIVE_STEP, + TASK_COMPLEX_EVASIVE_STEP, + TASK_SIMPLE_EVASIVE_DIVE, TASK_COMPLEX_EVASIVE_DIVE_AND_GET_UP, TASK_COMPLEX_HIT_PED_WITH_CAR, TASK_SIMPLE_KILL_PED_WITH_CAR, - TASK_SIMPLE_HURT_PED_WITH_CAR, + TASK_SIMPLE_HURT_PED_WITH_CAR, TASK_COMPLEX_WALK_ROUND_CAR, //SCRIPT_DECISION TASK_COMPLEX_WALK_ROUND_BUILDING_ATTEMPT, @@ -252,19 +252,19 @@ enum eTaskType : int TASK_COMPLEX_ENTER_BOAT_AS_DRIVER, TASK_COMPLEX_LEAVE_BOAT, - TASK_COMPLEX_ENTER_ANY_CAR_AS_DRIVER, - TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_WAIT, - TASK_SIMPLE_CAR_DRIVE_TIMED, + TASK_COMPLEX_ENTER_ANY_CAR_AS_DRIVER, + TASK_COMPLEX_ENTER_CAR_AS_PASSENGER_WAIT, + TASK_SIMPLE_CAR_DRIVE_TIMED, TASK_COMPLEX_SHUFFLE_SEATS, - TASK_COMPLEX_CAR_DRIVE_POINT_ROUTE, - TASK_COMPLEX_CAR_OPEN_DRIVER_DOOR, - TASK_SIMPLE_CAR_SET_TEMP_ACTION, + TASK_COMPLEX_CAR_DRIVE_POINT_ROUTE, + TASK_COMPLEX_CAR_OPEN_DRIVER_DOOR, + TASK_SIMPLE_CAR_SET_TEMP_ACTION, TASK_COMPLEX_CAR_DRIVE_MISSION, TASK_COMPLEX_CAR_DRIVE, TASK_COMPLEX_CAR_DRIVE_MISSION_FLEE_SCENE, //SCRIPT_DECISION - TASK_COMPLEX_ENTER_LEADER_CAR_AS_PASSENGER, + TASK_COMPLEX_ENTER_LEADER_CAR_AS_PASSENGER, TASK_COMPLEX_CAR_OPEN_PASSENGER_DOOR, TASK_COMPLEX_CAR_DRIVE_MISSION_KILL_PED, //SCRIPT_DECISION @@ -283,18 +283,18 @@ enum eTaskType : int TASK_SIMPLE_CAR_SHUFFLE, TASK_SIMPLE_CAR_WAIT_TO_SLOW_DOWN, TASK_SIMPLE_CAR_WAIT_FOR_DOOR_NOT_TO_BE_IN_USE, - TASK_SIMPLE_CAR_SET_PED_IN_AS_PASSENGER, - TASK_SIMPLE_CAR_SET_PED_IN_AS_DRIVER, + TASK_SIMPLE_CAR_SET_PED_IN_AS_PASSENGER, + TASK_SIMPLE_CAR_SET_PED_IN_AS_DRIVER, TASK_SIMPLE_CAR_GET_OUT, TASK_SIMPLE_CAR_JUMP_OUT, TASK_SIMPLE_CAR_FORCE_PED_OUT, TASK_SIMPLE_CAR_SET_PED_OUT, TASK_SIMPLE_CAR_QUICK_DRAG_PED_OUT, - TASK_SIMPLE_CAR_QUICK_BE_DRAGGED_OUT, + TASK_SIMPLE_CAR_QUICK_BE_DRAGGED_OUT, TASK_SIMPLE_CAR_SET_PED_QUICK_DRAGGED_OUT, - TASK_SIMPLE_CAR_SLOW_DRAG_PED_OUT, - TASK_SIMPLE_CAR_SLOW_BE_DRAGGED_OUT, + TASK_SIMPLE_CAR_SLOW_DRAG_PED_OUT, + TASK_SIMPLE_CAR_SLOW_BE_DRAGGED_OUT, TASK_SIMPLE_CAR_SET_PED_SLOW_DRAGGED_OUT, TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT, TASK_COMPLEX_CAR_SLOW_BE_DRAGGED_OUT_AND_STAND_UP, @@ -305,9 +305,9 @@ enum eTaskType : int TASK_SIMPLE_WAIT_UNTIL_PED_OUT_CAR, TASK_COMPLEX_GO_TO_BOAT_STEERING_WHEEL, TASK_COMPLEX_GET_ON_BOAT_SEAT, - TASK_SIMPLE_CREATE_CAR_AND_GET_IN, - TASK_SIMPLE_WAIT_UNTIL_PED_IN_CAR, - TASK_SIMPLE_CAR_FALL_OUT, + TASK_SIMPLE_CREATE_CAR_AND_GET_IN, + TASK_SIMPLE_WAIT_UNTIL_PED_IN_CAR, + TASK_SIMPLE_CAR_FALL_OUT, //goto tasks TASK_SIMPLE_GO_TO_POINT = 900, @@ -321,11 +321,11 @@ enum eTaskType : int TASK_COMPLEX_SEEK_ENTITY, //SCRIPT_DECISION TASK_COMPLEX_FLEE_POINT, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_FLEE_ENTITY, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_SMART_FLEE_POINT, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_SMART_FLEE_ENTITY, //SCRIPT_DECISION TASK_COMPLEX_WANDER, @@ -341,11 +341,11 @@ enum eTaskType : int TASK_COMPLEX_TURN_TO_FACE_ENTITY, //SCRIPT_DECISION TASK_COMPLEX_AVOID_BUILDING, - TASK_COMPLEX_SEEK_ENTITY_ANY_MEANS, - TASK_COMPLEX_FOLLOW_LEADER_ANY_MEANS, - TASK_COMPLEX_GO_TO_POINT_AIMING, - TASK_COMPLEX_TRACK_ENTITY, - TASK_SIMPLE_GO_TO_POINT_FINE, + TASK_COMPLEX_SEEK_ENTITY_ANY_MEANS, + TASK_COMPLEX_FOLLOW_LEADER_ANY_MEANS, + TASK_COMPLEX_GO_TO_POINT_AIMING, + TASK_COMPLEX_TRACK_ENTITY, + TASK_SIMPLE_GO_TO_POINT_FINE, TASK_COMPLEX_FLEE_ANY_MEANS, //SCRIPT_DECISION TASK_COMPLEX_FLEE_SHOOTING, @@ -359,46 +359,46 @@ enum eTaskType : int TASK_COMPLEX_INVESTIGATE_DISTURBANCE, //SCRIPT_DECISION TASK_COMPLEX_FOLLOW_PED_FOOTSTEPS, - TASK_COMPLEX_FOLLOW_NODE_ROUTE_SHOOTING, + TASK_COMPLEX_FOLLOW_NODE_ROUTE_SHOOTING, TASK_COMPLEX_USE_ENTRYEXIT, TASK_COMPLEX_AVOID_ENTITY, - TASK_SMART_FLEE_ENTITY_WALKING, + TASK_SMART_FLEE_ENTITY_WALKING, //fight tasks - TASK_COMPLEX_KILL_PED_ON_FOOT = 1000, + TASK_COMPLEX_KILL_PED_ON_FOOT = 1000, //SCRIPT_DECISION - TASK_COMPLEX_KILL_PED_ON_FOOT_MELEE, - TASK_COMPLEX_KILL_PED_ON_FOOT_ARMED, + TASK_COMPLEX_KILL_PED_ON_FOOT_MELEE, + TASK_COMPLEX_KILL_PED_ON_FOOT_ARMED, TASK_COMPLEX_DESTROY_CAR, //SCRIPT_DECISION - TASK_COMPLEX_DESTROY_CAR_MELEE, - TASK_COMPLEX_DESTROY_CAR_ARMED, - // TASK_COMPLEX_FIGHT, - // TASK_SIMPLE_FIRE_RANGED, - // TASK_SIMPLE_FIRE_RANGED_CROUCHED, - // TASK_SIMPLE_FIRE_RELOAD, - // TASK_SIMPLE_FIRE_SNIPER, - - // TASK_COMPLEX_ATTACK_RANGED, - // TASK_SIMPLE_AIM_GUN, - // TASK_SIMPLE_FIGHT_IDLE, - // TASK_SIMPLE_FIGHT_SHUFFLE, - // TASK_SIMPLE_ATTACK_MELEE, - // TASK_SIMPLE_FIRE_PROJECTILE, - // TASK_SIMPLE_ATTACK_UNARMED, - // TASK_COMPLEX_THROW_PROJECTILE, - // TASK_SIMPLE_THROW_WEAPON, - TASK_COMPLEX_REACT_TO_ATTACK, - TASK_SIMPLE_BE_KICKED_ON_GROUND, - TASK_SIMPLE_BE_HIT, - TASK_SIMPLE_BE_HIT_WHILE_MOVING, - TASK_COMPLEX_SIDE_STEP_AND_SHOOT, - TASK_SIMPLE_DRIVEBY_SHOOT, - TASK_SIMPLE_DRIVEBY_WATCH_FOR_TARGET, - TASK_COMPLEX_DO_DRIVEBY, - TASK_KILL_ALL_THREATS, - TASK_KILL_PED_GROUP_ON_FOOT, + TASK_COMPLEX_DESTROY_CAR_MELEE, + TASK_COMPLEX_DESTROY_CAR_ARMED, + //TASK_COMPLEX_FIGHT, + //TASK_SIMPLE_FIRE_RANGED, + //TASK_SIMPLE_FIRE_RANGED_CROUCHED, + //TASK_SIMPLE_FIRE_RELOAD, + //TASK_SIMPLE_FIRE_SNIPER, + + //TASK_COMPLEX_ATTACK_RANGED, + //TASK_SIMPLE_AIM_GUN, + //TASK_SIMPLE_FIGHT_IDLE, + //TASK_SIMPLE_FIGHT_SHUFFLE, + //TASK_SIMPLE_ATTACK_MELEE, + //TASK_SIMPLE_FIRE_PROJECTILE, + //TASK_SIMPLE_ATTACK_UNARMED, + //TASK_COMPLEX_THROW_PROJECTILE, + //TASK_SIMPLE_THROW_WEAPON, + TASK_COMPLEX_REACT_TO_ATTACK, + TASK_SIMPLE_BE_KICKED_ON_GROUND, + TASK_SIMPLE_BE_HIT, + TASK_SIMPLE_BE_HIT_WHILE_MOVING, + TASK_COMPLEX_SIDE_STEP_AND_SHOOT, + TASK_SIMPLE_DRIVEBY_SHOOT, + TASK_SIMPLE_DRIVEBY_WATCH_FOR_TARGET, + TASK_COMPLEX_DO_DRIVEBY, + TASK_KILL_ALL_THREATS, + TASK_KILL_PED_GROUP_ON_FOOT, // new weapon/fight tasks TASK_SIMPLE_FIGHT, @@ -411,42 +411,42 @@ enum eTaskType : int TASK_SIMPLE_GANG_DRIVEBY, //SCRIPT_DECISION - TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED, //SCRIPT_DECISION - TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL, //SCRIPT_DECISION + TASK_COMPLEX_KILL_PED_ON_FOOT_TIMED, //SCRIPT_DECISION + TASK_COMPLEX_KILL_PED_ON_FOOT_STAND_STILL, //SCRIPT_DECISION TASK_UNUSED2, TASK_KILL_PED_ON_FOOT_WHILE_DUCKING, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_SIMPLE_STEALTH_KILL, TASK_COMPLEX_KILL_PED_ON_FOOT_STEALTH, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_KILL_PED_ON_FOOT_KINDA_STAND_STILL, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_COMPLEX_KILL_PED_AND_REENTER_CAR, TASK_COMPLEX_ROAD_RAGE, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_KILL_PED_FROM_BOAT, - TASK_SIMPLE_SET_CHAR_IGNORE_WEAPON_RANGE_FLAG, + TASK_SIMPLE_SET_CHAR_IGNORE_WEAPON_RANGE_FLAG, - TASK_SEEK_COVER_UNTIL_TARGET_DEAD, + TASK_SEEK_COVER_UNTIL_TARGET_DEAD, //police tasks - TASK_SIMPLE_ARREST_PED = 1100, + TASK_SIMPLE_ARREST_PED = 1100, TASK_COMPLEX_ARREST_PED, //SCRIPT_DECISION - TASK_SIMPLE_BE_ARRESTED, - TASK_COMPLEX_POLICE_PURSUIT, - TASK_COMPLEX_BE_COP, + TASK_SIMPLE_BE_ARRESTED, + TASK_COMPLEX_POLICE_PURSUIT, + TASK_COMPLEX_BE_COP, TASK_COMPLEX_KILL_CRIMINAL, //SCRIPT_DECISION TASK_COMPLEX_COP_IN_CAR, //gang/partner tasks - TASK_SIMPLE_INFORM_GROUP = 1200, + TASK_SIMPLE_INFORM_GROUP = 1200, //SCRIPT_DECISION - TASK_COMPLEX_GANG_LEADER, + TASK_COMPLEX_GANG_LEADER, TASK_COMPLEX_PARTNER_DEAL, //SCRIPT_DECISION TASK_COMPLEX_PARTNER_GREET, @@ -454,22 +454,22 @@ enum eTaskType : int TASK_COMPLEX_PARTNER_CHAT, TASK_COMPLEX_GANG_HASSLE_VEHICLE, //SCRIPT_DECISION - TASK_COMPLEX_WALK_WITH_PED, - TASK_COMPLEX_GANG_FOLLOWER, - TASK_COMPLEX_WALK_ALONGSIDE_PED, - TASK_COMPLEX_PARTNER_SHOVE, - //SCRIPT_DECISION - TASK_COMPLEX_SIGNAL_AT_PED, + TASK_COMPLEX_WALK_WITH_PED, + TASK_COMPLEX_GANG_FOLLOWER, + TASK_COMPLEX_WALK_ALONGSIDE_PED, + TASK_COMPLEX_PARTNER_SHOVE, + //SCRIPT_DECISION + TASK_COMPLEX_SIGNAL_AT_PED, //SCRIPT_DECISION - TASK_COMPLEX_PASS_OBJECT, + TASK_COMPLEX_PASS_OBJECT, TASK_COMPLEX_GANG_HASSLE_PED, //SCRIPT_DECISION TASK_COMPLEX_WAIT_FOR_PED, TASK_SIMPLE_DO_HAND_SIGNAL, - // TASK_COMPLEX_THROW_OBJECT_BEING_HELD, - TASK_COMPLEX_BE_IN_COUPLE, - TASK_COMPLEX_GOTO_VEHICLE_AND_LEAN, - TASK_COMPLEX_LEAN_ON_VEHICLE, + //TASK_COMPLEX_THROW_OBJECT_BEING_HELD, + TASK_COMPLEX_BE_IN_COUPLE, + TASK_COMPLEX_GOTO_VEHICLE_AND_LEAN, + TASK_COMPLEX_LEAN_ON_VEHICLE, //SCRIPT_DECISION TASK_COMPLEX_CHAT, TASK_COMPLEX_GANG_JOIN_RESPOND, @@ -480,33 +480,32 @@ enum eTaskType : int TASK_SIMPLE_TOGGLE_PED_THREAT_SCANNER, TASK_FINISHED, TASK_SIMPLE_JETPACK, - TASK_SIMPLE_SWIM, + TASK_SIMPLE_SWIM, TASK_COMPLEX_SWIM_AND_CLIMB_OUT, TASK_SIMPLE_DUCK_TOGGLE, - TASK_WAIT_FOR_MATCHING_AREA_CODES, + TASK_WAIT_FOR_MATCHING_AREA_CODES, TASK_SIMPLE_ON_ESCALATOR, TASK_COMPLEX_PROSTITUTE_SOLICIT, // interior tasks - - TASK_INTERIOR_USE_INFO = 1400, - TASK_INTERIOR_GOTO_INFO, - TASK_INTERIOR_BE_IN_HOUSE, - TASK_INTERIOR_BE_IN_OFFICE, - TASK_INTERIOR_BE_IN_SHOP, - TASK_INTERIOR_SHOPKEEPER, - TASK_INTERIOR_LIE_IN_BED, - TASK_INTERIOR_SIT_ON_CHAIR, - TASK_INTERIOR_SIT_AT_DESK, - TASK_INTERIOR_LEAVE, - TASK_INTERIOR_SIT_IN_RESTAURANT, - TASK_INTERIOR_RESERVED2, - TASK_INTERIOR_RESERVED3, - TASK_INTERIOR_RESERVED4, - TASK_INTERIOR_RESERVED5, - TASK_INTERIOR_RESERVED6, - TASK_INTERIOR_RESERVED7, - TASK_INTERIOR_RESERVED8, + TASK_INTERIOR_USE_INFO = 1400, + TASK_INTERIOR_GOTO_INFO, + TASK_INTERIOR_BE_IN_HOUSE, + TASK_INTERIOR_BE_IN_OFFICE, + TASK_INTERIOR_BE_IN_SHOP, + TASK_INTERIOR_SHOPKEEPER, + TASK_INTERIOR_LIE_IN_BED, + TASK_INTERIOR_SIT_ON_CHAIR, + TASK_INTERIOR_SIT_AT_DESK, + TASK_INTERIOR_LEAVE, + TASK_INTERIOR_SIT_IN_RESTAURANT, + TASK_INTERIOR_RESERVED2, + TASK_INTERIOR_RESERVED3, + TASK_INTERIOR_RESERVED4, + TASK_INTERIOR_RESERVED5, + TASK_INTERIOR_RESERVED6, + TASK_INTERIOR_RESERVED7, + TASK_INTERIOR_RESERVED8, // group tasks TASK_GROUP_FOLLOW_LEADER_ANY_MEANS = 1500, @@ -542,18 +541,18 @@ enum eTaskType : int TASK_GROUP_HAND_SIGNAL, //SCRIPT_DECISION TASK_GROUP_DRIVEBY, - //SCRIPT_DECISION + //SCRIPT_DECISION TASK_GROUP_HASSLE_THREAT_PASSIVE, //SCRIPT_DECISION // phone / goggles tasks - TASK_COMPLEX_USE_MOBILE_PHONE = 1600, + TASK_COMPLEX_USE_MOBILE_PHONE = 1600, TASK_SIMPLE_PHONE_TALK, TASK_SIMPLE_PHONE_IN, TASK_SIMPLE_PHONE_OUT, - TASK_COMPLEX_USE_GOGGLES, - TASK_SIMPLE_GOGGLES_ON, - TASK_SIMPLE_GOGGLES_OFF, + TASK_COMPLEX_USE_GOGGLES, + TASK_SIMPLE_GOGGLES_ON, + TASK_SIMPLE_GOGGLES_OFF, // inform friends TASK_SIMPLE_INFORM_RESPECTED_FRIENDS = 1700, @@ -565,10 +564,11 @@ enum eTaskType : int /* // test tasks TASK_COMPLEX_A, - TASK_COMPLEX_B, + TASK_COMPLEX_B, TASK_COMPLEX_C, TASK_COMPLEX_D, - TASK_COMPLEX_E, - */ + TASK_COMPLEX_E, + */ + MAX_NUM_TASK_TYPES }; \ No newline at end of file From 4df15a5cb3c013a791ce3074c45d16cadbe9c31b Mon Sep 17 00:00:00 2001 From: Miran Date: Mon, 8 Dec 2025 03:06:00 +0100 Subject: [PATCH 09/13] CDecisionMaker updates --- plugin_sa/game_sa/CDecisionMaker.cpp | 11 +++++++++++ plugin_sa/game_sa/CDecisionMaker.h | 11 +++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 plugin_sa/game_sa/CDecisionMaker.cpp diff --git a/plugin_sa/game_sa/CDecisionMaker.cpp b/plugin_sa/game_sa/CDecisionMaker.cpp new file mode 100644 index 00000000..7bfe4d6d --- /dev/null +++ b/plugin_sa/game_sa/CDecisionMaker.cpp @@ -0,0 +1,11 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) header file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CDecisionMaker.h" + +CDecisionMaker::CDecisionMaker() { + plugin::CallMethod<0x4650A0, CDecisionMaker*>(this); +} diff --git a/plugin_sa/game_sa/CDecisionMaker.h b/plugin_sa/game_sa/CDecisionMaker.h index f681b7a7..5cb7d210 100644 --- a/plugin_sa/game_sa/CDecisionMaker.h +++ b/plugin_sa/game_sa/CDecisionMaker.h @@ -11,13 +11,8 @@ class PLUGIN_API CDecisionMaker { public: - CDecision m_decision[DM_TOTAL_NUM_EVENTS]; + CDecision m_decision[eDecisionMakerEvents::DM_TOTAL_NUM_EVENTS]; - inline CDecisionMaker() { // @0x4650A0 - for (unsigned int i = 0; i < DM_TOTAL_NUM_EVENTS; ++i) { - //m_decision[i].SetDefault(); - } - } + CDecisionMaker(); }; - -VALIDATE_SIZE(CDecisionMaker, 0x99C); \ No newline at end of file +VALIDATE_SIZE(CDecisionMaker, 0x99C); From 9d8e82053debbc80ce2c6eede8add211a4fcff37 Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 10 Dec 2025 00:05:32 +0100 Subject: [PATCH 10/13] CDecision updates --- plugin_sa/game_sa/CDecision.cpp | 11 ++++++++ plugin_sa/game_sa/CDecision.h | 50 ++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/plugin_sa/game_sa/CDecision.cpp b/plugin_sa/game_sa/CDecision.cpp index e69de29b..2f3b87d4 100644 --- a/plugin_sa/game_sa/CDecision.cpp +++ b/plugin_sa/game_sa/CDecision.cpp @@ -0,0 +1,11 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CDecision.h" + +CDecision::CDecision() { + plugin::CallMethod<0x6040C0, CDecision*>(this); +} diff --git a/plugin_sa/game_sa/CDecision.h b/plugin_sa/game_sa/CDecision.h index e9448418..3b870f06 100644 --- a/plugin_sa/game_sa/CDecision.h +++ b/plugin_sa/game_sa/CDecision.h @@ -6,32 +6,44 @@ */ #pragma once #include "PluginBase.h" +#include "eTaskType.h" -/* - https://www.gtamodding.com/wiki/Decision_Maker -*/ +struct DecisionContext +{ + bool onFoot = false; + bool inVehicle = false; -enum eDecisionTypes { - DECISION_ON_FOOT = 0, - DECISION_IN_VEHICLE = 1 + DecisionContext() = default; + DecisionContext(bool onFoot, bool inVehicle) : + onFoot(onFoot), inVehicle(inVehicle) + {} }; +VALIDATE_SIZE(DecisionContext, 0x2); + +struct DecisionChances +{ + // weights that sums up to total value of all responses applicable to current event, + // then chance is weight/total + unsigned char toNeutral = 0; + unsigned char toPlayer = 0; + unsigned char toFriend = 0; + unsigned char toEnemy = 0; -enum eDecisionRelationship { - DECISION_RELATIONSHIP_NEUTRAL = 0, - DECISION_RELATIONSHIP_PLAYER = 1, - DECISION_RELATIONSHIP_FRIEND = 2, - DECISION_RELATIONSHIP_THREAT = 3 + DecisionChances() = default; + DecisionChances(unsigned char toNeutral, unsigned char toPlayer, unsigned char toFriend, unsigned char toEnemy) : + toNeutral(toNeutral), toPlayer(toPlayer), toFriend(toFriend), toEnemy(toEnemy) + {} }; +VALIDATE_SIZE(DecisionChances, 0x4); class PLUGIN_API CDecision { public: - int m_anTaskTypes[6]; // see eTaskType - unsigned char m_anResponseChances[6][4]; // 4 different relationships : see eDecisionRelationship - unsigned char m_anTypeFlags[2][6]; // 2 different types : see eDecisionTypes + constexpr static auto RESPONSE_COUNT = 6; // max count of unique responses - inline CDecision() { // @0x6040C0 - //SetDefault(); - } -}; + eTaskType task[RESPONSE_COUNT]; // response's task + DecisionChances chances[RESPONSE_COUNT]; // response's chances for each relationship type + DecisionContext context[RESPONSE_COUNT]; // situations the response applies to -VALIDATE_SIZE(CDecision, 0x3C); \ No newline at end of file + CDecision(); +}; +VALIDATE_SIZE(CDecision, 0x3C); From 426c41133e462f1aa1fdc930d0ea9719d1825ace Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 10 Dec 2025 00:14:46 +0100 Subject: [PATCH 11/13] Added CDecisionMakerTypes class --- plugin_sa/game_sa/CDecisionMaker.cpp | 2 +- plugin_sa/game_sa/CDecisionMakerTypes.cpp | 46 ++++++++++++++ plugin_sa/game_sa/CDecisionMakerTypes.h | 76 +++++++++++++++++++++++ plugin_sa/game_sa/CPedIntelligence.cpp | 10 +-- plugin_sa/game_sa/CPedIntelligence.h | 55 ++++++++-------- 5 files changed, 157 insertions(+), 32 deletions(-) create mode 100644 plugin_sa/game_sa/CDecisionMakerTypes.cpp create mode 100644 plugin_sa/game_sa/CDecisionMakerTypes.h diff --git a/plugin_sa/game_sa/CDecisionMaker.cpp b/plugin_sa/game_sa/CDecisionMaker.cpp index 7bfe4d6d..14f56015 100644 --- a/plugin_sa/game_sa/CDecisionMaker.cpp +++ b/plugin_sa/game_sa/CDecisionMaker.cpp @@ -1,5 +1,5 @@ /* - Plugin-SDK (Grand Theft Auto San Andreas) header file + Plugin-SDK (Grand Theft Auto San Andreas) source file Authors: GTA Community. See more here https://github.com/DK22Pac/plugin-sdk Do not delete this comment block. Respect others' work! diff --git a/plugin_sa/game_sa/CDecisionMakerTypes.cpp b/plugin_sa/game_sa/CDecisionMakerTypes.cpp new file mode 100644 index 00000000..91ab1bc0 --- /dev/null +++ b/plugin_sa/game_sa/CDecisionMakerTypes.cpp @@ -0,0 +1,46 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) source file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#include "CDecisionMakerTypes.h" + +CDecisionMakerTypes* CDecisionMakerTypes::GetInstance() { + return plugin::CallAndReturn(); +} + +eDecisionMakerType CDecisionMakerTypes::AddDecisionMaker(CDecisionMaker* templateDm, eDecisionMakerType dm, bool bDecisionMakerForMission) { + return plugin::CallMethodAndReturn(this, templateDm, dm, bDecisionMakerForMission); +} + +void CDecisionMakerTypes::RemoveDecisionMaker(eDecisionMakerType dm) { + return plugin::Call<0x6043A0>(dm); +} + +void CDecisionMakerTypes::AddEventResponse(eDecisionMakerType dm, eEventType eventType, eTaskType taskId, DecisionChances chances, DecisionContext context) { + float chancesF[4]; // internally converted back to byte + chancesF[0] = chances.toNeutral; + chancesF[1] = chances.toPlayer; + chancesF[2] = chances.toFriend; + chancesF[3] = chances.toEnemy; + + plugin::CallMethod<0x6044C0, CDecisionMakerTypes*, eDecisionMakerType, eEventType, eTaskType, float*, DecisionContext&>(this, dm, eventType, taskId, chancesF, context); +} + +void CDecisionMakerTypes::FlushDecisionMakerEventResponse(eDecisionMakerType dm, eEventType eventId) { + plugin::CallMethod<0x604490>(this, dm, eventId); +} + +eTaskType CDecisionMakerTypes::MakeDecision(CPedGroup* pedGroup, eEventType eventType, int eventSourceType, bool bIsPedInVehicle, eTaskType taskId1, eTaskType taskId2, eTaskType taskId3, eTaskType taskId4) { + return plugin::CallMethodAndReturn( + this, pedGroup, eventType, eventSourceType, bIsPedInVehicle, taskId1, taskId2, taskId3, taskId4); +} + +void CDecisionMakerTypes::MakeDecision(CPed* ped, eEventType eventType, int eventSourceType, bool bIsPedInVehicle, eTaskType taskTypeToAvoid1, eTaskType taskTypeToAvoid2, eTaskType taskTypeToAvoid3, eTaskType taskTypeToSeek, bool bUseInGroupDecisionMaker, short& taskType, short& facialTaskType) { + plugin::CallMethod<0x606E70>(this, ped, eventType, eventSourceType, bIsPedInVehicle, taskTypeToAvoid1, taskTypeToAvoid2, taskTypeToAvoid3, taskTypeToSeek, bUseInGroupDecisionMaker, &taskType, &facialTaskType); +} + +void CDecisionMakerTypes::LoadEventIndices() { + plugin::CallMethod<0x600840>(this); +} diff --git a/plugin_sa/game_sa/CDecisionMakerTypes.h b/plugin_sa/game_sa/CDecisionMakerTypes.h new file mode 100644 index 00000000..e14ec152 --- /dev/null +++ b/plugin_sa/game_sa/CDecisionMakerTypes.h @@ -0,0 +1,76 @@ +/* + Plugin-SDK (Grand Theft Auto San Andreas) header file + Authors: GTA Community. See more here + https://github.com/DK22Pac/plugin-sdk + Do not delete this comment block. Respect others' work! +*/ +#pragma once + +#include "CDecision.h" +#include "CDecisionMaker.h" +#include "eEventType.h" +#include "eTaskType.h" + +class CPed; +class CPedGroup; + +enum class PLUGIN_API eDecisionMakerType : int { + UNKNOWN = -1, + + PED_GROUPMEMBER, + PED_COP, + PED_RANDOM1, + PED_RANDOM2, + PED_RANDOM3, + PED_FIREMAN, + PED_EMPTY, + PED_INDOORS, + + GROUP_RANDOM_AGGRESSIVE, + GROUP_RANDOM_PASSIVE, + + MISSION0, + MISSION1, + MISSION2, + MISSION3, + MISSION4, + MISSION5, + MISSION6, + MISSION7, + MISSION8, + MISSION9, + + COUNT_TOTAL, + COUNT_GAME_DM = MISSION0, // Number of built-in decision makers +}; + +class CDecisionMakerTypes { +public: + static constexpr auto NUM_TYPES = 20u; + + static inline auto& ScriptReferenceIndex = *(std::array*)0xC0AFF4; + static inline auto& m_IsActive = *(std::array*)0xC0B01C; + + static CDecisionMakerTypes* GetInstance(); // get global Decision Maker manager + + eDecisionMakerType AddDecisionMaker(CDecisionMaker* templateDm, eDecisionMakerType dm = eDecisionMakerType::UNKNOWN, bool bDecisionMakerForMission = false); + void RemoveDecisionMaker(eDecisionMakerType dm); + + void AddEventResponse(eDecisionMakerType dm, eEventType eventType, eTaskType taskId, DecisionChances chances, DecisionContext context); + void FlushDecisionMakerEventResponse(eDecisionMakerType dm, eEventType eventId); + + eTaskType MakeDecision(CPedGroup* pedGroup, eEventType eventType, int eventSourceType, bool bIsPedInVehicle, eTaskType taskId1, eTaskType taskId2, eTaskType taskId3, eTaskType taskId4); + void MakeDecision(CPed* ped, eEventType eventType, int eventSourceType, bool bIsPedInVehicle, eTaskType taskTypeToAvoid1, eTaskType taskTypeToAvoid2, eTaskType taskTypeToAvoid3, eTaskType taskTypeToSeek, bool bUseInGroupDecisionMaker, short& taskType, short& facialTaskType); + + void LoadEventIndices(); + +public: + int m_NoOfDecisionMakers; + CDecisionMaker m_DecisionMakers[(size_t)eDecisionMakerType::COUNT_TOTAL]; + int m_EventIndices[(size_t)eEventType::EVENT_TOTAL_NUM_EVENTS]; + CDecisionMaker m_DefaultRandomPedDecisionMaker; + CDecisionMaker m_DefaultMissionPedDecisionMaker; + CDecisionMaker m_DefaultPlayerPedDecisionMaker; + CDecisionMaker m_DefaultRandomPedGroupDecisionMaker; + CDecisionMaker m_DefaultMissionPedGroupDecisionMaker; +}; diff --git a/plugin_sa/game_sa/CPedIntelligence.cpp b/plugin_sa/game_sa/CPedIntelligence.cpp index 99039b01..e66af424 100644 --- a/plugin_sa/game_sa/CPedIntelligence.cpp +++ b/plugin_sa/game_sa/CPedIntelligence.cpp @@ -6,14 +6,16 @@ */ #include "CPedIntelligence.h" +using namespace plugin; + // Converted from thiscall void CPedIntelligence::SetPedDecisionMakerType(int newtype) 0x600B50 -void CPedIntelligence::SetPedDecisionMakerType(int newtype) { - plugin::CallMethod<0x600B50, CPedIntelligence *, int>(this, newtype); +void CPedIntelligence::SetPedDecisionMakerType(eDecisionMakerType dm) { + plugin::CallMethod<0x600B50, CPedIntelligence*, eDecisionMakerType>(this, dm); } // Converted from thiscall void CPedIntelligence::SetPedDecisionMakerTypeInGroup(int newtype) 0x600BB0 -void CPedIntelligence::SetPedDecisionMakerTypeInGroup(int newtype) { - plugin::CallMethod<0x600BB0, CPedIntelligence *, int>(this, newtype); +void CPedIntelligence::SetPedDecisionMakerTypeInGroup(eDecisionMakerType dm) { + plugin::CallMethod<0x600BB0, CPedIntelligence*, eDecisionMakerType>(this, dm); } // Converted from thiscall void CPedIntelligence::RestorePedDecisionMakerType(void) 0x600BC0 diff --git a/plugin_sa/game_sa/CPedIntelligence.h b/plugin_sa/game_sa/CPedIntelligence.h index 14575ab0..83d95fa1 100644 --- a/plugin_sa/game_sa/CPedIntelligence.h +++ b/plugin_sa/game_sa/CPedIntelligence.h @@ -7,6 +7,7 @@ #pragma once #include "PluginBase.h" +#include "CDecisionMakerTypes.h" #include "CTaskManager.h" #include "CEventHandler.h" #include "CEventGroup.h" @@ -28,35 +29,35 @@ class PLUGIN_API CPedIntelligence { public: - class CPed* m_pPed; - CTaskManager m_TaskMgr; - CEventHandler m_eventHandler; - CEventGroup m_eventGroup; - unsigned int m_nDecisionMakerType; - unsigned int m_nDecisionMakerTypeInGroup; - float m_fHearingRange; - float m_fSeeingRange; - unsigned int m_nDmNumPedsToScan; - float m_fDmRadius; - float m_FollowNodeThresholdDistance; - char m_NextEventResponseSequence; - unsigned char m_nEventId; - unsigned char m_nEventPriority; - char field_D3; - CEntityScanner m_vehicleScanner; - CEntityScanner m_pedScanner; - CMentalState m_mentalState; - char field_188; - CEventScanner m_eventScanner; + class CPed* m_pPed; + CTaskManager m_TaskMgr; + CEventHandler m_eventHandler; + CEventGroup m_eventGroup; + eDecisionMakerType m_nDecisionMakerType; + eDecisionMakerType m_nDecisionMakerTypeInGroup; + float m_fHearingRange; + float m_fSeeingRange; + unsigned int m_nDmNumPedsToScan; + float m_fDmRadius; + float m_FollowNodeThresholdDistance; + char m_NextEventResponseSequence; + unsigned char m_nEventId; + unsigned char m_nEventPriority; + char field_D3; + CEntityScanner m_vehicleScanner; + CEntityScanner m_pedScanner; + CMentalState m_mentalState; + char field_188; + CEventScanner m_eventScanner; CCollisionEventScanner m_collisionScanner; - CPedStuckChecker m_pedStuckChecker; - int m_AnotherStaticCounter; - int m_StaticCounter; - CVector m_vecLastPedPosDuringDamageEntity; - class CEntity* m_apInterestingEntities[3]; + CPedStuckChecker m_pedStuckChecker; + int m_AnotherStaticCounter; + int m_StaticCounter; + CVector m_vecLastPedPosDuringDamageEntity; + class CEntity* m_apInterestingEntities[3]; - void SetPedDecisionMakerType(int newtype); - void SetPedDecisionMakerTypeInGroup(int newtype); + void SetPedDecisionMakerType(eDecisionMakerType dm); + void SetPedDecisionMakerTypeInGroup(eDecisionMakerType dm); void RestorePedDecisionMakerType(); void SetHearingRange(float range); void SetSeeingRange(float range); From 24c513dd2c0f77920fe86a57396eabb7b0554bb7 Mon Sep 17 00:00:00 2001 From: MiranDMC <11084446+MiranDMC@users.noreply.github.com> Date: Tue, 9 Dec 2025 23:18:10 +0000 Subject: [PATCH 12/13] Update version info: v.1002 --- shared/plugin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/plugin.h b/shared/plugin.h index 07a0cd21..a58c3729 100644 --- a/shared/plugin.h +++ b/shared/plugin.h @@ -9,10 +9,10 @@ #define __TO_STR(x) #x #define TO_STR(x) __TO_STR(x) -#define PLUGIN_SDK_VERSION 1001 +#define PLUGIN_SDK_VERSION 1002 #define PLUGIN_SDK_VERSION_STR TO_STR(PLUGIN_SDK_VERSION) -#define PLUGIN_SDK_DATE 2025-12-07 23:52:00 +#define PLUGIN_SDK_DATE 2025-12-09 23:18:09 #define PLUGIN_SDK_DATE_STR TO_STR(PLUGIN_SDK_DATE) #include "PluginBase.h" From 2e3fb15a84d9ea9466ee4dc1c5c75800074ed1e3 Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 10 Dec 2025 00:45:32 +0100 Subject: [PATCH 13/13] Added DecisionMaker example project --- examples/DecisionMaker/Main.cpp | 77 ++++++++++++++++++++++++++++++++ examples/DecisionMaker/README.md | 2 + examples/examples.csv | 1 + 3 files changed, 80 insertions(+) create mode 100644 examples/DecisionMaker/Main.cpp create mode 100644 examples/DecisionMaker/README.md diff --git a/examples/DecisionMaker/Main.cpp b/examples/DecisionMaker/Main.cpp new file mode 100644 index 00000000..da9f870c --- /dev/null +++ b/examples/DecisionMaker/Main.cpp @@ -0,0 +1,77 @@ +#include // Plugin-SDK version 1002 from 2025-12-09 23:18:09 +#include +#include +#include +#include + +using namespace plugin; + +struct Main +{ + eDecisionMakerType decisionMakerHandle = eDecisionMakerType::UNKNOWN; + CPed* ped = nullptr; + + Main() + { + // register event callbacks + Events::restartGameEvent += []{ gInstance.OnGameRestart(); }; + Events::gameProcessEvent += []{ gInstance.OnGameProcess(); }; + } + + void OnGameRestart() + { + decisionMakerHandle = eDecisionMakerType::UNKNOWN; // game deletes the DM itself, just clear our reference + ped = nullptr; // game deletes the ped itself, just clear our reference + } + + void OnGameProcess() + { + // create our decision maker if not exists yet + if (decisionMakerHandle == eDecisionMakerType::UNKNOWN) + { + // create decision maker + auto dmManager = CDecisionMakerTypes::GetInstance(); + if (!dmManager) return; // try again later + + CDecisionMaker templateDm; // empty + decisionMakerHandle = dmManager->AddDecisionMaker(&templateDm); // take note the game only has 10 slots for custom DMs + + if (decisionMakerHandle == eDecisionMakerType::UNKNOWN) return; // failed to create DM, try again later + + dmManager->AddEventResponse(decisionMakerHandle, eEventType::EVENT_GUN_AIMED_AT, + eTaskType::TASK_SIMPLE_HANDS_UP, + DecisionChances(4, 4, 4, 4), // 4/5 chance + DecisionContext(true, false) + ); + + dmManager->AddEventResponse(decisionMakerHandle, eEventType::EVENT_GUN_AIMED_AT, + eTaskType::TASK_SIMPLE_DUCK, + DecisionChances(1, 1, 1, 1), // 1/5 chance + DecisionContext(true, false) + ); + } + + // create ped + if (ped == nullptr) + { + constexpr auto MODEL = 70; // scientist + CStreaming::RequestModel(MODEL, eStreamingFlags::PRIORITY_REQUEST); + CStreaming::LoadAllRequestedModels(true); + ped = new CCivilianPed(PED_TYPE_CIVMALE, MODEL); + + if (!ped) return; // failed to create ped, try again later + + ped->SetPosn(FindPlayerPed()->TransformFromObjectSpace(CVector(0.0f, 3.0f, 0.0f))); // in front of the player + ped->SetOrientation(0.0f, 0.0f, 0.0f); + CWorld::Add(ped); + ped->PositionAnyPedOutOfCollision(); + + ped->m_fMaxHealth = ped->m_fHealth = 1000.0f; // stronger for tests + + if (ped->m_pIntelligence) + { + ped->m_pIntelligence->SetPedDecisionMakerType(decisionMakerHandle); + } + } + } +} gInstance; diff --git a/examples/DecisionMaker/README.md b/examples/DecisionMaker/README.md new file mode 100644 index 00000000..4ff61d6c --- /dev/null +++ b/examples/DecisionMaker/README.md @@ -0,0 +1,2 @@ +## Decision Maker +Shows how to create custom DecisionMaker and assign it to ped. diff --git a/examples/examples.csv b/examples/examples.csv index 7e31945b..af3e1c11 100644 --- a/examples/examples.csv +++ b/examples/examples.csv @@ -1,6 +1,7 @@ PROJECT, TYPE, GTA2, GTA3, GTA-VC, GTA-SA, GTA4, DE-3, DE-VC, DE-SA, D3D ColouredObjects, ASI, ---, ---, ---, YES, ---, ---, ---, ---, --- CreateCar, ASI, ---, ---, ---, YES, ---, ---, ---, ---, --- +DecisionMaker, ASI, ---, ---, ---, YES, ---, ---, ---, ---, --- DXFont, ASI, ---, YES, YES, YES, ---, ---, ---, ---, YES FullNitrousControl, ASI, ---, ---, ---, YES, ---, ---, ---, ---, --- GPS, ASI, ---, ---, ---, YES, ---, ---, ---, ---, YES