mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-28 23:01:37 +00:00
FIX - restore camera input and configurator warning (#30)
* FIX - honor configured camera look control Camera focus was owned by hard-coded Space DOM handlers, bypassing Config.Phone.HoldToLook. Move focus input to the FiveM client and add a bounded scripted-camera orbit so selfie mode can rotate while the configured control is held. * FIX - preserve camera movement passthrough * FIX - restore Phone Configurator startup warning * FIX - keep camera modifier input readable
This commit is contained in:
+63
-5
@@ -4,6 +4,20 @@ local camera_target = nil
|
||||
local camera_created = false
|
||||
local camera_destroyed = false
|
||||
local scripted_camera_rendering = false
|
||||
local event_handlers = {}
|
||||
local threads = {}
|
||||
local hold_to_look_pressed = false
|
||||
local disabled_controls = {}
|
||||
local disabled_pressed_controls = {}
|
||||
local disabled_control_normals = {}
|
||||
local triggered_events = {}
|
||||
local thread_stop = {}
|
||||
|
||||
SkyPhoneFocus = {
|
||||
IsHoldToLookPressed = function()
|
||||
return hold_to_look_pressed
|
||||
end,
|
||||
}
|
||||
|
||||
local vector_meta = {}
|
||||
vector_meta.__index = vector_meta
|
||||
@@ -32,12 +46,20 @@ function RegisterNUICallback(name, callback)
|
||||
end
|
||||
|
||||
function RegisterNetEvent() end
|
||||
function AddEventHandler() end
|
||||
function TriggerEvent() end
|
||||
function AddEventHandler(name, callback)
|
||||
event_handlers[name] = callback
|
||||
end
|
||||
function TriggerEvent(name, data)
|
||||
triggered_events[#triggered_events + 1] = { name = name, data = data }
|
||||
end
|
||||
function TriggerServerEvent() end
|
||||
function SendNUIMessage() end
|
||||
function CreateThread() end
|
||||
function Wait() end
|
||||
function CreateThread(callback)
|
||||
threads[#threads + 1] = callback
|
||||
end
|
||||
function Wait()
|
||||
error(thread_stop, 0)
|
||||
end
|
||||
function PlayerPedId() return 7 end
|
||||
function PlayerId() return 8 end
|
||||
function GetFollowPedCamViewMode() return 1 end
|
||||
@@ -47,10 +69,19 @@ function DisplayRadar() end
|
||||
function SetFollowPedCamViewMode() end
|
||||
function SetFollowVehicleCamViewMode() end
|
||||
function IsPedInAnyVehicle() return false end
|
||||
function DisableControlAction() end
|
||||
function DisableControlAction(group, control, disabled)
|
||||
assert(group == 0 and disabled, "camera controls must be disabled in the primary input group")
|
||||
disabled_controls[control] = true
|
||||
end
|
||||
function DisablePlayerFiring() end
|
||||
function HideHudAndRadarThisFrame() end
|
||||
function GetCurrentResourceName() return "sky_phone" end
|
||||
function IsDisabledControlJustPressed() return false end
|
||||
function IsDisabledControlPressed(group, control)
|
||||
assert(group == 0, "camera passthrough must read the primary input group")
|
||||
return disabled_pressed_controls[control] == true
|
||||
end
|
||||
function GetDisabledControlNormal(_, control) return disabled_control_normals[control] or 0.0 end
|
||||
|
||||
function GetEntityCoords()
|
||||
return vector3(10.0, 20.0, 1.0)
|
||||
@@ -120,6 +151,33 @@ assert(close_enough(camera_target.x, 10.0))
|
||||
assert(close_enough(camera_target.y, 20.0))
|
||||
assert(close_enough(camera_target.z, 2.73))
|
||||
|
||||
event_handlers["sky_phone:client:cameraFocusApplied"]({
|
||||
active = true,
|
||||
cursor = false,
|
||||
focused = true,
|
||||
gameInput = true,
|
||||
})
|
||||
disabled_pressed_controls[22] = true
|
||||
disabled_control_normals[1] = 0.2
|
||||
local watcher_ok, watcher_error = pcall(threads[2])
|
||||
assert(not watcher_ok and watcher_error == thread_stop, "camera watcher must run one controlled frame")
|
||||
local camera_focus_event = triggered_events[#triggered_events]
|
||||
assert(
|
||||
camera_focus_event.name == "sky_phone:client:setCameraFocus"
|
||||
and camera_focus_event.data.active
|
||||
and not camera_focus_event.data.nuiFocused,
|
||||
"holding Space must release the camera cursor for simultaneous look and movement"
|
||||
)
|
||||
for _, control in ipairs({ 30, 31, 32, 33, 34, 35 }) do
|
||||
assert(not disabled_controls[control], ("camera passthrough must preserve movement control %d"):format(control))
|
||||
end
|
||||
local camera_ok, camera_error = pcall(threads[1])
|
||||
assert(not camera_ok and camera_error == thread_stop, "selfie camera must render one controlled frame")
|
||||
assert(not close_enough(camera_coord.x, 10.0), "horizontal look input must orbit the selfie camera around the player")
|
||||
assert(camera_coord.y < 21.05, "selfie orbit must retain its configured distance from the player")
|
||||
disabled_pressed_controls[22] = false
|
||||
disabled_control_normals[1] = 0.0
|
||||
|
||||
assert(response_from("camera:setFacing", { front = false }).success)
|
||||
assert(camera_destroyed and not scripted_camera_rendering, "rear mode must release the selfie camera")
|
||||
|
||||
|
||||
+57
-3
@@ -5,6 +5,9 @@ local event_handlers = {}
|
||||
local nui_callbacks = {}
|
||||
local nui_focus = nil
|
||||
local nui_keep_input = nil
|
||||
local pressed_controls = {}
|
||||
local disabled_pressed_controls = {}
|
||||
local triggered_events = {}
|
||||
|
||||
Config = {
|
||||
Phone = {
|
||||
@@ -34,7 +37,19 @@ function SetNuiFocusKeepInput(keep_input)
|
||||
nui_keep_input = keep_input
|
||||
end
|
||||
|
||||
function TriggerEvent() end
|
||||
function TriggerEvent(name, data)
|
||||
triggered_events[#triggered_events + 1] = { name = name, data = data }
|
||||
end
|
||||
|
||||
function IsControlPressed(group, control)
|
||||
assert(group == 0, "HoldToLook must read the primary input group")
|
||||
return pressed_controls[control] == true
|
||||
end
|
||||
|
||||
function IsDisabledControlPressed(group, control)
|
||||
assert(group == 0, "HoldToLook must read disabled controls from the primary input group")
|
||||
return disabled_pressed_controls[control] == true
|
||||
end
|
||||
|
||||
function DisableControlAction(group, control, disabled)
|
||||
assert(group == 0 and disabled, "phone controls must be disabled in the primary input group")
|
||||
@@ -56,6 +71,25 @@ end
|
||||
|
||||
dofile("sky_phone/source/client/focus.lua")
|
||||
|
||||
assert(not SkyPhoneFocus.IsHoldToLookPressed(), "HoldToLook must be idle until its configured control is held")
|
||||
pressed_controls[19] = true
|
||||
assert(SkyPhoneFocus.IsHoldToLookPressed(), "HoldToLook must read its configured active control")
|
||||
pressed_controls[19] = false
|
||||
Config.Phone.HoldToLook.Control = 38
|
||||
event_handlers["sky_phone:configurator:updated"]()
|
||||
disabled_pressed_controls[38] = true
|
||||
assert(
|
||||
SkyPhoneFocus.IsHoldToLookPressed(),
|
||||
"HoldToLook must read its configured control while NUI focus has disabled GTA input"
|
||||
)
|
||||
disabled_pressed_controls[38] = false
|
||||
Config.Phone.HoldToLook.Enabled = false
|
||||
event_handlers["sky_phone:configurator:updated"]()
|
||||
assert(not SkyPhoneFocus.IsHoldToLookPressed(), "disabled HoldToLook must reject every control state")
|
||||
Config.Phone.HoldToLook.Enabled = true
|
||||
Config.Phone.HoldToLook.Control = 19
|
||||
event_handlers["sky_phone:configurator:updated"]()
|
||||
|
||||
local function resolve(overrides)
|
||||
local state = {
|
||||
activity_suspended = false,
|
||||
@@ -233,6 +267,9 @@ disabled_controls = {}
|
||||
firing_disabled = false
|
||||
SkyPhoneFocus.ApplyGameInputControls(false)
|
||||
assert(not disabled_controls[1] and not disabled_controls[2], "camera passthrough must preserve camera look")
|
||||
for _, control in ipairs({ 30, 31, 32, 33, 34, 35 }) do
|
||||
assert(not disabled_controls[control], ("camera passthrough must preserve movement control %d"):format(control))
|
||||
end
|
||||
assert(firing_disabled, "player attacks must remain disabled during camera passthrough")
|
||||
|
||||
local movable_notification = resolve({ allow_movement = true, notification_focus = true })
|
||||
@@ -264,11 +301,28 @@ local focused_camera = resolve({
|
||||
assert(
|
||||
focused_camera.cursor
|
||||
and focused_camera.focused
|
||||
and not focused_camera.keep_input
|
||||
and focused_camera.keep_input
|
||||
and not focused_camera.game_input,
|
||||
"focused camera must override movement configuration until Space enables passthrough"
|
||||
"focused camera must forward readable input while blocking game actions until passthrough is held"
|
||||
)
|
||||
|
||||
event_handlers["sky_phone:client:setCameraFocus"]({ active = true, nuiFocused = true })
|
||||
local focused_camera_event = triggered_events[#triggered_events]
|
||||
assert(
|
||||
nui_focus.focused and nui_focus.cursor and nui_keep_input
|
||||
and focused_camera_event.name == "sky_phone:client:cameraFocusApplied"
|
||||
and not focused_camera_event.data.gameInput,
|
||||
"focused camera must keep controls readable without reporting movement passthrough"
|
||||
)
|
||||
event_handlers["sky_phone:client:setCameraFocus"]({ active = true, nuiFocused = false })
|
||||
local passthrough_camera_event = triggered_events[#triggered_events]
|
||||
assert(
|
||||
nui_focus.focused and not nui_focus.cursor and nui_keep_input
|
||||
and passthrough_camera_event.data.gameInput,
|
||||
"camera passthrough must apply keyboard focus without a cursor and keep GTA input enabled"
|
||||
)
|
||||
event_handlers["sky_phone:client:setCameraFocus"]({ active = false, nuiFocused = true })
|
||||
|
||||
local camera_interrupted_by_call = resolve({
|
||||
call_focus = true,
|
||||
camera_active = true,
|
||||
|
||||
Reference in New Issue
Block a user