266 lines
8.8 KiB
Lua
266 lines
8.8 KiB
Lua
local pendingScreenshots = {}
|
|
local uploadedResults = {}
|
|
|
|
furnitureCreator = {
|
|
visible = false,
|
|
token = nil
|
|
}
|
|
|
|
function furnitureCreator.updateUI(self)
|
|
if not self.visible then return end
|
|
|
|
local furnitureCopy = table.deepclone(Config.Furniture)
|
|
for _, category in pairs(furnitureCopy) do
|
|
category.items = table.filter(category.items, function(item)
|
|
return item.creator
|
|
end)
|
|
end
|
|
|
|
SendReactMessage("toggle_furniture_creator", {
|
|
visible = true,
|
|
furniture = furnitureCopy
|
|
})
|
|
end
|
|
|
|
function furnitureCreator.open(self)
|
|
ToggleHud(false)
|
|
self.visible = true
|
|
SetNuiFocus(true, true)
|
|
self:updateUI()
|
|
Debug("Furniture Creator opened")
|
|
end
|
|
|
|
function furnitureCreator.close(self)
|
|
if not self.visible then return end
|
|
self.visible = false
|
|
SendReactMessage("toggle_furniture_creator", { visible = false })
|
|
ToggleHud(true)
|
|
SetNuiFocus(false, false)
|
|
Debug("Furniture Creator closed")
|
|
end
|
|
|
|
RegisterNetEvent("garages:syncFurnitureData")
|
|
AddEventHandler("garages:syncFurnitureData", function(furnitureData)
|
|
Config.Furniture = furnitureData
|
|
InitializeFurnitures()
|
|
end)
|
|
|
|
RegisterCommand(Config.FurniCreatorCommand, function()
|
|
local hasPermission = lib.callback.await("garages:hasPermission", 0)
|
|
if not hasPermission then
|
|
return Notification(i18n.t("no_permission"), "error")
|
|
end
|
|
furnitureCreator:open()
|
|
end)
|
|
|
|
function furnitureCreator.takeScreenshot(self, requestId)
|
|
Wait(Config.FurniCreator.interval)
|
|
|
|
if not self.token then
|
|
self.token = lib.callback.await("garages:getFiveManageToken", false)
|
|
end
|
|
|
|
if not self.token then
|
|
return Notification(i18n.t("furniture_creator.token_not_set"), "error")
|
|
end
|
|
|
|
pendingScreenshots[requestId] = {
|
|
name = requestId,
|
|
timestamp = GetGameTimer()
|
|
}
|
|
|
|
Notification(i18n.t("furniture_creator.uploading_image"), "info")
|
|
|
|
exports["screenshot-basic"]:requestScreenshot({ encoding = "png" }, function(imageData)
|
|
SendReactMessage("upload_image", {
|
|
image = imageData,
|
|
fiveManageToken = self.token,
|
|
requestId = requestId
|
|
})
|
|
end)
|
|
|
|
Debug("Screenshot Request Sent", requestId)
|
|
return requestId
|
|
end
|
|
|
|
function furnitureCreator.hasPendingScreenshots(self)
|
|
return next(pendingScreenshots) ~= nil
|
|
end
|
|
|
|
RegisterNUICallback("handle_uploaded_image", function(data, cb)
|
|
local requestId = data.requestId
|
|
local pending = pendingScreenshots[requestId]
|
|
|
|
if not pending then
|
|
Error("No data found for requestId", data.requestId)
|
|
return cb("error")
|
|
end
|
|
|
|
uploadedResults[requestId] = {
|
|
filePath = data.url,
|
|
name = pending.name
|
|
}
|
|
|
|
Debug("Screenshot Results", uploadedResults[requestId], "data", data)
|
|
|
|
pendingScreenshots[requestId] = nil
|
|
|
|
Notification(i18n.t("furniture_creator.image_uploaded"), "success")
|
|
cb("ok")
|
|
end)
|
|
|
|
local GREEN_BOX_ORIGIN = vec3(-2407.29736328125, -2023.800537109375, 690.6831665039062)
|
|
local GREEN_BOX_OFFSET = vec3(0.0, 0.0, 0.5)
|
|
local MIN_CAMERA_DIST = 3.0
|
|
local ROTATE_SPEED = 100.0
|
|
local VERTICAL_SPEED = 0.5
|
|
local ZOOM_SPEED = 15.0
|
|
local MAX_ZOOM = 10.0
|
|
|
|
function furnitureCreator.takeObjectScreenshot(self, objectModelName)
|
|
if self.inGreenBox then return end
|
|
|
|
self.inGreenBox = true
|
|
self.initialPlayerCoords = GetEntityCoords(cache.ped)
|
|
|
|
FreezeEntityPosition(cache.ped, true)
|
|
SetEntityAlpha(cache.ped, 0, false)
|
|
|
|
local greenBoxModel = joaat("qs_gradient_032")
|
|
lib.requestModel(greenBoxModel)
|
|
local greenBoxEntity = CreateObject(greenBoxModel, GREEN_BOX_ORIGIN.x, GREEN_BOX_ORIGIN.y, GREEN_BOX_ORIGIN.z, false, false, false)
|
|
self.greenBox = greenBoxEntity
|
|
FreezeEntityPosition(greenBoxEntity, true)
|
|
|
|
local objectModel = joaat(objectModelName)
|
|
lib.requestModel(objectModel)
|
|
local spawnPos = GREEN_BOX_ORIGIN + GREEN_BOX_OFFSET
|
|
local objectEntity = CreateObject(objectModel, spawnPos.x, spawnPos.y, spawnPos.z, false, false, false)
|
|
self.object = objectEntity
|
|
FreezeEntityPosition(objectEntity, true)
|
|
SetEntityHeading(objectEntity, 0.0)
|
|
|
|
Wait(100)
|
|
|
|
local objectCoords = GetEntityCoords(objectEntity)
|
|
local minDim, maxDim = GetModelDimensions(objectModel)
|
|
local objectSize = #(maxDim - minDim)
|
|
local cameraOffset = math.min(objectSize * 2.5, MIN_CAMERA_DIST)
|
|
local verticalMidpoint = (maxDim.z - minDim.z) / 2
|
|
local cameraPos = vec3(objectCoords.x + cameraOffset, objectCoords.y, objectCoords.z + verticalMidpoint)
|
|
|
|
local greenBoxCamera = Utils.CreateCamera("DEFAULT_SCRIPTED_CAMERA", cameraPos, vec3(0, 0, 0), true, nil, 0)
|
|
self.greenBoxCamera = greenBoxCamera
|
|
|
|
SetCamCoord(greenBoxCamera, cameraPos.x, cameraPos.y, cameraPos.z)
|
|
PointCamAtCoord(greenBoxCamera, objectCoords.x, objectCoords.y, objectCoords.z)
|
|
|
|
Utils.DrawInstructional({ "zoom", "done", "cancel", "up", "rotate_z" })
|
|
|
|
local heading = 0.0
|
|
local verticalOffset = verticalMidpoint
|
|
local currentZoom = cameraOffset
|
|
local confirmed = false
|
|
|
|
while self.inGreenBox do
|
|
DisableAllControlActions(0)
|
|
SetEntityHeading(objectEntity, heading)
|
|
SetEntityCoords(objectEntity, objectCoords.x, objectCoords.y, objectCoords.z + verticalOffset, false, false, false, false)
|
|
|
|
if IsDisabledControlPressed(0, ActionControls.rotate_z.codes[1]) then
|
|
heading = (heading + ROTATE_SPEED * GetFrameTime()) % 360
|
|
elseif IsDisabledControlPressed(0, ActionControls.rotate_z.codes[2]) then
|
|
heading = (heading - ROTATE_SPEED * GetFrameTime()) % 360
|
|
end
|
|
|
|
if IsDisabledControlPressed(0, ActionControls.up.codes[1]) then
|
|
verticalOffset = verticalOffset + VERTICAL_SPEED * GetFrameTime()
|
|
elseif IsDisabledControlPressed(0, ActionControls.up.codes[2]) then
|
|
verticalOffset = verticalOffset - VERTICAL_SPEED * GetFrameTime()
|
|
end
|
|
|
|
if IsDisabledControlPressed(0, ActionControls.rotate_z_scroll.codes[1]) then
|
|
currentZoom = math.max(MIN_CAMERA_DIST / 3, currentZoom - ZOOM_SPEED * GetFrameTime())
|
|
local newCamPos = vec3(objectCoords.x + currentZoom, objectCoords.y, objectCoords.z + verticalMidpoint)
|
|
cameraPos = newCamPos
|
|
SetCamCoord(greenBoxCamera, newCamPos.x, newCamPos.y, newCamPos.z)
|
|
elseif IsDisabledControlPressed(0, ActionControls.rotate_z_scroll.codes[2]) then
|
|
currentZoom = math.min(MAX_ZOOM, currentZoom + ZOOM_SPEED * GetFrameTime())
|
|
local newCamPos = vec3(objectCoords.x + currentZoom, objectCoords.y, objectCoords.z + verticalMidpoint)
|
|
cameraPos = newCamPos
|
|
SetCamCoord(greenBoxCamera, newCamPos.x, newCamPos.y, newCamPos.z)
|
|
end
|
|
|
|
if IsDisabledControlJustPressed(0, ActionControls.done.codes[1]) then
|
|
confirmed = true
|
|
self.inGreenBox = false
|
|
break
|
|
end
|
|
|
|
if IsDisabledControlJustPressed(0, ActionControls.cancel.codes[1]) then
|
|
self.inGreenBox = false
|
|
Notification(i18n.t("furniture_creator.screenshot_cancelled"), "error")
|
|
break
|
|
end
|
|
|
|
Wait(0)
|
|
end
|
|
|
|
Utils.RemoveInstructional()
|
|
|
|
if confirmed then
|
|
local screenshotId = self:takeScreenshot(objectModelName)
|
|
if not screenshotId then return end
|
|
|
|
while self:hasPendingScreenshots() do
|
|
Wait(0)
|
|
end
|
|
|
|
local resultData = uploadedResults[screenshotId]
|
|
self:destroyScreenshot()
|
|
uploadedResults[screenshotId] = nil
|
|
return resultData and resultData.filePath
|
|
else
|
|
self:destroyScreenshot()
|
|
return nil
|
|
end
|
|
end
|
|
|
|
RegisterCommand("test", function()
|
|
local url = furnitureCreator:takeObjectScreenshot("prop_rub_washer_01")
|
|
Debug("Screenshot URL", url)
|
|
end)
|
|
|
|
function furnitureCreator.destroyScreenshot(self)
|
|
if self.greenBox and DoesEntityExist(self.greenBox) then
|
|
DeleteEntity(self.greenBox)
|
|
self.greenBox = nil
|
|
end
|
|
|
|
if self.object and DoesEntityExist(self.object) then
|
|
DeleteEntity(self.object)
|
|
self.object = nil
|
|
end
|
|
|
|
if self.greenBoxCamera then
|
|
Utils.DestroyFlyCam(self.greenBoxCamera)
|
|
self.greenBoxCamera = nil
|
|
end
|
|
|
|
if self.initialPlayerCoords then
|
|
local coords = self.initialPlayerCoords
|
|
SetEntityCoords(cache.ped, coords.x, coords.y, coords.z, false, false, false, false)
|
|
FreezeEntityPosition(cache.ped, false)
|
|
SetEntityAlpha(cache.ped, 255, false)
|
|
self.initialPlayerCoords = nil
|
|
end
|
|
|
|
self.inGreenBox = false
|
|
end
|
|
|
|
AddEventHandler("onResourceStop", function(resourceName)
|
|
if resourceName == GetCurrentResourceName() then
|
|
furnitureCreator:destroyScreenshot()
|
|
end
|
|
end)
|