forked from zxbc/BAR_widgets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gui_instant_overview.lua
210 lines (175 loc) · 7.46 KB
/
gui_instant_overview.lua
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
function widget:GetInfo()
return {
name = "Overview - No Transition Animation",
desc = "Press and hold 'tab' to instantly switch to a top-down full map overview. Release 'tab' to return to the original view. You can edit param in file to disable hide UI.",
author = "Errrrrrr",
date = "2023",
license = "GNU GPL, v2 or later",
layer = 0,
enabled = true,
}
end
local hide_all_ui = false -- Hide all ui elements when in overview mode
-- Set this to false if you only want to disable minimap, advplayerslist and chat
local oldCamState = nil
local oldIconsState = nil
local oldCamDir = nil
local viewSizeX, viewSizeY, _, _ = Spring.GetViewGeometry()
local aspectRatio = viewSizeX / viewSizeY
local mapRatio = Game.mapSizeX / Game.mapSizeZ
--[[
-- Rotate a vector by an angle around the Y-axis
function rotateVector(vec, angle)
local cos = math.cos(angle)
local sin = math.sin(angle)
return {
cos * vec[1] + sin * vec[3],
vec[2],
-sin * vec[1] + cos * vec[3]
}
end
-- Multiply a vector by a scalar
function multiplyVector(vec, scalar)
return {
vec[1] * scalar,
vec[2] * scalar,
vec[3] * scalar
}
end
-- Add two vectors
function addVectors(vec1, vec2)
return {
vec1[1] + vec2[1],
vec1[2] + vec2[2],
vec1[3] + vec2[3]
}
end
-- Subtract two vectors
function subtractVectors(vec1, vec2)
return {
vec1[1] - vec2[1],
vec1[2] - vec2[2],
vec1[3] - vec2[3]
}
end
local function calculateTrapezoidCorners(camState, dir)
-- Calculate the forward, right, and up vectors
local forward = {dir[1], dir[2], dir[3]}
local right = {dir[3], 0, -dir[1]} -- cross product of dir and up = {0, 1, 0}
local up = {0, 1, 0} -- points straight up in Y
-- normalize direction vectors
local lenForward = math.sqrt(forward[1]*forward[1] + forward[2]*forward[2] + forward[3]*forward[3])
forward[1], forward[2], forward[3] = forward[1]/lenForward, forward[2]/lenForward, forward[3]/lenForward
local lenRight = math.sqrt(right[1]*right[1] + right[2]*right[2] + right[3]*right[3])
right[1], right[2], right[3] = right[1]/lenRight, right[2]/lenRight, right[3]/lenRight
local lenUp = math.sqrt(up[1]*up[1] + up[2]*up[2] + up[3]*up[3])
up[1], up[2], up[3] = up[1]/lenUp, up[2]/lenUp, up[3]/lenUp
local height = camState.height or 0
if height == 0 then height = camState.dist end
local halfWidth = height * math.tan(math.rad(camState.fov / 2)) -- horizontal half-width
local halfHeight = halfWidth / aspectRatio -- vertical half-height (adjusted by the aspect ratio)
-- Calculate the four corners of the trapezoid
local center = {camState.px, camState.py, camState.pz}
local d1 = multiplyVector(up, halfHeight)
local d2 = multiplyVector(right, halfWidth)
local p1 = addVectors(subtractVectors(center, d1), d2)
local p2 = addVectors(addVectors(center, d1), d2)
local p3 = subtractVectors(addVectors(center, d1), d2)
local p4 = subtractVectors(subtractVectors(center, d1), d2)
return p1, p2, p3, p4
end
]]
function widget:KeyPress(key, mods, isRepeat)
if key == Spring.GetKeyCode("tab") then
if not oldCamState then
-- Save the original camera state and icons state
oldCamState = Spring.GetCameraState()
oldIconsState = Spring.GetConfigInt("icons", 1)
-- Save the current camera direction
oldCamDir = {Spring.GetCameraDirection()}
-- Hide the chat using the chat widget's function
if WG['chat'] then
WG['chat'].setHide(true)
end
-- Disable the engine's minimap
Spring.SendCommands("minimap minimize 1")
-- Disable advplayerslist widget
--widgetHandler:DisableWidget('AdvPlayersList')
Spring.SendCommands("luaui disablewidget AdvPlayersList")
if hide_all_ui then
Spring.SendCommands("HideInterface")
end
-- Switch to the custom view
local camState = Spring.GetCameraState()
camState.name = "ta"
camState.mode = 1
camState.px = Game.mapSizeX * 0.5
camState.py = Spring.GetGroundHeight(Game.mapSizeX * 0.5, Game.mapSizeZ * 0.5)
camState.pz = Game.mapSizeZ * 0.5
camState.rx = oldCamState.rx or 0
camState.ry = oldCamState.ry or 0
camState.rz = oldCamState.rz or 0
if mapRatio > aspectRatio then
camState.height = Game.mapSizeX / (2 * math.tan(math.rad(camState.fov / 2)))
else
camState.height = Game.mapSizeZ / (2 * math.tan(math.rad(camState.fov / 2))) * aspectRatio
end
camState.height = camState.height * 0.6
camState.angle = 0.0
Spring.SetCameraState(camState, 0)
Spring.SendCommands("viewicons") -- enable icons
end
return true -- block the event from other widgets or game default functionality
end
return false
end
function widget:KeyRelease(key)
if key == Spring.GetKeyCode("tab") then
if oldCamState then
-- Restore the original camera state and icons state
Spring.SetCameraState(oldCamState, 0)
Spring.SendCommands("icons " .. oldIconsState) -- restore icons state
oldCamState = nil
oldIconsState = nil
oldCamDir = nil
-- Show the chat using the chat widget's function
if WG['chat'] then
WG['chat'].setHide(false)
end
-- Re-enable the engine's minimap
Spring.SendCommands("minimap minimize 0")
-- Re-enable advplayerslist widget
--widgetHandler:EnableWidget('AdvPlayersList')
Spring.SendCommands("luaui enablewidget AdvPlayersList")
if hide_all_ui then
Spring.SendCommands("HideInterface")
end
end
return true -- block the event from other widgets or game default functionality
end
return false
end
function widget:DrawWorld()
if oldCamState then
-- Calculate the previous camera's position
local px, py, pz = oldCamState.px, oldCamState.py, oldCamState.pz
-- Setup circle parameters
local maxRadius = oldCamState.height or 0
if maxRadius == nil then maxRadius = oldCamState.dist or 0 end -- maximum radius of the circle is now the camera's height
if maxRadius == 0 then maxRadius = 1000
else maxRadius = maxRadius / 2 end -- if the camera's height is 0, set the maximum radius to 1000
local shrinkTime = 0.5 -- how long it takes for the circle to shrink to the center, halved for a faster shrink
local pauseTime = 1 -- pause time in seconds between each shrink
-- Draw the pulsing circle
gl.Color(0, 1, 0, 1) -- green color
-- Calculate a shrinking radius
local time = Spring.GetGameSeconds()
local phase = time % (shrinkTime + pauseTime) -- phase of the shrink-pause cycle
if phase < shrinkTime then -- during the shrinking animation
local radius = (1 - phase / shrinkTime) * maxRadius
-- Draw the circle
gl.DrawGroundCircle(px, py, pz, radius, 128) -- 128 is the number of vertices, adjust for performance
end
gl.Color(1, 1, 1, 1) -- reset color to white
end
end