Log in to reply

How to get a wheel address from wheel ID?

  • Does anyone know how to get a wheel address from (vehicle memory address and) a wheel ID?
    Wheel structs don't seem to have their wheel IDs, and only RPH can access wheel structs with wheel IDs (via its properties) for now. But I'll add some properties and methods that need to access them to SHVDN if someone tells me the info.
    @Unknown-Modder ?


    @kagikn I'm in school right now so I can't post any code but maybe @ikt has time. He also knows how to do that.

  • I took a look at (wheel pointer +) 0x108 and 0x10F as ikt said, but the wheel ID (that is used by natives) wasn't at either. I tested both before ikt said, though.
    I could use a workaround by storing vehicle bone strings somewhere and checking if the vehicle has bones, but I'm afraid of adding vehicle bones by Rockstar.
    I'm so freaking sure Mulle won't tell me how to get a wheel pointer from a wheel ID even If I ask him.


    @kagikn ikt is right with offset 0x108. It's just that the number (uint16_t btw) isn't the ID that you use for natives. R* uses a lookup table for this. You could implement it like this:

    uint32_t wheelIdLookupTable[] =

    and then get the real ID like so:

    uint32_t realId = wheelIdLookupTable[wheelIndex];

  • @Unknown-Modder Wait, would you show me practical usage? I'm not completely sure how to use this, and how about 45 and 47 (which are used for mid wheels of 6-wheel trailers in natives)?
    (I believe ikt wasn't completely sure he was right with offset 0x108 (and I didn't realized until you said), because we need to use a lookup table to get correct wheel ID after all, but it doesn't matter if he was sure.)


    @kagikn Can you post the natives that use 45 and 47?


    @kagikn That wouldn't even work.

    bool __fastcall IS_VEHICLE_TYRE_BURST(signed int vehicle, int wheelId, bool completely)
      bool v3; // bp@1
      __int64 v4; // rsi@1
      __int64 v5; // rax@1
      bool v6; // bl@1
      __int64 v7; // rdi@1
      int v8; // esi@3
      __int64 v9; // rax@4
      v3 = completely;
      v4 = wheelId;
      v5 = GetVehicleFromScriptGuid(vehicle);
      v6 = 0;
      v7 = v5;
      if ( v5 )
        if ( *(_DWORD *)(v5 + 0xB38) <= 12u )
          v8 = g_wheelIdLookupTable[v4]; // contains only 8 items, so only 0 - 7 is allowed
          if ( CVehicle__GetWheelById(v5, v8) )
            v9 = CVehicle__GetWheelById(v7, v8);
            if ( v3 )
              if ( *(float *)(v9 + 0x1E4) == 0.0 )
                v6 = 1;
              v6 = 0;
              if ( *(float *)(v9 + 0x1E4) < 1000.0 )
                v6 = 1;
      return v6;

  • @Unknown-Modder Probably I got confused by their descriptions in Native DB. I'll test 45 and 47 with natives and RPH to confirm if the descriptions are wrong for real, but I'm going to bed and I can't test them for at least about 7 hours.

  • @Unknown-Modder I confirmed the natives didn't accept 45 or 47 after all (at least in v1.0.1180.2). Instead, 167 and 215 represent middle left wheels of trailers, and 166 and 217 represent middle right wheels of trailers. But the natives accepts some values that is larger than 1 byte, strange.
    Btw, I noticed RPH didn't accept any of the 4 values (or 45 or 47).

  • Alright, I'll test what wheelIDs (including middle wheels of trailers) the 3 natives accept and will show the result.

  • EDIT: Damn, the lookup table Unknown Modder posted is invalid at least in v1.0.1032.1. 0x108 is not the offset of real wheel IDs!
    I happened to think the IDs of middle wheels of trailer for native functions were different from those in v1.0.1180.2, and was able to realized this fact. Without it, I wouldn't have notice this fact.
    I need to find the real offset of wheel IDs if 0x10F is not the real offset.

    I found the real wheel IDs of the left middle wheel and right middle wheel of trailers. Left one is 17 and right one is 18.
    I'll implement some additional properties and methods on SHVDN after some additional tests.


    @kagikn The table is the same across all game builds, the ID offset also. I think only those 8 wheels are intended to be used with scripts since internally there are more wheels used by the game (12, I think).
    I just call CVehicleWheel* CVehicle__GetWheelById(CVehicle* This, int wheelId) (BA ? ? ? ? 48 8B CF E8 ? ? ? ? 48 85 C0 0F 84 ? ? ? ? 48 8B 4F 20 [call instruction at pattern + 8]) which is the best way.

  • @Unknown-Modder I didn't think you found the pattern, will test it and report the result then.

  • @Unknown-Modder I couldn't get CVehicle__GetWheelById working even in C++ after all. Is there something wrong with this code? (ignore stringstream, IsKeyDown and drawing texts, just for convenience in test) https://pastebin.com/WEWk0utN


    @kagikn In build 1180 (SC version) the pattern is at 0x140355302 and the function at 0x140EF8278 so make sure that these are valid for you.

  • @Unknown-Modder Sorry, but I don't have SC version but Steam version, so I can't verify my pattern and function addresses with the 2 values you posted.
    Btw, the code that I posted can find some address with the pattern at least (not sure if the offset from pattern is correct though).

  • I’m still struggling with CVehicle__GetWheelById, and I'm not even sure what can crash the game in calling it (expect for invalid function call due to wrong function address).
    I doubt if I can access the function by calling instruction at pattern + 8 in steam version.


    @kagikn Replace GetWheelById = (GetWheelById_t)(patternAddr + 8); with GetWheelById = (GetWheelById_t)(patternAddr + *(int*)(patternAddr + 9) + 13);

  • @Unknown-Modder Ah, I've tried many cases but I haven't tried this case. Will try this.

  • @Unknown-Modder I confirmed CVehicle__GetWheelById worked in Steam version and worked well in older versions. I really appreciated it.
    I'll add some wheel functions that need to directly access wheel structs to SHVDN.

Log in to reply

Looks like your connection to GTA5-Mods.com Forums was lost, please wait while we try to reconnect.