@@ -235,6 +235,107 @@ function Adjustments:Multipliers()
235235 end )
236236end
237237
238+ function Adjustments :ApplyPlayerStats ()
239+ if not Config .PlayerStatsByGender .enabled then return end
240+
241+ if Config .EnableDebug then
242+ print (' [^3adjustments^7] applying player stats...' )
243+ end
244+
245+ local gender = self :GetPlayerGender ()
246+ if not gender then
247+ if Config .EnableDebug then
248+ print (' [^1adjustments^7] failed to detect gender' )
249+ end
250+ return
251+ end
252+
253+ local stats = Config .PlayerStatsByGender [gender ]
254+ if not stats then
255+ if Config .EnableDebug then
256+ print (' [^1adjustments^7] no stats found for gender: ' .. gender )
257+ end
258+ return
259+ end
260+
261+ if stats .stamina then
262+ SetRunSprintMultiplierForPlayer (ESX .playerId , stats .stamina )
263+ end
264+
265+ if stats .strength then
266+ SetPlayerMeleeWeaponDamageModifier (ESX .playerId , stats .strength )
267+ end
268+
269+ if stats .swimSpeed then
270+ SetSwimMultiplierForPlayer (ESX .playerId , stats .swimSpeed )
271+ end
272+
273+ -- moveSpeed requires continuous loop
274+ if stats .moveSpeed then
275+ self .currentMoveSpeed = stats .moveSpeed
276+ if not self .moveSpeedThreadRunning then
277+ self .moveSpeedThreadRunning = true
278+ CreateThread (function ()
279+ while Config .PlayerStatsByGender .enabled and self .currentMoveSpeed do
280+ if ESX .PlayerData .ped then
281+ SetPedMoveRateOverride (ESX .PlayerData .ped , self .currentMoveSpeed )
282+ end
283+ Wait (0 )
284+ end
285+ self .moveSpeedThreadRunning = false
286+ end )
287+ end
288+ end
289+
290+ if Config .EnableDebug then
291+ print (' [^2adjustments^7] stats applied for gender: ' .. gender )
292+ end
293+ end
294+
295+ function Adjustments :GetPlayerGender ()
296+ if not ESX .PlayerLoaded then
297+ if Config .EnableDebug then
298+ print (' [^1adjustments^7] player not loaded yet' )
299+ end
300+ return
301+ end
302+
303+ if Config .EnableDebug then
304+ print (' [^3adjustments^7] detecting gender using: ' .. (Config .PlayerStatsByGender .useCharacterData and ' character data' or ' ped model' ))
305+ end
306+
307+ if Config .PlayerStatsByGender .useCharacterData then
308+ -- Option 1: character data
309+ if ESX .PlayerData .sex then
310+ return ESX .PlayerData .sex == ' m' and ' male' or ' female'
311+ end
312+ else
313+ -- Option 2: ped model
314+ local model = GetEntityModel (ESX .PlayerData .ped )
315+
316+ for i = 1 , # Config .PlayerStatsByGender .malePeds do
317+ if model == Config .PlayerStatsByGender .malePeds [i ] then
318+ return ' male'
319+ end
320+ end
321+
322+ for i = 1 , # Config .PlayerStatsByGender .femalePeds do
323+ if model == Config .PlayerStatsByGender .femalePeds [i ] then
324+ return ' female'
325+ end
326+ end
327+
328+ -- Native fallback
329+ if IsPedMale (ESX .PlayerData .ped ) then
330+ return ' male'
331+ else
332+ return ' female'
333+ end
334+ end
335+
336+ return nil
337+ end
338+
238339function Adjustments :Load ()
239340 self :RemoveHudComponents ()
240341 self :DisableAimAssist ()
@@ -250,4 +351,25 @@ function Adjustments:Load()
250351 self :WantedLevel ()
251352 self :DisableRadio ()
252353 self :Multipliers ()
354+
355+ AddEventHandler (' esx:playerLoaded' , function (xPlayer , isNew , skin )
356+ self :ApplyPlayerStats ()
357+ end )
358+
359+ if not Config .PlayerStatsByGender .useCharacterData then
360+ AddEventHandler (' skinchanger:modelLoaded' , function ()
361+ self :ApplyPlayerStats ()
362+ end )
363+ end
364+
365+ AddEventHandler (' esx:onPlayerSpawn' , function ()
366+ self :ApplyPlayerStats ()
367+ end )
368+
369+ if Config .PlayerStatsByGender .enabled and Config .EnableDebug then
370+ print (' [^2adjustments^7] player stats by gender loaded' )
371+ print (' [^3adjustments^7] enabled: ' .. tostring (Config .PlayerStatsByGender .enabled ))
372+ print (' [^3adjustments^7] use character data: ' .. tostring (Config .PlayerStatsByGender .useCharacterData ))
373+ print (' [^3adjustments^7] debug mode: active' )
374+ end
253375end
0 commit comments