183 lines
5.6 KiB
Lua
183 lines
5.6 KiB
Lua
--- Desencrypted By PrejuicioX
|
|
|
|
-- Global state
|
|
local wasRadarVisible = true
|
|
|
|
-- Texture resources for backdrop
|
|
local backdropTxdName = "kq_outfitbag2_backdrop_txd"
|
|
local backdropTextureName = "kq_outfitbag2_backdrop_tx"
|
|
local backdropTxdHandle = CreateRuntimeTxd(backdropTxdName)
|
|
CreateRuntimeTextureFromImage(backdropTxdHandle, backdropTextureName, "html/img/backdrop.png")
|
|
|
|
function CreatePreviewPed(shouldCreate)
|
|
if not Config.preview.enabled then
|
|
return
|
|
end
|
|
|
|
-- Clean up existing preview ped
|
|
if PREVIEW_PED ~= nil then
|
|
DeletePreviewPed()
|
|
end
|
|
|
|
local playerPed = PlayerPedId()
|
|
local playerModel = GetEntityModel(playerPed)
|
|
|
|
-- Calculate spawn position offset from player
|
|
local spawnCoords = GetOffsetFromEntityInWorldCoords(playerPed, 0.38, 1.15, -0.73)
|
|
|
|
-- Adjust height if not using a bag object
|
|
if not IsBagObject(CURRENT_BAG) then
|
|
spawnCoords = spawnCoords + vector3(0.0, 0.0, 0.4)
|
|
end
|
|
|
|
local playerHeading = GetEntityHeading(playerPed)
|
|
|
|
-- Ensure model is loaded
|
|
DoRequestModel(playerModel)
|
|
|
|
-- Clone the player ped
|
|
local previewPed = ClonePed(playerPed, 0, 0, 0)
|
|
PREVIEW_PED = previewPed
|
|
|
|
-- Initial setup - invisible
|
|
SetEntityAlpha(previewPed, 0, 0)
|
|
SetEntityCoords(previewPed, spawnCoords)
|
|
SetEntityHeading(previewPed, playerHeading + 40.0)
|
|
|
|
-- Lock ped in place and disable AI
|
|
FreezeEntityPosition(previewPed, true)
|
|
TaskSetBlockingOfNonTemporaryEvents(previewPed, true)
|
|
SetBlockingOfNonTemporaryEvents(previewPed, true)
|
|
|
|
-- Set initial size
|
|
SetPedSize(previewPed, 0.21)
|
|
|
|
-- Early exit if bag is not open
|
|
if not BAG_OPEN then
|
|
DeletePreviewPed()
|
|
return
|
|
end
|
|
|
|
-- Brief delay before making visible
|
|
Citizen.Wait(1)
|
|
ResetEntityAlpha(previewPed)
|
|
|
|
-- Start render thread
|
|
Citizen.CreateThread(function()
|
|
-- Store and hide radar state
|
|
wasRadarVisible = not IsRadarHidden()
|
|
if wasRadarVisible then
|
|
DisplayRadar(false)
|
|
end
|
|
|
|
-- Main preview render loop
|
|
while PREVIEW_PED ~= nil do
|
|
SetPedSize(previewPed, 0.25)
|
|
DrawBackdrop(previewPed)
|
|
|
|
-- Add lighting effect
|
|
local lightPosition = GetOffsetFromEntityInWorldCoords(previewPed, 0.0, 0.4, 0.5)
|
|
DrawLightWithRange(lightPosition, 255, 255, 255, 0.7, 1.0)
|
|
|
|
-- Exit if bag closes
|
|
if not BAG_OPEN then
|
|
DeletePreviewPed()
|
|
end
|
|
|
|
Citizen.Wait(1)
|
|
end
|
|
|
|
-- Restore radar state
|
|
DisplayRadar(wasRadarVisible)
|
|
end)
|
|
|
|
return previewPed
|
|
end
|
|
|
|
function DrawBackdrop(ped)
|
|
-- Calculate backdrop corner positions
|
|
local topRight = GetOffsetFromEntityInWorldCoords(ped, 0.7, -1.2, 1.4)
|
|
local topLeft = GetOffsetFromEntityInWorldCoords(ped, -0.7, -1.2, 1.92)
|
|
local bottomRight = GetOffsetFromEntityInWorldCoords(ped, 0.39, -0.2, -1.25)
|
|
local bottomLeft = GetOffsetFromEntityInWorldCoords(ped, -0.65, -0.2, -1.6)
|
|
|
|
local alpha = 234
|
|
local primaryColor = Config.theme.colors.primary
|
|
|
|
-- Draw backdrop as two triangular polygons
|
|
-- Left triangle: bottom-left, top-left, top-right
|
|
DrawSpritePoly(
|
|
bottomLeft.x, bottomLeft.y, bottomLeft.z,
|
|
topLeft.x, topLeft.y, topLeft.z,
|
|
topRight.x, topRight.y, topRight.z,
|
|
primaryColor.r, primaryColor.g, primaryColor.b, alpha,
|
|
backdropTxdName, backdropTextureName,
|
|
1.0, 1.0, 1.0, 1.0,
|
|
0.0, 1.0, 0.0, 0.0, 0.0
|
|
)
|
|
|
|
-- Right triangle: bottom-left, top-right, bottom-right
|
|
DrawSpritePoly(
|
|
bottomLeft.x, bottomLeft.y, bottomLeft.z,
|
|
topRight.x, topRight.y, topRight.z,
|
|
bottomRight.x, bottomRight.y, bottomRight.z,
|
|
primaryColor.r, primaryColor.g, primaryColor.b, alpha,
|
|
backdropTxdName, backdropTextureName,
|
|
1.0, 1.0, 1.0, 0.0,
|
|
0.0, 0.0, 0.0, 1.0, 0.0
|
|
)
|
|
end
|
|
|
|
function DeletePreviewPed()
|
|
if not Config.preview.enabled then
|
|
return
|
|
end
|
|
|
|
if PREVIEW_PED then
|
|
DeleteEntity(PREVIEW_PED)
|
|
PREVIEW_PED = nil
|
|
end
|
|
end
|
|
|
|
function SetPedSize(ped, scale)
|
|
local rightVector, forwardVector, upVector, position = GetEntityMatrix(ped)
|
|
local shouldAdjust = false
|
|
|
|
-- Check if scale adjustment requires position correction
|
|
if not shouldAdjust then
|
|
if scale > 1.0 and upVector.z <= 1.0 then
|
|
shouldAdjust = true
|
|
end
|
|
if scale < 1.0 and upVector.z >= 1.0 then
|
|
shouldAdjust = true
|
|
end
|
|
end
|
|
|
|
-- Apply scaling
|
|
if shouldAdjust then
|
|
position = position + vector3(0.0, 0.0, scale - 1)
|
|
rightVector = rightVector * scale
|
|
forwardVector = forwardVector * scale
|
|
upVector = upVector * scale
|
|
end
|
|
|
|
SetEntityMatrix(ped, rightVector, forwardVector, upVector, position)
|
|
end
|
|
|
|
function PreviewOutfit(outfit)
|
|
if not Config.preview.enabled then
|
|
return
|
|
end
|
|
|
|
-- Select random animation from config
|
|
local animations = Config.preview.animations
|
|
local randomAnimation = animations[math.random(1, #animations)]
|
|
|
|
-- Play animation on preview ped
|
|
PlayAnim(randomAnimation[1], randomAnimation[2], 0, PREVIEW_PED)
|
|
|
|
-- Apply outfit to preview ped
|
|
ApplyPreviewOutfit(outfit, PREVIEW_PED)
|
|
end
|
|
|
|
--- Desencrypted By PrejuicioX |