Files
sky_phone-sky-systems/tests/client_camera.lua
T
Leon.Schmidt 30559048fd FIX - complete LB custom app compatibility (#11)
* FIX - preserve LB custom app lifecycle

* FIX - reset LB export aliases before startup

* FIX - report competing custom app providers

* FIX - identify LB app frames as live NUI

* FIX - complete LB custom app compatibility

* FIX - provide LB PicChat runtime exports

* FIX - route LB PicChat through Sky Phone

* FIX - return cached LB equipped phone number

* FIX - harden PicChat compatibility migration

* ENH - complete modular phone provider and Creator APIs

* DOC - document the Sky Phone Creator API

---------

Co-authored-by: DerEchteAlec <bycraky@gmail.com>
Co-authored-by: DerEchteAlec <alec.schitzkat@luwan.io>
2026-08-20 18:19:16 +02:00

152 lines
5.0 KiB
Lua

local callbacks = {}
local camera_coord = nil
local camera_target = nil
local camera_created = false
local camera_destroyed = false
local scripted_camera_rendering = false
local vector_meta = {}
vector_meta.__index = vector_meta
function vector_meta.__add(left, right)
return vector3(left.x + right.x, left.y + right.y, left.z + right.z)
end
function vector_meta.__sub(left, right)
return vector3(left.x - right.x, left.y - right.y, left.z - right.z)
end
function vector_meta.__mul(left, right)
if type(left) == "number" then
left, right = right, left
end
return vector3(left.x * right, left.y * right, left.z * right)
end
function vector3(x, y, z)
return setmetatable({ x = x, y = y, z = z }, vector_meta)
end
function RegisterNUICallback(name, callback)
callbacks[name] = callback
end
function RegisterNetEvent() end
function AddEventHandler() end
function TriggerEvent() end
function TriggerServerEvent() end
function SendNUIMessage() end
function CreateThread() end
function Wait() end
function PlayerPedId() return 7 end
function PlayerId() return 8 end
function GetFollowPedCamViewMode() return 1 end
function GetFollowVehicleCamViewMode() return 2 end
function IsRadarHidden() return false end
function DisplayRadar() end
function SetFollowPedCamViewMode() end
function SetFollowVehicleCamViewMode() end
function IsPedInAnyVehicle() return false end
function DisableControlAction() end
function DisablePlayerFiring() end
function HideHudAndRadarThisFrame() end
function GetCurrentResourceName() return "sky_phone" end
function GetEntityCoords()
return vector3(10.0, 20.0, 1.0)
end
function GetPedBoneCoords()
return vector3(10.0, 20.0, 2.7)
end
function GetEntityForwardVector()
return vector3(0.0, 1.0, 0.0)
end
function CreateCam(name, active)
assert(name == "DEFAULT_SCRIPTED_CAMERA" and active, "selfie camera must be created active")
camera_created = true
camera_destroyed = false
return 73
end
function DoesCamExist(handle)
return camera_created and not camera_destroyed and handle == 73
end
function SetCamFov() end
function SetCamActive() end
function RenderScriptCams(active)
scripted_camera_rendering = active
end
function SetCamCoord(_, x, y, z)
camera_coord = vector3(x, y, z)
end
function PointCamAtCoord(_, x, y, z)
camera_target = vector3(x, y, z)
end
function DestroyCam(handle)
assert(handle == 73, "the selfie camera handle must be destroyed")
camera_destroyed = true
end
local function response_from(name, data)
local response = nil
callbacks[name](data, function(value)
response = value
end)
return response
end
local function close_enough(actual, expected)
return math.abs(actual - expected) < 0.0001
end
dofile("sky_phone/source/client/camera.lua")
assert(response_from("camera:setActive", { active = true }).success)
assert(response_from("camera:setFacing", { front = true }).success)
assert(camera_created and scripted_camera_rendering, "selfie mode must render a scripted camera")
assert(camera_coord and camera_target, "selfie mode must position and aim the camera")
assert(close_enough(camera_coord.x, 10.0))
assert(close_enough(camera_coord.y, 21.05))
assert(close_enough(camera_coord.z, 2.75))
assert(close_enough(camera_target.x, 10.0))
assert(close_enough(camera_target.y, 20.0))
assert(close_enough(camera_target.z, 2.73))
assert(response_from("camera:setFacing", { front = false }).success)
assert(camera_destroyed and not scripted_camera_rendering, "rear mode must release the selfie camera")
assert(type(SkyPhoneCamera.EnableWalkable) == "function", "walkable camera enable seam must exist")
assert(type(SkyPhoneCamera.DisableWalkable) == "function", "walkable camera disable seam must exist")
assert(type(SkyPhoneCamera.SetSelfie) == "function", "selfie camera seam must exist")
assert(type(SkyPhoneCamera.ToggleFrozen) == "function", "frozen camera seam must exist")
assert(type(SkyPhoneCamera.SetFlashlight) == "function", "flashlight seam must exist")
assert(type(SkyPhoneCamera.GetState) == "function", "camera state seam must exist")
SkyPhoneCamera.SetFlashlight(true)
assert(SkyPhoneCamera.GetState().flashEnabled, "flashlight state must report enabled")
SkyPhoneCamera.SetFlashlight(false)
assert(not SkyPhoneCamera.GetState().flashEnabled, "flashlight state must report disabled")
SkyPhoneCamera.EnableWalkable(true)
local walkable_state = SkyPhoneCamera.GetState()
assert(walkable_state.walkable, "walkable camera must report enabled")
assert(walkable_state.selfie, "walkable camera must preserve selfie mode")
assert(walkable_state.active, "walkable camera must open the camera")
SkyPhoneCamera.SetSelfie(false)
assert(not SkyPhoneCamera.GetState().selfie, "selfie camera must switch back to rear mode")
SkyPhoneCamera.ToggleFrozen()
SkyPhoneCamera.DisableWalkable()
local closed_state = SkyPhoneCamera.GetState()
assert(not closed_state.walkable, "walkable camera must report disabled")
assert(not closed_state.active, "walkable camera disable must close the camera")
print("Client camera tests passed")