CLEO Help Get Player/Actor/Car/Object Health/Armor in Float

CLEO related
Status
Not open for further replies.

ajom

Well-known member
Joined
Apr 14, 2020
Messages
389
Solutions
2
Reaction score
268
Location
Pluto
Hello, this is my first post. I have learned so many things on this website and I just got a problem that I cannot find anywhere around the internet. OK, so this opcodes gets the actor/player/Car/Object health in "Integer" Format:
Code:
0226: $6459 = actor 164@ health // health of an actor handle
0227: 4@ = car 22@ health // health of a car handle
071E: get_object 102@ health_to 103@ // health of an object handle
0B25: samp 2@ = get_player_health 1@ // health of player id 1@

But as on my experience when playing samp, I noticed that sometimes when a "Player" has a health of 0, it is still alive! That is why I suspected the health of that player was around (0.01 - 0.49) but only shows 0 because it is was truncated into an integer value...

So my question is, How can I get the HP or Armor of my target type of entity that is a float number(so that I can get the decimal part of their Health/Armor)?

Also, obviously this will not extract the decimal part of the decimal part of the health/armor:
Code:
0B25: samp 2@ = get_player_health 1@
0093: 2@ = integer 2@ to_float // this will only add a decimal part on the number... but will not extract the decimal part of the player hp



I have found a thread that does detect floating number health, but is on C++ format:
Getting Player HP(C++)

Please Help :( I really need this feature so that I can detect if the player_ped is "dead" in SAMP.
 
Last edited:

Zin

Expert
Joined
Aug 1, 2013
Messages
1,690
Reaction score
103
CPed +0x540 = [float] Health
CPed +0x548 = [float] Armor

E.g. for health.
C++:
0A96: 0@ = actor $PLAYER_ACTOR struct // CPed pointer
0@ += 0x548 // Health
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0AD1: "%f" 1 0@
 

Zin

Expert
Joined
Aug 1, 2013
Messages
1,690
Reaction score
103
Yeah I'm pretty sure samp has it's own ped stuff which will most likely use an "int" for health hence why that's how sampfuncs does it so your problem with people not being dead could be due to something else. There's most likely other ways like checking if they're in the dead animation.
 

ajom

Well-known member
Joined
Apr 14, 2020
Messages
389
Solutions
2
Reaction score
268
Location
Pluto
CPed + 0x540 should work for all CPED actors.
https://gtamods.com/wiki/Memory_Addresses_(SA)

OK, so it works on "local peds" around you and is good for single players. Now my only problem is for SAMP Players. As @Parazitas says, all peds are always 1000 HP because I think samp do not use the local HP pointers but has its own hp addresses (as what sampfuncs opcode 0B25 reads). That is why all peds are "always detected as ALIVE" which is actually my problem at samp.

Yeah I'm pretty sure samp has it's own ped stuff which will most likely use an "int" for health hence why that's how sampfuncs does it so your problem with people not being dead could be due to something else. There's most likely other ways like checking if they're in the dead animation.

Yes, detecting the player death animation is the old way of how I detect if a player is dead. But it is "not accurate" because , sometimes when a player is dead at samp, they are just performing their "last animation"(like shooting, walking, running,stop animation) instead of performing some known death/dying animation, but the only thing that is always happening is that they are stuck on their location while performing their "Last Animation".

That is why I want to detect their HP floating point to accurately predict if they are dead. but sampfuncs opcode 0B25 only returns integer values. Maybe someone can reverse how that opcode was made? I actually am not good on memory hacking that is why i cannot do it hehe.
 

ajom

Well-known member
Joined
Apr 14, 2020
Messages
389
Solutions
2
Reaction score
268
Location
Pluto
Yeah I'm pretty sure samp has it's own ped stuff which will most likely use an "int" for health hence why that's how sampfuncs does it so your problem with people not being dead could be due to something else. There's most likely other ways like checking if they're in the dead animation.

And I think is just that this Opcode 0B25 is almost the same as Opcode 0226. The crappy thing about this opcode is that they return an integer value instead of a floating pointer number.

If I reverse Opcode 0226 and 04DD, I know this is how it works:
Code:
0AD2: 31@ = player $PLAYER_CHAR targeted_actor //IF and SET
call @OP_0226 1 _actor 31@ _store_to 30@ // returns the integer health = 0226:
call @OP_04DD 1 _actor 31@ _store_to 30@ // returns the integer armor = 04DD:


:OP_0226
0A96: 0@ = actor $PLAYER_ACTOR struct // CPed pointer
0@ += 0x540 // Health
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@

:OP_04DD
0A96: 0@ = actor $PLAYER_ACTOR struct // CPed pointer
0@ += 0x548 // Armor
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@


So I suspect that if Opcode 0B25 does the same thing... I/We just need to know the proper pointers to get there I think, I just dont have an idea what address should be pointed to...
Code:
call @OP_0B25 1 _player_id 6 _store_to 31@// get health of player ID 6

:OP_0B25
0@ = <Pointer where samp hides all stream player actor's structure>
0@ += <offset of the health>
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@
 

dovidas147

Active member
Joined
Nov 1, 2018
Messages
32
Reaction score
2
And I think is just that this Opcode 0B25 is almost the same as Opcode 0226. The crappy thing about this opcode is that they return an integer value instead of a floating pointer number.

If I reverse Opcode 0226 and 04DD, I know this is how it works:
Code:
0AD2: 31@ = player $PLAYER_CHAR targeted_actor //IF and SET
call @OP_0226 1 _actor 31@ _store_to 30@ // returns the integer health = 0226:
call @OP_04DD 1 _actor 31@ _store_to 30@ // returns the integer armor = 04DD:


:OP_0226
0A96: 0@ = actor $PLAYER_ACTOR struct // CPed pointer
0@ += 0x540 // Health
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@

:OP_04DD
0A96: 0@ = actor $PLAYER_ACTOR struct // CPed pointer
0@ += 0x548 // Armor
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@


So I suspect that if Opcode 0B25 does the same thing... I/We just need to know the proper pointers to get there I think, I just dont have an idea what address should be pointed to...
Code:
call @OP_0B25 1 _player_id 6 _store_to 31@// get health of player ID 6

:OP_0B25
0@ = <Pointer where samp hides all stream player actor's structure>
0@ += <offset of the health>
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0092: 0@ = float 0@ to_integer // <<<< this is the crappy thing
0AB2: ret 1 0@
Your best bet would be to try to find an streamed entity list with cheat engine and check if health offsets are floats by damaging them. If I were you I would start searching it from player's name tag.
 

ajom

Well-known member
Joined
Apr 14, 2020
Messages
389
Solutions
2
Reaction score
268
Location
Pluto
Your best bet would be to try to find an streamed entity list with cheat engine and check if health offsets are floats by damaging them. If I were you I would start searching it from player's name tag.

OK, I might try that. Thank you(case still unsolved xD).
 

0x_

Wtf I'm not new....
Administrator
Joined
Feb 18, 2013
Messages
1,118
Reaction score
166
You can't use GTA:SA to obtain the health value of remote players.
Here's C++ code you can convert it easily to CLEO:

C++:
SAMPPTR_POOLS_PLAYER = 0x21A0F8(read ptr) + 0x3CD (read ptr) + 0x18
SAMP::CSAMPPlayer SAMP::CPlayerPool::GetSAMPPlayerAt(PLAYERID playerid)
{
    return CSAMPPlayer(*(Address*)(SAMPM->ResolvePtr(SAMPPTR_POOLS_PLAYER) + 4 * playerid + 46), playerid);
}

float SAMP::CSAMPPlayer::GetHealth()
{
    Address pPlayerData = (Address)NWMem::Read<Address*>(m_this);
    return NWMem::Read<float>(pPlayerData + 0x1BC);
}

// To obtain the playerid by GTA:SA Ped you can call 0x10420 of SAMPPTR_POOLS_PLAYER (params: void* this(POOLS_PLAYER), DWORD ped ptr

Oh.. and there's not floating precision left due to the compression of the health & armour values in the sync.
 

Parazitas

God
Joined
Jan 2, 2017
Messages
3,115
Solutions
5
Reaction score
879
Location
Lithuania
Edit:
Tested And Works..
0.3.7 - R1

PHP:
:Get_Some_Information
/// 0AB1: @Get_Some_Information 1 PlayerID 125
0AA2: 1@ = loadLib "samp.dll" //samp base offset      
1@ += 0x21A0F8
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stInfo
1@ += 0x3CD
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stPools
10@ += 0x18
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stPlayerPools
1@ += 0x2E
0@ *= 0x4 // 4 * playerid
005A: 1@ += 0@
0A8D: 1@ readMem 1@ sz 4 vp 0 // Playerremote
1@ += 0x0
0A8D: 1@ readMem 1@ sz 4 vp 0 // PlayerData
1@ += 0x1BC // health offset
0A8D: 1@ readMem 1@ sz 4 vp 0 // Playerhealth
0AD1: "%f" 1337 1@
0AB2: ret 0
 
Last edited:

ajom

Well-known member
Joined
Apr 14, 2020
Messages
389
Solutions
2
Reaction score
268
Location
Pluto
You can't use GTA:SA to obtain the health value of remote players.
Here's C++ code you can convert it easily to CLEO:

C++:
SAMPPTR_POOLS_PLAYER = 0x21A0F8(read ptr) + 0x3CD (read ptr) + 0x18
SAMP::CSAMPPlayer SAMP::CPlayerPool::GetSAMPPlayerAt(PLAYERID playerid)
{
    return CSAMPPlayer(*(Address*)(SAMPM->ResolvePtr(SAMPPTR_POOLS_PLAYER) + 4 * playerid + 46), playerid);
}

float SAMP::CSAMPPlayer::GetHealth()
{
    Address pPlayerData = (Address)NWMem::Read<Address*>(m_this);
    return NWMem::Read<float>(pPlayerData + 0x1BC);
}

// To obtain the playerid by GTA:SA Ped you can call 0x10420 of SAMPPTR_POOLS_PLAYER (params: void* this(POOLS_PLAYER), DWORD ped ptr

Oh.. and there's not floating precision left due to the compression of the health & armour values in the sync.

So its impossible to get the floating precision of the health then? Ok, How about detecting whether the player is dead or alive? My current way of detecting if they are dead is when they perform death animation. But that is just inaccurate, so I was wondering how samp knows when the player is now dead.

I'm not good when need convert c++ to cleo , but i tried xD

PHP:
:Get_Some_Information
/// 0AB1: @Get_Some_Information 1 PlayerID 125 _Return: 0@
0AA2: 1@ = loadLib "samp.dll" //samp base offset       
1@ += 0x21A0F8
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stInfo
1@ += 0x3CD
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stPools
10@ += 0x18
0A8D: 1@ = readmem 1@ sz 4 vp 0 //stPlayerPools
0@ *= 0x4 // 4 * playerid
005A: 1@ += 0@
1@ += 0x46
0A8D: 1@ readMem 1@ sz 4 vp 0
0AB2: ret 1 1@

I only get a float of 0.00000 and an integer value of 0 after the result. Does this extract the health? Sorry for asking, im actually dumb at this xD
 
Status
Not open for further replies.
Top