Open TrymTube opened 5 days ago
This isn't a bug, first if you aren't please make sure you wait for IsPedheadshotReady
(and possibly HasStreamedPedAssetsLoaded
) and make sure you UnregisterPedheadshot
when you're finished with them.
A hopefully understandable explanation on why this happens (thanks to gottfriedleibniz for most of this, this is largely paraphrasing him):
REGISTER_PEDHEADSHOT_TRANSPARENT
is hard coded to use pedmugshot_01.ytd
(128x128px) the ytds are encoded as DXT5/BC3
and has 128x128 which has alpha channels.
REGISTER_PEDHEADSHOT_HIRES
is coded to use pedmugshot_0[2..8].ytd
(which is also 128x128px) the ytds are encoded as DXT1/BC1
.
REGISTER_PEDHEADSHOT
is coded to use pedmugshot_0[9..34].ytd
(which is 64x64px) these ytds are encoded as DXT1/BC1
To note: BC1 has 1 bit for alpha data BC3 has 1 byte for alpha data
The notable things here though is that the they both use 128x128px textures, so if you replace pedmugshot_0[2..8].ytd
with a copy of pedmugshot_01.ytd
it will be BC3 which means it will actually be able to store alpha data, and you'll be able to use 7 ped headshots at a time (or 8 if you still use RegisterPedheadshotTransparent)
TLDR:
RegisterPedheadshotTransparent
only has 1 available texture slot to draw to (being pedmugshot_01.ytd
), which is why this happens.
You can use RegisterPedheadshot_3
(aka REGISTER_PEDHEADSHOT_HIRES
) with transparent textures streamed over the original slots and it will work the same as RegisterPedshotTransparent
, you will only have 7 slots to work with at a time though.
Here's a zip with the stream-able files
Put these into a resources stream/ folder and you should be able to request 7 slots at a time for RegisterPedheadshot_3
.
Some example code for how I've used this:
Client:
// note this isn't complete code, we have stuff to request this 7 at a time & spam retry 20 times until it eventually get it
// or just fails.
const getPedHeadshot = async (pedHandle: number): Promise<boolean> => {
let pedShot = RegisterPedheadshot_3(pedHandle);
const abortAt = GetGameTimer() + 100;
while (!IsPedheadshotReady(pedShot)) {
const gt = GetGameTimer();
if (gt > abortAt) {
// might get stuck if we don't stop the request
UnregisterPedheadshot(pedShot);
return false;
}
await Delay(0);
}
const txd: string = GetPedheadshotTxdString(pedShot);
await nuiHandler.sendNUIMessage({
app: "headshot",
method: "RegisterHeadshot",
data: txd
});
UnregisterPedheadshot(pedShot);
return true;
};
Ui:
useNuiEvent("headshot", "RegisterHeadshot", async (txd: string) => {
const imgFetch = await fetch(`https://nui-img/${txd}/${txd}`);
const imgBlob = await imgFetch.blob();
setImageBlob(imgBlob);
});
This isn't a bug, first if you aren't please make sure you wait for
IsPedheadshotReady
(and possiblyHasStreamedPedAssetsLoaded
) and make sure youUnregisterPedheadshot
when you're finished with them
I have done the exact that, I have been taking the headshot and I have a wait to ensure the headshot is usable and ready, at the end I use Unregister, but still sometimes when I try to load my ID the photo is not there and it is stuck in an endless loop trying to wait for a usable headshot. I dont know if Understood that correct but if I put in the Stream files it might work better?
this is currently the code for the headshot
local function getPlayerHeadshot(playerSource)
local playerPed = GetPlayerPed(GetPlayerFromServerId(playerSource))
local handle, test = RegisterPedheadshotTransparent(playerPed)
local abortAt = GetGameTimer() + 100
-- print(1, handle, IsPedheadshotReady(handle), IsPedheadshotValid(handle))
while not IsPedheadshotReady(handle) do
local gt = GetGameTimer()
if gt > abortAt then
UnregisterPedheadshot(handle)
return false
end
Wait(0)
end
local txd = GetPedheadshotTxdString(handle)
UnregisterPedheadshot(handle)
return txd
end
function ClientShowCardEvent(data)
data.player.character.head = './images/person.png'
if data.player.character.head == './images/person.png' then
local headTxt = getPlayerHeadshot(data.playerSource)
if headTxt then
data.player.character.head = string.format("https://nui-img/%s/%s", headTxt, headTxt)
end
end
SetNuiFocus(true, true)
SendNUIMessage({
action = 'showCard',
data = data
})
SendNUIMessage({
action = 'setVisible',
data = true
})
end
What happened?
Issue:
I am trying to use RegisterPedheadshotTransparent but this is not reliable and it is randomly working. It is like a 50/50 Chance that it gives me a Headshot or not.
Expected result
it should give me a Picture of my player head
Reproduction steps
try using it and displaying it
Importancy
Unknown
Area(s)
FiveM
Specific version(s)
FiveM Build 3095 // Artifacts 8633
Additional information
No response