Skip to content

Fix armor limit and synchronization between client and server #3983

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 7 commits into from
Jan 28, 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
6 changes: 3 additions & 3 deletions Client/game_sa/CPedSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,14 @@ void CPedSA::SetHealth(float fHealth)
GetPedInterface()->fHealth = fHealth;
}

float CPedSA::GetArmor()
float CPedSA::GetArmor() noexcept
{
return GetPedInterface()->fArmor;
}

void CPedSA::SetArmor(float fArmor)
void CPedSA::SetArmor(float armor) noexcept
{
GetPedInterface()->fArmor = fArmor;
GetPedInterface()->fArmor = armor;
}

float CPedSA::GetOxygenLevel()
Expand Down
4 changes: 2 additions & 2 deletions Client/game_sa/CPedSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ class CPedSA : public virtual CPed, public virtual CPhysicalSA
float GetHealth();
void SetHealth(float fHealth);

float GetArmor();
void SetArmor(float fArmor);
float GetArmor() noexcept;
void SetArmor(float armor) noexcept;

float GetOxygenLevel();
void SetOxygenLevel(float fOxygen);
Expand Down
6 changes: 3 additions & 3 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4371,7 +4371,7 @@ bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage,
{
float fPreviousHealth = pDamagedPed->m_fHealth;
float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth();
float fPreviousArmor = pDamagedPed->m_fArmor;
float fPreviousArmor = pDamagedPed->m_armor;
float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor();

// Have we taken any damage here?
Expand Down Expand Up @@ -4407,7 +4407,7 @@ bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage,
{
// Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick)
fPreviousHealth = pDamagedPed->m_fHealth;
fPreviousArmor = pDamagedPed->m_fArmor;
fPreviousArmor = pDamagedPed->m_armor;
}
pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth);
pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor);
Expand Down Expand Up @@ -4453,7 +4453,7 @@ bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage,

// Update our stored health/armor
pDamagedPed->m_fHealth = fCurrentHealth;
pDamagedPed->m_fArmor = fCurrentArmor;
pDamagedPed->m_armor = fCurrentArmor;

ElementID damagerID = INVALID_ELEMENT_ID;
if (pInflictingEntity && !pInflictingEntity->IsLocalEntity())
Expand Down
45 changes: 22 additions & 23 deletions Client/mods/deathmatch/logic/CClientPed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI
m_uiOccupiedVehicleSeat = 0xFF;
m_bHealthLocked = false;
m_bDontChangeRadio = false;
m_bArmorLocked = false;
m_armorLocked = false;
m_ulLastOnScreenTime = 0;
m_pLoadedModelInfo = NULL;
m_pOutOfVehicleWeaponSlot = WEAPONSLOT_MAX; // WEAPONSLOT_MAX = invalid
Expand Down Expand Up @@ -157,7 +157,7 @@ void CClientPed::Init(CClientManager* pManager, unsigned long ulModelID, bool bI
m_bVisible = true;
m_bUsesCollision = true;
m_fHealth = 100.0f;
m_fArmor = 0.0f;
m_armor = 0.0f;
m_bDead = false;
m_bWorldIgnored = false;
m_fCurrentRotation = 0.0f;
Expand Down Expand Up @@ -1793,29 +1793,28 @@ void CClientPed::InternalSetHealth(float fHealth)
}
}

float CClientPed::GetArmor()
float CClientPed::GetArmor() const noexcept
{
if (m_bArmorLocked)
return m_fArmor;
if (m_armorLocked)
return m_armor;

if (m_pPlayerPed)
{
return m_pPlayerPed->GetArmor();
}
return m_fArmor;

return m_armor;
}

void CClientPed::SetArmor(float fArmor)
void CClientPed::SetArmor(float armor) noexcept
{
// If our armor is locked, dont allow any change
if (m_bArmorLocked)
if (m_armorLocked)
return;

armor = std::clamp(armor, 0.0f, 100.0f);

if (m_pPlayerPed)
{
m_pPlayerPed->SetArmor(fArmor);
}
m_fArmor = fArmor;
m_pPlayerPed->SetArmor(armor);

m_armor = armor;
}

void CClientPed::LockHealth(float fHealth)
Expand All @@ -1824,10 +1823,10 @@ void CClientPed::LockHealth(float fHealth)
m_fHealth = fHealth;
}

void CClientPed::LockArmor(float fArmor)
void CClientPed::LockArmor(float armor) noexcept
{
m_bArmorLocked = true;
m_fArmor = fArmor;
m_armorLocked = true;
m_armor = armor;
}

float CClientPed::GetOxygenLevel()
Expand Down Expand Up @@ -2772,9 +2771,9 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses)
}

// Is our armor locked?
if (m_bArmorLocked)
if (m_armorLocked)
{
m_pPlayerPed->SetArmor(m_fArmor);
m_pPlayerPed->SetArmor(m_armor);
}

// In a vehicle?
Expand Down Expand Up @@ -3623,7 +3622,7 @@ void CClientPed::_CreateModel()
m_pPlayerPed->SetVisible(m_bVisible);
m_pPlayerPed->SetUsesCollision(m_bUsesCollision);
m_pPlayerPed->SetHealth(m_fHealth);
m_pPlayerPed->SetArmor(m_fArmor);
m_pPlayerPed->SetArmor(m_armor);
m_pPlayerPed->SetLighting(m_fLighting);
WorldIgnore(m_bWorldIgnored);

Expand Down Expand Up @@ -4225,10 +4224,10 @@ bool CClientPed::PerformChecks()
// The player should not be able to gain any health/armor without us knowing..
// meaning all health/armor giving must go through SetHealth/SetArmor.
if ((m_fHealth > 0.0f && m_pPlayerPed->GetHealth() > m_fHealth + FLOAT_EPSILON) ||
(m_fArmor < 100.0f && m_pPlayerPed->GetArmor() > m_fArmor + FLOAT_EPSILON))
(m_armor < 100.0f && m_pPlayerPed->GetArmor() > m_armor + FLOAT_EPSILON))
{
g_pCore->GetConsole()->Printf("healthCheck: %f %f", m_pPlayerPed->GetHealth(), m_fHealth);
g_pCore->GetConsole()->Printf("armorCheck: %f %f", m_pPlayerPed->GetArmor(), m_fArmor);
g_pCore->GetConsole()->Printf("armorCheck: %f %f", m_pPlayerPed->GetArmor(), m_armor);
return false;
}
// Perform the checks in CGame
Expand Down
14 changes: 7 additions & 7 deletions Client/mods/deathmatch/logic/CClientPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,17 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule
float GetHealth();
void SetHealth(float fHealth);
void InternalSetHealth(float fHealth);
float GetArmor();
void SetArmor(float fArmor);
float GetArmor() const noexcept;
void SetArmor(float armor) noexcept;
float GetOxygenLevel();
void SetOxygenLevel(float fOxygen);

void LockHealth(float fHealth);
void LockArmor(float fArmor);
void LockArmor(float armor) noexcept;
void UnlockHealth() noexcept { m_bHealthLocked = false; };
void UnlockArmor() noexcept { m_bArmorLocked = false; };
void UnlockArmor() noexcept { m_armorLocked = false; };
bool IsHealthLocked() const noexcept { return m_bHealthLocked; };
bool IsArmorLocked() const noexcept { return m_bArmorLocked; };
bool IsArmorLocked() const noexcept { return m_armorLocked; };

bool IsDying();
bool IsDead();
Expand Down Expand Up @@ -619,7 +619,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule
bool m_bRadioOn;
unsigned char m_ucRadioChannel;
bool m_bHealthLocked;
bool m_bArmorLocked;
bool m_armorLocked;
unsigned long m_ulLastOnScreenTime;
CClientVehiclePtr m_pOccupiedVehicle;
CClientVehiclePtr m_pOccupyingVehicle;
Expand Down Expand Up @@ -678,7 +678,7 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule
bool m_bVisible;
bool m_bUsesCollision;
float m_fHealth;
float m_fArmor;
float m_armor;
bool m_bDead;
bool m_bWorldIgnored;
float m_fCurrentRotation;
Expand Down
6 changes: 3 additions & 3 deletions Client/mods/deathmatch/logic/CClientPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,13 @@ void CClientPlayer::DischargeWeapon(eWeaponType weaponType, const CVector& vecSt
// CPlayerPed has post damage health/armor

float fPreviousHealth = pBackupDamagedPlayer->m_fHealth;
float fPreviousArmor = pBackupDamagedPlayer->m_fArmor;
float fPreviousArmor = pBackupDamagedPlayer->m_armor;

// Calculate how much damage should be applied to health/armor
float fArmorDamage = std::min(fBackupDamage, pBackupDamagedPlayer->m_fArmor);
float fArmorDamage = std::min(fBackupDamage, pBackupDamagedPlayer->m_armor);
float fHealthDamage = std::min(fBackupDamage - fArmorDamage, pBackupDamagedPlayer->m_fHealth);

float fNewArmor = pBackupDamagedPlayer->m_fArmor - fArmorDamage;
float fNewArmor = pBackupDamagedPlayer->m_armor - fArmorDamage;
float fNewHealth = pBackupDamagedPlayer->m_fHealth - fHealthDamage;

// Ensure CPlayerPed has post damage health/armor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void CLuaCompatibilityDefs::LoadFunctions()
{"getPlayerTotalAmmo", CLuaPedDefs::GetPedTotalAmmo},
{"getPedWeaponMuzzlePosition", CLuaPedDefs::GetPedWeaponMuzzlePosition},
{"getPlayerOccupiedVehicle", CLuaPedDefs::GetPedOccupiedVehicle},
{"getPlayerArmor", CLuaPedDefs::GetPedArmor},
{"getPlayerArmor", ArgumentParserWarn<false, CLuaPedDefs::GetPedArmor>},
{"getPlayerSkin", CLuaElementDefs::GetElementModel},
{"isPlayerChoking", CLuaPedDefs::IsPedChoking},
{"isPlayerDucked", CLuaPedDefs::IsPedDucked},
Expand Down
29 changes: 9 additions & 20 deletions Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void CLuaPedDefs::LoadFunctions()

{"getPedStat", GetPedStat},
{"getPedOxygenLevel", GetPedOxygenLevel},
{"getPedArmor", GetPedArmor},
{"getPedArmor", ArgumentParserWarn<false, GetPedArmor>},
{"isPedBleeding", ArgumentParser<IsPedBleeding>},

{"getPedContactElement", GetPedContactElement},
Expand Down Expand Up @@ -784,26 +784,9 @@ int CLuaPedDefs::OOP_GetPedTargetCollision(lua_State* luaVM)
return 1;
}

int CLuaPedDefs::GetPedArmor(lua_State* luaVM)
float CLuaPedDefs::GetPedArmor(CClientPed* const ped) noexcept
{
// Verify the argument
CClientPed* pPed = NULL;
CScriptArgReader argStream(luaVM);
argStream.ReadUserData(pPed);

if (!argStream.HasErrors())
{
// Grab the armor and return it
float fArmor = pPed->GetArmor();
lua_pushnumber(luaVM, fArmor);
return 1;
}
else
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());

// Failed
lua_pushboolean(luaVM, false);
return 1;
return ped->GetArmor();
}

int CLuaPedDefs::GetPedStat(lua_State* luaVM)
Expand Down Expand Up @@ -2395,6 +2378,12 @@ int CLuaPedDefs::SetPedMoveAnim(lua_State* luaVM)

bool CLuaPedDefs::SetPedArmor(CClientPed* const ped, const float armor)
{
if (armor < 0.0f)
throw std::invalid_argument("Armor must be greater than or equal to 0");

if (armor > 100.0f)
throw std::invalid_argument("Armor must be less than or equal to 100");

ped->SetArmor(armor);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class CLuaPedDefs : public CLuaDefs
LUA_DECLARE(GetPedStat);
LUA_DECLARE(GetPedOccupiedVehicle);
LUA_DECLARE(GetPedOccupiedVehicleSeat);
LUA_DECLARE(GetPedArmor);
static float GetPedArmor(CClientPed* const ped) noexcept;
LUA_DECLARE(IsPedChoking);
LUA_DECLARE(IsPedDucked);
LUA_DECLARE(IsPedInVehicle);
Expand Down
2 changes: 1 addition & 1 deletion Client/sdk/game/CPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class CPed : public virtual CPhysical
virtual float GetHealth() = 0;
virtual void SetHealth(float fHealth) = 0;
virtual float GetArmor() = 0;
virtual void SetArmor(float fArmor) = 0;
virtual void SetArmor(float armor) = 0;
virtual float GetOxygenLevel() = 0;
virtual void SetOxygenLevel(float fOxygen) = 0;
virtual bool AddProjectile(eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity) = 0;
Expand Down
4 changes: 2 additions & 2 deletions Server/mods/deathmatch/logic/CPed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ CPed::CPed(CPedManager* pPedManager, CElement* pParent, unsigned short usModel)
m_bWearingGoggles = false;

m_fHealth = 0.0f;
m_fArmor = 0.0f;
m_armor = 0.0f;

memset(&m_fStats[0], 0, sizeof(m_fStats));
m_fStats[24] = 569.0f; // default max_health
Expand Down Expand Up @@ -239,7 +239,7 @@ bool CPed::ReadSpecialData(const int iLine)
m_fHealth = 100.0f;

// Grab the "armor" data
GetCustomDataFloat("armor", m_fArmor, true);
GetCustomDataFloat("armor", m_armor, true);

// Grab the "interior" data
if (GetCustomDataInt("interior", iTemp, true))
Expand Down
6 changes: 3 additions & 3 deletions Server/mods/deathmatch/logic/CPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ class CPed : public CElement
float GetMaxHealth();
float GetHealth() { return m_fHealth; }
void SetHealth(float fHealth) { m_fHealth = fHealth; }
float GetArmor() { return m_fArmor; }
void SetArmor(float fArmor) { m_fArmor = fArmor; }
float GetArmor() const noexcept { return m_armor; }
void SetArmor(float armor) noexcept { m_armor = std::clamp(armor, 0.0f, 100.0f); }

float GetPlayerStat(unsigned short usStat) { return (usStat < NUM_PLAYER_STATS) ? m_fStats[usStat] : 0; }
void SetPlayerStat(unsigned short usStat, float fValue)
Expand Down Expand Up @@ -317,7 +317,7 @@ class CPed : public CElement
bool m_bWearingGoggles;
bool m_bIsOnFire;
float m_fHealth;
float m_fArmor;
float m_armor;
SFixedArray<float, NUM_PLAYER_STATS> m_fStats;
CPlayerClothes* m_pClothes;
bool m_bHasJetPack;
Expand Down
Loading
Loading