SyntaxGameServer/RCCService2021/ExtraContent/scripts/PlayerScripts/StarterPlayerScripts/CameraScript/ShiftLockController.lua

207 lines
5.7 KiB
Lua

--[[
// FileName: ShiftLockController
// Written by: jmargh
// Version 1.2
// Description: Manages the state of shift lock mode
// Required by:
RootCamera
// Note: ContextActionService sinks keys, so until we allow binding to ContextActionService without sinking
// keys, this module will use UserInputService.
--]]
local Players = game:GetService('Players')
local UserInputService = game:GetService('UserInputService')
-- Settings and GameSettings are read only
local Settings = UserSettings() -- ignore warning
local GameSettings = Settings.GameSettings
local ShiftLockController = {}
--[[ Script Variables ]]--
while not Players.LocalPlayer do
Players.PlayerAdded:wait()
end
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local PlayerGui = LocalPlayer:WaitForChild('PlayerGui')
local ScreenGui = nil
local ShiftLockIcon = nil
local InputCn = nil
local IsShiftLockMode = false
local IsShiftLocked = false
local IsActionBound = false
local IsInFirstPerson = false
-- Toggle Event
ShiftLockController.OnShiftLockToggled = Instance.new('BindableEvent')
-- wrapping long conditional in function
local function isShiftLockMode()
return LocalPlayer.DevEnableMouseLock and GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch and
LocalPlayer.DevComputerMovementMode ~= Enum.DevComputerMovementMode.ClickToMove and
GameSettings.ComputerMovementMode ~= Enum.ComputerMovementMode.ClickToMove and
LocalPlayer.DevComputerMovementMode ~= Enum.DevComputerMovementMode.Scriptable
end
if not UserInputService.TouchEnabled then -- TODO: Remove when safe on mobile
IsShiftLockMode = isShiftLockMode()
end
--[[ Constants ]]--
local SHIFT_LOCK_OFF = 'rbxasset://textures/ui/mouseLock_off.png'
local SHIFT_LOCK_ON = 'rbxasset://textures/ui/mouseLock_on.png'
local SHIFT_LOCK_CURSOR = 'rbxasset://textures/MouseLockedCursor.png'
--[[ Local Functions ]]--
local function onShiftLockToggled()
IsShiftLocked = not IsShiftLocked
if IsShiftLocked then
ShiftLockIcon.Image = SHIFT_LOCK_ON
Mouse.Icon = SHIFT_LOCK_CURSOR
else
ShiftLockIcon.Image = SHIFT_LOCK_OFF
Mouse.Icon = ""
end
ShiftLockController.OnShiftLockToggled:Fire()
end
local function initialize()
if ScreenGui then
ScreenGui:Destroy()
ScreenGui = nil
end
ScreenGui = Instance.new('ScreenGui')
ScreenGui.Name = "ControlGui"
local frame = Instance.new('Frame')
frame.Name = "BottomLeftControl"
frame.Size = UDim2.new(0, 130, 0, 46)
frame.Position = UDim2.new(0, 0, 1, -46)
frame.BackgroundTransparency = 1
frame.Parent = ScreenGui
ShiftLockIcon = Instance.new('ImageButton')
ShiftLockIcon.Name = "MouseLockLabel"
ShiftLockIcon.Size = UDim2.new(0, 31, 0, 31)
ShiftLockIcon.Position = UDim2.new(0, 12, 0, 2)
ShiftLockIcon.BackgroundTransparency = 1
ShiftLockIcon.Image = IsShiftLocked and SHIFT_LOCK_ON or SHIFT_LOCK_OFF
ShiftLockIcon.Visible = true
ShiftLockIcon.Parent = frame
ShiftLockIcon.MouseButton1Click:connect(onShiftLockToggled)
ScreenGui.Parent = IsShiftLockMode and PlayerGui or nil
end
--[[ Public API ]]--
function ShiftLockController:IsShiftLocked()
return IsShiftLockMode and IsShiftLocked
end
function ShiftLockController:SetIsInFirstPerson(isInFirstPerson)
IsInFirstPerson = isInFirstPerson
end
--[[ Input/Settings Changed Events ]]--
local mouseLockSwitchFunc = function(actionName, inputState, inputObject)
if IsShiftLockMode then
onShiftLockToggled()
end
end
local function disableShiftLock()
if ScreenGui then ScreenGui.Parent = nil end
IsShiftLockMode = false
Mouse.Icon = ""
if InputCn then
InputCn:disconnect()
InputCn = nil
end
IsActionBound = false
ShiftLockController.OnShiftLockToggled:Fire()
end
-- TODO: Remove when we figure out ContextActionService without sinking keys
local function onShiftInputBegan(inputObject, isProcessed)
if isProcessed then return end
if inputObject.UserInputType == Enum.UserInputType.Keyboard and
(inputObject.KeyCode == Enum.KeyCode.LeftShift or inputObject.KeyCode == Enum.KeyCode.RightShift) then
--
mouseLockSwitchFunc()
end
end
local function enableShiftLock()
IsShiftLockMode = isShiftLockMode()
if IsShiftLockMode then
if ScreenGui then
ScreenGui.Parent = PlayerGui
end
if IsShiftLocked then
Mouse.Icon = SHIFT_LOCK_CURSOR
ShiftLockController.OnShiftLockToggled:Fire()
end
if not IsActionBound then
InputCn = UserInputService.InputBegan:connect(onShiftInputBegan)
IsActionBound = true
end
end
end
GameSettings.Changed:connect(function(property)
if property == 'ControlMode' then
if GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch then
enableShiftLock()
else
disableShiftLock()
end
elseif property == 'ComputerMovementMode' then
if GameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove then
disableShiftLock()
else
enableShiftLock()
end
end
end)
LocalPlayer.Changed:connect(function(property)
if property == 'DevEnableMouseLock' then
if LocalPlayer.DevEnableMouseLock then
enableShiftLock()
else
disableShiftLock()
end
elseif property == 'DevComputerMovementMode' then
if LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.ClickToMove or
LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.Scriptable then
--
disableShiftLock()
else
enableShiftLock()
end
end
end)
LocalPlayer.CharacterAdded:connect(function(character)
-- we need to recreate guis on character load
if not UserInputService.TouchEnabled then
initialize()
end
end)
--[[ Initialization ]]--
-- TODO: Remove when safe! ContextActionService crashes touch clients with tupele is 2 or more
if not UserInputService.TouchEnabled then
initialize()
if isShiftLockMode() then
InputCn = UserInputService.InputBegan:connect(onShiftInputBegan)
IsActionBound = true
end
end
return ShiftLockController