Skip to content

Fix & improvement getPedMoveState #4316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Client/game_sa/CPedSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class CPedSAInterface : public CPhysicalSAInterface
int unk_52C;

int pedState;
int moveState;
PedMoveState::Enum moveState;
int swimmingMoveState;

int unk_53C;
Expand All @@ -276,10 +276,10 @@ class CPedSAInterface : public CPhysicalSAInterface
float fRotationSpeed;
float fMoveAnim;

CEntitySAInterface* pContactEntity;
CEntitySAInterface* pContactEntity; // m_standingOnEntity
CVector unk_56C;
CVector unk_578;
CEntitySAInterface* pLastContactEntity;
CEntitySAInterface* pLastContactEntity; // m_contactEntity

CVehicleSAInterface* pLastVehicle;
CVehicleSAInterface* pVehicle;
Expand Down Expand Up @@ -421,8 +421,9 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA
void SetFightingStyle(eFightingStyle style, std::uint8_t styleExtra = 6) override;

CEntity* GetContactEntity() const override;
bool IsStandingOnEntity() const override { return GetPedInterface()->pContactEntity != nullptr; };

int GetRunState() const override { return GetPedInterface()->moveState; }
PedMoveState::Enum GetMoveState() const override { return GetPedInterface()->moveState; }

bool GetCanBeShotInVehicle() const override{ return GetPedInterface()->pedFlags.bCanBeShotInVehicle; }
bool GetTestForShotInVehicle() const override { return GetPedInterface()->pedFlags.bTestForShotInVehicle; }
Expand Down
76 changes: 45 additions & 31 deletions Client/mods/deathmatch/logic/CClientPed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,16 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI
m_MovementStateNames[MOVEMENTSTATE_JOG] = "jog";
m_MovementStateNames[MOVEMENTSTATE_SPRINT] = "sprint";
m_MovementStateNames[MOVEMENTSTATE_CROUCH] = "crouch";
// These two are inactive for now
m_MovementStateNames[MOVEMENTSTATE_CRAWL] = "crawl";
m_MovementStateNames[MOVEMENTSTATE_ROLL] = "roll";
m_MovementStateNames[MOVEMENTSTATE_JUMP] = "jump";
m_MovementStateNames[MOVEMENTSTATE_FALL] = "fall";
m_MovementStateNames[MOVEMENTSTATE_CLIMB] = "climb";
m_MovementStateNames[MOVEMENTSTATE_SWIM] = "swim";
m_MovementStateNames[MOVEMENTSTATE_WALK_TO_POINT] = "walk_to_point";
m_MovementStateNames[MOVEMENTSTATE_ASCENT_JETPACK] = "ascent_jetpack";
m_MovementStateNames[MOVEMENTSTATE_DESCENT_JETPACK] = "descent_jetpack";
m_MovementStateNames[MOVEMENTSTATE_JETPACK] = "jetpack_flying";

// Create the player model
if (m_bIsLocalPlayer)
Expand Down Expand Up @@ -2422,53 +2426,63 @@ eMovementState CClientPed::GetMovementState()
const char* szComplexTaskName = GetTaskManager()->GetActiveTask()->GetTaskName();
const char* szSimpleTaskName = GetTaskManager()->GetSimplestActiveTask()->GetTaskName();

// Is he climbing?
if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0)
// Check tasks
if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0) // Is he climbing?
return MOVEMENTSTATE_CLIMB;

// Is he jumping?
else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0)
else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0) // Is he jumping?
return MOVEMENTSTATE_JUMP;
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_GO_TO_POINT") == 0) // Entering vehicle (walking to the doors)?
return MOVEMENTSTATE_WALK_TO_POINT;
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_SWIM") == 0) // Is he swimming?
return MOVEMENTSTATE_SWIM;
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_JETPACK") == 0) // Is he flying?
{
if (cs.ButtonCross != 0)
return MOVEMENTSTATE_ASCENT_JETPACK;
else if (cs.ButtonSquare != 0)
return MOVEMENTSTATE_DESCENT_JETPACK;
else
return MOVEMENTSTATE_JETPACK;
}

// Is he falling?
else if (!IsOnGround() && !GetContactEntity())
// Check movement state
if (!IsOnGround() && !GetContactEntity() && !m_pPlayerPed->IsStandingOnEntity() && !m_pPlayerPed->IsInWater() && (strcmp(szSimpleTaskName, "TASK_SIMPLE_IN_AIR") == 0 || strcmp(szSimpleTaskName, "TASK_SIMPLE_FALL") == 0)) // Is he falling?
return MOVEMENTSTATE_FALL;

// Grab his controller state
bool bWalkKey = false;
if (GetType() == CCLIENTPLAYER)
bWalkKey = CClientPad::GetControlState("walk", cs, true);
else
m_Pad.GetControlState("walk", bWalkKey);
// Sometimes it returns 'fall' or 'walk', so it's better to return false instead
if (IsEnteringVehicle() || IsLeavingVehicle())
return MOVEMENTSTATE_UNKNOWN;

// Is he standing up?
if (!IsDucked())
{
unsigned int iRunState = m_pPlayerPed->GetRunState();
bool walking = false;
if (GetType() == CCLIENTPLAYER)
walking = CClientPad::GetControlState("walk", cs, true);
else
m_Pad.GetControlState("walk", walking);

// Is he moving the contoller at all?
if (iRunState == 1 && cs.LeftStickX == 0 && cs.LeftStickY == 0)
return MOVEMENTSTATE_STAND;

// Is he either pressing the walk key, or has run state 1?
if (iRunState == 1 || bWalkKey && iRunState == 6)
return MOVEMENTSTATE_WALK;
else if (iRunState == 4)
return MOVEMENTSTATE_POWERWALK;
else if (iRunState == 6)
return MOVEMENTSTATE_JOG;
else if (iRunState == 7)
return MOVEMENTSTATE_SPRINT;
switch (m_pPlayerPed->GetMoveState())
{
case PedMoveState::PEDMOVE_STILL:
return MOVEMENTSTATE_STAND;
case PedMoveState::PEDMOVE_WALK:
return (cs.LeftStickX == 0 && cs.LeftStickY == 0) ? MOVEMENTSTATE_STAND : MOVEMENTSTATE_WALK;
case PedMoveState::PEDMOVE_SPRINT:
return MOVEMENTSTATE_SPRINT;
case PedMoveState::PEDMOVE_RUN:
return walking ? MOVEMENTSTATE_WALK : MOVEMENTSTATE_JOG; // FileEX: It should be MOVEMENTSTATE_RUN, but we're keeping JOG for backward compatibility (PEDMOVE_JOG is unused in SA)
}
}
else
{
// Is he moving the contoller at all?
if (cs.LeftStickX == 0 && cs.LeftStickY == 0)
return MOVEMENTSTATE_CROUCH;
else
return MOVEMENTSTATE_CRAWL;
return (cs.LeftStickX != 0 && cs.RightShoulder1 != 0) ? MOVEMENTSTATE_ROLL : MOVEMENTSTATE_CRAWL;
}
}

return MOVEMENTSTATE_UNKNOWN;
}

Expand Down Expand Up @@ -6098,7 +6112,7 @@ bool CClientPed::ShouldBeStealthAiming()
{
// We need to be either crouched, walking or standing
SBindableGTAControl* pWalkControl = pKeyBinds->GetBindableFromControl("walk");
if (m_pPlayerPed->GetRunState() == 1 || m_pPlayerPed->GetRunState() == 4 || pWalkControl && pWalkControl->bState)
if (m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_STILL || m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_WALK || pWalkControl && pWalkControl->bState)
{
// Do we have a target ped?
CClientPed* pTargetPed = GetTargetedPed();
Expand Down
27 changes: 16 additions & 11 deletions Client/mods/deathmatch/logic/CClientPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,22 @@ enum eBodyPart
enum eMovementState
{
MOVEMENTSTATE_UNKNOWN,
MOVEMENTSTATE_STAND, // Standing still
MOVEMENTSTATE_WALK, // Walking
MOVEMENTSTATE_POWERWALK, // Walking quickly
MOVEMENTSTATE_JOG, // Jogging
MOVEMENTSTATE_SPRINT, // Sprinting
MOVEMENTSTATE_CROUCH, // Crouching still
MOVEMENTSTATE_CRAWL, // Crouch-moving
MOVEMENTSTATE_ROLL, // Crouch-rolling (Needs adding)
MOVEMENTSTATE_JUMP, // Jumping
MOVEMENTSTATE_FALL, // Falling
MOVEMENTSTATE_CLIMB // Climbing
MOVEMENTSTATE_STAND, // Standing still
MOVEMENTSTATE_WALK, // Walking
MOVEMENTSTATE_POWERWALK, // Walking quickly
MOVEMENTSTATE_JOG, // Jogging (Unused)
MOVEMENTSTATE_SPRINT, // Sprinting
MOVEMENTSTATE_CROUCH, // Crouching still
MOVEMENTSTATE_CRAWL, // Crouch-moving
MOVEMENTSTATE_ROLL, // Crouch-rolling
MOVEMENTSTATE_JUMP, // Jumping
MOVEMENTSTATE_FALL, // Falling
MOVEMENTSTATE_CLIMB, // Climbing
MOVEMENTSTATE_SWIM, // Swimming
MOVEMENTSTATE_WALK_TO_POINT, // Entering vehicle (walking to the door)
MOVEMENTSTATE_ASCENT_JETPACK, // Ascending with jetpack
MOVEMENTSTATE_DESCENT_JETPACK, // Descending with jetpack
MOVEMENTSTATE_JETPACK, // Jetpack flying
};

enum eDeathAnims
Expand Down
4 changes: 3 additions & 1 deletion Client/sdk/game/CPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "CWeaponInfo.h"
#include "CPedSound.h"
#include "enums/PedState.h"
#include "enums/PedMoveState.h"

// To avoid VS intellisense highlight errors
#include <memory>
Expand Down Expand Up @@ -253,8 +254,9 @@ class CPed : public virtual CPhysical
virtual void SetFightingStyle(eFightingStyle style, std::uint8_t styleExtra) = 0;

virtual CEntity* GetContactEntity() const = 0;
virtual bool IsStandingOnEntity() const = 0;

virtual int GetRunState() const = 0;
virtual PedMoveState::Enum GetMoveState() const = 0;

virtual bool GetCanBeShotInVehicle() const = 0;
virtual bool GetTestForShotInVehicle() const = 0;
Expand Down
27 changes: 27 additions & 0 deletions Shared/sdk/enums/PedMoveState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: sdk/PedMoveState.h
* PURPOSE: Header for common definitions
*
* Multi Theft Auto is available from https://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

namespace PedMoveState
{
enum Enum
{
PEDMOVE_NONE = 0,
PEDMOVE_STILL,
PEDMOVE_TURN_L,
PEDMOVE_TURN_R,
PEDMOVE_WALK,
PEDMOVE_JOG,
PEDMOVE_RUN,
PEDMOVE_SPRINT,
};
}
Loading