Introduction
So, we’re going to talk about the standard playerSpawned event in conjunction with RedMenu . There is a problem - when the Default Skin is selected in RedMenu (see Picture 1), there may be issues during development using the playerSpawned
event and native PlayerPedId()
.
Picture 1. RedMenu Default Skin.
Problem Description
The issue is that if you want to do something with the player’s ped right after they spawn, it might not work as the player’s ped changes approximately 4-4.5 seconds later, as indicated in the code here and here.
Example
AddEventHandler('playerSpawned', function()
print(PlayerPedId()) -- 1584645
Wait(4500)
print(PlayerPedId()) -- 1210117
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
Initial Solution
The simplest solution is to add a delay as follows:
AddEventHandler('playerSpawned', function()
Wait(4500) -- We wait for RedMenu to set Default Skin
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
1. Critique of Initial Solution and Improved Solution with Check
However, proposed approach is not yet effective, due to that:
- It introduces a hard-coded delay, regardless of whether the Default Skin is selected in RedMenu.
To address this concern, a better practice would be to check whether RedMenu is running and only introduce a delay under specific conditions:
AddEventHandler('playerSpawned', function()
-- 1. Checking if RedMenu is running
if GetResourceState('RedMenu') == 'started' then
Wait(4500)
end
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
Remaining Issues
Despite the improvement, some issues remain:
- Occasionally, the delay may need to be longer due to factors such as extended loading times for in-game models (e.g., RequestModel).
- If RedMenu is running but the Default Skin is not selected, the delay will still be applied.
2. Optimized Solution with KVP Check
A more thorough solution involves exploring the RedM source code to identify event triggers or alternative approaches. Unfortunately, no triggers were found, but we did discover a valuable piece of information. RedMenu employs a Key-Value Pair (KVP) storage, which can be leveraged. Specifically, RedMenu stores the default skin under the key int_PlayerDefaultSavedPed
(source code).
With this knowledge, the delay can be refined to apply only when the Default Ped is set:
AddEventHandler('playerSpawned', function()
-- 1. Checking if RedMenu is running
if GetResourceState('RedMenu') == 'started' then
-- 2. Checking if Default Ped is selected
if GetExternalKvpInt('RedMenu', 'int_PlayerDefaultSavedPed') ~= 0 then
Wait(4500)
end
end
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
3. Eliminating the Delay
To further optimize this, we can eliminate the delay by continuously checking for changes in the player’s ped:
AddEventHandler('playerSpawned', function()
-- 1. Checking if RedMenu is running
if GetResourceState('RedMenu') == 'started' then
-- 2. Checking if Default Ped is selected
if GetExternalKvpInt('RedMenu', 'int_PlayerDefaultSavedPed') ~= 0 then
-- 3. Waiting until our player ped model changes
local oldPed = PlayerPedId()
while PlayerPedId() == oldPed do
Wait(0)
end
end
end
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
4. Adding a Timeout Check
Additionally, we can add a check for the duration of the loop execution, just in case our player ped hasn’t changed for some reason:
AddEventHandler('playerSpawned', function()
-- 1. Checking if RedMenu is running
if GetResourceState('RedMenu') == 'started' then
-- 2. Checking if Default Ped is selected
if GetExternalKvpInt('RedMenu', 'int_PlayerDefaultSavedPed') ~= 0 then
-- 3. Waiting until our player ped model changes
local oldPed = PlayerPedId()
-- 4. Additionally, add the timeout check
local timeoutAt = GetGameTimer() + 10000
while PlayerPedId() == oldPed and GetGameTimer() < timeoutAt do
Wait(0)
end
end
end
SetEntityMaxHealth(PlayerPedId(), 250)
SetEntityHealth(PlayerPedId(), 250)
end)
Summary
In summary, we’ve examined the playerSpawned
event in conjunction with RedMenu and the challenges it poses, particularly with the RedMenu Default Skin. We’ve explored several solutions, ranging from simple delays to more sophisticated options like KVP storage.