mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-04 16:23:22 +00:00
ADD - integrate phone housing providers
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
local camera_state = nil
|
||||
|
||||
local function server_prepare(action, data)
|
||||
local request = {
|
||||
action = action,
|
||||
propertyId = data and data.propertyId,
|
||||
target = data and data.target,
|
||||
identifier = data and data.identifier,
|
||||
}
|
||||
return Bridge.Callbacks.Trigger("sky_phone:housing:prepare", request)
|
||||
end
|
||||
|
||||
local function suspend_phone()
|
||||
SetNuiFocus(false, false)
|
||||
TriggerEvent("sky_phone:animation:phone", false)
|
||||
SendNUIMessage({ type = "app:suspend" })
|
||||
end
|
||||
|
||||
local function resume_phone()
|
||||
SendNUIMessage({ type = "app:resume" })
|
||||
SetNuiFocus(true, true)
|
||||
TriggerEvent("sky_phone:animation:phone", true)
|
||||
end
|
||||
|
||||
local function stop_camera()
|
||||
local state = camera_state
|
||||
if not state then
|
||||
return
|
||||
end
|
||||
camera_state = nil
|
||||
RenderScriptCams(false, true, 350, true, true)
|
||||
if state.camera and DoesCamExist(state.camera) then
|
||||
DestroyCam(state.camera, false)
|
||||
end
|
||||
ClearFocus()
|
||||
SetNightvision(state.night_vision)
|
||||
if DoesEntityExist(state.ped) then
|
||||
FreezeEntityPosition(state.ped, state.frozen)
|
||||
end
|
||||
resume_phone()
|
||||
end
|
||||
|
||||
local function camera_number(value, fallback)
|
||||
local number = tonumber(value)
|
||||
if not number or number ~= number or number == math.huge or number == -math.huge then
|
||||
return fallback
|
||||
end
|
||||
return number
|
||||
end
|
||||
|
||||
local function run_camera(provider_name, camera_data)
|
||||
if camera_state or type(camera_data) ~= "table"
|
||||
or type(camera_data.coords) ~= "table"
|
||||
or type(camera_data.rotation) ~= "table"
|
||||
then
|
||||
return
|
||||
end
|
||||
local coords = {
|
||||
x = camera_number(camera_data.coords.x),
|
||||
y = camera_number(camera_data.coords.y),
|
||||
z = camera_number(camera_data.coords.z),
|
||||
}
|
||||
local rotation = {
|
||||
x = camera_number(camera_data.rotation.x),
|
||||
y = camera_number(camera_data.rotation.y, 0.0),
|
||||
z = camera_number(camera_data.rotation.z),
|
||||
}
|
||||
if not coords.x or not coords.y or not coords.z or not rotation.x or not rotation.z then
|
||||
Bridge.Debug("error", "[sky_phone] Rejected invalid housing camera data.")
|
||||
return
|
||||
end
|
||||
|
||||
local config = Config.Housing.Camera
|
||||
local ped = PlayerPedId()
|
||||
local camera = CreateCamWithParams(
|
||||
"DEFAULT_SCRIPTED_CAMERA",
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z,
|
||||
rotation.x,
|
||||
rotation.y,
|
||||
rotation.z,
|
||||
config.FieldOfView,
|
||||
true,
|
||||
2
|
||||
)
|
||||
if not camera or camera == 0 then
|
||||
Bridge.Debug("error", "[sky_phone] Failed to create housing camera.")
|
||||
return
|
||||
end
|
||||
|
||||
camera_state = {
|
||||
camera = camera,
|
||||
frozen = IsEntityPositionFrozen(ped),
|
||||
night_vision = GetUsingnightvision(),
|
||||
ped = ped,
|
||||
provider = provider_name,
|
||||
}
|
||||
suspend_phone()
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetFocusArea(coords.x, coords.y, coords.z, 0.0, 0.0, 0.0)
|
||||
SetCamActive(camera, true)
|
||||
RenderScriptCams(true, true, 350, true, true)
|
||||
|
||||
local maximum_left = camera_number(camera_data.maximumLeft)
|
||||
local maximum_right = camera_number(camera_data.maximumRight)
|
||||
local night_vision = camera_state.night_vision
|
||||
while camera_state and camera_state.camera == camera do
|
||||
Wait(0)
|
||||
DisableAllControlActions(0)
|
||||
if IsDisabledControlJustPressed(0, config.ExitControl)
|
||||
or IsPedDeadOrDying(ped, true)
|
||||
or GetResourceState(provider_name) ~= "started"
|
||||
then
|
||||
break
|
||||
end
|
||||
|
||||
local camera_rotation = GetCamRot(camera, 2)
|
||||
local next_x = camera_rotation.x
|
||||
local next_z = camera_rotation.z
|
||||
if IsDisabledControlPressed(0, config.LeftControl)
|
||||
and (not maximum_left or next_z < maximum_left)
|
||||
then
|
||||
next_z = next_z + config.RotateSpeed
|
||||
elseif IsDisabledControlPressed(0, config.RightControl)
|
||||
and (not maximum_right or next_z > maximum_right)
|
||||
then
|
||||
next_z = next_z - config.RotateSpeed
|
||||
end
|
||||
if IsDisabledControlPressed(0, config.UpControl) then
|
||||
next_x = math.min(85.0, next_x + config.RotateSpeed)
|
||||
elseif IsDisabledControlPressed(0, config.DownControl) then
|
||||
next_x = math.max(-85.0, next_x - config.RotateSpeed)
|
||||
end
|
||||
if next_x ~= camera_rotation.x or next_z ~= camera_rotation.z then
|
||||
SetCamRot(camera, next_x, camera_rotation.y, next_z, 2)
|
||||
end
|
||||
|
||||
local field_of_view = GetCamFov(camera)
|
||||
if IsDisabledControlJustPressed(0, config.ZoomInControl) then
|
||||
SetCamFov(camera, math.max(config.MinimumFieldOfView, field_of_view - 3.0))
|
||||
elseif IsDisabledControlJustPressed(0, config.ZoomOutControl) then
|
||||
SetCamFov(camera, math.min(config.MaximumFieldOfView, field_of_view + 3.0))
|
||||
end
|
||||
if IsDisabledControlJustPressed(0, config.NightVisionControl) then
|
||||
night_vision = not night_vision
|
||||
SetNightvision(night_vision)
|
||||
end
|
||||
end
|
||||
stop_camera()
|
||||
end
|
||||
|
||||
RegisterNUICallback("housing:overview", function(_, cb)
|
||||
local result = Bridge.Callbacks.Trigger("sky_phone:housing:overview", {})
|
||||
cb(result or { success = false, error = "request_failed" })
|
||||
end)
|
||||
|
||||
RegisterNUICallback("housing:key-candidates", function(data, cb)
|
||||
if type(data) ~= "table" or type(data.propertyId) ~= "string" then
|
||||
cb({ success = false, error = "invalid_request" })
|
||||
return
|
||||
end
|
||||
local result = server_prepare("key_candidates", data)
|
||||
cb(result or { success = false, error = "request_failed" })
|
||||
end)
|
||||
|
||||
RegisterNUICallback("housing:command", function(data, cb)
|
||||
if type(data) ~= "table" or type(data.action) ~= "string" or type(data.propertyId) ~= "string" then
|
||||
cb({ success = false, error = "invalid_request" })
|
||||
return
|
||||
end
|
||||
local actions = {
|
||||
grant_key = true,
|
||||
open_cctv = true,
|
||||
revoke_key = true,
|
||||
set_waypoint = true,
|
||||
toggle_lock = true,
|
||||
}
|
||||
if not actions[data.action] then
|
||||
cb({ success = false, error = "invalid_action" })
|
||||
return
|
||||
end
|
||||
|
||||
local prepared = server_prepare(data.action, data)
|
||||
if not prepared or not prepared.success or type(prepared.data) ~= "table" then
|
||||
cb(prepared or { success = false, error = "request_failed" })
|
||||
return
|
||||
end
|
||||
if data.action == "set_waypoint" then
|
||||
local coords = prepared.data.coords
|
||||
if type(coords) ~= "table" or not tonumber(coords.x) or not tonumber(coords.y) then
|
||||
cb({ success = false, error = "invalid_coordinates" })
|
||||
return
|
||||
end
|
||||
SetNewWaypoint(tonumber(coords.x) + 0.0, tonumber(coords.y) + 0.0)
|
||||
cb({ success = true })
|
||||
return
|
||||
end
|
||||
if data.action == "open_cctv" then
|
||||
if type(prepared.data.camera) ~= "table" or type(prepared.data.provider) ~= "string" then
|
||||
cb({ success = false, error = "cctv_unavailable" })
|
||||
return
|
||||
end
|
||||
cb({ success = true })
|
||||
CreateThread(function()
|
||||
run_camera(prepared.data.provider, prepared.data.camera)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
local success, error_code = Bridge.Housing.Execute(prepared.data.provider, data.action, prepared.data)
|
||||
cb(success and { success = true } or { success = false, error = error_code or "provider_rejected" })
|
||||
end)
|
||||
|
||||
AddEventHandler("onResourceStop", function(resource_name)
|
||||
if resource_name == GetCurrentResourceName() and camera_state then
|
||||
stop_camera()
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user