Jump to content

Player's oxygen


Recommended Posts

Hi,

I'm trying to write get-/setPedOxygen. I already found the correct memory address in Mantis (click me), but I don't understand, why my reversed stuff didn't work.

Here is it (pastebin):

void __thiscall sub_60A8D0(int this, char a2, float a3) 
{ 
  int pPlayer; // esi@1 
  int pPlayerData; // ecx@3 // pPlayer + 1152 
  double v5; // st7@3 
  double v6; // st7@5 
  int v7; // eax@8 
  
  pPlayer = this; 
  if ( !a2 || HasInfiniteOxygen ) 
  { 
    if ( sub_559AF0( > *(float *)(*(_DWORD *)(this + 1152) + 68) ) 
      *(float *)(*(_DWORD *)(pPlayer + 1152) + 68) = flt_B7CB5C * a3// 1152: CPlayerPedDataSAInterface* 
                                                //  
                                                   + flt_B7CB5C * a3 
                                                   + *(float *)(*(_DWORD *)(pPlayer + 1152) + 68); 
  } 
  else 
  { 
    pPlayerData = *(_DWORD *)(this + 1152); 
    v5 = flt_B7CB5C * a3; 
    if ( *(float *)(pPlayerData + 68) > 0.0 && *(_DWORD *)(pPlayer + 1136) & 0x100000 ) 
    { 
      v6 = *(float *)(pPlayerData + 68) - v5; 
      if ( v6 < 0.0 ) 
        v6 = 0.0; 
      *(float *)(pPlayerData + 68) = v6; 
    } 
    else 
    { 
      v7 = sub_821B80(v5 * 3.0); 
      sub_73A530(pPlayer, pPlayer, 53, v7, 3, 0); 
    } 
  } 
  *(_DWORD *)(*(_DWORD *)(pPlayer + 1152) + 52) &= 0xFFFFFF7Fu; 
} 

Wouldn't v6 or *(float *)(*(_DWORD *)(pPlayer + 1152) + 68) the player's oxygen?

But with the following code I'll always get 0.0:

float CPedSA::GetOxygen ( void ) 
{ 
    CPlayerPedDataSAInterface* pInterface = GetPedInterface ()->pPlayerData; 
    float* ptr = (float*)(pInterface+68); 
    float fBreath = *ptr; 
     
    return fBreath; 
} 

My approach was to find this code by the "infinite oxygen" cheat flag (in this code "HasInfiniteOxygen").

I know the memory address from DEFCON1 is correct, but I want to understand why my stuff doesn't works ;)

Best regards

Link to comment

the input seems to be a CPedSAInterface.

it adds 1152 to the CPedSAInterface which is a pointer to a CPlayerPedDataSAInterface

then you shall find that CPlayerPedDataSAInterface + 64 is a float which contains the breath (not a pointer to a float just a float)

so what you are doing is right apart from that it's not a pointer (btw we already have breath documented)

it's m_fBreath

this might work better but like I say m_fBreath is a member inside pPlayerData anyway

float CPedSA::GetOxygen ( void ) 
{ 
    CPlayerPedDataSAInterface* pInterface = GetPedInterface ()->pPlayerData; 
    DWORD dwBreath = (DWORD)pInterface+68; 
    float fBreath = *(float*)(dwBreath); 
    
    return fBreath; 
} 

you might want to look into the interfaces, you'l find them in C*SA.h

e.g.

CVehicleSA.h contains the vehicle interface

CPedSA.h contains the ped related interfaces

CWeaponSA.h has the weapon related interfaces and so on...

if you are stuck they usually have the offsets documented and that should help a lot in determining what x + 1152 is

Link to comment

Thank you, your example works.

I forgot to mention that "m_fBreath" is wrong. I found out that it has to be 2 bytes later.

The following fields should also be correct now (tested with "m_bPlayerSprintDisabled").

Patch uploaded here: https://dl.dropbox.com/u/53602417/mta/ped_oxygen.patch

Is there any special reason why getters use CClientPed directly and setters CClientEntity + casting?

Link to comment
  • 1 month later...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...