StatGetInt return a 32 bits value but Stats can be 64 bits
What happened?
To know if a stuntjump is done, GTA use a binary mask system in the stat : MP0_USJS_COMPLETED_MASK (for male, and use MP1 for female)
When you never did stuntjump, MP0_USJS_COMPLETED_MASK is binary : 0 For exemple if you success stunt jump number 6, MP0_USJS_COMPLETED_MASK will be binary : 100000 (decimal 32) An other name that you can give to this is "flags", for 6 it will be 2^(6-1) because we begin at 0, not 1, and you add all flags you want in your final number.
So i tryed this theory, i did stunjump 6 and my script returned 0 0 0 0 0 1 (because my script count binary right to left) I reseted the Stat using : StatSetInt(GetHashKey("MP0_USJS_COMPLETED_MASK"), 0) I tryed stunjump 32 and my script returned 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 (1073741824 in decimal)
At this moment all is cool, but the problem is that there is 50 stunjumps, so i tryed stuntjump 42 The number returned was the same because this stat is only returned with 32 bits (there is an overflow)
Expected result
64 bits return value
Reproduction steps
You can use : StatSetInt(GetHashKey("MP0_USJS_COMPLETED_MASK"), 0) to set the stat to 0 Use : StatSetMaskedInt(GetHashKey("MP0_USJS_COMPLETED_MASK"), 1, 42, 1, true) to set the 42th bit to 1 Use this to get the Stat value : local isValid, returnedInt = StatGetInt(GetHashKey("MP0_USJS_COMPLETED_MASK"), -1)
Use this function on returnedInt to have it in binary :
function ToBits(num)
local t={}
while num>0 do
rest=math.fmod(num,2)
t[#t+1]=math.floor(rest+0.5)
num=(num-rest)/2
end
return table.concat(t, " ")
end
You will get a 32 bits value
Importancy
Slight inconvenience
Area(s)
FiveM, Natives, ScRT: Lua
Specific version(s)
FiveM 7990 (and other versions)
Additional information
For Native : StatSetMaskedInt Parameters are : int keyHash, int data, int shift, int numberOfBits, bool save
For Native : StatGetMaskedInt Parameters are : int keyHash, int shift, int numberOfBits, I don't know the last I tryed this Native to choose bit one by one, but it didn't wotk : [ 3037531] [ GTAProcess] MainThrd/ __Lua_InvokeNative: execution failed: Error executing native 0x655185a06d9eeaab at address FiveM_GTAProcess.exe+CF2A83. [ 3037531] [ GTAProcess] MainThrd/ Execution of native 655185a06d9eeaab in script host failed: Error executing native 0x655185a06d9eeaab at address FiveM_GTAProcess.exe+CF2A83.
The FiveM implementation of the Native StatGetInt is :
--- p2 appears to always be -1
function Global.StatGetInt(statHash, p2)
return _in(0x767FBC2AC802EF3D, _ch(statHash), _i, p2, _r)
end
So i hunderstand it return a lightuserdata that is a pointer, and by default it seems to be 32 bit data, i will try to pass float pointer. Eddit : Floats are 32 bits and we don't have access to long that are 64 bits
A solution can be to add Citizen.PointerValueInt64() and use this for the Native.
I saw that 2take1 menu added a Native stat_get_i64 to get a 64 bits int, it can be a good solution.
I found a workaround Use StatGetBool It works on int and will give you binary bit of this int
I think this should stay open as the workaround of using *Bool for *Int is a bit weird. There's still some problem with StatGetInt that should be fixed
I think this should stay open as the workaround of using *Bool for *Int is a bit weird. There's still some problem with StatGetInt that should be fixed
Ok i re-open it