source: trunk/luaui/widgets/gui_easyFacing.lua @ 3505

Revision 3505, 9.9 KB checked in by Bluestone, 5 years ago (diff)

fix easy facing and build split trying to use meta in the same context - fixes build split having no effect if easy facing was enabled
easy facing requires the middle mouse button (instead of meta)

Line 
1include("keysym.h.lua")
2local versionNumber = "1.5"
3
4function widget:GetInfo()
5        return {
6                name      = "Easy Facing",
7                desc      = "[v" .. string.format("%s", versionNumber ) .. "] Enables changing building facing by holding left mouse button. Press (META) to change facing when using shift.",
8                author    = "very_bad_soldier",
9                date      = "2009.08.10",
10                license   = "GNU GPL v2",
11                layer     = 0,
12                enabled   = false
13        }
14end
15
16--1.1 Tweaks by Pako, big thx!
17
18-- CONFIGURATION
19local debug = false
20local updateInt = 1 --seconds for the ::update loop
21local sens = 150        --rotate mouse sensitivity - length of mouse movement vector
22local drawForAll = false --draw facing direction also for other buildings than labs
23--------------------------------------------------------------------------------
24local inDrag = false
25local mmbStart = false
26local mouseDeltaX = 0
27local mouseDeltaY = 0
28local mouseXStartRotate = 0
29local mouseYStartRotate = 0
30local mouseXStartDrag = 0
31local mouseYStartDrag = 0
32local mouseLbLast = false
33-------------------------------------------------------------------------------
34local udefTab                           = UnitDefs
35
36local spGetActiveCommand        = Spring.GetActiveCommand
37local spGetKeyState         = Spring.GetKeyState
38local spGetModKeyState      = Spring.GetModKeyState
39local spGetSelectedUnits    = Spring.GetSelectedUnits
40local spGetUnitDefID        = Spring.GetUnitDefID
41local spGetUnitPosition     = Spring.GetUnitPosition
42local spGetGameSeconds      = Spring.GetGameSeconds
43local spGetActiveCommand        = Spring.GetActiveCommand
44local spGetActiveCmdDesc        = Spring.GetActiveCmdDesc
45local spGetMouseState       = Spring.GetMouseState
46local spTraceScreenRay      = Spring.TraceScreenRay
47local spGetMyPlayerID       = Spring.GetMyPlayerID
48local spGetPlayerInfo       = Spring.GetPlayerInfo
49local spGetCameraVectors    = Spring.GetCameraVectors
50local spEcho                = Spring.Echo
51local spWarpMouse                       = Spring.WarpMouse
52local spGetBuildFacing          = Spring.GetBuildFacing
53local spSetBuildFacing          = Spring.SetBuildFacing
54local spPos2BuildPos            = Spring.Pos2BuildPos
55local spGetGroundHeight         = Spring.GetGroundHeight
56
57local floor                 = math.floor
58local abs                                       = math.abs
59local atan2                 = math.atan2
60local pi                    = math.pi
61local sqrt                  = math.sqrt
62
63local glColor               = gl.Color
64local glLineWidth           = gl.LineWidth
65local glDepthTest           = gl.DepthTest
66local glTexture             = gl.Texture
67local glDrawGroundCircle    = gl.DrawGroundCircle
68local glPopMatrix           = gl.PopMatrix
69local glPushMatrix          = gl.PushMatrix
70local glTranslate           = gl.Translate
71local glText                = gl.Text
72local glVertex              = gl.Vertex
73local glRotate                          = gl.Rotate
74local glBeginEnd                        = gl.BeginEnd
75local glScale                           = gl.Scale
76
77local GL_TRIANGLES                      = GL.TRIANGLES
78----------------------------------------------------------------------------------
79function widget:Update()
80        local timef = spGetGameSeconds()
81        local time = floor(timef)
82       
83        -- update timers once every <updateInt> seconds
84        if (time % updateInt == 0 and time ~= lastTimeUpdate) then     
85                lastTimeUpdate = time
86                --do update stuff:
87               
88                if ( CheckSpecState() == false ) then
89                        return false
90                end
91        end
92       
93        manipulateFacing()
94end
95
96function widget:DrawWorld()
97        drawOrientation()
98       
99        ResetGl()
100end
101
102function getVector2dLen( vector )
103        return sqrt( ( vector[1] * vector[1] ) + ( vector[2] * vector[2] ) )
104end
105
106function getRotationVectors2d( vectorA, vectorB )
107        vectorA = normalizeVector2d( vectorA )
108        vectorB = normalizeVector2d( vectorB )
109        local radian = atan2( vectorA[2], vectorA[1] ) - atan2( vectorB[2], vectorB[1] )
110        local val = ( 360.0 * radian) / ( 2 * pi )
111        return normalizeDegreeRange(val)
112end
113
114--i currently get all degress in a range from 0 to 270 and 0 to -90
115--this is a hack to correct this
116--also corrects values >360
117function normalizeDegreeRange( degree )
118        if ( degree < 0.0 ) then
119                degree = 360.0 + degree
120        elseif ( degree > 360.0 ) then
121                degree = degree - 360.0
122        end
123        return degree
124end
125
126--returns the rotation degrees between mouse move vector and defined forward vector
127function getMouseFacingDegree( mouseVec )
128        local forwVec = { 0.0, 1.0 }
129        return getRotationVectors2d( forwVec, mouseVec )
130end
131
132function normalizeVector2d( vector )
133        local len = getVector2dLen( vector )
134        local normVec = {0.0,0.0};
135        normVec[1] = vector[1] / len
136        normVec[2] = vector[2] / len
137        return normVec
138end
139
140function getFacingByMouseDelta( mouseDeltaX,mouseDeltaY )
141        local camVecs = spGetCameraVectors()    --would be cool to update this only on a callin like "onCameraMoved()"
142       
143        local mouseMovVec = { mouseDeltaX, mouseDeltaY }
144        local mMovVecLen = getVector2dLen( mouseMovVec )
145       
146        if ( mMovVecLen < sens ) then
147                return nil
148        end
149       
150        local mouseDegree = getMouseFacingDegree( mouseMovVec )
151       
152        --calculate the camera angle
153        local camRight2d = { camVecs.right[1], -camVecs.right[3] }
154        local camDegree = getMouseFacingDegree( camRight2d ) - 90
155        camDegree = normalizeDegreeRange( camDegree )
156       
157        --take the camera angle into account here
158        mouseDegree = mouseDegree + camDegree
159        mouseDegree = normalizeDegreeRange( mouseDegree )
160       
161        local newFacing = nil
162        if ( ( mouseDegree >= 280.0 ) or ( mouseDegree < 45.0 ) ) then
163                newFacing = 2
164        elseif ( ( mouseDegree >= 45.0 ) and ( mouseDegree < 135.0 ) ) then
165                newFacing = 1
166        elseif ( ( mouseDegree >= 135.0 ) and ( mouseDegree < 225.0 ) ) then
167                newFacing = 0
168        elseif ( ( mouseDegree >= 225.0 ) and ( mouseDegree < 280.0 ) ) then
169                newFacing = 3
170        else
171                newFacing = 0 --should not happen
172        end
173       
174        return newFacing
175end
176
177function manipulateFacing()     
178        local mx,my,lmb,mmb,rmb = spGetMouseState()
179        local alt,ctrl,meta,shift = spGetModKeyState()
180       
181        if (lmb and mmb) then
182                --in       
183        if not inDrag then
184            mouseDeltaX = 0
185            mouseDeltaY = 0
186            mouseXStartRotate = mx
187            mouseYStartRotate = my
188            mouseXStartDrag = mx
189            mouseYStartDrag = my
190        end
191       
192                inDrag = true
193                printDebug("IN")       
194        else
195                --out
196                printDebug("OUT")
197                inDrag = false
198        end
199               
200        --check if valid command
201        local idx, cmd_id, cmd_type, cmd_name = spGetActiveCommand()
202        if (not cmd_id) then return end
203
204        --check if build command
205        local cmdDesc = spGetActiveCmdDesc( idx )
206        if ( cmdDesc["type"] ~= 20 ) then
207                --quit here if not a build command
208                return
209        end
210       
211        if ( inDrag ) then
212                local curDeltaX = mx - mouseXStartRotate
213                mouseDeltaX = mouseDeltaX + curDeltaX
214                local curDeltaY = my - mouseYStartRotate
215                mouseDeltaY = mouseDeltaY + curDeltaY
216       
217                local newFacing = getFacingByMouseDelta( mouseDeltaX, mouseDeltaY )
218                if ( newFacing ~= nil ) then
219                        mouseDeltaX = 0
220                        mouseDeltaY = 0
221                       
222                        if ( newFacing ~= spGetBuildFacing() ) then
223                                spSetBuildFacing( newFacing )
224                        end
225                end
226                       
227                if mouseXStartRotate~=mx or mouseYStartRotate~=my then
228                        spWarpMouse( mouseXStartRotate, mouseYStartRotate ) --set old mouse coords to prevent mouse movement
229                end
230        end
231end
232
233function drawOrientation()
234        local idx, cmd_id, cmd_type, cmd_name = spGetActiveCommand()
235        local cmdDesc = spGetActiveCmdDesc( idx )
236       
237        if ( cmdDesc == nil or cmdDesc["type"] ~= 20 ) then
238                --quit here if not a build command
239                return
240        end
241       
242        local unitDefID = -cmd_id
243        local alt,ctrl,meta,shift = spGetModKeyState()
244       
245        local udef = udefTab[unitDefID]
246       
247        --check for an empty buildlist to avoid to draw for air repair pads
248        if (drawForAll == false and (udef["isFactory"] == false or #udef["buildOptions"] == 0)) then
249                return
250        end
251       
252        local mx, my = spGetMouseState()
253       
254        if ( shift and inDrag ) then
255                mx = mouseXStartDrag
256                my = mouseYStartDrag
257                printDebug("UDEFID: " .. mx )
258        end
259
260        local _, coords = spTraceScreenRay(mx, my, true, true)
261       
262        if not coords then return end
263               
264        local centerX = coords[1]
265        local centerY = coords[2]
266        local centerZ = coords[3]
267       
268        centerX, centerY, centerZ = spPos2BuildPos( unitDefID, centerX, centerY, centerZ )
269       
270        glLineWidth(1)
271        glColor( 0.0, 1.0, 0.0, 0.5 )
272       
273        local function drawFunc()
274                glVertex( 0, 0, -8)
275                glVertex( 0, 0, 8)
276                glVertex( 50, 0, -3)
277
278                glVertex( 0, 0,  8)
279                glVertex( 50, 0, 3)
280                glVertex( 50, 0, -3 )
281               
282                glVertex( 50, 0, 0)
283                glVertex( 30, 0, -30 )
284                glVertex( 80, 0, 0 )
285
286                glVertex( 50, 0, 0)
287                glVertex( 80, 0, 0 )
288                glVertex( 30, 0, 30 )
289        end
290 
291        --local height = spGetGroundHeight( centerX, centerZ )
292        local transSpace = udef["zsize"] * 4   --should be ysize but its not there?!?
293
294        local transX, transZ
295        local facing = spGetBuildFacing()
296        if ( facing == 0 ) then
297                transX = 0
298                transZ = transSpace
299        elseif ( facing == 1 ) then
300                transX = transSpace
301                transZ = 0
302        elseif ( facing == 2 ) then
303                transX = 0
304                transZ = -transSpace
305        elseif ( facing == 3 ) then
306                transX = -transSpace
307                transZ = 0
308        end
309
310        glPushMatrix()
311       
312        glTranslate( centerX + transX, centerY, centerZ + transZ)
313        glRotate( ( 3 + facing ) * 90, 0, 1, 0 )
314        glScale( (transSpace or 70)/70, 1.0, (transSpace or 70)/70)
315        glBeginEnd( GL_TRIANGLES, drawFunc )
316       
317        glScale( 1.0, 1.0, 1.0 )
318       
319        glPopMatrix()
320
321        glColor( 1.0, 1.0, 1.0 )
322end
323
324--Commons
325function ResetGl()
326        glColor( { 1.0, 1.0, 1.0, 1.0 } )
327        glLineWidth( 1.0 )
328        glDepthTest(false)
329        glTexture(false)
330end
331
332function CheckSpecState()
333        local playerID = spGetMyPlayerID()
334        local _, _, spec, _, _, _, _, _ = spGetPlayerInfo(playerID)
335               
336        if ( spec == true ) then
337                widgetHandler:RemoveWidget()
338                return false
339        end
340       
341        return true     
342end
343
344function printDebug( value )
345        if ( debug ) then
346                if ( type( value ) == "boolean" ) then
347                        if ( value == true ) then spEcho( "true" )
348                                else spEcho("false") end
349                elseif ( type(value ) == "table" ) then
350                        spEcho("Dumping table:")
351                        for key,val in pairs(value) do
352                                spEcho(key,val)
353                        end
354                else
355                        spEcho( value )
356                end
357        end
358end
359       
Note: See TracBrowser for help on using the repository browser.