File size: 5,505 Bytes
b6a38d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
--- Initializes the camera lock and unlock reason tables when the game is first loaded.
-- This ensures the camera lock state is properly reset when a new map is loaded.
if FirstLoad then
    s_CameraLockReasons = {}
    s_CameraUnlockReasons = {}
end

---
--- Locks the camera with the given reason.
--- If the camera was not previously locked, sends the "OnLockCamera" message.
---
--- @param reason string|boolean The reason for locking the camera. If not provided, defaults to `false`.
function LockCamera(reason)
    local locked = IsCameraLocked()
    s_CameraLockReasons[reason or false] = true
    UpdateCameraLock()
    if locked ~= IsCameraLocked() then
        Msg("OnLockCamera")
    end
end

---
--- Unlocks the camera with the given reason.
--- If the camera was previously locked, sends the "OnLockCamera" message.
---
--- @param reason string|boolean The reason for unlocking the camera. If not provided, defaults to `false`.
function UnlockCamera(reason)
    s_CameraLockReasons[reason or false] = nil
    UpdateCameraLock()
end

---
--- Forces the camera to be unlocked with the given reason.
--- If the camera was previously locked, sends the "OnLockCamera" message.
---
--- @param reason string|boolean The reason for unlocking the camera. If not provided, defaults to `false`.
function ForceUnlockCameraStart(reason)
    s_CameraUnlockReasons[reason or false] = true
    UpdateCameraLock()
end

---
--- Removes the given reason for forcibly unlocking the camera.
--- If the camera was previously locked, sends the "OnLockCamera" message.
---
--- @param reason string|boolean The reason for forcibly unlocking the camera. If not provided, defaults to `false`.
function ForceUnlockCameraEnd(reason)
    s_CameraUnlockReasons[reason or false] = nil
    UpdateCameraLock()
end

---
--- Resets the camera lock state when a new map is loaded.
---
--- This function is called in response to the `ChangeMap` message, and ensures that the
--- camera lock state is properly reset when a new map is loaded. It clears the
--- `s_CameraLockReasons` and `s_CameraUnlockReasons` tables, and then calls `UpdateCameraLock()`
--- to update the camera lock state.
---
--- @function OnMsg.ChangeMap
--- @return nil
function OnMsg.ChangeMap()
    s_CameraLockReasons = {}
    s_CameraUnlockReasons = {}
    UpdateCameraLock()
end

---
--- Updates the camera lock state based on the current lock and unlock reasons.
---
--- If there are any active unlock reasons, or no active lock reasons, the camera is unlocked.
--- Otherwise, the camera is locked.
---
--- This function is called whenever the lock or unlock reasons change, to ensure the camera
--- lock state is up-to-date.
---
--- @function UpdateCameraLock
--- @return nil
function UpdateCameraLock()
    if next(s_CameraUnlockReasons) or next(s_CameraLockReasons) == nil then
        camera.Unlock(1)
    else
        camera.Lock(1)
    end
end

---
--- Checks if the camera is currently locked.
---
--- If no reason is provided, this function returns `true` if the camera is locked for any reason.
--- If a reason is provided, this function returns `true` if the camera is locked for that specific reason.
---
--- @param reason string|boolean The reason to check for. If not provided, the function checks if the camera is locked for any reason.
--- @return boolean `true` if the camera is locked, `false` otherwise.
function IsCameraLocked(reason)
    if not reason then
        return next(s_CameraLockReasons) ~= nil
    end
    for r, _ in pairs(s_CameraLockReasons) do
        if r == reason then
            return true
        end
    end
    return false
end

---
--- Unlocks the mouse when the camera is locked, to prevent the game from entering an unresponsive state when opening a dialog during camera rotation.
---
--- This function is called in response to the `OnMsg.OnLockCamera` message, which is triggered when the camera is locked.
---
--- @function OnMsg.OnLockCamera
--- @return nil
function OnMsg.OnLockCamera()
    SetMouseDeltaMode(false)
end
function OnMsg.OnLockCamera() -- free mouse when locking camera (ex. don't leave unresponsive game state when opening a dialog during camera rotation)
    SetMouseDeltaMode(false)
end

---
--- Prints the camera lock reasons.
---
--- @param reasons table The table of camera lock reasons.
--- @param print_func function The print function to use.
--- @param indent string The indentation to use for each line.
---
local function _PrintCameraLockReasons(reasons, print_func, indent)
    print_func = print_func or print
    for reason in pairs(reasons) do
        print_func(indent, type(reason) == "table" and reason.class or tostring(reason))
    end
end

---
--- Prints the active camera lock and unlock reasons when a bug report is started.
---
--- This function is called in response to the `OnMsg.BugReportStart` message, which is triggered when a bug report is started.
---
--- @function OnMsg.BugReportStart
--- @param print_func function The print function to use for printing the camera lock and unlock reasons.
--- @return nil
function OnMsg.BugReportStart(print_func)
    if next(s_CameraLockReasons) ~= nil then
        print_func("Active camera lock reasons:")
        _PrintCameraLockReasons(s_CameraLockReasons, print_func, "\t")
        print_func("")
    end
    if next(s_CameraUnlockReasons) ~= nil then
        print_func("Active camera unlock reasons:")
        _PrintCameraLockReasons(s_CameraUnlockReasons, print_func, "\t")
        print_func("")
    end
end