Skip to content

Commit 9bb68a3

Browse files
authored
Merge branch 'master' into debugscript-client-behavior
2 parents a6ab9ab + 449cf0f commit 9bb68a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+5654
-5362
lines changed

Client/game_sa/CPedSA.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class CPedSAInterface : public CPhysicalSAInterface
261261
int unk_52C;
262262

263263
int pedState;
264-
int moveState;
264+
PedMoveState::Enum moveState;
265265
int swimmingMoveState;
266266

267267
int unk_53C;
@@ -276,10 +276,10 @@ class CPedSAInterface : public CPhysicalSAInterface
276276
float fRotationSpeed;
277277
float fMoveAnim;
278278

279-
CEntitySAInterface* pContactEntity;
279+
CEntitySAInterface* pContactEntity; // m_standingOnEntity
280280
CVector unk_56C;
281281
CVector unk_578;
282-
CEntitySAInterface* pLastContactEntity;
282+
CEntitySAInterface* pLastContactEntity; // m_contactEntity
283283

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

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

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

427428
bool GetCanBeShotInVehicle() const override{ return GetPedInterface()->pedFlags.bCanBeShotInVehicle; }
428429
bool GetTestForShotInVehicle() const override { return GetPedInterface()->pedFlags.bTestForShotInVehicle; }

Client/loader/MainFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ void CheckDataFiles()
977977
//////////////////////////////////////////////////////////
978978
void CheckLibVersions()
979979
{
980-
#if MTASA_VERSION_TYPE < VERSION_TYPE_UNTESTED
980+
#if MTASA_VERSION_TYPE >= VERSION_TYPE_UNTESTED
981981

982982
const char* moduleList[] = {"MTA\\loader.dll",
983983
"MTA\\cgui.dll",

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,9 +3551,9 @@ void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReas
35513551
g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart);
35523552
}
35533553

3554-
void CClientGame::StaticFireHandler(CFire* pFire)
3554+
bool CClientGame::StaticFireHandler(CEntitySAInterface* target, CEntitySAInterface* creator)
35553555
{
3556-
g_pClientGame->FireHandler(pFire);
3556+
return g_pClientGame->FireHandler(target, creator);
35573557
}
35583558

35593559
void CClientGame::StaticRender3DStuffHandler()
@@ -3813,10 +3813,22 @@ bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle)
38133813
return true;
38143814
}
38153815

3816-
void CClientGame::FireHandler(CFire* pFire)
3816+
bool CClientGame::FireHandler(CEntitySAInterface* target, CEntitySAInterface* creator)
38173817
{
3818-
// Disable spreading fires
3819-
pFire->SetNumGenerationsAllowed(0);
3818+
CClientEntity* creatorClientEntity = g_pGame->GetPools()->GetClientEntity((DWORD*)creator);
3819+
CClientEntity* targetClientEntity = g_pGame->GetPools()->GetClientEntity((DWORD*)target);
3820+
3821+
if (creatorClientEntity && targetClientEntity && IS_PLAYER(targetClientEntity) && IS_PLAYER(creatorClientEntity))
3822+
{
3823+
CClientPlayer* targetPlayer = static_cast<CClientPlayer*>(targetClientEntity);
3824+
CClientPlayer* creatorPlayer = static_cast<CClientPlayer*>(creatorClientEntity);
3825+
3826+
CClientTeam* targetPlayerTeam = targetPlayer->GetTeam();
3827+
if (targetPlayerTeam && targetPlayer->IsOnMyTeam(creatorPlayer) && !targetPlayerTeam->GetFriendlyFire() && creatorPlayer != targetPlayer)
3828+
return false;
3829+
}
3830+
3831+
return true;
38203832
}
38213833

38223834
void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile)

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class CClientModelCacheManager;
5353
class CDebugHookManager;
5454
class CResourceFileDownloadManager;
5555
class CServerInfo;
56+
class CFire;
5657
enum class eAnimID;
5758

5859
struct SVehExtrapolateSettings
@@ -522,7 +523,7 @@ class CClientGame
522523

523524
static bool StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent);
524525
static void StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart);
525-
static void StaticFireHandler(CFire* pFire);
526+
static bool StaticFireHandler(CEntitySAInterface* target, CEntitySAInterface* creator);
526527
static bool StaticBreakTowLinkHandler(CVehicle* pTowedVehicle);
527528
static void StaticDrawRadarAreasHandler();
528529
static void StaticRender3DStuffHandler();
@@ -573,7 +574,7 @@ class CClientGame
573574

574575
bool DamageHandler(CPed* pDamagePed, CEventDamage* pEvent);
575576
void DeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart);
576-
void FireHandler(CFire* pFire);
577+
bool FireHandler(CEntitySAInterface* target, CEntitySAInterface* creator);
577578
bool BreakTowLinkHandler(CVehicle* pTowedVehicle);
578579
void DrawRadarAreasHandler();
579580
void Render3DStuffHandler();

Client/mods/deathmatch/logic/CClientPed.cpp

Lines changed: 95 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,16 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI
231231
m_MovementStateNames[MOVEMENTSTATE_JOG] = "jog";
232232
m_MovementStateNames[MOVEMENTSTATE_SPRINT] = "sprint";
233233
m_MovementStateNames[MOVEMENTSTATE_CROUCH] = "crouch";
234-
// These two are inactive for now
235234
m_MovementStateNames[MOVEMENTSTATE_CRAWL] = "crawl";
236235
m_MovementStateNames[MOVEMENTSTATE_ROLL] = "roll";
237236
m_MovementStateNames[MOVEMENTSTATE_JUMP] = "jump";
238237
m_MovementStateNames[MOVEMENTSTATE_FALL] = "fall";
239238
m_MovementStateNames[MOVEMENTSTATE_CLIMB] = "climb";
239+
m_MovementStateNames[MOVEMENTSTATE_SWIM] = "swim";
240+
m_MovementStateNames[MOVEMENTSTATE_WALK_TO_POINT] = "walk_to_point";
241+
m_MovementStateNames[MOVEMENTSTATE_ASCENT_JETPACK] = "ascent_jetpack";
242+
m_MovementStateNames[MOVEMENTSTATE_DESCENT_JETPACK] = "descent_jetpack";
243+
m_MovementStateNames[MOVEMENTSTATE_JETPACK] = "jetpack_flying";
240244

241245
// Create the player model
242246
if (m_bIsLocalPlayer)
@@ -2420,53 +2424,63 @@ eMovementState CClientPed::GetMovementState()
24202424
const char* szComplexTaskName = GetTaskManager()->GetActiveTask()->GetTaskName();
24212425
const char* szSimpleTaskName = GetTaskManager()->GetSimplestActiveTask()->GetTaskName();
24222426

2423-
// Is he climbing?
2424-
if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0)
2427+
// Check tasks
2428+
if (strcmp(szSimpleTaskName, "TASK_SIMPLE_CLIMB") == 0) // Is he climbing?
24252429
return MOVEMENTSTATE_CLIMB;
2426-
2427-
// Is he jumping?
2428-
else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0)
2430+
else if (strcmp(szComplexTaskName, "TASK_COMPLEX_JUMP") == 0) // Is he jumping?
24292431
return MOVEMENTSTATE_JUMP;
2432+
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_GO_TO_POINT") == 0) // Entering vehicle (walking to the doors)?
2433+
return MOVEMENTSTATE_WALK_TO_POINT;
2434+
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_SWIM") == 0) // Is he swimming?
2435+
return MOVEMENTSTATE_SWIM;
2436+
else if (strcmp(szSimpleTaskName, "TASK_SIMPLE_JETPACK") == 0) // Is he flying?
2437+
{
2438+
if (cs.ButtonCross != 0)
2439+
return MOVEMENTSTATE_ASCENT_JETPACK;
2440+
else if (cs.ButtonSquare != 0)
2441+
return MOVEMENTSTATE_DESCENT_JETPACK;
2442+
else
2443+
return MOVEMENTSTATE_JETPACK;
2444+
}
24302445

2431-
// Is he falling?
2432-
else if (!IsOnGround() && !GetContactEntity())
2446+
// Check movement state
2447+
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?
24332448
return MOVEMENTSTATE_FALL;
24342449

2435-
// Grab his controller state
2436-
bool bWalkKey = false;
2437-
if (GetType() == CCLIENTPLAYER)
2438-
bWalkKey = CClientPad::GetControlState("walk", cs, true);
2439-
else
2440-
m_Pad.GetControlState("walk", bWalkKey);
2450+
// Sometimes it returns 'fall' or 'walk', so it's better to return false instead
2451+
if (IsEnteringVehicle() || IsLeavingVehicle())
2452+
return MOVEMENTSTATE_UNKNOWN;
24412453

2442-
// Is he standing up?
24432454
if (!IsDucked())
24442455
{
2445-
unsigned int iRunState = m_pPlayerPed->GetRunState();
2456+
bool walking = false;
2457+
if (GetType() == CCLIENTPLAYER)
2458+
walking = CClientPad::GetControlState("walk", cs, true);
2459+
else
2460+
m_Pad.GetControlState("walk", walking);
24462461

2447-
// Is he moving the contoller at all?
2448-
if (iRunState == 1 && cs.LeftStickX == 0 && cs.LeftStickY == 0)
2449-
return MOVEMENTSTATE_STAND;
2450-
2451-
// Is he either pressing the walk key, or has run state 1?
2452-
if (iRunState == 1 || bWalkKey && iRunState == 6)
2453-
return MOVEMENTSTATE_WALK;
2454-
else if (iRunState == 4)
2455-
return MOVEMENTSTATE_POWERWALK;
2456-
else if (iRunState == 6)
2457-
return MOVEMENTSTATE_JOG;
2458-
else if (iRunState == 7)
2459-
return MOVEMENTSTATE_SPRINT;
2462+
switch (m_pPlayerPed->GetMoveState())
2463+
{
2464+
case PedMoveState::PEDMOVE_STILL:
2465+
return MOVEMENTSTATE_STAND;
2466+
case PedMoveState::PEDMOVE_WALK:
2467+
return (cs.LeftStickX == 0 && cs.LeftStickY == 0) ? MOVEMENTSTATE_STAND : MOVEMENTSTATE_WALK;
2468+
case PedMoveState::PEDMOVE_SPRINT:
2469+
return MOVEMENTSTATE_SPRINT;
2470+
case PedMoveState::PEDMOVE_RUN:
2471+
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)
2472+
}
24602473
}
24612474
else
24622475
{
24632476
// Is he moving the contoller at all?
24642477
if (cs.LeftStickX == 0 && cs.LeftStickY == 0)
24652478
return MOVEMENTSTATE_CROUCH;
24662479
else
2467-
return MOVEMENTSTATE_CRAWL;
2480+
return (cs.LeftStickX != 0 && cs.RightShoulder1 != 0) ? MOVEMENTSTATE_ROLL : MOVEMENTSTATE_CRAWL;
24682481
}
24692482
}
2483+
24702484
return MOVEMENTSTATE_UNKNOWN;
24712485
}
24722486

@@ -2893,6 +2907,11 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses)
28932907
}
28942908
}
28952909

2910+
// Are we need to update anim speed & progress?
2911+
// We need to do it here because the anim starts on the next frame after calling RunNamedAnimation
2912+
if (m_pAnimationBlock && m_AnimationCache.progressWaitForStreamIn && IsAnimationInProgress())
2913+
UpdateAnimationProgressAndSpeed();
2914+
28962915
// Update our alpha
28972916
unsigned char ucAlpha = m_ucAlpha;
28982917
// Are we in a different interior to the camera? set our alpha to 0
@@ -3683,8 +3702,8 @@ void CClientPed::_CreateModel()
36833702
Kill(WEAPONTYPE_UNARMED, 0, false, true);
36843703
}
36853704

3686-
// Are we still playing animation?
3687-
if ((m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame || m_AnimationCache.progressWaitForStreamIn) && m_pAnimationBlock)
3705+
// Are we still playing a animation?
3706+
if (m_pAnimationBlock && IsAnimationInProgress())
36883707
{
36893708
if (m_bisCurrentAnimationCustom)
36903709
{
@@ -3961,8 +3980,8 @@ void CClientPed::_ChangeModel()
39613980
}
39623981
m_bDontChangeRadio = false;
39633982

3964-
// Are we still playing a looped animation?
3965-
if ((m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame || m_AnimationCache.progressWaitForStreamIn) && m_pAnimationBlock)
3983+
// Are we still playing a animation?
3984+
if (m_pAnimationBlock && IsAnimationInProgress())
39663985
{
39673986
if (m_bisCurrentAnimationCustom)
39683987
{
@@ -5729,7 +5748,23 @@ bool CClientPed::IsRunningAnimation()
57295748
}
57305749
return false;
57315750
}
5732-
return (m_AnimationCache.bLoop && m_pAnimationBlock);
5751+
return (m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame) && m_pAnimationBlock;
5752+
}
5753+
5754+
bool CClientPed::IsAnimationInProgress()
5755+
{
5756+
bool constAnim = m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame;
5757+
5758+
if (!m_pAnimationBlock)
5759+
return constAnim;
5760+
5761+
float elapsedTime = static_cast<float>(GetTimestamp() - m_AnimationCache.startTime) / 1000.0f;
5762+
5763+
auto animBlendHierarchy = g_pGame->GetAnimManager()->GetAnimation(m_AnimationCache.strName.c_str(), m_pAnimationBlock);
5764+
if (!animBlendHierarchy)
5765+
return constAnim;
5766+
5767+
return constAnim || elapsedTime < animBlendHierarchy->GetTotalTime();
57335768
}
57345769

57355770
void CClientPed::RunNamedAnimation(std::unique_ptr<CAnimBlock>& pBlock, const char* szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition,
@@ -5817,10 +5852,6 @@ void CClientPed::RunNamedAnimation(std::unique_ptr<CAnimBlock>& pBlock, const ch
58175852
m_AnimationCache.bUpdatePosition = bUpdatePosition;
58185853
m_AnimationCache.bInterruptable = bInterruptable;
58195854
m_AnimationCache.bFreezeLastFrame = bFreezeLastFrame;
5820-
m_AnimationCache.progress = 0.0f;
5821-
m_AnimationCache.speed = 1.0f;
5822-
m_AnimationCache.progressWaitForStreamIn = false;
5823-
m_AnimationCache.elapsedTime = 0.0f;
58245855
}
58255856

58265857
void CClientPed::KillAnimation()
@@ -5859,39 +5890,45 @@ void CClientPed::RunAnimationFromCache()
58595890
if (!m_pAnimationBlock)
58605891
return;
58615892

5862-
bool needCalcProgress = m_AnimationCache.progressWaitForStreamIn;
5863-
float elapsedTime = m_AnimationCache.elapsedTime;
5864-
58655893
// Copy our name incase it gets deleted
58665894
std::string animName = m_AnimationCache.strName;
58675895

58685896
// Run our animation
58695897
RunNamedAnimation(m_pAnimationBlock, animName.c_str(), m_AnimationCache.iTime, m_AnimationCache.iBlend, m_AnimationCache.bLoop, m_AnimationCache.bUpdatePosition, m_AnimationCache.bInterruptable, m_AnimationCache.bFreezeLastFrame);
58705898

5871-
auto animAssoc = g_pGame->GetAnimManager()->RpAnimBlendClumpGetAssociation(GetClump(), animName.c_str());
5899+
// Set anim progress & speed
5900+
m_AnimationCache.progressWaitForStreamIn = true;
5901+
}
5902+
5903+
void CClientPed::UpdateAnimationProgressAndSpeed()
5904+
{
5905+
if (!m_AnimationCache.progressWaitForStreamIn)
5906+
return;
5907+
5908+
// Get current anim
5909+
auto animAssoc = g_pGame->GetAnimManager()->RpAnimBlendClumpGetAssociation(GetClump(), m_AnimationCache.strName.c_str());
58725910
if (!animAssoc)
58735911
return;
58745912

5875-
// If the anim is synced from the server side, we need to calculate the progress
5876-
float progress = m_AnimationCache.progress;
5877-
if (needCalcProgress)
5878-
{
5879-
float animLength = animAssoc->GetLength();
5913+
float animLength = animAssoc->GetLength();
5914+
float progress = 0.0f;
5915+
float elapsedTime = static_cast<float>(GetTimestamp() - m_AnimationCache.startTime) / 1000.0f;
58805916

5881-
if (m_AnimationCache.bFreezeLastFrame) // time and loop is ignored if freezeLastFrame is true
5882-
progress = (elapsedTime / animLength) * m_AnimationCache.speed;
5917+
if (m_AnimationCache.bFreezeLastFrame) // time and loop is ignored if freezeLastFrame is true
5918+
progress = (elapsedTime / animLength) * m_AnimationCache.speed;
5919+
else
5920+
{
5921+
if (m_AnimationCache.bLoop)
5922+
progress = std::fmod(elapsedTime * m_AnimationCache.speed, animLength) / animLength;
58835923
else
5884-
{
5885-
if (m_AnimationCache.bLoop)
5886-
progress = std::fmod(elapsedTime * m_AnimationCache.speed, animLength) / animLength;
5887-
else
5888-
// For non-looped animations, limit duration to animLength if time exceeds it
5889-
progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed;
5890-
}
5924+
// For non-looped animations, limit duration to animLength if time exceeds it
5925+
progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed;
58915926
}
58925927

58935928
animAssoc->SetCurrentProgress(std::clamp(progress, 0.0f, 1.0f));
58945929
animAssoc->SetCurrentSpeed(m_AnimationCache.speed);
5930+
5931+
m_AnimationCache.progressWaitForStreamIn = false;
58955932
}
58965933

58975934
void CClientPed::PostWeaponFire()
@@ -6096,7 +6133,7 @@ bool CClientPed::ShouldBeStealthAiming()
60966133
{
60976134
// We need to be either crouched, walking or standing
60986135
SBindableGTAControl* pWalkControl = pKeyBinds->GetBindableFromControl("walk");
6099-
if (m_pPlayerPed->GetRunState() == 1 || m_pPlayerPed->GetRunState() == 4 || pWalkControl && pWalkControl->bState)
6136+
if (m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_STILL || m_pPlayerPed->GetMoveState() == PedMoveState::PEDMOVE_WALK || pWalkControl && pWalkControl->bState)
61006137
{
61016138
// Do we have a target ped?
61026139
CClientPed* pTargetPed = GetTargetedPed();

0 commit comments

Comments
 (0)