· 5 years ago · Apr 16, 2020, 12:46 PM
1-- Free Rotation Settings
2local FreeRotation_CameraResetKey = Keys.T;
3local FreeRotation_useQE_keys :boolean = true;
4local FreeRotation_useWASD_keys :boolean = true;
5local FreeRotation_useShiftRotate :boolean = true;
6
7local AlternativeShiftCycle = Keys.X; -- City/Unit Cylce: Alternative to Shift key.
8
9-- These keys will function like the arrow keys if useWASD_keys is set to true.
10local FreeRotation_UpKey = Keys.W;
11local FreeRotation_LeftKey = Keys.A;
12local FreeRotation_DownKey = Keys.S;
13local FreeRotation_RightKey = Keys.D;
14-- These keys will rotate the map if useQE_keys is set to true.
15local FreeRotation_SpinLeftKey = Keys.Q;
16local FreeRotation_SpinRightKey = Keys.E;
17
18-- ===========================================================================
19-- World Input
20-- Copyright 2015-2018, Firaxis Games
21--
22-- Handle input that occurs within the 3D world.
23--
24-- In-file functions are organized in 3 areas:
25-- 1) "Operation" functions, occur agnostic of the input device
26-- 2) "Input State" functions, handle input base on up/down/update/or
27-- another state of the input device.
28-- 3) Event listening, mapping, and pre-processing
29--
30-- ===========================================================================
31
32include("PopupDialog.lua");
33include("civ6common")
34-- More interface-specific includes before the initialization
35
36-- ===========================================================================
37-- Debug
38-- ===========================================================================
39
40local m_isDebuging :boolean = false; -- Turn on local debug systems
41
42-- ===========================================================================
43-- CONSTANTS
44-- ===========================================================================
45
46
47local NORMALIZED_DRAG_THRESHOLD :number = 0.035; -- How much movement to kick off a drag
48local NORMALIZED_DRAG_THRESHOLD_SQR :number = NORMALIZED_DRAG_THRESHOLD*NORMALIZED_DRAG_THRESHOLD;
49local MOUSE_SCALAR :number = 6.0;
50local PAN_SPEED :number = 1;
51local ZOOM_SPEED :number = 0.1;
52local DOUBLETAP_THRESHHOLD :number = 2;
53
54
55-- ===========================================================================
56-- Table of tables of functions for each interface mode & event the mode handles
57-- (Must be defined before support functions in includes.)
58-- ===========================================================================
59InterfaceModeMessageHandler =
60{
61 [InterfaceModeTypes.DEBUG] = {},
62 [InterfaceModeTypes.SELECTION] = {},
63 [InterfaceModeTypes.MOVE_TO] = {},
64 [InterfaceModeTypes.ROUTE_TO] = {},
65 [InterfaceModeTypes.ATTACK] = {},
66 [InterfaceModeTypes.RANGE_ATTACK] = {},
67 [InterfaceModeTypes.CITY_RANGE_ATTACK] = {},
68 [InterfaceModeTypes.DISTRICT_RANGE_ATTACK] = {},
69 [InterfaceModeTypes.AIR_ATTACK] = {},
70 [InterfaceModeTypes.WMD_STRIKE] = {},
71 [InterfaceModeTypes.ICBM_STRIKE] = {},
72 [InterfaceModeTypes.EMBARK] = {},
73 [InterfaceModeTypes.DISEMBARK] = {},
74 [InterfaceModeTypes.DEPLOY] = {},
75 [InterfaceModeTypes.REBASE] = {},
76 [InterfaceModeTypes.BUILDING_PLACEMENT] = {},
77 [InterfaceModeTypes.DISTRICT_PLACEMENT] = {},
78 [InterfaceModeTypes.MAKE_TRADE_ROUTE] = {},
79 [InterfaceModeTypes.TELEPORT_TO_CITY] = {},
80 [InterfaceModeTypes.FORM_CORPS] = {},
81 [InterfaceModeTypes.FORM_ARMY] = {},
82 [InterfaceModeTypes.AIRLIFT] = {},
83 [InterfaceModeTypes.COASTAL_RAID] = {},
84 [InterfaceModeTypes.PLACE_MAP_PIN] = {},
85 [InterfaceModeTypes.CITY_MANAGEMENT] = {},
86 [InterfaceModeTypes.WB_SELECT_PLOT] = {},
87 [InterfaceModeTypes.SPY_CHOOSE_MISSION] = {},
88 [InterfaceModeTypes.SPY_TRAVEL_TO_CITY] = {},
89 [InterfaceModeTypes.NATURAL_WONDER] = {}, -- DEPRECATED: Use CINEMATIC
90 [InterfaceModeTypes.CINEMATIC] = {},
91 [InterfaceModeTypes.VIEW_MODAL_LENS] = {}
92}
93
94-- ===========================================================================
95-- GLOBALS
96-- ===========================================================================
97g_isTouchEnabled = false;
98g_isMouseDragging = false;
99g_isMouseDownInWorld = false; -- Did mouse-down start here (true), or in some other UI context?
100g_targetPlots = nil;
101INTERFACEMODE_ENTER = "InterfaceModeEnter";
102INTERFACEMODE_LEAVE = "InterfaceModeLeave";
103
104-- ===========================================================================
105-- MEMBERS
106-- ===========================================================================
107
108local DefaultMessageHandler :table = {};
109local m_actionHotkeyToggleGrid :number = Input.GetActionId("ToggleGrid"); -- Hot Key Handling
110local m_actionHotkeyOnlinePause :number = Input.GetActionId("OnlinePause"); -- Hot Key Handling
111local m_actionHotkeyToggleYield :number = Input.GetActionId("ToggleYield"); -- Hot Key Handling
112local m_actionHotkeyToggleRes :number = Input.GetActionId("ToggleResources"); -- Hot Key Handling
113local m_actionHotkeyPrevUnit :number = Input.GetActionId("PrevUnit"); -- Hot Key Handling
114local m_actionHotkeyNextUnit :number = Input.GetActionId("NextUnit"); -- Hot Key Handling
115local m_actionHotkeyPrevCity :number = Input.GetActionId("PrevCity"); -- Hot Key Handling
116local m_actionHotkeyNextCity :number = Input.GetActionId("NextCity"); -- Hot Key Handling
117local m_actionHotkeyCapitalCity :number = Input.GetActionId("CapitalCity"); -- Hot Key Handling
118local m_kTouchesDownInWorld :table = {}; -- Tracks "down" touches that occurred in this context.
119local m_isALTDown :boolean= false;
120local m_isMouseButtonLDown :boolean= false;
121local m_isMouseButtonMDown :boolean= false;
122local m_isMouseButtonRDown :boolean= false;
123local m_isTouchDragging :boolean= false;
124local m_isTouchZooming :boolean= false;
125local m_isTouchPathing :boolean= false;
126local m_isDoubleTapping :boolean= false;
127local m_touchCount :number = 0; -- # of touches currently occuring
128local m_touchStartPlotX :number = -1;
129local m_touchStartPlotY :number = -1;
130local m_touchTotalNum :number = 0; -- # of multiple touches that occurred
131local m_mapZoomStart :number = 0;
132local m_dragStartWorldX :number = 0;
133local m_dragStartWorldY :number = 0;
134local m_dragStartFocusWorldX :number = 0;
135local m_dragStartFocusWorldY :number = 0;
136local m_dragStartX :number = 0; -- Mouse or virtual mouse (of average touch points) X
137local m_dragStartY :number = 0; -- Mouse or virtual mouse (of average touch points) Y
138local m_dragX :number = 0;
139local m_dragY :number = 0;
140local m_edgePanX :number = 0;
141local m_edgePanY :number = 0;
142local m_constrainToPlotID :number = 0;
143local ms_bGridOn :boolean= true;
144local m_isMapDragDisabled :boolean = false;
145local m_isCancelDisabled :boolean = false; -- Is a cancelable action (e.g., right-click for district placement) been disabled?
146local m_debugTrace :table = {}; -- debug
147local m_cachedPathUnit :table;
148local m_cachedPathPlotId :number;
149local m_previousTurnsCount :number = 0;
150local m_kConfirmWarDialog :table;
151local m_focusedTargetPlot :number = -1;
152local m_WBMouseOverPlot :number = -1;
153local m_kTutorialPermittedHexes :table = nil; -- Which hexes are permitted for selection by the tutorial (nil if disabled)
154local m_kTutorialUnitHexRestrictions :table = nil; -- Any restrictions on where units can move. (Key=UnitType, Value={restricted plotIds})
155local m_isPlotFlaggedRestricted :boolean = false; -- In a previous operation to determine a move path, was a plot flagged restrticted/bad? (likely due to the tutorial system)
156local m_kTutorialUnitMoveRestrictions :table = nil; -- Restrictions for moving (anywhere) of a selected unit type.
157local m_isInputBlocked :boolean = false;
158
159g_MovementPath = UILens.CreateLensLayerHash("Movement_Path");
160g_Numbers = UILens.CreateLensLayerHash("Numbers");
161g_AttackRange = UILens.CreateLensLayerHash("Attack_Range");
162g_HexColoringAttack = UILens.CreateLensLayerHash("Hex_Coloring_Attack");
163g_HexColoringMovement = UILens.CreateLensLayerHash("Hex_Coloring_Movement");
164g_HexColoringPlacement = UILens.CreateLensLayerHash("Hex_Coloring_Placement");
165
166--CQUI MEMBERS
167local CQUI_cityview = false;
168local CQUI_hotkeyMode = 1; -- 0: V-Style with enhancements 1: V-Style 2: No changes
169local CQUI_isShiftDown :boolean = false;
170
171function CQUI_OnSettingsUpdate()
172 CQUI_hotkeyMode = GameConfiguration.GetValue("CQUI_BindingsMode");
173end
174
175LuaEvents.CQUI_SettingsUpdate.Add( CQUI_OnSettingsUpdate );
176LuaEvents.CQUI_SettingsInitialized.Add( CQUI_OnSettingsUpdate );
177
178-- FREE CAM MEMBERS
179local m_isQDown :boolean = false;
180local m_isEDown :boolean = false;
181local SPIN_SPEED :number = 0.035;
182local m_prevSpinX :number = 0;
183local m_SpinX :number = 0;
184
185local m_GameMods = Modding.GetActiveMods();
186local isCQUI_Enabled = false;
187for _, aMod in pairs( m_GameMods ) do
188 if aMod.Id == "1d44b5e7-753e-405b-af24-5ee634ec8a01" then
189 isCQUI_Enabled = true;
190 end
191 if aMod.Id == "1d44b5e7-753e-405b-af24-5ee634ec8a02" then
192 isCQUI_Enabled = true;
193 end
194end
195if isCQUI_Enabled then print( "FreeRotation: CQUI is enabled." );
196else print( "FreeRotation: CQUI is NOT enabled" ); end
197
198-- Check if the Rise and Fall patch is installed.
199local RFPatchIsInstalled = false;
200for row in GameInfo.Notifications() do
201 if ( ( row.NotificationType == "NOTIFICATION_WONDER_FAILED" ) and ( row.Message == "LOC_NOTIFICATION_WONDER_FAILED_MESSAGE" ) ) then
202 RFPatchIsInstalled = true;
203 break;
204 end
205end
206if RFPatchIsInstalled == true then
207 print( "The 7 Feb 2018 Rise and Fall patch is installed for this game." );
208else
209 print( "The 7 Feb 2018 Rise and Fall patch is NOT installed for this game!" );
210end
211
212
213-- ===========================================================================
214-- FUNCTIONS
215-- ===========================================================================
216
217
218-- ===========================================================================
219-- DEBUG:
220-- trace(msg) Add a trace message to be output later (to prevent stalling
221-- game while looking at per-frame input).
222-- dump() Send to output all the collected traces
223-- clear() Empties trace buffer
224-- ===========================================================================
225function trace( msg:string ) m_debugTrace[table.count(m_debugTrace)+1] = msg; end
226function dump() print("DebugTrace: "..table.concat(m_debugTrace)); end
227function clear() m_debugTrace = {}; end
228
229
230
231-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
232--
233-- OPERATIONS
234--
235-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
236
237
238-- ===========================================================================
239-- Empty function (to override default)
240-- ===========================================================================
241function OnDoNothing()
242end
243
244
245-- ===========================================================================
246-- Pan camera
247-- ===========================================================================
248function ProcessPan( panX :number, panY :number )
249
250 -- Free Cam: only pan with these keys if Shift and Alt are not down.
251 if not ( CQUI_isShiftDown or m_isALTDown ) then
252 if( panY == 0.0 ) then
253 if( m_isUPpressed ) then panY = panY + PAN_SPEED; end
254 if( m_isDOWNpressed) then panY = panY - PAN_SPEED; end
255 end
256
257 if( panX == 0.0 ) then
258 if( m_isRIGHTpressed ) then panX = panX + PAN_SPEED; end
259 if( m_isLEFTpressed ) then panX = panX - PAN_SPEED; end
260 end
261 end
262
263 UI.PanMap( panX, panY );
264end
265
266
267--==============================================================================================================
268function IsInDefaultRotation()
269 if ( ( math.abs(m_SpinX) < 0.5 ) ) then return true; else return false; end
270end
271-- Sets the map spin based on current values.
272function ProcessSpin()
273 -- Save a non-default spin.
274 if not IsInDefaultRotation() then
275 m_prevSpinX = m_SpinX;
276 end
277 UI.SpinMap( m_SpinX, 0.0 );
278end
279-- Free Rotation function: Spins the map if Q and E are pressed.
280function AdjustSpin()
281 if not CQUI_isShiftDown then
282 if m_isQDown then m_SpinX = m_SpinX - SPIN_SPEED; end
283 if m_isEDown then m_SpinX = m_SpinX + SPIN_SPEED; end
284 if ( m_isQDown or m_isEDown ) then UI.PlaySound("Main_Menu_Mouse_Over"); end
285 ProcessSpin();
286 end
287end
288-- Free Rotation function: Resets spin to default.
289function ResetSpin()
290 m_SpinX = 0;
291 ProcessSpin();
292end
293-- Restores previous spin from default.
294function RestoreSpin()
295 m_SpinX = m_prevSpinX;
296 ProcessSpin();
297end
298
299
300-- ===========================================================================
301function OnInterfaceModeChange_NaturalWonder()
302 UIManager:SetUICursor(CursorTypes.NORMAL);
303 UI.SetFixedTiltMode( true );
304end
305
306-- ===========================================================================
307function OnInterfaceModeLeave_NaturalWonder( eNewMode:number )
308 UIManager:SetUICursor(CursorTypes.NORMAL);
309 UI.SetFixedTiltMode( false );
310 OnCycleUnitSelectionRequest();
311end
312
313-- ===========================================================================
314function OnInterfaceModeEnter_CityManagement( eNewMode:number )
315 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
316 UILens.SetActive("CityManagement");
317end
318
319-- ===========================================================================
320function OnInterfaceModeLeave_CityManagement( eNewMode:number )
321 UIManager:SetUICursor(CursorTypes.NORMAL);
322 UILens.SetActive("Default");
323end
324
325-- ===========================================================================
326-- Input conditions are set for edge camera panning
327-- ===========================================================================
328function IsAbleToEdgePan()
329 return UserConfiguration.IsEdgePanEnabled() or ( (UI.GetInterfaceMode() == InterfaceModeTypes.SELECTION) and m_isMouseButtonRDown );
330end
331
332-- ===========================================================================
333-- Have world camera focus on a plot
334-- plotId, the plot # to look at
335-- ===========================================================================
336function SnapToPlot( plotId:number )
337 if (Map.IsPlot(plotId)) then
338 local plot = Map.GetPlotByIndex(plotId);
339 UI.LookAtPlot( plot );
340 end
341end
342
343-- ===========================================================================
344function IsCancelAllowed()
345 return (not m_isCancelDisabled);
346end
347
348-- ===========================================================================
349-- Perform a camera zoom based on the native 2-finger gesture
350-- ===========================================================================
351function RealizeTouchGestureZoom()
352 if TouchManager:IsInGesture(Gestures.Stretching) then
353 local fDistance:number = TouchManager:GetGestureDistance(Gestures.Stretching);
354 local normalizedX :number, normalizedY:number = UIManager:GetNormalizedMousePos();
355
356 -- If zooming just started, get the starting zoom level.
357 if not m_isTouchZooming then
358 m_mapZoomStart = UI.GetMapZoom();
359 m_isTouchZooming = true;
360 end
361
362 local fSpeed :number = 2.4; -- TODO: This speed scalar should be put into the UI configuration.
363 local fZoomDelta:number = - (fDistance * fSpeed);
364 local fZoom :number = m_mapZoomStart + fZoomDelta; -- Adjust the zoom level.
365
366 if( fZoomDelta < 0.0 ) then
367 --UI.SetMapZoom( fZoom, normalizedX, normalizedY );
368 UI.SetMapZoom( fZoom, 0.0, 0.0 );
369 else
370 --UI.SetMapZoom( fZoom, normalizedX, normalizedY );
371 UI.SetMapZoom( fZoom, 0.0, 0.0 );
372 end
373
374 --LuaEvents.WorldInput_TouchPlotTooltipHide(); -- Once this gestures starts, stop and plot tooltip
375 else
376 m_isTouchZooming = false;
377 end
378end
379
380-- ===========================================================================
381function GetCurrentlySelectUnitIndex( unitList:table, ePlayer:number )
382 local iSelectedUnit :number = -1; -- Which unit index is selected. This is the unit index for the player's units, not all the units in the list
383 local iCount :number = 0; -- # of units in the list owned by the player
384 for i, pUnit in ipairs(unitList) do
385 -- Owned by the local player?
386 if (pUnit:GetOwner() == ePlayer) then
387 -- Already selected?
388 if UI.IsUnitSelected(pUnit) then
389 iSelectedUnit = iCount;
390 end
391 iCount = iCount + 1;
392 end
393 end
394
395 return iSelectedUnit;
396end
397
398-- ===========================================================================
399function SelectNextUnit(unitList:table, iCurrentlySelectedUnit:number, ePlayer:number, bWrap:boolean)
400 if iCurrentlySelectedUnit == -1 then
401 -- Nothing selected yet
402 for i, pUnit in ipairs(unitList) do
403 -- Owned by the player?
404 if (pUnit:GetOwner() == ePlayer) then
405 SelectUnit(pUnit);
406 end
407 end
408 else
409 local bSelected = false;
410 local iCount = 0; -- number of units in the list owned by the player
411 for i, pUnit in ipairs(unitList) do
412 -- Owned by the player?
413 if (pUnit:GetOwner() == ePlayer) then
414 if (iCount > iCurrentlySelectedUnit) then
415 SelectUnit(pUnit);
416 bSelected = true;
417 break;
418 end
419 iCount = iCount + 1;
420 end
421 end
422
423 if not bSelected and bWrap then
424 -- Either the input was wrong or we wrapped, go back and select the first one.
425 for i, pUnit in ipairs(unitList) do
426 -- Owned by the player?
427 if (pUnit:GetOwner() == ePlayer) then
428 SelectUnit(pUnit);
429 break;
430 end
431 end
432 end
433 end
434end
435
436-- ===========================================================================
437-- Selects a unit but firsts deselect any current unit, thereby forcing
438-- a cache refresh.
439-- ===========================================================================
440function SelectUnit( kUnit:table )
441 UI.DeselectUnit(kUnit);
442 UI.SelectUnit(kUnit);
443end
444
445-- ===========================================================================
446-- Returns if a specific plot is allowed to be selected.
447-- This is generally always true except when the tutorial is running to lock
448-- down some (or all) of the plots.
449-- ===========================================================================
450function IsSelectionAllowedAt( plotId:number )
451 if m_kTutorialPermittedHexes == nil then return true; end
452 for i,allowedId:number in ipairs( m_kTutorialPermittedHexes ) do
453 if allowedId == plotId then
454 return true;
455 end
456 end
457 return false;
458end
459
460-- ===========================================================================
461-- Selects the unit or city at the plot passed in.
462-- ===========================================================================
463function SelectInPlot( plotX:number, plotY:number )
464
465 local kUnitList :table = Units.GetUnitsInPlotLayerID( plotX, plotY, MapLayers.ANY );
466 local tryCity :boolean= false;
467 local eLocalPlayer :number = Game.GetLocalPlayer();
468 local pCity :table = Cities.GetCityInPlot( plotX, plotY );
469 if pCity ~= nil then
470 if (pCity:GetOwner() ~= eLocalPlayer) then
471 pCity = nil;
472 end
473 end
474
475 -- If there are units to try selecting...
476 if table.count(kUnitList) ~= 0 then
477 -- Get any currently selected unit so we can cycle to the next.
478 local iSelected:number = GetCurrentlySelectUnitIndex(kUnitList, eLocalPlayer);
479
480 -- Cycle to the next, or select the first one if nothing was selected and there is no city
481 SelectNextUnit(kUnitList, iSelected, eLocalPlayer, pCity == nil);
482
483 local iNewSelected = GetCurrentlySelectUnitIndex(kUnitList, eLocalPlayer);
484 if (iNewSelected == -1 or (iNewSelected == iSelected and pCity ~= nil)) then
485 -- No valid units to select
486 UI.DeselectAllUnits();
487 tryCity = true;
488 else
489 if (iNewSelected ~= -1 and iNewSelected ~= iSelected) then
490 local pNewSelectedUnit = UI.GetHeadSelectedUnit();
491 if (pNewSelectedUnit ~= nil and UI.RebuildSelectionList ~= nil) then -- Checking UI.RebuildSelectionList, so that if an artist fetches the scripts before the next build, they won't be stuck. Remove that check ASAP.
492 -- The user has manually selected a unit, rebuild the selection list from that unit.
493 UI.RebuildSelectionList(pNewSelectedUnit);
494 UI.SetCycleAdvanceTimer(0); -- Cancel any auto-advance timer
495 end
496 end
497 end
498 else
499 UI.DeselectAllUnits();
500 tryCity = true;
501 end
502
503 if tryCity then
504 if pCity ~= nil then
505 UI.SelectCity(pCity);
506 UI.SetCycleAdvanceTimer(0); -- Cancel any auto-advance timer
507 else
508 local uiProductionPanel:table = ContextPtr:LookUpControl("/InGame/ProductionPanel");
509 if uiProductionPanel and not uiProductionPanel:IsHidden() then
510 LuaEvents.CityBannerManager_ProductionToggle();
511 else
512 UI.DeselectAllCities();
513 end
514 end
515 -- No else, as this would be the case when click on a city banner,
516 -- and so the CityBannerManager will handle the selection.
517 end
518
519 return true;
520end
521
522-- ===========================================================================
523-- Has the player moved a down mouse or touch enough that a drag should be
524-- considered?
525-- RETURNS: true if a drag is occurring.
526-- ===========================================================================
527function IsDragThreshholdMet()
528 local normalizedX:number, normalizedY:number = UIManager:GetNormalizedMousePos();
529
530 local diffX:number = normalizedX - m_dragStartX;
531 local diffY:number = normalizedY - m_dragStartY;
532
533 return ( diffX*diffX + diffY*diffY) > NORMALIZED_DRAG_THRESHOLD_SQR;
534end
535
536-- ===========================================================================
537-- Setup to start dragging the map.
538-- ===========================================================================
539function ReadyForDragMap()
540 m_dragStartX, m_dragStartY = UIManager:GetNormalizedMousePos();
541 m_dragStartFocusWorldX, m_dragStartFocusWorldY = UI.GetMapLookAtWorldTarget();
542 m_dragStartWorldX, m_dragStartWorldY = UI.GetWorldFromNormalizedScreenPos_NoWrap( m_dragStartX, m_dragStartY );
543 m_dragX = m_dragStartX;
544 m_dragY = m_dragStartY;
545 LuaEvents.WorldInput_DragMapBegin();
546end
547
548function StartDragMap()
549
550 --Don't override m_dragStartX/Y because it is used in rotation, and we ony
551 local dragStartX:number, dragStartY:number = UIManager:GetNormalizedMousePos();
552 m_dragStartFocusWorldX, m_dragStartFocusWorldY = UI.GetMapLookAtWorldTarget();
553 m_dragStartWorldX, m_dragStartWorldY = UI.GetWorldFromNormalizedScreenPos_NoWrap( dragStartX, dragStartY );
554 m_dragX = dragStartX;
555 m_dragY = dragStartY;
556end
557
558-- ===========================================================================
559-- Drag (or spin) the camera based new position
560-- ===========================================================================
561function UpdateDragMap()
562
563 -- Obtain either the actual mouse position, or for touch, the virtualized
564 -- mouse position based on the "average" of all touches:
565 local x:number, y:number= UIManager:GetNormalizedMousePos();
566 local dx:number = m_dragX - x;
567 local dy:number = m_dragY - y;
568
569 -- Early out if no change:
570 -- Need m_drag... checks or snap to 0,0 can occur.
571 if (dx==0 and dy==0) or (m_dragStartWorldX==0 and m_dragStartFocusWorldX==0) then
572 return;
573 end
574 if m_isMapDragDisabled then
575 return;
576 end
577
578 -- Free Rotation change. Shift + click also rotates the camera.
579 if (m_isALTDown or (FreeRotation_useShiftRotate and CQUI_isShiftDown)) then
580
581 m_SpinX = m_SpinX + dx;
582 ProcessSpin();
583 -- /Free Rotation change.
584 else
585 UI.DragMap( x, y, m_dragStartWorldX, m_dragStartWorldY, m_dragStartFocusWorldX, m_dragStartFocusWorldY );
586 end
587
588 m_dragX = x;
589 m_dragY = y;
590end
591
592-- ===========================================================================
593-- Reset drag variables for next go around.
594-- ===========================================================================
595function EndDragMap()
596 --UI.SpinMap( 0.0, 0.0 );
597
598 LuaEvents.WorldInput_DragMapEnd();
599 m_dragX = 0;
600 m_dragY = 0;
601 m_dragStartX = 0;
602 m_dragStartY = 0;
603 m_dragStartFocusWorldX = 0;
604 m_dragStartFocusWorldY = 0;
605 m_dragStartWorldX = 0;
606 m_dragStartWorldY = 0;
607end
608
609
610-- ===========================================================================
611-- True if a given unit type is allowed to move to a plot.
612-- ===========================================================================
613function IsUnitTypeAllowedToMoveToPlot( unitType:string, plotId:number )
614 if m_kTutorialUnitHexRestrictions == nil then return true; end
615 if m_kTutorialUnitHexRestrictions[unitType] ~= nil then
616 for _,restrictedPlotId:number in ipairs(m_kTutorialUnitHexRestrictions[unitType]) do
617 if plotId == restrictedPlotId then
618 return false; -- Found in restricted list, nope, permission denied to move.
619 end
620 end
621 end
622 return true;
623end
624
625-- ===========================================================================
626-- Returns true if a unit can move to a particular plot.
627-- This is after the pathfinder may have returned that it's okay, but another
628-- system (such as the tutorial) has locked it down.
629-- ===========================================================================
630function IsUnitAllowedToMoveToCursorPlot( pUnit:table )
631 local unitType :string = GameInfo.Units[pUnit:GetUnitType()].UnitType;
632 local plotId :number = UI.GetCursorPlotID();
633
634 -- Units cannot move to the plot they are already on
635 local unitPlot :number = Map.GetPlot(pUnit:GetX(),pUnit:GetY()):GetIndex();
636 if unitPlot == plotId then
637 return false;
638 end
639 if m_kTutorialUnitHexRestrictions == nil then return true; end
640 if m_isPlotFlaggedRestricted then return false; end -- Previous call to check path showed player ending on hex that was restricted.
641
642 return (not m_isPlotFlaggedRestricted) and IsUnitTypeAllowedToMoveToPlot( unitType, plotId );
643end
644
645-- ===========================================================================
646-- RETURNS true if the plot is considered a bad move for a unit.
647-- Also returns the plotId (if bad)
648-- ===========================================================================
649function IsPlotPathRestrictedForUnit( kPlotPath:table, kTurnsList:table, pUnit:table )
650 local endPlotId:number = kPlotPath[table.count(kPlotPath)];
651 if m_constrainToPlotID ~= 0 and endPlotId ~= m_constrainToPlotID then
652 return true, m_constrainToPlotID;
653 end
654
655 local unitType:string = GameInfo.Units[pUnit:GetUnitType()].UnitType;
656
657 -- Is the unit type just not allowed to be moved at all.
658 if m_kTutorialUnitMoveRestrictions ~= nil and m_kTutorialUnitMoveRestrictions[unitType] ~= nil then
659 return true, -1;
660 end
661
662 -- Is path traveling through a restricted plot?
663 -- Ignore the first plot, as a unit may be on a restricted plot and the
664 -- goal is just to get it off of it (and never come back.)
665 if m_kTutorialUnitHexRestrictions ~= nil then
666 if m_kTutorialUnitHexRestrictions[unitType] ~= nil then
667 local lastTurn :number = 1;
668 local lastRestrictedPlot:number = -1;
669 for i,plotId in ipairs(kPlotPath) do
670 -- Past the first plot
671 if i > 1 then
672 if kTurnsList[i] == lastTurn then
673 lastRestrictedPlot = -1; -- Same turn? Reset and previously found restricitions (unit is passing through)
674 if (not IsUnitTypeAllowedToMoveToPlot( unitType, plotId )) then
675 lastTurn = kTurnsList[i];
676 lastRestrictedPlot = plotId;
677 end
678 else
679 if lastRestrictedPlot ~= -1 then
680 return true, lastRestrictedPlot;
681 end
682 if (not IsUnitTypeAllowedToMoveToPlot( unitType, plotId )) then
683 lastTurn = kTurnsList[i];
684 lastRestrictedPlot = plotId;
685 end
686 end
687 end
688 end
689 if lastRestrictedPlot ~= -1 then
690 return true, lastRestrictedPlot;
691 end
692 end
693 end
694
695 m_isPlotFlaggedRestricted = false;
696 return false;
697end
698
699
700-- ===========================================================================
701-- LUA Event
702-- Add plot(s) to the restriction list; units of a certain type may not
703-- move to there.
704-- ===========================================================================
705function OnTutorial_AddUnitHexRestriction( unitType:string, kPlotIds:table )
706 if m_kTutorialUnitHexRestrictions == nil then
707 m_kTutorialUnitHexRestrictions = {};
708 end
709 if m_kTutorialUnitHexRestrictions[unitType] == nil then
710 m_kTutorialUnitHexRestrictions[unitType] = {};
711 end
712 for _,plotId:number in ipairs(kPlotIds) do
713 table.insert(m_kTutorialUnitHexRestrictions[unitType], plotId );
714 end
715end
716
717-- ===========================================================================
718-- LUA Event
719-- ===========================================================================
720function OnTutorial_RemoveUnitHexRestriction( unitType:string, kPlotIds:table )
721 if m_kTutorialUnitHexRestrictions == nil then
722 UI.DataError("Cannot RemoveUnitHexRestriction( "..unitType.." ...) as no restrictions are set.");
723 return;
724 end
725 if m_kTutorialUnitHexRestrictions[unitType] == nil then
726 UI.DataError("Cannot RemoveUnitHexRestriction( "..unitType.." ...) as a restriction for that unit type is not set.");
727 return;
728 end
729
730 -- Remove all the items in the restriction list based on what was passed in.
731 for _,plotId in ipairs( kPlotIds ) do
732 local isRemoved:boolean = false;
733 for i=#m_kTutorialUnitHexRestrictions[unitType],1,-1 do
734 if m_kTutorialUnitHexRestrictions[unitType][i] == plotId then
735 table.remove( m_kTutorialUnitHexRestrictions[unitType], i);
736 isRemoved = true;
737 break;
738 end
739 end
740 if (not isRemoved) then
741 UI.DataError("Cannot remove restriction for the plot "..tostring(plotId)..", it wasn't found in the list for unit "..unitType);
742 end
743 end
744end
745
746-- ===========================================================================
747-- LUA Event
748-- ===========================================================================
749function OnTutorial_ClearAllUnitHexRestrictions()
750 m_kTutorialUnitHexRestrictions = nil;
751end
752
753
754-- ===========================================================================
755-- LUA Event
756-- Prevent a unit type from being selected.
757-- ===========================================================================
758function OnTutorial_AddUnitMoveRestriction( unitType:string )
759 if m_kTutorialUnitMoveRestrictions == nil then
760 m_kTutorialUnitMoveRestrictions = {};
761 end
762 if m_kTutorialUnitMoveRestrictions[unitType] then
763 UI.DataError("Setting tutorial WorldInput unit selection for '"..unitType.."' but it's already set to restricted!");
764 end
765
766 m_kTutorialUnitMoveRestrictions[unitType] = true;
767end
768
769
770-- ===========================================================================
771-- LUA Event
772-- optionalUnitType The unit to remove from the restriction list or nil
773-- to completely clear the list.
774-- ===========================================================================
775function OnTutorial_RemoveUnitMoveRestrictions( optionalUnitType:string )
776 -- No arg, clear all...
777 if optionalUnitType == nil then
778 m_kTutorialUnitMoveRestrictions = nil;
779 else
780 -- Clear a specific type from restriction list.
781 if m_kTutorialUnitMoveRestrictions[optionalUnitType] == nil then
782 UI.DataError("Tutorial did not reset WorldInput selection for the unit type '"..optionalUnitType.."' since it's not in the restriction list.");
783 end
784 m_kTutorialUnitMoveRestrictions[optionalUnitType] = nil;
785 end
786end
787
788
789-- ===========================================================================
790-- Perform a movement path operation (if there is a selected unit).
791-- ===========================================================================
792function MoveUnitToCursorPlot( pUnit:table )
793
794 -- Clear any paths set for moving the unit and ensure any raised lens
795 -- due to the selection, is turned off.
796 ClearMovementPath();
797 UILens.SetActive("Default");
798
799 local plotID:number = UI.GetCursorPlotID();
800 if (not Map.IsPlot(plotID)) then
801 return;
802 end
803
804 if (m_constrainToPlotID == 0 or plotID == m_constrainToPlotID) and not GameInfo.Units[pUnit:GetUnitType()].IgnoreMoves then
805 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
806 if m_previousTurnsCount >= 1 then
807 UI.PlaySound("UI_Move_Confirm");
808 end
809 MoveUnitToPlot( pUnit, plotX, plotY );
810 end
811end
812
813-- ===========================================================================
814function UnitMovementCancel()
815 ClearMovementPath();
816 UILens.SetActive("Default");
817
818 -- If we have a unit selected with queued movement display that path
819 if (not UI.IsGameCoreBusy()) then
820 local pSelectedUnit :table = UI.GetHeadSelectedUnit();
821 if pSelectedUnit then
822 local endPlotId = UnitManager.GetQueuedDestination( pSelectedUnit );
823 if endPlotId then
824 RealizeMovementPath(true);
825 end
826 end
827 end
828end
829
830-- ===========================================================================
831function OnUnitCommandStarted(player, unitId, hCommand, iData1)
832 if (hCommand == UnitCommandTypes.CANCEL) then
833 UnitMovementCancel();
834 end
835end
836
837-- ===========================================================================
838-- Unit Range Attack
839-- ===========================================================================
840function UnitRangeAttack( plotID:number )
841 local plot :table = Map.GetPlotByIndex(plotID);
842 local tParameters :table = {};
843 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
844 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
845
846 local pSelectedUnit :table = UI.GetHeadSelectedUnit();
847 if pSelectedUnit == nil then
848 UI.DataError("A UnitRangeAttack( "..tostring(plotID).." ) was attempted but there is no selected unit.");
849 return;
850 end
851
852 if UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.RANGE_ATTACK, nil, tParameters) then
853 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.RANGE_ATTACK, tParameters);
854 else
855 -- LClicking on an empty hex, deselect unit.
856 UI.DeselectUnit( pSelectedUnit );
857 end
858 -- Always leave ranged attack mode after interaction.
859 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
860end
861
862-- ===========================================================================
863-- Clear the visual representation (and cache) of the movement path
864-- ===========================================================================
865function ClearMovementPath()
866 UILens.ClearLayerHexes( g_MovementPath );
867 UILens.ClearLayerHexes( g_Numbers );
868 -- CQUI : As we show path on over
869 if (UI.GetInterfaceMode() ~= InterfaceModeTypes.CITY_RANGE_ATTACK and UI.GetInterfaceMode() ~= InterfaceModeTypes.DISTRICT_RANGE_ATTACK) then
870 UILens.ClearLayerHexes( g_AttackRange );
871 end
872 m_cachedPathUnit = nil;
873 m_cachedPathPlotId = -1;
874end
875
876-- ===========================================================================
877function ClearRangeAttackDragging()
878 local bWasDragging:boolean = g_isMouseDragging;
879 OnMouseEnd( pInputStruct );
880 return bWasDragging;
881end
882
883-- ===========================================================================
884-- Update the 3D displayed path for a unit.
885-- ===========================================================================
886-- AZURENCY : added unitID to use this function on hover in unitflagmanager
887function RealizeMovementPath(showQueuedPath:boolean, unitID:number)
888
889 if not UI.IsMovementPathOn() or UI.IsGameCoreBusy() then
890 return;
891 end
892
893 -- CQUI (Azurency) : Check if in CITY_MANAGEMENT or STRIKE modes
894 CQUI_im = UI.GetInterfaceMode();
895 if (CQUI_im == InterfaceModeTypes.CITY_MANAGEMENT or CQUI_im == InterfaceModeTypes.CITY_RANGE_ATTACK or CQUI_im == InterfaceModeTypes.DISTRICT_RANGE_ATTACK) then
896 return;
897 end
898
899 -- Bail if no selected unit.
900 local kUnit :table = nil;
901 if unitID then
902 kUnit = Players[Game.GetLocalPlayer()]:GetUnits():FindID(unitID);
903 else
904 kUnit = UI.GetHeadSelectedUnit();
905 end
906 if kUnit == nil then
907 UILens.SetActive("Default");
908 m_cachedPathUnit = nil;
909 m_cachedPathPlotId = -1;
910 return;
911 end
912
913 -- Bail if unit is not a type that allows movement.
914 if GameInfo.Units[kUnit:GetUnitType()].IgnoreMoves then
915 return;
916 end
917
918 -- Bail if end plot is not determined.
919 local endPlotId :number = UI.GetCursorPlotID();
920
921 -- Use the queued destination to show the queued path
922 if (showQueuedPath) then
923 local queuedEndPlotId:number = UnitManager.GetQueuedDestination( kUnit );
924 if queuedEndPlotId then
925 endPlotId = queuedEndPlotId;
926 elseif unitID then -- AZURENCY : bail if the unit have no endplot and we wanted to draw its path
927 return;
928 end
929 end
930
931 -- Ensure this is a proper plot ID
932 if (not Map.IsPlot(endPlotId)) then
933 return;
934 end
935
936 -- Only update if a new unit or new plot from the previous update.
937 if m_cachedPathUnit ~= kUnit or m_cachedPathPlotId ~= endPlotId then
938 UILens.ClearLayerHexes( g_MovementPath );
939 UILens.ClearLayerHexes( g_Numbers );
940 UILens.ClearLayerHexes( g_AttackRange );
941 if m_cachedPathPlotId ~= -1 then
942 UILens.UnFocusHex( g_AttackRange, m_cachedPathPlotId );
943 end
944
945 m_cachedPathUnit = kUnit;
946 m_cachedPathPlotId = endPlotId;
947
948
949 -- Obtain ordered list of plots.
950 local variations : table = {}; -- 2 to 3 values
951 local eLocalPlayer : number = Game.GetLocalPlayer();
952
953 --check for unit position swap first
954 local startPlotId :number = Map.GetPlot(kUnit:GetX(),kUnit:GetY()):GetIndex();
955 if startPlotId ~= endPlotId then
956 local pathPlots :table = {};
957 local plot :table = Map.GetPlotByIndex(endPlotId);
958 local tParameters :table = {};
959 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
960 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
961 if ( UnitManager.CanStartOperation( kUnit, UnitOperationTypes.SWAP_UNITS, nil, tParameters) ) then
962 lensNameBase = "MovementGood";
963 if not UILens.IsLensActive(lensNameBase) then
964 UILens.SetActive(lensNameBase);
965 end
966 table.insert(pathPlots, startPlotId);
967 table.insert(pathPlots, endPlotId);
968 table.insert(variations, {lensNameBase.."_Destination",startPlotId} );
969 table.insert(variations, {lensNameBase.."_Counter", startPlotId} ); -- show counter pip
970 UI.AddNumberToPath( 1, startPlotId);
971 table.insert(variations, {lensNameBase.."_Destination",endPlotId} );
972 table.insert(variations, {lensNameBase.."_Counter", endPlotId} ); -- show counter pip
973 UI.AddNumberToPath( 1, endPlotId);
974 UILens.SetLayerHexesPath(g_MovementPath, eLocalPlayer, pathPlots, variations);
975 return;
976 end
977 end
978
979 local pathInfo : table = UnitManager.GetMoveToPathEx( kUnit, endPlotId );
980
981 if table.count(pathInfo.plots) > 1 then
982 -- Start and end art "variations" when drawing path
983 local startHexId:number = kUnit:GetPlotId();
984 local endHexId :number = pathInfo.plots[table.count(pathInfo.plots)];
985
986 -- Don't show the implicit arrow if the unit has no remaining moves
987 -- NOTE: UnitManager.CanStartOperation and kUnit:GetAttacksRemaining both indicate a ranged
988 -- unit with 0 remaining moves can still attack, so we check using kUnit:GetMovesRemaining
989 if kUnit:GetMovesRemaining() > 0 then
990 -- Check if our desired "movement" is actually a ranged attack. Early out if so.
991 local isImplicitRangedAttack :boolean = false;
992
993 local pResults = UnitManager.GetOperationTargets(kUnit, UnitOperationTypes.RANGE_ATTACK );
994 local pAllPlots = pResults[UnitOperationResults.PLOTS];
995 if pAllPlots ~= nil then
996 for i, modifier in ipairs( pResults[UnitOperationResults.MODIFIERS] ) do
997 if modifier == UnitOperationResults.MODIFIER_IS_TARGET then
998 if pAllPlots[i] == endPlotId then
999 isImplicitRangedAttack = true;
1000 break;
1001 end
1002 end
1003 end
1004 end
1005
1006 if isImplicitRangedAttack then
1007 -- Unit can apparently perform a ranged attack on that hex. Show the arrow!
1008 local kVariations:table = {};
1009 local kEmpty:table = {};
1010 table.insert(kVariations, {"EmptyVariant", startHexId, endHexId} );
1011 UILens.SetLayerHexesArea(g_AttackRange, eLocalPlayer, kEmpty, kVariations);
1012
1013 -- Focus must be called AFTER the attack range variants are set.
1014 UILens.FocusHex( g_AttackRange, endHexId );
1015 return; -- We're done here. Do not show a movement path.
1016 end
1017 end
1018
1019 -- Any plots of path in Fog Of War or midfog?
1020 local isPathInFog:boolean = false;
1021 local pPlayerVis :table = PlayersVisibility[eLocalPlayer];
1022 if pPlayerVis ~= nil then
1023 for _,plotIds in pairs(pathInfo.plots) do
1024 isPathInFog = not pPlayerVis:IsVisible(plotIds);
1025 if isPathInFog then
1026 break;
1027 end
1028 end
1029 end
1030
1031 -- If any plots are in Fog Of War (FOW) then switch to the FOW movement lens.
1032 local lensNameBase :string = "MovementGood";
1033 local movePostfix :string = "";
1034 local isPathHaveRestriction,restrictedPlotId = IsPlotPathRestrictedForUnit( pathInfo.plots, pathInfo.turns, kUnit );
1035
1036 if showQueuedPath then
1037 lensNameBase = "MovementQueue";
1038 elseif isPathHaveRestriction then
1039 lensNameBase = "MovementBad";
1040 m_isPlotFlaggedRestricted = true;
1041 if restrictedPlotId ~= nil and restrictedPlotId ~= -1 then
1042 table.insert(variations, {"MovementBad_Destination", restrictedPlotId} );
1043 end
1044 elseif isPathInFog then
1045 lensNameBase = "MovementFOW";
1046 movePostfix = "_FOW";
1047 end
1048 -- Turn on lens.
1049 if not UILens.IsLensActive(lensNameBase) then
1050 UILens.SetActive(lensNameBase);
1051 end
1052
1053 -- is there an enemy unit at the end?
1054 local bIsEnemyAtEnd:boolean = false;
1055 local endPlot :table = Map.GetPlotByIndex(endPlotId);
1056 if( endPlot ~= nil ) then
1057 local unitList = Units.GetUnitsInPlotLayerID( endPlot:GetX(), endPlot:GetY(), MapLayers.ANY );
1058 for i, pUnit in ipairs(unitList) do
1059 if( eLocalPlayer ~= pUnit:GetOwner() and pPlayerVis ~= nil and pPlayerVis:IsVisible(endPlot:GetX(), endPlot:GetY()) and pPlayerVis:IsUnitVisible(pUnit) ) then
1060 bIsEnemyAtEnd = true;
1061 end
1062 end
1063 end
1064
1065 -- Hide the destination indicator only if the attack is guaranteed this turn.
1066 -- Regular movements and attacks planned for later turns still get the indicator.
1067 if not showQueuedPath then
1068 table.insert(variations, {lensNameBase.."_Origin",startHexId} );
1069 end
1070 local nTurnCount :number = pathInfo.turns[table.count( pathInfo.turns )];
1071 if not bIsEnemyAtEnd or nTurnCount > 1 then
1072 table.insert(variations, {lensNameBase.."_Destination",endHexId} );
1073 end
1074
1075 -- Since pathInfo.turns are matched against plots, this should be the same # as above.
1076 if table.count(pathInfo.turns) > 1 then
1077
1078 -- Track any "holes" in the path.
1079 local pathHole:table = {};
1080 for i=1,table.count(pathInfo.plots),1 do
1081 pathHole[i] = true;
1082 end
1083
1084 local lastTurn:number = 1;
1085 for i,value in pairs(pathInfo.turns) do
1086
1087 -- If a new turn entry exists, or it's the very last entry of the path... show turn INFO.
1088 if value > lastTurn then
1089 if i > 1 then
1090 table.insert(variations, {lensNameBase.."_Counter", pathInfo.plots[i-1]} ); -- show counter pip
1091 UI.AddNumberToPath( lastTurn, pathInfo.plots[i-1] );
1092 pathHole[i-1]=false;
1093 end
1094 lastTurn = value;
1095 end
1096 if i == table.count(pathInfo.turns) and i > 1 then
1097 table.insert(variations, {lensNameBase.."_Counter", pathInfo.plots[i]} ); -- show counter pip
1098 UI.AddNumberToPath( lastTurn, pathInfo.plots[i] );
1099 if lastTurn == 2 then
1100 if m_previousTurnsCount == 1 then
1101 UI.PlaySound("UI_Multi_Turn_Movement_Alert");
1102 end
1103 end
1104 m_previousTurnsCount = lastTurn;
1105 pathHole[i]=false;
1106 end
1107 end
1108
1109 -- Any obstacles? (e.g., rivers)
1110 if not showQueuedPath then
1111 local plotIndex:number = 1;
1112 for i,value in pairs(pathInfo.obstacles) do
1113 while( pathInfo.plots[plotIndex] ~= value ) do plotIndex = plotIndex + 1; end -- Get ID to use for river's next plot
1114 table.insert(variations, {lensNameBase.."_Minus", value, pathInfo.plots[plotIndex+1]} );
1115 end
1116 end
1117
1118 -- Any variations not filled in earlier (holes), are filled in with Pips
1119 for i,isHole in pairs(pathHole) do
1120 if isHole then
1121 table.insert(variations, {lensNameBase.."_Pip", pathInfo.plots[i]} ); -- non-counter pip
1122 end
1123 end
1124 end
1125
1126 else
1127 -- No path; is it a bad path or is the player have the cursor on the same hex as the unit?
1128 local startPlotId :number = Map.GetPlot(kUnit:GetX(),kUnit:GetY()):GetIndex();
1129 if startPlotId ~= endPlotId then
1130 if not UILens.IsLensActive("MovementBad") then
1131 UILens.SetActive("MovementBad");
1132 lensNameBase = "MovementBad";
1133 end
1134 table.insert(pathInfo.plots, endPlotId);
1135 table.insert(variations, {"MovementBad_Destination", endPlotId} );
1136 else
1137 table.insert(pathInfo.plots, endPlotId);
1138 table.insert(variations, {"MovementGood_Destination", endPlotId} );
1139 end
1140 end
1141
1142 -- Handle mountain tunnels
1143 -- TODO consider adding variations for entering/exiting portals
1144 local pPathSegment = { };
1145 for i,plot in pairs(pathInfo.plots) do
1146
1147 -- Prepend an exit portal if one exists
1148 local pExit = pathInfo.exitPortals[i];
1149 if (pExit and pExit >= 0) then
1150 table.insert(pPathSegment, pExit);
1151 end
1152
1153 -- Add the next plot to the segment
1154 table.insert(pPathSegment, plot);
1155
1156 -- Append an entrance portal if one exists
1157 local pEntrance = pathInfo.entrancePortals[i];
1158 if (pEntrance and pEntrance >= 0) then
1159 table.insert(pPathSegment, pEntrance);
1160
1161 -- Submit the segment so far and start a new segment
1162 UILens.SetLayerHexesPath(g_MovementPath, eLocalPlayer, pPathSegment, { });
1163 pPathSegment = { };
1164 end
1165 end
1166
1167 -- Submit the final segment
1168 UILens.SetLayerHexesPath(g_MovementPath, eLocalPlayer, pPathSegment, variations);
1169 end
1170end
1171
1172-- ===========================================================================
1173-- Game Engine Event
1174-- ===========================================================================
1175function OnUnitSelectionChanged( playerID:number, unitID:number, hexI:number, hexJ:number, hexK:number, isSelected:boolean, isEditable:boolean )
1176 if playerID ~= Game.GetLocalPlayer() then
1177 return;
1178 end
1179
1180 -- CQUI (Azurency) : Fixes a Vanilla bug from SelectUnit.lua (not taking in account the district range attack)
1181 -- CQUI (Azurency) : If a selection is occuring and the district attack interface mode is up, take it down.
1182 if UI.GetInterfaceMode() == InterfaceModeTypes.DISTRICT_RANGE_ATTACK then
1183 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1184 end
1185
1186 -- Show queued path when unit is selected
1187 if isSelected and not UI.IsGameCoreBusy() then
1188 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1189 if pSelectedUnit and UnitManager.GetQueuedDestination( pSelectedUnit ) then
1190 RealizeMovementPath(true);
1191 end
1192 else
1193 -- Make sure to hide any path when deselecting a unit
1194 ClearMovementPath();
1195 end
1196end
1197
1198-- ===========================================================================
1199function CQUI_BuildImprovement (unit, improvementHash: number)
1200 if unit == nil then return end
1201
1202 local tParameters = {};
1203 tParameters[UnitOperationTypes.PARAM_X] = unit:GetX();
1204 tParameters[UnitOperationTypes.PARAM_Y] = unit:GetY();
1205 tParameters[UnitOperationTypes.PARAM_IMPROVEMENT_TYPE] = improvementHash;
1206
1207 UnitManager.RequestOperation( unit, UnitOperationTypes.BUILD_IMPROVEMENT, tParameters );
1208end
1209
1210-- ===========================================================================
1211function DefaultKeyDownHandler( uiKey:number )
1212 local keyPanChanged :boolean = false;
1213 local keySpinChanged :boolean = false; -- Free Cam
1214
1215 if uiKey == Keys.VK_ALT then
1216 if m_isALTDown == false then
1217 m_isALTDown = true;
1218 EndDragMap();
1219 ReadyForDragMap();
1220 end
1221 end
1222
1223 -- Free Rotation Keybinds
1224 if( uiKey == FreeRotation_CameraResetKey ) then
1225 if IsInDefaultRotation() then RestoreSpin(); else ResetSpin(); end
1226 end
1227
1228 if FreeRotation_useQE_keys then
1229 if ( uiKey == FreeRotation_SpinLeftKey ) then
1230 keySpinChanged = true;
1231 m_isQDown = true;
1232 end
1233 if ( uiKey == FreeRotation_SpinRightKey ) then
1234 keySpinChanged = true;
1235 m_isEDown = true;
1236 end
1237 end
1238
1239 -- Free Rotation: spin the map on key press
1240 if( keySpinChanged == true ) then
1241 AdjustSpin();
1242 end
1243
1244 --CQUI Keybinds
1245 if uiKey == Keys.VK_SHIFT then
1246 -- Free Rotation change: reset drag stuff.
1247 if CQUI_isShiftDown == false then
1248 CQUI_isShiftDown = true;
1249 EndDragMap();
1250 ReadyForDragMap();
1251 end
1252 -- /Free Rotation change
1253 end
1254
1255 if CQUI_hotkeyMode ~= 0 or FreeRotation_useWASD_keys then
1256 if CQUI_hotkeyMode == 2 or FreeRotation_useWASD_keys then
1257 -- Free Rotation change: Override CQUI WASD panning if user changed setting.
1258 if FreeRotation_useWASD_keys then
1259 -- /Free Rotation change
1260 if( uiKey == FreeRotation_UpKey ) then
1261 keyPanChanged = true;
1262 m_isUPpressed = true;
1263 end
1264 if( uiKey == FreeRotation_RightKey ) then
1265 keyPanChanged = true;
1266 m_isRIGHTpressed = true;
1267 end
1268 if( uiKey == FreeRotation_DownKey ) then
1269 keyPanChanged = true;
1270 m_isDOWNpressed = true;
1271 end
1272 if( uiKey == FreeRotation_LeftKey ) then
1273 keyPanChanged = true;
1274 m_isLEFTpressed = true;
1275 end
1276 end
1277 end
1278 end
1279 if( uiKey == Keys.VK_UP ) then
1280 keyPanChanged = true;
1281 m_isUPpressed = true;
1282 end
1283 if( uiKey == Keys.VK_RIGHT ) then
1284 keyPanChanged = true;
1285 m_isRIGHTpressed = true;
1286 end
1287 if( uiKey == Keys.VK_DOWN ) then
1288 keyPanChanged = true;
1289 m_isDOWNpressed = true;
1290 end
1291 if( uiKey == Keys.VK_LEFT ) then
1292 keyPanChanged = true;
1293 m_isLEFTpressed = true;
1294 end
1295 if( keyPanChanged == true ) then
1296 ProcessPan(m_edgePanX,m_edgePanY);
1297 end
1298 return false;
1299end
1300
1301-- ===========================================================================
1302-- ===========================================================================
1303function DefaultKeyUpHandler( uiKey:number )
1304 local keyPanChanged :boolean = false;
1305 local keySpinChanged :boolean = false;
1306
1307 if uiKey == Keys.VK_ALT then
1308 if m_isALTDown == true then
1309 m_isALTDown = false;
1310 EndDragMap();
1311 ReadyForDragMap();
1312 end
1313 end
1314
1315 if uiKey == Keys.VK_SHIFT then
1316 -- Free Rotation change: reset drag stuff on shift.
1317 if CQUI_isShiftDown == true then
1318 CQUI_isShiftDown = false;
1319 EndDragMap();
1320 ReadyForDragMap();
1321 end
1322 -- /Free Rotation change
1323 end
1324
1325 --print("Key Up: " .. uiKey);
1326 local selectedUnit = UI.GetHeadSelectedUnit();
1327 local unitType = nil;
1328 local formationClass = nil;
1329 if selectedUnit then
1330 unitType = GameInfo.Units[selectedUnit:GetUnitType()].UnitType;
1331 formationClass = GameInfo.Units[selectedUnit:GetUnitType()].FormationClass;
1332 --print("Unit Type: " .. unitType .. " Formation Class: " .. formationClass);
1333 end
1334
1335 -- Free Rotation keybinds
1336 if( uiKey == FreeRotation_SpinLeftKey ) then
1337 keySpinChanged = true;
1338 m_isQDown = false;
1339 end
1340
1341 if( uiKey == FreeRotation_SpinRightKey ) then
1342 keySpinChanged = true;
1343 m_isEDown = false;
1344 end
1345
1346 if( keySpinChanged == true ) then
1347 AdjustSpin();
1348 end
1349
1350 if( uiKey == FreeRotation_UpKey ) then
1351 m_isUPpressed = false;
1352 keyPanChanged = true;
1353 end
1354 if( uiKey == FreeRotation_RightKey ) then
1355 m_isRIGHTpressed = false;
1356 keyPanChanged = true;
1357 end
1358 if( uiKey == FreeRotation_DownKey ) then
1359 m_isDOWNpressed = false;
1360 keyPanChanged = true;
1361 end
1362 if( uiKey == FreeRotation_LeftKey ) then
1363 m_isLEFTpressed = false;
1364 keyPanChanged = true;
1365 end
1366
1367 if( uiKey == Keys.VK_UP ) then
1368 m_isUPpressed = false;
1369 keyPanChanged = true;
1370 end
1371 if( uiKey == Keys.VK_RIGHT ) then
1372 m_isRIGHTpressed = false;
1373 keyPanChanged = true;
1374 end
1375 if( uiKey == Keys.VK_DOWN ) then
1376 m_isDOWNpressed = false;
1377 keyPanChanged = true;
1378 end
1379 if( uiKey == Keys.VK_LEFT ) then
1380 m_isLEFTpressed = false;
1381 keyPanChanged = true;
1382 end
1383
1384 if( keyPanChanged == true ) then
1385 ProcessPan(m_edgePanX,m_edgePanY);
1386 end
1387
1388 --CQUI Keybinds
1389 if CQUI_hotkeyMode ~= 0 then
1390 if CQUI_hotkeyMode == 2 then
1391
1392 if ( ((CQUI_isShiftDown) and ( uiKey == Keys.E )) or ((not FreeRotation_useQE_keys) and (uiKey == Keys.E)) ) then
1393 if(CQUI_cityview) then
1394 LuaEvents.CQUI_GoNextCity();
1395 else
1396 UI.SelectNextReadyUnit();
1397 end
1398 end
1399 if ( ((CQUI_isShiftDown) and ( uiKey == Keys.Q )) or ((not FreeRotation_useQE_keys) and (uiKey == Keys.Q)) ) then
1400 if(CQUI_cityview) then
1401 LuaEvents.CQUI_GoPrevCity();
1402 else
1403 UI.SelectPrevReadyUnit();
1404 end
1405 end
1406 if ( ( ( (uiKey == Keys.VK_SHIFT) and (not FreeRotation_useShiftRotate) ) or ( FreeRotation_useShiftRotate and (uiKey == AlternativeShiftCycle) ) )
1407 and ContextPtr:LookUpControl("/InGame/TechTree"):IsHidden() and ContextPtr:LookUpControl("/InGame/CivicsTree"):IsHidden()) then
1408 if(CQUI_cityview) then
1409 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1410 UI.SelectNextReadyUnit();
1411 else
1412 LuaEvents.CQUI_GoNextCity();
1413 end
1414 end
1415 else --Classic binds that would overlap with the enhanced binds
1416 if( uiKey == Keys.Q ) and UI.GetHeadSelectedUnit() then
1417 if (unitType == "UNIT_BUILDER") then
1418 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), -80493497); --Quarry
1419 end
1420 end
1421 if( uiKey == Keys.S ) and UI.GetHeadSelectedUnit() then
1422 UnitManager.RequestCommand(UI.GetHeadSelectedUnit(), UnitOperationTypes.AIR_ATTACK);
1423 end
1424 end
1425 -- Fortify until healed hotkey
1426 if( uiKey == Keys.H ) and UI.GetHeadSelectedUnit() then
1427 if (unitType ~= nil) then -- OPTIMIZATION -- if unit health 100% alert not heal
1428 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), 2126026491); -- OH MY GOD IT WAS SO HARD TO FIND THAT ID. WHAT WAS FIRAXIS THINKING
1429 end
1430 return;
1431 end
1432 -- Focus Capital hotkey
1433 if( uiKey == Keys.VK_HOME ) then
1434 UI.SelectCity(Players[Game.GetLocalPlayer()]:GetCities():GetCapitalCity());
1435 end
1436 if( uiKey == Keys.VK_BACK ) then
1437 if (unitType ~= nil) and UI.GetHeadSelectedUnit() then
1438 UnitManager.RequestCommand(UI.GetHeadSelectedUnit(), UnitCommandTypes.CANCEL);
1439 end
1440 end
1441 if( uiKey == Keys.I ) and UI.GetHeadSelectedUnit()then
1442 if (unitType == "UNIT_BUILDER") then
1443 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 168372657); --Farm
1444 end
1445 end
1446 if( uiKey == Keys.P ) then
1447 if ( CQUI_isShiftDown) then
1448 CQUI_isShiftDown = false;
1449 PlaceMapPin();
1450 else
1451 if (unitType == "UNIT_BUILDER") and UI.GetHeadSelectedUnit() then
1452 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 154488225); --Pasture
1453 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 1523996587); --Plantation
1454 end
1455 end
1456 end
1457 if( uiKey == Keys.N ) and UI.GetHeadSelectedUnit() then
1458 if (unitType == "UNIT_BUILDER") then
1459 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 1001859687); --Mine
1460 else
1461 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), UnitOperationTypes.WMD_STRIKE);
1462 end
1463 end
1464 if( uiKey == Keys.H ) and UI.GetHeadSelectedUnit() then
1465 if (unitType == "UNIT_BUILDER") then
1466 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), -1819558972); --Camp
1467 end
1468 end
1469 if( uiKey == Keys.L ) and UI.GetHeadSelectedUnit() then
1470 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 2048582848); --Lumber Mill
1471 end
1472 if( uiKey == Keys.R ) and UI.GetHeadSelectedUnit() then
1473 if (unitType == "UNIT_MILITARY_ENGINEER") then
1474 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 115772143); --Road
1475 elseif (formationClass == "FORMATION_CLASS_AIR") then
1476 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), UnitOperationTypes.REBASE);
1477 else
1478 return false;
1479 end
1480 end
1481 if( uiKey == Keys.F ) and UI.GetHeadSelectedUnit() then
1482 if (unitType == "UNIT_BUILDER") then
1483 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 578093457); --Fishing Boats
1484 elseif (unitType == "UNIT_MILITARY_ENGINEER") then
1485 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), 1694280827); --Fort
1486 else
1487 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), -744032280); --Sleep
1488 end
1489 end
1490 if( uiKey == Keys.Z ) and UI.GetHeadSelectedUnit() then
1491 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), -41338758); --Sleep
1492 end
1493 if( uiKey == Keys.O ) and UI.GetHeadSelectedUnit() then
1494 if (unitType == "UNIT_BUILDER") then
1495 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), -1355513600); --Oil Well
1496 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), -396628467); --Offshore Platform
1497 end
1498 end
1499 if( m_isALTDown ) then --Overridden classic binds get an alt-version as well as the normal alt-shortcuts
1500 if( uiKey == Keys.C ) and UI.GetHeadSelectedUnit() then
1501 if (unitType == "UNIT_BUILDER") or (unitType == "UNIT_MILITARY_ENGINEER") then
1502 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), UnitOperationTypes.HARVEST_RESOURCE);
1503 UnitManager.RequestOperation(UI.GetHeadSelectedUnit(), UnitOperationTypes.REMOVE_FEATURE);
1504 end
1505 end
1506 if( uiKey == Keys.Q ) and UI.GetHeadSelectedUnit() then
1507 CQUI_BuildImprovement(UI.GetHeadSelectedUnit(), -80493497); --Quarry
1508 end
1509 if( uiKey == Keys.S ) and UI.GetHeadSelectedUnit() then
1510 if (formationClass == "FORMATION_CLASS_AIR") then
1511 UnitManager.RequestCommand(UI.GetHeadSelectedUnit(), UnitOperationTypes.AIR_ATTACK);
1512 end
1513 end
1514 end
1515 end
1516
1517 if( uiKey == Keys.VK_ADD or uiKey == Keys.VK_SUBTRACT ) then
1518 local oldZoom = UI.GetMapZoom();
1519 if( uiKey == Keys.VK_ADD ) then
1520 UI.SetMapZoom( oldZoom - ZOOM_SPEED, 0.0, 0.0 );
1521 elseif( uiKey == Keys.VK_SUBTRACT ) then
1522 UI.SetMapZoom( oldZoom + ZOOM_SPEED, 0.0, 0.0 );
1523 end
1524 return true;
1525 end
1526
1527 return false;
1528end
1529
1530
1531-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
1532--
1533-- INPUT STATE
1534--
1535-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
1536
1537-- ===========================================================================
1538function OnBlockInput()
1539 m_isInputBlocked = true;
1540end
1541
1542-- ===========================================================================
1543function OnUnblockInput()
1544 m_isInputBlocked = false;
1545 ClearAllCachedInputState();
1546end
1547
1548-- ===========================================================================
1549function OnDefaultKeyDown( pInputStruct:table )
1550 if m_isInputBlocked then return; end
1551 local uiKey :number = pInputStruct:GetKey();
1552 return DefaultKeyDownHandler( uiKey );
1553end
1554
1555-- ===========================================================================
1556function OnDefaultKeyUp( pInputStruct:table )
1557 if m_isInputBlocked then return; end
1558 local uiKey :number = pInputStruct:GetKey();
1559 return DefaultKeyUpHandler( uiKey );
1560end
1561
1562-- ===========================================================================
1563-- Placing a building, wonder, or district; ESC to leave
1564-- ===========================================================================
1565function OnPlacementKeyUp( pInputStruct:table )
1566 if m_isInputBlocked then return; end
1567 local uiKey :number = pInputStruct:GetKey();
1568 if uiKey == Keys.VK_ESCAPE then
1569 if UI.GetInterfaceMode() ~= InterfaceModeTypes.SELECTION then
1570 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1571 return true;
1572 elseif UI.GetHeadSelectedCity() ~= nil then
1573 UI.DeselectAllCities();
1574 return true;
1575 end
1576 end
1577 return DefaultKeyUpHandler( uiKey );
1578end
1579
1580
1581-- ===========================================================================
1582function TogglePause()
1583 local localPlayerID = Network.GetLocalPlayerID();
1584 local localPlayerConfig = PlayerConfigurations[localPlayerID];
1585 local newPause = not localPlayerConfig:GetWantsPause();
1586 localPlayerConfig:SetWantsPause(newPause);
1587 Network.BroadcastPlayerInfo();
1588end
1589
1590-- ===========================================================================
1591function OnDefaultChangeToSelectionMode( pInputStruct )
1592 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1593end
1594
1595-- ===========================================================================
1596function OnMouseDebugEnd( pInputStruct:table )
1597 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1598 -- is in the plot the mouse is currently at.
1599 if g_isMouseDragging then
1600 print_debug("Stopping drag");
1601 g_isMouseDragging = false;
1602
1603 else
1604 print_debug("Debug placing!!!");
1605 local plotID:number = UI.GetCursorPlotID();
1606 if (Map.IsPlot(plotID)) then
1607 local edge = UI.GetCursorNearestPlotEdge();
1608 DebugPlacement( plotID, edge );
1609 end
1610 end
1611 EndDragMap(); -- Reset any dragging
1612 g_isMouseDownInWorld = false;
1613 return true;
1614
1615end
1616
1617-- ===========================================================================
1618function OnDebugCancelPlacement( pInputStruct )
1619 local plotID:number = UI.GetCursorPlotID();
1620 if (Map.IsPlot(plotID)) then
1621 local edge = UI.GetCursorNearestPlotEdge();
1622 local plot:table = Map.GetPlotByIndex(plotID);
1623 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
1624 worldX, worldY, worldZ = UI.GetWorldFromNormalizedScreenPos(normalizedX, normalizedY);
1625
1626 -- Communicate this to the TunerMapPanel handler
1627 LuaEvents.TunerMapRButtonDown(plot:GetX(), plot:GetY(), worldX, worldY, worldZ, edge);
1628 end
1629 return true;
1630end
1631
1632-- ===========================================================================
1633function OnInterfaceModeChange_Debug( eNewMode:number )
1634 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1635end
1636
1637
1638-- ===========================================================================
1639function OnInterfaceModeEnter_CityManagement( eNewMode:number )
1640 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1641 -- AZURENCY : fix the Appeal lens not being applied in city view
1642 --UILens.SetActive("CityManagement");
1643end
1644
1645-- ===========================================================================
1646function OnInterfaceModeLeave_CityManagement( eNewMode:number )
1647 UIManager:SetUICursor(CursorTypes.NORMAL);
1648 UILens.SetActive("Default");
1649end
1650
1651
1652-- ===========================================================================
1653function OnMouseSelectionEnd( pInputStruct:table )
1654 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1655 -- is in the plot the mouse is currently at.
1656 if g_isMouseDragging then
1657 g_isMouseDragging = false;
1658 else
1659 -- If something (such as the tutorial) hasn't disabled mouse deslecting.
1660 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1661 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
1662 SelectInPlot( plotX, plotY );
1663 end
1664 end
1665 EndDragMap(); -- Reset any dragging
1666 g_isMouseDownInWorld = false;
1667 return true;
1668end
1669
1670-- ===========================================================================
1671function OnMouseSelectionMove( pInputStruct:table )
1672
1673 if not g_isMouseDownInWorld then
1674 return false;
1675 end
1676
1677 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
1678 if g_isMouseDragging then
1679 UpdateDragMap();
1680 return true;
1681 else
1682 if m_isMouseButtonLDown then
1683 -- A mouse button is down but isn't currently marked for "dragging",
1684 -- do some maths to see if this is actually a drag state.
1685 if not g_isMouseDragging then
1686 if IsDragThreshholdMet() then
1687 g_isMouseDragging = true;
1688 StartDragMap();
1689 end
1690 end
1691 end
1692
1693 local playerID :number = Game.GetLocalPlayer();
1694 if playerID == -1 or (not Players[playerID]:IsTurnActive()) then
1695 return false;
1696 end
1697
1698 if m_isMouseButtonRDown then
1699 RealizeMovementPath();
1700 end
1701 end
1702 return false;
1703end
1704
1705-- ===========================================================================
1706function OnMouseSelectionUnitMoveStart( pInputStruct:table )
1707 g_isMouseDownInWorld = true;
1708 RealizeMovementPath();
1709 return true;
1710end
1711
1712-- ===========================================================================
1713function OnMouseSelectionUnitMoveEnd( pInputStruct:table )
1714 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1715 if pSelectedUnit ~= nil then
1716 local playerID :number = Game.GetLocalPlayer();
1717 if playerID ~= -1 and Players[playerID]:IsTurnActive() then
1718 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1719 MoveUnitToCursorPlot( pSelectedUnit );
1720 else
1721 UnitMovementCancel();
1722 end
1723 end
1724 else
1725 UnitMovementCancel();
1726 end
1727 g_isMouseDownInWorld = false;
1728 return true;
1729end
1730
1731-- ===========================================================================
1732function OnMouseSelectionSnapToPlot( pInputStruct:table )
1733 local plotId :number= UI.GetCursorPlotID();
1734 SnapToPlot( plotId );
1735end
1736
1737-- ===========================================================================
1738function OnMouseMove( pInputStruct:table )
1739
1740 if not g_isMouseDownInWorld then
1741 return false;
1742 end
1743
1744 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
1745 if g_isMouseDragging then
1746 UpdateDragMap();
1747 return true;
1748 else
1749 if m_isMouseButtonLDown then
1750 -- A mouse button is down but isn't currently marked for "dragging".
1751 if not g_isMouseDragging then
1752 if IsDragThreshholdMet() then
1753 g_isMouseDragging = true;
1754 StartDragMap();
1755 end
1756 end
1757 end
1758 end
1759 return false;
1760end
1761
1762
1763-- ===========================================================================
1764-- Common way for mouse to function with a press start.
1765-- ===========================================================================
1766function OnMouseStart( pInputStruct:table )
1767 ReadyForDragMap();
1768 g_isMouseDownInWorld = true;
1769 return true;
1770end
1771
1772-- ===========================================================================
1773function OnMouseEnd( pInputStruct:table )
1774 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1775 -- is in the plot the mouse is currently at.
1776 if g_isMouseDragging then
1777 g_isMouseDragging = false;
1778 end
1779 EndDragMap(); -- Reset any dragging
1780 g_isMouseDownInWorld = false;
1781 return true;
1782end
1783
1784-- ===========================================================================
1785-- Zoom
1786-- ===========================================================================
1787function OnMouseWheelZoom( pInputStruct:table )
1788 local wheelValue = pInputStruct:GetWheel() * (-( (1.0/12000.0) * MOUSE_SCALAR)); -- Wheel values come in as multiples of 120, make it so that one 'click' is %1, modified by a speed scalar.
1789 local normalizedX :number, normalizedY:number = UIManager:GetNormalizedMousePos();
1790 local oldZoom = UI.GetMapZoom();
1791 local newZoom = oldZoom + wheelValue;
1792
1793 if( wheelValue < 0.0 ) then
1794 --UI.SetMapZoom( newZoom, normalizedX, normalizedY );
1795 UI.SetMapZoom( newZoom, 0.0, 0.0 );
1796 else
1797 --UI.SetMapZoom( newZoom, normalizedX, normalizedY );
1798 UI.SetMapZoom( newZoom, 0.0, 0.0 );
1799 end
1800
1801 return true;
1802end
1803
1804-- ===========================================================================
1805-- Either Mouse Double-Click or Touch Double-Tap
1806-- ===========================================================================
1807function OnSelectionDoubleTap( pInputStruct:table )
1808 -- Determine if mouse or touch...
1809 if g_isMouseDownInWorld then
1810 -- Ignore if mouse.
1811 else
1812 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1813 if pSelectedUnit ~= nil then
1814 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1815 MoveUnitToCursorPlot( pSelectedUnit );
1816 end
1817 m_isDoubleTapping = true;
1818 return true;
1819 end
1820 end
1821 return false;
1822end
1823
1824-- ===========================================================================
1825function OnMouseMakeTradeRouteEnd( pInputStruct:table )
1826 -- If a drag was occurring, end it; otherwise raise event.
1827 if g_isMouseDragging then
1828 g_isMouseDragging = false;
1829 else
1830 local plotId:number = UI.GetCursorPlotID();
1831 if (Map.IsPlot(plotId)) then
1832 UI.PlaySound("Play_UI_Click");
1833 LuaEvents.WorldInput_MakeTradeRouteDestination( plotId );
1834 end
1835 end
1836 EndDragMap();
1837 g_isMouseDownInWorld = true;
1838 return true;
1839end
1840
1841-- ===========================================================================
1842function OnMouseMakeTradeRouteSnapToPlot( pInputStruct:table )
1843 local plotId :number= UI.GetCursorPlotID();
1844 SnapToPlot( plotId );
1845end
1846
1847-- ===========================================================================
1848function OnMouseTeleportToCityEnd( pInputStruct:table )
1849 -- If a drag was occurring, end it; otherwise raise event.
1850 if g_isMouseDragging then
1851 g_isMouseDragging = false;
1852 else
1853 TeleportToCity();
1854 end
1855 EndDragMap();
1856 g_isMouseDownInWorld = true;
1857 return true;
1858end
1859
1860-- ===========================================================================
1861function OnMouseTeleportToCitySnapToPlot( pInputStruct:table )
1862 local plotId :number= UI.GetCursorPlotID();
1863 SnapToPlot( plotId );
1864end
1865
1866-- ===========================================================================
1867function OnMouseBuildingPlacementEnd( pInputStruct:table )
1868 -- If a drag was occurring, end it; otherwise raise event.
1869 if g_isMouseDragging then
1870 g_isMouseDragging = false;
1871 else
1872 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1873 ConfirmPlaceWonder(pInputStruct); -- StrategicView_MapPlacement.lua
1874 end
1875 end
1876 EndDragMap();
1877 g_isMouseDownInWorld = false;
1878 return true;
1879end
1880
1881-- ===========================================================================
1882function OnMouseBuildingPlacementCancel( pInputStruct:table )
1883 if IsCancelAllowed() then
1884 LuaEvents.CQUI_CityviewEnable();
1885 --ExitPlacementMode( true );
1886 end
1887end
1888
1889-- ===========================================================================
1890function OnMouseBuildingPlacementMove( pInputStruct:table)
1891 OnMouseMove( pInputStruct );
1892 RealizeCurrentPlaceDistrictOrWonderPlot();
1893end
1894
1895-- ===========================================================================
1896function OnMouseDistrictPlacementEnd( pInputStruct:table )
1897 -- If a drag was occurring, end it; otherwise raise event.
1898 if g_isMouseDragging then
1899 g_isMouseDragging = false;
1900 else
1901 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1902 ConfirmPlaceDistrict(pInputStruct);
1903 end
1904 end
1905 EndDragMap();
1906 g_isMouseDownInWorld = false;
1907 return true;
1908end
1909
1910-- ===========================================================================
1911function OnMouseDistrictPlacementCancel( pInputStruct:table )
1912 if IsCancelAllowed() then
1913 LuaEvents.StoreHash(0);
1914 LuaEvents.CQUI_CityviewEnable();
1915 --ExitPlacementMode( true );
1916 end
1917end
1918
1919-- ===========================================================================
1920function OnMouseDistrictPlacementMove( pInputStruct:table)
1921 OnMouseMove( pInputStruct );
1922 RealizeCurrentPlaceDistrictOrWonderPlot();
1923end
1924
1925-- ===========================================================================
1926function OnMouseUnitRangeAttack( pInputStruct:table )
1927 if ClearRangeAttackDragging() then
1928 return true;
1929 end
1930
1931 local plotID:number = UI.GetCursorPlotID();
1932 if (Map.IsPlot(plotID)) then
1933 UnitRangeAttack( plotID );
1934 end
1935 return true;
1936end
1937
1938-- ===========================================================================
1939function OnMouseMoveRangeAttack( pInputStruct:table )
1940 OnMouseMove( pInputStruct );
1941
1942 local plotID:number = UI.GetCursorPlotID();
1943
1944 if (Map.IsPlot(plotID)) then
1945 if m_focusedTargetPlot ~= plotID then
1946 if m_focusedTargetPlot ~= -1 then
1947 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
1948 m_focusedTargetPlot = -1;
1949 end
1950
1951 if (g_targetPlots ~= nil) then
1952 local bPlotIsTarget:boolean = false;
1953 for i=1,#g_targetPlots do
1954 if g_targetPlots[i] == plotID then
1955 bPlotIsTarget = true;
1956 break;
1957 end
1958 end
1959
1960 if bPlotIsTarget then
1961 m_focusedTargetPlot = plotID;
1962 UILens.FocusHex(g_AttackRange, plotID);
1963 end
1964 end
1965 end
1966 end
1967 return true;
1968end
1969
1970-- ===========================================================================
1971function OnMouseMoveToStart( pInputStruct:table )
1972 ReadyForDragMap();
1973 g_isMouseDownInWorld = true;
1974 return true;
1975end
1976
1977-- ===========================================================================
1978function OnMouseMoveToEnd( pInputStruct:table )
1979 -- Stop a dragging or kick off a move selection.
1980 if g_isMouseDragging then
1981 g_isMouseDragging = false;
1982 else
1983 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1984 if pSelectedUnit ~= nil and IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1985 MoveUnitToCursorPlot( pSelectedUnit );
1986 else
1987 UnitMovementCancel();
1988 end
1989 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
1990 end
1991 EndDragMap();
1992 g_isMouseDownInWorld = false;
1993 return true;
1994end
1995
1996-- ===========================================================================
1997function OnMouseMoveToUpdate( pInputStruct:table )
1998
1999 if g_isMouseDownInWorld then
2000 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
2001 if g_isMouseDragging then
2002 UpdateDragMap();
2003 else
2004 if m_isMouseButtonLDown then
2005 -- A mouse button is down but isn't currently marked for "dragging",
2006 -- do some maths to see if this is actually a drag state.
2007 if not g_isMouseDragging then
2008 if IsDragThreshholdMet() then
2009 g_isMouseDragging = true;
2010 StartDragMap();
2011 end
2012 end
2013 end
2014 end
2015 end
2016 RealizeMovementPath();
2017 return true;
2018end
2019
2020-- ===========================================================================
2021function OnMouseMoveToCancel( pInputStruct:table )
2022 UnitMovementCancel();
2023 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
2024 return true;
2025end
2026
2027
2028-- ===========================================================================
2029-- Start touch, until release or move, do not take action.
2030-- ===========================================================================
2031function OnTouchDebugEnd( pInputStruct:table )
2032
2033 -- If last touch in a sequence or double tapping.
2034 if m_touchCount > 0 then
2035 return true;
2036 end
2037
2038 -- If a drag was occurring, end it; otherwise attempt selection of whatever
2039 -- is in the plot the mouse is currently at.
2040 if m_isTouchDragging then
2041 m_isTouchDragging = false;
2042 else
2043 if m_touchTotalNum == 1 then
2044 print_debug("Debug placing!!!");
2045 local plotID:number = UI.GetCursorPlotID();
2046 if (Map.IsPlot(plotID)) then
2047 local edge = UI.GetCursorNearestPlotEdge();
2048 DebugPlacement( plotID, edge );
2049 end
2050 else
2051 print_debug("Debug removing!!!");
2052 OnDebugCancelPlacement( pInputStruct );
2053 end
2054 end
2055
2056 EndDragMap(); -- Reset any dragging
2057 m_touchTotalNum = 0;
2058 m_isTouchZooming = false;
2059 m_touchStartPlotX = -1;
2060 m_touchStartPlotY = -1;
2061 return true;
2062end
2063
2064function OnTouchSelectionStart( pInputStruct:table )
2065 -- Determine maximum # of touches that have occurred.
2066 if m_touchCount > m_touchTotalNum then
2067 m_touchTotalNum = m_touchCount;
2068 end
2069
2070 -- If the first touch then obtain the plot the touch started in.
2071 if m_touchTotalNum == 1 then
2072 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
2073 m_touchStartPlotX, m_touchStartPlotY = UI.GetPlotCoordFromNormalizedScreenPos(normalizedX, normalizedY);
2074
2075 -- Potentially draw path based on if a unit is selected.
2076 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
2077 if pSelectedUnit ~= nil and m_touchStartPlotX == pSelectedUnit:GetX() and m_touchStartPlotY == pSelectedUnit:GetY() then
2078 m_isTouchPathing = true;
2079 RealizeMovementPath();
2080 else
2081 -- No unit selected to draw a path, the player is either about to
2082 -- start a drag or is just now selecting a unit.
2083 ReadyForDragMap();
2084 end
2085 end
2086 return true;
2087end
2088
2089
2090-- ===========================================================================
2091function OnTouchSelectionUpdate( pInputStruct:table )
2092
2093 -- Determine maximum # of touches that have occurred.
2094 if m_touchCount > m_touchTotalNum then
2095 m_touchTotalNum = m_touchCount;
2096 end
2097
2098 RealizeTouchGestureZoom();
2099
2100 -- If more than one touch ever occured; take no more actions.
2101 if m_touchTotalNum > 1 then
2102 return true;
2103 end
2104
2105 -- Drawing a path or dragging?
2106 if m_isTouchPathing then
2107 RealizeMovementPath();
2108 else
2109 if m_isTouchDragging then
2110 UpdateDragMap();
2111 else
2112 if IsDragThreshholdMet() then
2113 g_isMouseDragging = true;
2114 StartDragMap();
2115 end
2116 end
2117 end
2118 return true;
2119end
2120
2121-- ===========================================================================
2122function OnTouchSelectionEnd( pInputStruct:table )
2123
2124 -- If last touch in a sequence or double tapping.
2125 if m_touchCount > 0 then
2126 return true;
2127 end
2128
2129 if m_isDoubleTapping then
2130 -- If a double tap just happened, clear out.
2131 m_isDoubleTapping = false;
2132 m_isTouchPathing = false;
2133 m_isTouchDragging = false;
2134 else
2135 -- Moving a unit?
2136 if m_isTouchPathing then
2137 m_isTouchPathing = false;
2138 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
2139 if pSelectedUnit ~= nil then
2140 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
2141 MoveUnitToCursorPlot( pSelectedUnit );
2142 else
2143 UnitMovementCancel();
2144 end
2145 else
2146 UnitMovementCancel();
2147 end
2148 else
2149 -- Selection or Dragging
2150 if m_isTouchDragging then
2151 m_isTouchDragging = false;
2152 else
2153 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
2154 if plotX == m_touchStartPlotX and plotY == m_touchStartPlotY then
2155 SelectInPlot( plotX, plotY );
2156 end
2157 end
2158 end
2159 end
2160
2161 EndDragMap();
2162 m_touchTotalNum = 0;
2163 m_isTouchZooming = false;
2164 m_touchStartPlotX = -1;
2165 m_touchStartPlotY = -1;
2166 return true;
2167end
2168
2169-- ===========================================================================
2170-- Common start for touch
2171-- ===========================================================================
2172function OnTouchStart( pInputStruct:table )
2173 if m_touchCount > m_touchTotalNum then
2174 m_touchTotalNum = m_touchCount;
2175 end
2176
2177 -- If the first touch then obtain the plot the touch started in.
2178 if m_touchTotalNum == 1 then
2179 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
2180 m_touchStartPlotX, m_touchStartPlotY = UI.GetPlotCoordFromNormalizedScreenPos(normalizedX, normalizedY);
2181 ReadyForDragMap();
2182 end
2183 return true;
2184end
2185
2186-- ===========================================================================
2187-- Common update for touch
2188-- ===========================================================================
2189function OnTouchUpdate( pInputStruct:table )
2190 -- Determine maximum # of touches that have occurred.
2191 if m_touchCount > m_touchTotalNum then
2192 m_touchTotalNum = m_touchCount;
2193 end
2194
2195 RealizeTouchGestureZoom();
2196
2197 -- If more than one touch ever occured; take no more actions.
2198 if m_touchTotalNum > 1 then
2199 return true;
2200 end
2201
2202 if m_isTouchDragging then
2203 UpdateDragMap();
2204 else
2205 if IsDragThreshholdMet() then
2206 g_isMouseDragging = true;
2207 StartDragMap();
2208 end
2209 end
2210 return true;
2211end
2212
2213
2214-- ===========================================================================
2215function OnTouchTradeRouteEnd( pInputStruct:table )
2216
2217 -- If last touch in a sequence or double tapping.
2218 if m_touchCount > 0 then
2219 return true;
2220 end
2221
2222 -- Selection or Dragging
2223 if m_isTouchDragging then
2224 m_isTouchDragging = false;
2225 else
2226 local plotId:number = UI.GetCursorPlotID();
2227 if (Map.IsPlot(plotId)) then
2228 LuaEvents.WorldInput_MakeTradeRouteDestination( plotId );
2229 end
2230 end
2231
2232 EndDragMap();
2233 m_touchTotalNum = 0;
2234 m_isTouchZooming = false;
2235 m_touchStartPlotX = -1;
2236 m_touchStartPlotY = -1;
2237 return true;
2238end
2239
2240-- ===========================================================================
2241function OnTouchTeleportToCityEnd( pInputStruct:table )
2242
2243 -- If last touch in a sequence or double tapping.
2244 if m_touchCount > 0 then
2245 return true;
2246 end
2247
2248 -- Selection or Dragging
2249 if m_isTouchDragging then
2250 m_isTouchDragging = false;
2251 else
2252 TeleportToCity();
2253 end
2254
2255 EndDragMap();
2256 m_touchTotalNum = 0;
2257 m_isTouchZooming = false;
2258 m_touchStartPlotX = -1;
2259 m_touchStartPlotY = -1;
2260 return true;
2261end
2262
2263-- ===========================================================================
2264function OnTouchDistrictPlacementEnd( pInputStruct:table )
2265 ConfirmPlaceDistrict(pInputStruct);
2266end
2267
2268-- ===========================================================================
2269function OnTouchBuildingPlacementEnd( pInputStruct:table )
2270 ConfirmPlaceWonder(pInputStruct);
2271end
2272
2273-- ===========================================================================
2274function OnTouchMoveToStart( pInputStruct:table )
2275 return true;
2276end
2277
2278-- ===========================================================================
2279function OnTouchMoveToUpdate( pInputStruct:table )
2280 -- Determine maximum # of touches that have occurred.
2281 if m_touchCount > m_touchTotalNum then
2282 m_touchTotalNum = m_touchCount;
2283 end
2284
2285 if m_touchTotalNum == 1 then
2286 RealizeMovementPath();
2287 else
2288 UnitMovementCancel();
2289 end
2290 return true;
2291end
2292
2293-- ===========================================================================
2294function OnTouchMoveToEnd( pInputStruct:table )
2295 -- If last touch in a sequence or double tapping.
2296 if m_touchCount > 0 then
2297 return true;
2298 end
2299
2300 if m_touchTotalNum == 1 then
2301 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
2302 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
2303 MoveUnitToCursorPlot( pSelectedUnit );
2304 else
2305 UnitMovementCancel();
2306 end
2307 else
2308 UnitMovementCancel();
2309 end
2310
2311 m_touchTotalNum = 0;
2312 m_isTouchZooming = false;
2313 m_touchStartPlotX = -1;
2314 m_touchStartPlotY = -1;
2315 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
2316 return true;
2317end
2318
2319-- ===========================================================================
2320function OnTouchUnitRangeAttack( pInputStruct:table )
2321 local plotID:number = UI.GetCursorPlotID();
2322 if (Map.IsPlot(plotID)) then
2323 UnitRangeAttack( plotID );
2324 end
2325 return true;
2326end
2327
2328
2329-------------------------------------------------------------------------------
2330function OnInterfaceModeChange_UnitRangeAttack(eNewMode)
2331 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2332 local pSelectedUnit = UI.GetHeadSelectedUnit();
2333 if (pSelectedUnit ~= nil) then
2334
2335 if m_focusedTargetPlot ~= -1 then
2336 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
2337 m_focusedTargetPlot = -1;
2338 end
2339
2340 local unitPlotID = pSelectedUnit:GetPlotId();
2341 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.RANGE_ATTACK );
2342 local allPlots = tResults[UnitOperationResults.PLOTS];
2343 if (allPlots ~= nil) then
2344 g_targetPlots = {};
2345 for i,modifier in ipairs(tResults[UnitOperationResults.MODIFIERS]) do
2346 if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
2347 table.insert(g_targetPlots, allPlots[i]);
2348 end
2349 end
2350
2351 -- Highlight the plots available to attack
2352 if (table.count(g_targetPlots) ~= 0) then
2353 -- Variation will hold specific targets in range
2354 local kVariations:table = {};
2355 for _,targetPlotId in ipairs(g_targetPlots) do
2356 -- Variant needed to place the attack arc, but we don't want to double-draw the crosshair on the hex.
2357 table.insert(kVariations, {"EmptyVariant", unitPlotID, targetPlotId} );
2358 end
2359 local eLocalPlayer:number = Game.GetLocalPlayer();
2360
2361 UILens.SetLayerHexesArea(g_AttackRange, eLocalPlayer, allPlots, kVariations);
2362 end
2363 end
2364 end
2365end
2366
2367-------------------------------------------------------------------------------
2368function OnInterfaceModeLeave_UnitRangeAttack(eNewMode)
2369 UILens.ClearLayerHexes( g_AttackRange );
2370end
2371
2372-- ===========================================================================
2373-- Code related to the Unit Air Attack interface mode
2374-- ===========================================================================
2375function UnitAirAttack( pInputStruct )
2376 local plotID = UI.GetCursorPlotID();
2377 if (Map.IsPlot(plotID)) then
2378 local plot = Map.GetPlotByIndex(plotID);
2379 local plotX = plot:GetX();
2380 local plotY = plot:GetY();
2381 local tParameters = {};
2382 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2383 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2384
2385 local pSelectedUnit = UI.GetHeadSelectedUnit();
2386 local eAttackingPlayer = pSelectedUnit:GetOwner();
2387 local eUnitComponentID:table = pSelectedUnit:GetComponentID();
2388
2389 local bWillStartWar = false;
2390 local results:table;
2391 if (PlayersVisibility[eAttackingPlayer]:IsVisible(plotX, plotY)) then
2392 results = CombatManager.IsAttackChangeWarState(eUnitComponentID, plotX, plotY);
2393 if (results ~= nil and #results > 0) then
2394 bWillStartWar = true;
2395 end
2396 end
2397
2398 if (bWillStartWar) then
2399 local eDefendingPlayer = results[1];
2400 LuaEvents.Civ6Common_ConfirmWarDialog(eAttackingPlayer, eDefendingPlayer, WarTypes.SURPRISE_WAR);
2401 else
2402 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.AIR_ATTACK, nil, tParameters)) then
2403 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.AIR_ATTACK, tParameters);
2404 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2405 end
2406 end
2407 end
2408 return true;
2409end
2410-------------------------------------------------------------------------------
2411function OnInterfaceModeChange_Air_Attack(eNewMode)
2412 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2413 local pSelectedUnit = UI.GetHeadSelectedUnit();
2414 if (pSelectedUnit ~= nil) then
2415
2416 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.AIR_ATTACK );
2417 local allPlots = tResults[UnitOperationResults.PLOTS];
2418 if (allPlots ~= nil) then
2419 g_targetPlots = {};
2420 for i,modifier in ipairs(tResults[UnitOperationResults.MODIFIERS]) do
2421 if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
2422 table.insert(g_targetPlots, allPlots[i]);
2423 end
2424 end
2425
2426 -- Highlight the plots available to attack
2427 if (table.count(g_targetPlots) ~= 0) then
2428 local eLocalPlayer:number = Game.GetLocalPlayer();
2429 UILens.ToggleLayerOn(g_HexColoringAttack);
2430 UILens.SetLayerHexesArea(g_HexColoringAttack, eLocalPlayer, g_targetPlots);
2431 end
2432 end
2433 end
2434end
2435
2436---------------------------------------------------------------------------------
2437function OnInterfaceModeLeave_Air_Attack( eNewMode:number )
2438 UIManager:SetUICursor(CursorTypes.NORMAL);
2439 UILens.ToggleLayerOff( g_HexColoringAttack );
2440 UILens.ClearLayerHexes( g_HexColoringAttack );
2441end
2442
2443-- ===========================================================================
2444-- Code related to the WMD Strike interface mode
2445-- ===========================================================================
2446function OnWMDStrikeEnd( pInputStruct )
2447 if ClearRangeAttackDragging() then
2448 return true;
2449 end
2450
2451 local pSelectedUnit = UI.GetHeadSelectedUnit();
2452 if (pSelectedUnit == nil) then
2453 return false;
2454 end
2455
2456 local plotID = UI.GetCursorPlotID();
2457 if (Map.IsPlot(plotID)) then
2458 local plot = Map.GetPlotByIndex(plotID);
2459 local eWMD = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_WMD_TYPE);
2460 local strikeFn = function() WMDStrike(plot, pSelectedUnit, eWMD); end;
2461 local tParameters = {};
2462 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2463 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2464 tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
2465 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.WMD_STRIKE, nil, tParameters)) then
2466
2467 local bWillStartWar = false;
2468 local results:table = CombatManager.IsAttackChangeWarState(pSelectedUnit:GetComponentID(), plot:GetX(), plot:GetY(), eWMD);
2469 if (results ~= nil and #results > 0) then
2470 bWillStartWar = true;
2471 end
2472
2473 if (bWillStartWar) then
2474 LuaEvents.WorldInput_ConfirmWarDialog(pSelectedUnit:GetOwner(), results, WarTypes.SURPRISE_WAR, strikeFn);
2475 else
2476 local pPopupDialog :table = PopupDialogInGame:new("ConfirmWMDStrike");
2477 pPopupDialog:AddText(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_ARE_YOU_SURE"));
2478 pPopupDialog:AddCancelButton(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_CANCEL"), nil);
2479 pPopupDialog:AddConfirmButton(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_LAUNCH"), strikeFn);
2480 pPopupDialog:Open();
2481 end
2482 end
2483 end
2484 return true;
2485end
2486-------------------------------------------------------------------------------
2487function WMDStrike( plot, unit, eWMD )
2488 local tParameters = {};
2489 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2490 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2491 tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
2492 if (UnitManager.CanStartOperation( unit, UnitOperationTypes.WMD_STRIKE, nil, tParameters)) then
2493 UnitManager.RequestOperation( unit, UnitOperationTypes.WMD_STRIKE, tParameters);
2494 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2495 end
2496end
2497-------------------------------------------------------------------------------
2498function OnInterfaceModeChange_WMD_Strike(eNewMode)
2499 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2500 local pSelectedUnit = UI.GetHeadSelectedUnit();
2501 if (pSelectedUnit ~= nil) then
2502 if m_focusedTargetPlot ~= -1 then
2503 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
2504 m_focusedTargetPlot = -1;
2505 end
2506 local sourcePlot : number = Map.GetPlot(pSelectedUnit:GetX(),pSelectedUnit:GetY()):GetIndex();
2507 local tParameters = {};
2508 local eWMD = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_WMD_TYPE);
2509 tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
2510
2511 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.WMD_STRIKE, tParameters );
2512 local allPlots = tResults[UnitOperationResults.PLOTS];
2513 if (allPlots ~= nil) then
2514 g_targetPlots = {}; -- Used shared list
2515 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2516 table.insert(g_targetPlots, allPlots[i]);
2517 end
2518
2519 -- Highlight the plots available to attack
2520 if (table.count(g_targetPlots) ~= 0) then
2521 -- Variation will hold specific targets in range
2522 local kVariations:table = {};
2523 for _,plotId in ipairs(g_targetPlots) do
2524 table.insert(kVariations, {"AttackRange_Target", sourcePlot, plotId} );
2525 end
2526 local eLocalPlayer:number = Game.GetLocalPlayer();
2527 UILens.ToggleLayerOn(g_HexColoringAttack);
2528 UILens.SetLayerHexesArea(g_HexColoringAttack, eLocalPlayer, g_targetPlots, kVariations);
2529 end
2530 end
2531 end
2532end
2533
2534-------------------------------------------------------------------------------
2535function OnInterfaceModeLeave_WMD_Strike( eNewMode:number )
2536 UIManager:SetUICursor(CursorTypes.NORMAL);
2537 UILens.ToggleLayerOff( g_HexColoringAttack );
2538 UILens.ClearLayerHexes( g_HexColoringAttack );
2539end
2540
2541-- ===========================================================================
2542-- Code related to the ICBM Strike interface mode
2543-- ===========================================================================
2544function OnICBMStrikeEnd( pInputStruct )
2545 if ClearRangeAttackDragging() then
2546 return true;
2547 end
2548
2549 local pSelectedCity = UI.GetHeadSelectedCity();
2550 if (pSelectedCity == nil) then
2551 return false;
2552 end
2553
2554 local targetPlotID = UI.GetCursorPlotID();
2555 if (Map.IsPlot(targetPlotID)) then
2556 local targetPlot = Map.GetPlotByIndex(targetPlotID);
2557 local eWMD = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_WMD_TYPE);
2558 local sourcePlotX = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_X0);
2559 local sourcePlotY = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_Y0);
2560 local strikeFn = function() ICBMStrike(pSelectedCity, sourcePlotX, sourcePlotY, targetPlot, eWMD); end;
2561 --PlayersVisibility[ pSelectedCity:GetOwner() ]:IsVisible(targetPlot:GetX(), targetPlot:GetY())
2562 local tParameters = {};
2563 tParameters[CityCommandTypes.PARAM_X0] = sourcePlotX;
2564 tParameters[CityCommandTypes.PARAM_Y0] = sourcePlotY;
2565 tParameters[CityCommandTypes.PARAM_X1] = targetPlot:GetX();
2566 tParameters[CityCommandTypes.PARAM_Y1] = targetPlot:GetY();
2567 tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;
2568 if (CityManager.CanStartCommand( pSelectedCity, CityCommandTypes.WMD_STRIKE, tParameters)) then
2569
2570 local bWillStartWar = false;
2571 local results:table = CombatManager.IsAttackChangeWarState(pSelectedCity:GetComponentID(), targetPlot:GetX(), targetPlot:GetY(), eWMD);
2572 if (results ~= nil and #results > 0) then
2573 bWillStartWar = true;
2574 end
2575
2576 if (bWillStartWar) then
2577 LuaEvents.WorldInput_ConfirmWarDialog(pSelectedCity:GetOwner(), results, WarTypes.SURPRISE_WAR, strikeFn);
2578 else
2579 local pPopupDialog :table = PopupDialogInGame:new("ConfirmICBMStrike");
2580 pPopupDialog:AddText(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_ARE_YOU_SURE"));
2581 pPopupDialog:AddCancelButton(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_CANCEL"), nil);
2582 pPopupDialog:AddConfirmButton(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_LAUNCH"), strikeFn);
2583 pPopupDialog:Open();
2584 end
2585 end
2586 end
2587end
2588-------------------------------------------------------------------------------
2589function ICBMStrike( fromCity, sourcePlotX, sourcePlotY, targetPlot, eWMD )
2590 local tParameters = {};
2591 tParameters[CityCommandTypes.PARAM_X0] = sourcePlotX;
2592 tParameters[CityCommandTypes.PARAM_Y0] = sourcePlotY;
2593 tParameters[CityCommandTypes.PARAM_X1] = targetPlot:GetX();
2594 tParameters[CityCommandTypes.PARAM_Y1] = targetPlot:GetY();
2595 tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;
2596 if (CityManager.CanStartCommand( fromCity, CityCommandTypes.WMD_STRIKE, tParameters)) then
2597 CityManager.RequestCommand( fromCity, CityCommandTypes.WMD_STRIKE, tParameters);
2598 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2599 end
2600end
2601-------------------------------------------------------------------------------
2602function OnInterfaceModeChange_ICBM_Strike(eNewMode)
2603 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2604 local pCity = UI.GetHeadSelectedCity();
2605
2606 if (pCity ~= nil) then
2607 if m_focusedTargetPlot ~= -1 then
2608 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
2609 m_focusedTargetPlot = -1;
2610 end
2611 local eWMD = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_WMD_TYPE);
2612 local iSourceLocX = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_X0);
2613 local iSourceLocY = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_Y0);
2614
2615 local tParameters = {};
2616 tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;
2617 tParameters[CityCommandTypes.PARAM_X0] = iSourceLocX;
2618 tParameters[CityCommandTypes.PARAM_Y0] = iSourceLocY;
2619
2620 local sourcePlot : number = Map.GetPlot(iSourceLocX,iSourceLocY):GetIndex();
2621
2622 local tResults = CityManager.GetCommandTargets(pCity, CityCommandTypes.WMD_STRIKE, tParameters);
2623 local allPlots = tResults[CityCommandResults.PLOTS];
2624 if (allPlots ~= nil) then
2625 g_targetPlots = {}; -- Use shared list so other functions know our targets
2626 for i,modifier in ipairs(tResults[CityCommandResults.PLOTS]) do
2627 table.insert(g_targetPlots, allPlots[i]);
2628 end
2629
2630 -- Highlight the plots available to attack
2631 if (table.count(g_targetPlots) ~= 0) then
2632 local kVariations:table = {};
2633 for _,plotId in ipairs(g_targetPlots) do
2634 table.insert(kVariations, {"AttackRange_Target", sourcePlot , plotId} );
2635 end
2636 local eLocalPlayer:number = Game.GetLocalPlayer();
2637 UILens.ToggleLayerOn(g_HexColoringAttack);
2638 UILens.SetLayerHexesArea(g_HexColoringAttack, eLocalPlayer, g_targetPlots, kVariations);
2639 end
2640 else
2641 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2642 end
2643 end
2644end
2645
2646---------------------------------------------------------------------------------
2647function OnInterfaceModeLeave_ICBM_Strike( eNewMode:number )
2648 UIManager:SetUICursor(CursorTypes.NORMAL);
2649 UILens.ToggleLayerOff( g_HexColoringAttack );
2650 UILens.ClearLayerHexes( g_HexColoringAttack );
2651end
2652
2653-- ===========================================================================
2654-- Code related to the Coastal Raid interface mode
2655-- ===========================================================================
2656function CoastalRaid( pInputStruct )
2657 local plotID = UI.GetCursorPlotID();
2658 if (Map.IsPlot(plotID)) then
2659 local plot = Map.GetPlotByIndex(plotID);
2660
2661 local tParameters = {};
2662 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2663 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2664
2665 local pSelectedUnit = UI.GetHeadSelectedUnit();
2666
2667 local bWillStartWar = false;
2668 local results:table = CombatManager.IsAttackChangeWarState(pSelectedUnit:GetComponentID(), plot:GetX(), plot:GetY());
2669 if (results ~= nil and #results > 0) then
2670 bWillStartWar = true;
2671 end
2672
2673 if (bWillStartWar) then
2674 -- Create the action specific parameters
2675 LuaEvents.WorldInput_ConfirmWarDialog(pSelectedUnit:GetOwner(), results, WarTypes.SURPRISE_WAR);
2676 else
2677 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.COASTAL_RAID, nil, tParameters)) then
2678 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.COASTAL_RAID, tParameters);
2679 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2680 end
2681 end
2682 end
2683 return true;
2684end
2685-------------------------------------------------------------------------------
2686function OnInterfaceModeChange_CoastalRaid(eNewMode)
2687 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2688 local pSelectedUnit = UI.GetHeadSelectedUnit();
2689 if (pSelectedUnit ~= nil) then
2690 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.COASTAL_RAID );
2691 local allPlots = tResults[UnitOperationResults.PLOTS];
2692 if (allPlots ~= nil) then
2693 g_targetPlots = {};
2694 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2695 table.insert(g_targetPlots, allPlots[i]);
2696 end
2697
2698 -- Highlight the plots available to attack
2699 if (table.count(g_targetPlots) ~= 0) then
2700 local eLocalPlayer:number = Game.GetLocalPlayer();
2701 UILens.ToggleLayerOn(g_HexColoringAttack);
2702 UILens.SetLayerHexesArea(g_HexColoringAttack, eLocalPlayer, g_targetPlots);
2703 end
2704 end
2705 end
2706end
2707
2708---------------------------------------------------------------------------------
2709function OnInterfaceModeLeave_CoastalRaid( eNewMode:number )
2710 UIManager:SetUICursor(CursorTypes.NORMAL);
2711 UILens.ToggleLayerOff( g_HexColoringAttack );
2712 UILens.ClearLayerHexes( g_HexColoringAttack );
2713end
2714
2715-- ===========================================================================
2716-- Code related to the Unit Air Deploy interface mode
2717-- ===========================================================================
2718function OnMouseDeployEnd( pInputStruct )
2719 -- If a drag was occurring, end it; otherwise raise event.
2720 if g_isMouseDragging then
2721 g_isMouseDragging = false;
2722 else
2723 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
2724 AirUnitDeploy(pInputStruct);
2725 end
2726 end
2727 EndDragMap();
2728 g_isMouseDownInWorld = false;
2729 return true;
2730end
2731-------------------------------------------------------------------------------
2732function AirUnitDeploy( pInputStruct )
2733 local plotID = UI.GetCursorPlotID();
2734 if (Map.IsPlot(plotID)) then
2735 local plot = Map.GetPlotByIndex(plotID);
2736
2737 local tParameters = {};
2738 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2739 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2740
2741 local pSelectedUnit = UI.GetHeadSelectedUnit();
2742 -- Assuming that the operation is DEPLOY. Store this in the InterfaceMode somehow?
2743 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.DEPLOY, nil, tParameters)) then
2744 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.DEPLOY, tParameters);
2745 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2746 end
2747 end
2748 return true;
2749end
2750-------------------------------------------------------------------------------
2751function OnInterfaceModeChange_Deploy(eNewMode)
2752 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2753 local pSelectedUnit = UI.GetHeadSelectedUnit();
2754 if (pSelectedUnit ~= nil) then
2755
2756 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.DEPLOY );
2757 local allPlots = tResults[UnitOperationResults.PLOTS];
2758 if (allPlots ~= nil) then
2759 g_targetPlots = {};
2760 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2761 --if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
2762 table.insert(g_targetPlots, allPlots[i]);
2763 --end
2764 end
2765
2766 -- Highlight the plots available to deploy to
2767 if (table.count(g_targetPlots) ~= 0) then
2768 local eLocalPlayer:number = Game.GetLocalPlayer();
2769 UILens.ToggleLayerOn(g_HexColoringMovement);
2770 UILens.SetLayerHexesArea(g_HexColoringMovement, eLocalPlayer, g_targetPlots);
2771 end
2772 end
2773 end
2774end
2775
2776---------------------------------------------------------------------------------
2777function OnInterfaceModeLeave_Deploy( eNewMode:number )
2778 UIManager:SetUICursor(CursorTypes.NORMAL);
2779 UILens.ToggleLayerOff( g_HexColoringMovement );
2780 UILens.ClearLayerHexes( g_HexColoringMovement );
2781end
2782
2783-- ===========================================================================
2784-- Code related to the Unit Air Re-Base interface mode
2785-- ===========================================================================
2786function OnMouseRebaseEnd( pInputStruct )
2787 -- If a drag was occurring, end it; otherwise raise event.
2788 if g_isMouseDragging then
2789 g_isMouseDragging = false;
2790 else
2791 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
2792 AirUnitReBase(pInputStruct);
2793 end
2794 end
2795 EndDragMap();
2796 g_isMouseDownInWorld = false;
2797 return true;
2798end
2799-------------------------------------------------------------------------------
2800function AirUnitReBase( pInputStruct )
2801 local plotID = UI.GetCursorPlotID();
2802 if (Map.IsPlot(plotID)) then
2803 local plot = Map.GetPlotByIndex(plotID);
2804
2805 local tParameters = {};
2806 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2807 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2808
2809 local pSelectedUnit = UI.GetHeadSelectedUnit();
2810 -- Assuming that the operation is DEPLOY. Store this in the InterfaceMode somehow?
2811 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.REBASE, nil, tParameters)) then
2812 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.REBASE, tParameters);
2813 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2814 end
2815 end
2816 return true;
2817end
2818-------------------------------------------------------------------------------
2819function OnInterfaceModeChange_ReBase(eNewMode)
2820 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2821 local pSelectedUnit = UI.GetHeadSelectedUnit();
2822 if (pSelectedUnit ~= nil) then
2823
2824 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.REBASE );
2825 local allPlots = tResults[UnitOperationResults.PLOTS];
2826 if (allPlots ~= nil) then
2827 g_targetPlots = {};
2828 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2829 table.insert(g_targetPlots, allPlots[i]);
2830 end
2831
2832 -- Highlight the plots available to deploy to
2833 if (table.count(g_targetPlots) ~= 0) then
2834 local eLocalPlayer:number = Game.GetLocalPlayer();
2835 UILens.ToggleLayerOn(g_HexColoringMovement);
2836 UILens.SetLayerHexesArea(g_HexColoringMovement, eLocalPlayer, g_targetPlots);
2837 end
2838 end
2839 end
2840end
2841
2842---------------------------------------------------------------------------------
2843function OnInterfaceModeLeave_ReBase( eNewMode:number )
2844 UIManager:SetUICursor(CursorTypes.NORMAL);
2845 UILens.ToggleLayerOff( g_HexColoringMovement );
2846 UILens.ClearLayerHexes( g_HexColoringMovement );
2847end
2848
2849-- ===========================================================================
2850-- Code related to the Place Map Pin interface mode
2851-- ===========================================================================
2852function PlaceMapPin()
2853 local plotId = UI.GetCursorPlotID();
2854 if (Map.IsPlot(plotId)) then
2855 local kPlot = Map.GetPlotByIndex(plotId);
2856 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION); -- Revert to default interface mode.
2857 LuaEvents.MapPinPopup_RequestMapPin(kPlot:GetX(), kPlot:GetY());
2858 end
2859 return true;
2860end
2861
2862------------------------------------------------------------------------------------------------
2863-- Code related to the City and District Range Attack interface mode
2864------------------------------------------------------------------------------------------------
2865function CityRangeAttack( pInputStruct )
2866 if ClearRangeAttackDragging() then
2867 return true;
2868 end
2869
2870 local plotID = UI.GetCursorPlotID();
2871 if (Map.IsPlot(plotID)) then
2872 local plot = Map.GetPlotByIndex(plotID);
2873
2874 local tParameters = {};
2875 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2876 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2877
2878 local pSelectedCity = UI.GetHeadSelectedCity();
2879 -- Assuming that the command is RANGE_ATTACK. Store this in the InterfaceMode somehow?
2880 if (CityManager.CanStartCommand( pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters)) then
2881 CityManager.RequestCommand( pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters);
2882 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2883 end
2884 end
2885 return true;
2886end
2887
2888-------------------------------------------------------------------------------
2889function OnInterfaceModeChange_CityRangeAttack(eNewMode)
2890 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2891 local pSelectedCity = UI.GetHeadSelectedCity();
2892 if (pSelectedCity ~= nil) then
2893
2894 if m_focusedTargetPlot ~= -1 then
2895 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
2896 m_focusedTargetPlot = -1;
2897 end
2898
2899 local tParameters = {};
2900 tParameters[CityCommandTypes.PARAM_RANGED_ATTACK] = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_RANGED_ATTACK);
2901
2902 local sourcePlotID = Map.GetPlotIndex(pSelectedCity:GetX(), pSelectedCity:GetY());
2903
2904 local tResults = CityManager.GetCommandTargets(pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters );
2905 local allPlots = tResults[CityCommandResults.PLOTS];
2906 if (allPlots ~= nil) then
2907 g_targetPlots = {};
2908 for i,modifier in ipairs(tResults[CityCommandResults.MODIFIERS]) do
2909 if(modifier == CityCommandResults.MODIFIER_IS_TARGET) then
2910 table.insert(g_targetPlots, allPlots[i]);
2911 end
2912 end
2913
2914 -- Highlight the plots available to attack
2915 if (table.count(g_targetPlots) ~= 0) then
2916 -- Variation will hold specific targets in range
2917 local kVariations:table = {};
2918 for _,plotId in ipairs(g_targetPlots) do
2919 table.insert(kVariations, {"AttackRange_Target", sourcePlotID, plotId} );
2920 end
2921 local eLocalPlayer:number = Game.GetLocalPlayer();
2922
2923 UILens.SetLayerHexesArea(g_AttackRange, eLocalPlayer, allPlots, kVariations);
2924
2925 end
2926 end
2927 end
2928end
2929
2930-------------------------------------------------------------------------------
2931function OnInterfaceModeLeave_CityRangeAttack(eNewMode)
2932 UILens.ClearLayerHexes( g_AttackRange );
2933end
2934
2935-------------------------------------------------------------------------------
2936function DistrictRangeAttack( pInputStruct )
2937 if ClearRangeAttackDragging() then
2938 return true;
2939 end
2940
2941 local plotID = UI.GetCursorPlotID();
2942 if (Map.IsPlot(plotID)) then
2943 local plot = Map.GetPlotByIndex(plotID);
2944
2945 local tParameters = {};
2946 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2947 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2948
2949 local pSelectedDistrict = UI.GetHeadSelectedDistrict();
2950 -- Assuming that the command is RANGE_ATTACK. Store this in the InterfaceMode somehow?
2951 if (CityManager.CanStartCommand( pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters)) then
2952 CityManager.RequestCommand( pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters);
2953 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2954 end
2955 end
2956 return true;
2957end
2958-------------------------------------------------------------------------------
2959function OnInterfaceModeChange_DistrictRangeAttack(eNewMode)
2960 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2961 local pSelectedDistrict = UI.GetHeadSelectedDistrict();
2962 if (pSelectedDistrict ~= nil) then
2963
2964 if m_focusedTargetPlot ~= -1 then
2965 UILens.UnFocusHex(g_AttackRange, m_focusedTargetPlot);
2966 m_focusedTargetPlot = -1;
2967 end
2968
2969 local tParameters = {};
2970 tParameters[CityCommandTypes.PARAM_RANGED_ATTACK] = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_RANGED_ATTACK);
2971
2972 --The source of the attack is the plot that the district is in
2973 local sourcePlotID = Map.GetPlotIndex(pSelectedDistrict:GetX(), pSelectedDistrict:GetY());
2974
2975 local tResults :table = CityManager.GetCommandTargets(pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters );
2976 local allPlots :table = tResults[CityCommandResults.PLOTS];
2977 if (allPlots ~= nil) then
2978 g_targetPlots = {};
2979 for i,modifier in ipairs(tResults[CityCommandResults.MODIFIERS]) do
2980 if(modifier == CityCommandResults.MODIFIER_IS_TARGET) then
2981 table.insert(g_targetPlots, allPlots[i]);
2982 end
2983 end
2984
2985 -- Highlight the plots available to attack
2986 if (table.count(g_targetPlots) ~= 0) then
2987 -- Variation will hold specific targets in range
2988 local kVariations:table = {};
2989 for _,plotId in ipairs(g_targetPlots) do
2990 table.insert(kVariations, {"AttackRange_Target", sourcePlotID, plotId} );
2991 end
2992 local eLocalPlayer:number = Game.GetLocalPlayer();
2993
2994 UILens.SetLayerHexesArea(g_AttackRange, eLocalPlayer, allPlots, kVariations);
2995
2996 end
2997 end
2998 end
2999end
3000
3001-------------------------------------------------------------------------------
3002function OnInterfaceModeLeave_DistrictRangeAttack(eNewMode)
3003 UILens.ClearLayerHexes( g_AttackRange );
3004end
3005
3006-------------------------------------------------------------------------------
3007function OnInterfaceModeLeave_WMDRangeAttack(eNewMode)
3008 UILens.ClearLayerHexes( g_AttackRange );
3009end
3010
3011------------------------------------------------------------------------------------------------
3012-- Code related to the Unit's Make Trade Route interface mode
3013-- Some input is handled separately, by TradePanel.lua
3014------------------------------------------------------------------------------------------------
3015function OnInterfaceModeChange_MakeTradeRoute(eNewMode)
3016 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3017end
3018
3019------------------------------------------------------------------------------------------------
3020-- Code related to the Unit's 'Teleport to City' mode
3021------------------------------------------------------------------------------------------------
3022function TeleportToCity()
3023 local plotID = UI.GetCursorPlotID();
3024 if (Map.IsPlot(plotID)) then
3025 local plot = Map.GetPlotByIndex(plotID);
3026
3027 local tParameters = {};
3028 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
3029 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
3030
3031 local eOperation = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_OPERATION_TYPE);
3032
3033 local pSelectedUnit = UI.GetHeadSelectedUnit();
3034 if (UnitManager.CanStartOperation( pSelectedUnit, eOperation, nil, tParameters)) then
3035 UnitManager.RequestOperation( pSelectedUnit, eOperation, tParameters);
3036 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
3037 UI.PlaySound("Unit_Relocate");
3038 end
3039 end
3040 return true;
3041end
3042-------------------------------------------------------------------------------
3043function OnInterfaceModeChange_TeleportToCity(eNewMode)
3044 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3045 local pSelectedUnit = UI.GetHeadSelectedUnit();
3046 if (pSelectedUnit ~= nil) then
3047
3048 local eOperation = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_OPERATION_TYPE);
3049 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, eOperation );
3050 local allPlots = tResults[UnitOperationResults.PLOTS];
3051 if (allPlots ~= nil) then
3052 g_targetPlots = {};
3053 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
3054 table.insert(g_targetPlots, allPlots[i]);
3055 end
3056
3057 -- Highlight the plots available to deploy to
3058 if (table.count(g_targetPlots) ~= 0) then
3059 local eLocalPlayer:number = Game.GetLocalPlayer();
3060 UILens.ToggleLayerOn(g_HexColoringMovement);
3061 UILens.SetLayerHexesArea(g_HexColoringMovement, eLocalPlayer, g_targetPlots);
3062 end
3063 end
3064 end
3065end
3066
3067---------------------------------------------------------------------------------
3068function OnInterfaceModeLeave_TeleportToCity( eNewMode:number )
3069 UIManager:SetUICursor(CursorTypes.NORMAL);
3070 UILens.ToggleLayerOff( g_HexColoringMovement );
3071 UILens.ClearLayerHexes( g_HexColoringMovement );
3072end
3073
3074-- =============================================================================================
3075function OnInterfaceModeChange_MoveTo( eNewMode:number )
3076 m_cachedPathUnit = nil;
3077 m_cachedPathPlotId = -1 ;
3078 RealizeMovementPath();
3079end
3080
3081-- =============================================================================================
3082function OnInterfaceModeChange_MoveToLeave( eOldMode:number )
3083 ClearMovementPath();
3084 UILens.SetActive("Default");
3085end
3086
3087-- =============================================================================================
3088function OnInterfaceModeChange_PlaceMapPin( eNewMode:number )
3089 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3090end
3091
3092------------------------------------------------------------------------------------------------
3093-- Code related to the World Builder's Select Plot Mode
3094------------------------------------------------------------------------------------------------
3095
3096-- =============================================================================================
3097function OnInterfaceModeChange_WBSelectPlot()
3098 m_WBMouseOverPlot = -1;
3099end
3100
3101-- =============================================================================================
3102function OnInterfaceModeChange_SpyChooseMission()
3103 UIManager:SetUICursor(CursorTypes.NORMAL);
3104 UILens.SetActive("Default");
3105end
3106
3107-- =============================================================================================
3108function OnInterfaceModeChange_SpyTravelToCity()
3109 UIManager:SetUICursor(CursorTypes.NORMAL);
3110 UILens.SetActive("Default");
3111
3112end
3113
3114-- ===========================================================================
3115function OnInterfaceModeChange_Cinematic()
3116 UIManager:SetUICursor(CursorTypes.NORMAL);
3117 UI.SetFixedTiltMode( true );
3118end
3119
3120-- ===========================================================================
3121function OnInterfaceModeLeave_Cinematic( eNewMode:number )
3122 UIManager:SetUICursor(CursorTypes.NORMAL);
3123 UI.SetFixedTiltMode( false );
3124 OnCycleUnitSelectionRequest();
3125end
3126
3127-- ===========================================================================
3128function OnMouseEnd_WBSelectPlot( pInputStruct:table )
3129 -- If a drag was occurring, end it; otherwise attempt selection of whatever
3130 -- is in the plot the mouse is currently at.
3131 if g_isMouseDragging then
3132 --print("Stopping drag");
3133 g_isMouseDragging = false;
3134 else
3135 --print("World Builder Placement");
3136 if (Map.IsPlot(UI.GetCursorPlotID())) then
3137 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), true);
3138 end
3139 end
3140 EndDragMap(); -- Reset any dragging
3141 g_isMouseDownInWorld = false;
3142 return true;
3143end
3144
3145-- ===========================================================================
3146function OnRButtonUp_WBSelectPlot( pInputStruct )
3147 if (Map.IsPlot(UI.GetCursorPlotID())) then
3148 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), false);
3149 end
3150 return true;
3151end
3152
3153-- ===========================================================================
3154function OnRButtonDown_WBSelectPlot( pInputStruct )
3155 if (Map.IsPlot(UI.GetCursorPlotID())) then
3156 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), true);
3157 end
3158 return true;
3159end
3160
3161-- ===========================================================================
3162function OnMouseMove_WBSelectPlot( pInputStruct )
3163
3164 -- Check to see if the plot the mouse is over has changed
3165 if not g_isMouseDragging then
3166 local mouseOverPlot = UI.GetCursorPlotID();
3167 if (Map.IsPlot(mouseOverPlot)) then
3168 if mouseOverPlot ~= m_WBMouseOverPlot then
3169 m_WBMouseOverPlot = mouseOverPlot;
3170 LuaEvents.WorldInput_WBMouseOverPlot(mouseOverPlot);
3171
3172 if m_isMouseButtonRDown then
3173 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), true);
3174 end
3175 end
3176 end
3177 end
3178
3179 return OnMouseMove();
3180end
3181
3182------------------------------------------------------------------------------------------------
3183-- Code related to the Unit's 'Form Corps' mode
3184------------------------------------------------------------------------------------------------
3185function FormCorps( pInputStruct )
3186 local plotID = UI.GetCursorPlotID();
3187 if (Map.IsPlot(plotID)) then
3188 local plot = Map.GetPlotByIndex(plotID);
3189 local unitList = Units.GetUnitsInPlotLayerID( plot:GetX(), plot:GetY(), MapLayers.ANY );
3190 local pSelectedUnit = UI.GetHeadSelectedUnit();
3191
3192 local tParameters :table = {};
3193 for i, pUnit in ipairs(unitList) do
3194 tParameters[UnitCommandTypes.PARAM_UNIT_PLAYER] = pUnit:GetOwner();
3195 tParameters[UnitCommandTypes.PARAM_UNIT_ID] = pUnit:GetID();
3196 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.FORM_CORPS, tParameters)) then
3197 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.FORM_CORPS, tParameters);
3198 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
3199 end
3200 end
3201 end
3202 return true;
3203end
3204
3205------------------------------------------------------------------------------------------------
3206function OnInterfaceModeChange_UnitFormCorps(eNewMode)
3207 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3208 local pSelectedUnit = UI.GetHeadSelectedUnit();
3209 local player = pSelectedUnit:GetOwner();
3210 local tResults = UnitManager.GetCommandTargets( pSelectedUnit, UnitCommandTypes.FORM_CORPS );
3211 if (tResults[UnitCommandResults.UNITS] ~= nil and #tResults[UnitCommandResults.UNITS] ~= 0) then
3212 local tUnits = tResults[UnitCommandResults.UNITS];
3213 local unitPlots :table = {};
3214 g_targetPlots = {};
3215 for i, unitComponentID in ipairs(tUnits) do
3216 local unit = Players[player]:GetUnits():FindID(unitComponentID.id);
3217 table.insert(unitPlots, Map.GetPlotIndex(unit:GetX(), unit:GetY()));
3218 end
3219 UILens.ToggleLayerOn(g_HexColoringPlacement);
3220 UILens.SetLayerHexesArea(g_HexColoringPlacement, player, unitPlots);
3221 g_targetPlots = unitPlots;
3222 end
3223end
3224
3225--------------------------------------------------------------------------------------------------
3226function OnInterfaceModeLeave_UnitFormCorps( eNewMode:number )
3227 UIManager:SetUICursor(CursorTypes.NORMAL);
3228 UILens.ToggleLayerOff( g_HexColoringPlacement );
3229 UILens.ClearLayerHexes( g_HexColoringPlacement );
3230end
3231
3232------------------------------------------------------------------------------------------------
3233-- Code related to the Unit's 'Form Army' mode
3234------------------------------------------------------------------------------------------------
3235function FormArmy( pInputStruct )
3236 local plotID = UI.GetCursorPlotID();
3237 if (Map.IsPlot(plotID)) then
3238 local plot = Map.GetPlotByIndex(plotID);
3239 local unitList = Units.GetUnitsInPlotLayerID( plot:GetX(), plot:GetY(), MapLayers.ANY );
3240 local pSelectedUnit = UI.GetHeadSelectedUnit();
3241
3242 local tParameters :table = {};
3243 for i, pUnit in ipairs(unitList) do
3244 tParameters[UnitCommandTypes.PARAM_UNIT_PLAYER] = pUnit:GetOwner();
3245 tParameters[UnitCommandTypes.PARAM_UNIT_ID] = pUnit:GetID();
3246 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.FORM_ARMY, tParameters)) then
3247 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.FORM_ARMY, tParameters);
3248 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
3249 end
3250 end
3251 end
3252
3253 return true;
3254end
3255
3256------------------------------------------------------------------------------------------------
3257function OnInterfaceModeChange_UnitFormArmy(eNewMode)
3258 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3259 local pSelectedUnit = UI.GetHeadSelectedUnit();
3260 local player = pSelectedUnit:GetOwner();
3261 local tResults = UnitManager.GetCommandTargets( pSelectedUnit, UnitCommandTypes.FORM_ARMY );
3262 if (tResults[UnitCommandResults.UNITS] ~= nil and #tResults[UnitCommandResults.UNITS] ~= 0) then
3263 local tUnits = tResults[UnitCommandResults.UNITS];
3264 local unitPlots :table = {};
3265 g_targetPlots = {};
3266 for i, unitComponentID in ipairs(tUnits) do
3267 local unit = Players[player]:GetUnits():FindID(unitComponentID.id);
3268 table.insert(unitPlots, Map.GetPlotIndex(unit:GetX(), unit:GetY()));
3269 end
3270 UILens.ToggleLayerOn(g_HexColoringPlacement);
3271 UILens.SetLayerHexesArea(g_HexColoringPlacement, player, unitPlots);
3272 g_targetPlots = unitPlots;
3273 end
3274end
3275
3276--------------------------------------------------------------------------------------------------
3277function OnInterfaceModeLeave_UnitFormArmy( eNewMode:number )
3278 UIManager:SetUICursor(CursorTypes.NORMAL);
3279 UILens.ToggleLayerOff( g_HexColoringPlacement );
3280 UILens.ClearLayerHexes( g_HexColoringPlacement );
3281end
3282
3283------------------------------------------------------------------------------------------------
3284-- Code related to the Unit's 'Airlift' mode
3285------------------------------------------------------------------------------------------------
3286function OnMouseAirliftEnd( pInputStruct )
3287 -- If a drag was occurring, end it; otherwise raise event.
3288 if g_isMouseDragging then
3289 g_isMouseDragging = false;
3290 else
3291 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
3292 UI.PlaySound("Unit_Airlift");
3293 UnitAirlift(pInputStruct);
3294 end
3295 end
3296 EndDragMap();
3297 g_isMouseDownInWorld = false;
3298 return true;
3299end
3300------------------------------------------------------------------------------------------------
3301function UnitAirlift( pInputStruct )
3302 local plotID = UI.GetCursorPlotID();
3303 if (Map.IsPlot(plotID)) then
3304 local plot = Map.GetPlotByIndex(plotID);
3305
3306 local tParameters = {};
3307 tParameters[UnitCommandTypes.PARAM_X] = plot:GetX();
3308 tParameters[UnitCommandTypes.PARAM_Y] = plot:GetY();
3309
3310 local pSelectedUnit = UI.GetHeadSelectedUnit();
3311 -- Assuming that the operation is AIRLIFT. Store this in the InterfaceMode somehow?
3312 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.AIRLIFT, nil, tParameters)) then
3313 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.AIRLIFT, tParameters);
3314 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
3315 end
3316 end
3317 return true;
3318end
3319------------------------------------------------------------------------------------------------
3320function OnInterfaceModeChange_UnitAirlift(eNewMode)
3321 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
3322 local pSelectedUnit = UI.GetHeadSelectedUnit();
3323 local tResults = UnitManager.GetCommandTargets(pSelectedUnit, UnitCommandTypes.AIRLIFT );
3324 local allPlots = tResults[UnitCommandResults.PLOTS];
3325 if (allPlots ~= nil) then
3326 g_targetPlots = {};
3327 for i,modifier in ipairs(tResults[UnitCommandResults.PLOTS]) do
3328 table.insert(g_targetPlots, allPlots[i]);
3329 end
3330
3331 -- Highlight the plots available to airlift to
3332 if (table.count(g_targetPlots) ~= 0) then
3333 local eLocalPlayer:number = Game.GetLocalPlayer();
3334 UILens.ToggleLayerOn(g_HexColoringMovement);
3335 UILens.SetLayerHexesArea(g_HexColoringMovement, eLocalPlayer, g_targetPlots);
3336 end
3337 end
3338end
3339--------------------------------------------------------------------------------------------------
3340function OnInterfaceModeLeave_UnitAirlift( eNewMode:number )
3341 UIManager:SetUICursor(CursorTypes.NORMAL);
3342 UILens.ToggleLayerOff( g_HexColoringMovement );
3343 UILens.ClearLayerHexes( g_HexColoringMovement );
3344end
3345
3346
3347-- ===========================================================================
3348function OnInterfaceModeChange_Selection(eNewMode)
3349 UIManager:SetUICursor(CursorTypes.NORMAL);
3350 UILens.SetActive("Default");
3351end
3352
3353
3354
3355-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
3356--
3357-- EVENT MAPPINGS, PRE-PROCESSING & HANDLING
3358--
3359-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
3360
3361
3362-- ===========================================================================
3363-- ENGINE Event
3364-- Will only be called once the animation from the previous player is
3365-- complete or will be skipped if a player has no selection or explicitly
3366-- selected another unit/city.
3367-- ===========================================================================
3368function OnCycleUnitSelectionRequest()
3369
3370 -- If the right button is (still) down, do not select a new unit otherwise
3371 -- a long path may be created if there is a long camera pan.
3372 --if m_isMouseButtonRDown then
3373 -- return;
3374 --end
3375
3376 if(UI.GetInterfaceMode() ~= InterfaceModeTypes.CINEMATIC or m_isMouseButtonRDown) then
3377
3378 -- AZURENCY : OnCycleUnitSelectionRequest is called by UI.SetCycleAdvanceTimer()
3379 -- in SelectedUnit.lua causing a conflict with the auto-cyling of unit
3380 -- (not the same given by UI.SelectNextReadyUnit() and player:GetUnits():GetFirstReadyUnit())
3381 local pPlayer :table = Players[Game.GetLocalPlayer()];
3382 if pPlayer ~= nil then
3383 if pPlayer:IsTurnActive() then
3384 local unit:table = pPlayer:GetUnits():GetFirstReadyUnit();
3385 -- AZURENCY : we also check if there is not already a unit selected,
3386 -- bacause UI.SetCycleAdvanceTimer() is always called after deselecting a unit
3387 if unit ~= nil and not UI.GetHeadSelectedUnit() then
3388 UI.DeselectAllUnits();
3389 UI.DeselectAllCities();
3390 UI.SelectUnit(unit);
3391 UI.LookAtPlot(unit:GetX(), unit:GetY());
3392 end
3393 end
3394 end
3395 -- Auto-advance selection to the next unit.
3396 -- if not UI.SelectClosestReadyUnit() then
3397 -- UI.DeselectAllUnits();
3398 -- end
3399 end
3400end
3401
3402
3403-- ===========================================================================
3404-- ENGINE Event
3405-- eOldMode, mode the engine was formally in
3406-- eNewMode, new mode the engine has just changed to
3407-- ===========================================================================
3408function OnInterfaceModeChanged( eOldMode:number, eNewMode:number )
3409
3410 -- Optional: function run before a mode is exited.
3411 local pOldModeHandler :table = InterfaceModeMessageHandler[eOldMode];
3412 if pOldModeHandler then
3413 local pModeLeaveFunc :ifunction = pOldModeHandler[INTERFACEMODE_LEAVE];
3414 if pModeLeaveFunc ~= nil then
3415 pModeLeaveFunc(eOldMode);
3416 end
3417 end
3418
3419 -- Required: function to setup next interface mode in world input
3420 local pNewModeHandler :table = InterfaceModeMessageHandler[eNewMode];
3421 if pNewModeHandler then
3422 local pModeChangeFunc :ifunction = pNewModeHandler[INTERFACEMODE_ENTER];
3423 if pModeChangeFunc ~= nil then
3424 pModeChangeFunc(eNewMode);
3425 end
3426 else
3427 local msg:string = string.format("Change requested an unhandled interface mode of value '0x%x'. (Previous mode '0x%x')",eNewMode,eOldMode);
3428 --print(msg);
3429 UIManager:SetUICursor(CursorTypes.NORMAL);
3430 UILens.SetActive("Default");
3431 end
3432end
3433
3434-- ===========================================================================
3435-- TODO: Move out of WorldInput
3436-- ===========================================================================
3437function IsEndGame()
3438 return Game.GetWinningTeam() ~= nil; -- Not great, direct game core call. :/
3439end
3440
3441-- ===========================================================================
3442-- TODO: Move out of WorldInput
3443-- ===========================================================================
3444function OnMultiplayerGameLastPlayer()
3445 -- Only show the last player popup in multiplayer games where the session is a going concern
3446 if(GameConfiguration.IsNetworkMultiplayer()
3447 and not Network.IsSessionInCloseState()
3448 -- suppress popup when the end game screen is up.
3449 -- This specifically prevents a turn spinning issue that can occur if the host migrates to a dead human player on the defeated screen. TTP 18902
3450 and not IsEndGame()) then
3451 local lastPlayerStr = Locale.Lookup( "TXT_KEY_MP_LAST_PLAYER" );
3452 local lastPlayerTitleStr = Locale.Lookup( "TXT_KEY_MP_LAST_PLAYER_TITLE" );
3453 local okStr = Locale.Lookup( "LOC_OK_BUTTON" );
3454 local pPopupDialog :table = PopupDialogInGame:new("LastPlayer");
3455 pPopupDialog:AddTitle(lastPlayerTitleStr);
3456 pPopupDialog:AddText(lastPlayerStr);
3457 pPopupDialog:AddDefaultButton(okStr, nil );
3458 pPopupDialog:Open();
3459 end
3460end
3461
3462-- ===========================================================================
3463-- ENGINE Event
3464-- ===========================================================================
3465function OnMultiplayerGameAbandoned(eReason)
3466 if(GameConfiguration.IsAnyMultiplayer()) then
3467 local errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_CONNECTION_LOST" );
3468 local errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_CONNECTION_LOST_TITLE" );
3469 local exitStr = Locale.Lookup( "LOC_GAME_MENU_EXIT_TO_MAIN" );
3470
3471 -- Select error message based on KickReason.
3472 -- Not all of these should be possible while in game but we include them anyway.
3473 if (eReason == KickReason.KICK_HOST) then
3474 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_KICKED" );
3475 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_KICKED_TITLE" );
3476 elseif (eReason == KickReason.KICK_NO_HOST) then
3477 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_HOST_LOSTED" );
3478 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_HOST_LOSTED_TITLE" );
3479 elseif (eReason == KickReason.KICK_NO_ROOM) then
3480 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_ROOM_FULL" );
3481 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_ROOM_FULL_TITLE" );
3482 elseif (eReason == KickReason.KICK_VERSION_MISMATCH) then
3483 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_VERSION_MISMATCH" );
3484 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_VERSION_MISMATCH_TITLE" );
3485 elseif (eReason == KickReason.KICK_MOD_ERROR) then
3486 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_MOD_ERROR" );
3487 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_MOD_ERROR_TITLE" );
3488 elseif (eReason == KickReason.KICK_MATCH_DELETED) then
3489 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_MATCH_DELETED" );
3490 errorTitle = Locale.Lookup( "LOC_GAME_ABANDONED_MATCH_DELETED_TITLE" );
3491 end
3492
3493 local pPopupDialog :table = PopupDialogInGame:new("PlayerKicked");
3494 pPopupDialog:AddTitle(errorTitle);
3495 pPopupDialog:AddText(errorStr);
3496 pPopupDialog:AddDefaultButton(exitStr,
3497 function()
3498 Events.ExitToMainMenu();
3499 end);
3500 pPopupDialog:Open();
3501 end
3502end
3503
3504function OnMatchEndTurnComplete( success:boolean, resultCode:number )
3505 if( success == false ) then
3506 -- Something went wrong while trying to commit a PlayByCloud turn. Display a generic popup and get us out of here.
3507 local errorStr = Locale.Lookup( "LOC_GAME_CLOUD_END_TURN_FAILED", resultCode);
3508 local errorTitle = Locale.Lookup( "LOC_GAME_CLOUD_END_TURN_FAILED_TITLE" );
3509 local exitStr = Locale.Lookup( "LOC_GAME_MENU_EXIT_TO_MAIN" );
3510
3511 local pPopupDialog :table = PopupDialogInGame:new("TurnCommitFailed");
3512 pPopupDialog:AddTitle(errorTitle);
3513 pPopupDialog:AddText(errorStr);
3514 pPopupDialog:AddDefaultButton(exitStr,
3515 function()
3516 Events.ExitToMainMenu();
3517 end);
3518 pPopupDialog:Open();
3519 end
3520end
3521
3522-- ===========================================================================
3523-- LUA Event
3524-- ===========================================================================
3525function OnTutorial_ConstrainMovement( plotID:number )
3526 m_constrainToPlotID = plotID;
3527end
3528
3529-- ===========================================================================
3530-- LUA Event
3531-- Effectively turns on/off ability to drag pan the map.
3532-- ===========================================================================
3533function OnTutorial_DisableMapDrag( isDisabled:boolean )
3534 m_isMapDragDisabled = isDisabled;
3535end
3536
3537-- ===========================================================================
3538-- LUA Event
3539-- Turns off canceling an event via a cancel action
3540-- (e.g., right click for district placement)
3541-- ===========================================================================
3542function OnTutorial_DisableMapCancel( isDisabled:boolean )
3543 m_isCancelDisabled = isDisabled;
3544end
3545
3546-- ===========================================================================
3547-- LUA Event
3548-- Effectively turns on/off ability to deselect unit.
3549-- exceptionHexIds (optional) a list of hex Ids that are still permitted to
3550-- be selected even in this state.
3551-- ===========================================================================
3552function OnTutorial_DisableMapSelect( isDisabled:boolean, kExceptionHexIds:table )
3553 if isDisabled then
3554 -- Set to either an empty table or the table of exception Ids if one was passed in.
3555 m_kTutorialPermittedHexes = (kExceptionHexIds ~= nil) and kExceptionHexIds or {};
3556 else
3557 m_kTutorialPermittedHexes = nil; -- Disabling
3558 end
3559end
3560
3561-- ===========================================================================
3562-- TEST
3563-- ===========================================================================
3564function Test()
3565 if (UI.GetHeadSelectedUnit() == nil) then
3566 print("Need head unit!");
3567 return false;
3568 end
3569 local kUnit :table = UI.GetHeadSelectedUnit();
3570-- local startPlotId :table = Map.GetPlot(sx, sy);
3571-- local endPlotId :number = UI.GetCursorPlotID();
3572
3573 local plots:table = UnitManager.GetReachableZonesOfControl( kUnit );
3574 if plots == nil then
3575 print("NIL plots return");
3576 else
3577 for k,v in pairs(plots) do
3578 print("LENSTest Plot: " .. tostring(k) .. " = " .. tostring(v) );
3579 end
3580 end
3581 return true;
3582end
3583
3584
3585-- ===========================================================================
3586-- UI Event
3587-- Input Event Processing
3588-- ===========================================================================
3589function OnInputHandler( pInputStruct:table )
3590
3591 local uiMsg :number = pInputStruct:GetMessageType();
3592 local mode :number = UI.GetInterfaceMode();
3593
3594 if uiMsg == MouseEvents.PointerLeave then
3595 ClearAllCachedInputState();
3596 ProcessPan(0,0);
3597 return;
3598 end
3599
3600
3601 -- DEBUG: T for Test (remove eventually; or at least comment out)
3602 --if pInputStruct:GetKey() == Keys.T and pInputStruct:IsControlDown() and pInputStruct:IsShiftDown() then
3603 if pInputStruct:GetKey() == Keys.T and pInputStruct:IsAltDown() and pInputStruct:IsControlDown() then
3604 return Test(); --??TRON
3605 end
3606
3607 -- Set internal represenation of inputs.
3608 m_isMouseButtonLDown = pInputStruct:IsLButtonDown();
3609 m_isMouseButtonRDown = pInputStruct:IsRButtonDown();
3610 m_isMouseButtonMDown = pInputStruct:IsMButtonDown();
3611
3612 -- Prevent "sticky" button down issues where a mouse release occurs else-where in UI so this context is unaware.
3613 g_isMouseDownInWorld = m_isMouseButtonLDown or m_isMouseButtonRDown or m_isMouseButtonMDown;
3614
3615 -- TODO: Below is test showing endPlot is not updating fast enough via event system
3616 -- (even with ImmediatePublish) and a direct/alternative way into the pathfinder
3617 -- needs to be added. Remove once new update paradigm is added. --??TRON debug:
3618 --local endPlotId :number = UI.GetCursorPlotID();
3619 --print("endPlotId, ",endPlotId,uiMsg);
3620
3621 -- Only except touch "up" or "move", if a mouse "down" occurred in the world.
3622 if g_isTouchEnabled then
3623 m_touchCount = TouchManager:GetTouchPointCount();
3624
3625 -- Show touch ID in squares
3626 if m_isDebuging then
3627 local kTouchIds:table = {};
3628 if m_touchCount > 0 then
3629 Controls.a1:SetToBeginning();
3630 Controls.a1:Play();
3631 local index:number = next(m_kTouchesDownInWorld,nil);
3632 table.insert(kTouchIds, index);
3633 if m_touchCount > 1 then
3634 Controls.a2:SetToBeginning();
3635 Controls.a2:Play();
3636 index = next(m_kTouchesDownInWorld,index);
3637 table.insert(kTouchIds, index);
3638 if m_touchCount > 2 then
3639 Controls.a3:SetToBeginning();
3640 Controls.a3:Play();
3641 index = next(m_kTouchesDownInWorld,index);
3642 table.insert(kTouchIds, index);
3643 end
3644 end
3645 end
3646 table.sort(kTouchIds);
3647 if m_touchCount > 0 then Controls.t1:SetText(tostring(kTouchIds[1])); end
3648 if m_touchCount > 1 then Controls.t2:SetText(tostring(kTouchIds[2])); end
3649 if m_touchCount > 2 then Controls.t3:SetText(tostring(kTouchIds[3])); end
3650 end
3651
3652 if uiMsg == MouseEvents.PointerUpdate then
3653 if m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] == nil then
3654 return false; -- Touch "down" did not occur in this context; ignore related touch sequence input.
3655 end
3656 elseif uiMsg == MouseEvents.PointerUp then
3657 -- Stop plot tool tippin' if more or less than 2 digits
3658 if m_touchCount < 2 then
3659 LuaEvents.WorldInput_TouchPlotTooltipHide();
3660 end
3661 if m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] == nil then
3662 return false; -- Touch "down" did not occur in this context; ignore related touch sequence input.
3663 end
3664 m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] = nil;
3665 elseif uiMsg == MouseEvents.PointerDown then
3666 m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] = true;
3667 -- If the 2nd touch occurs in the world (first one doesn't) then use it
3668 -- like a mouse for plot tool tips.
3669 if m_touchCount == 2 and not TouchManager:IsTouchToolTipDisabled() then
3670 LuaEvents.WorldInput_TouchPlotTooltipShow( pInputStruct:GetTouchID() );
3671 end
3672 end
3673 end
3674
3675 local isHandled:boolean = false;
3676
3677 -- Get the handler for the mode
3678 local modeHandler = InterfaceModeMessageHandler[mode];
3679
3680 -- Is it valid and is able to handle this message?
3681 if modeHandler and modeHandler[uiMsg] then
3682 isHandled = modeHandler[uiMsg]( pInputStruct );
3683 elseif DefaultMessageHandler[uiMsg] then
3684 isHandled = DefaultMessageHandler[uiMsg]( pInputStruct );
3685 end
3686
3687 -- Do this after the handler has completed as it may be making decisions based on if mouse dragging occurred.
3688 if not g_isMouseDownInWorld and g_isMouseDragging then
3689 --print("Forced mouse dragging false!");
3690 g_isMouseDragging = false; -- No mouse down, no dragging is occuring!
3691 end
3692
3693 local msg = pInputStruct:GetMessageType();
3694 if msg == KeyEvents.KeyUp then
3695 if pInputStruct:GetKey() == Keys.VK_ESCAPE then
3696 if UI.GetHeadSelectedUnit() ~= nil then
3697 UI.DeselectAllUnits();
3698 return true;
3699 end
3700 end
3701 end
3702
3703 return isHandled;
3704end
3705
3706
3707-- ===========================================================================
3708-- UI Event
3709-- Per-frame (e.g., expensive) event.
3710-- ===========================================================================
3711function OnRefresh()
3712 -- If there is a panning delta, and screen can pan, do the pan and request
3713 -- this is refreshed again.
3714 --if (m_edgePanX ~= 0 or m_edgePanY ~= 0) and IsAbleToEdgePan() then
3715 -- RealizePan();
3716 -- ContextPtr:RequestRefresh()
3717 --end
3718end
3719
3720
3721-- ===========================================================================
3722--
3723-- ===========================================================================
3724function ClearAllCachedInputState()
3725 m_isALTDown = false;
3726 m_isUPpressed = false;
3727 m_isDOWNpressed = false;
3728 m_isLEFTpressed = false;
3729 m_isRIGHTpressed = false;
3730
3731 m_isDoubleTapping = false;
3732 g_isMouseDownInWorld= false;
3733 m_isMouseButtonLDown= false;
3734 m_isMouseButtonMDown= false;
3735 m_isMouseButtonRDown= false;
3736 g_isMouseDragging = false;
3737 m_isTouchDragging = false;
3738 m_isTouchZooming = false;
3739 m_isTouchPathing = false;
3740 m_mapZoomStart = 0;
3741 m_dragStartFocusWorldX = 0;
3742 m_dragStartFocusWorldY = 0;
3743 m_dragStartWorldX = 0;
3744 m_dragStartWorldY = 0;
3745 m_dragStartX = 0;
3746 m_dragStartY = 0;
3747 m_dragX = 0;
3748 m_dragY = 0;
3749 m_edgePanX = 0.0;
3750 m_edgePanY = 0.0;
3751 m_touchTotalNum = 0;
3752 m_touchStartPlotX = -1;
3753 m_touchStartPlotY = -1;
3754 ms_bGridOn = true;
3755
3756 -- FreeRotation: reset input from additional keys
3757 CQUI_isShiftDown = false;
3758 m_isQDown = false;
3759 m_isEDown = false;
3760end
3761
3762
3763-- ===========================================================================
3764function OnUpdateUI( type:number, tag:string, iData1:number, iData2:number, strData1:string )
3765 if type == SystemUpdateUI.TouchInputChanged then
3766 g_isTouchEnabled = Options.GetAppOption("UI", "IsTouchScreenEnabled") ~= 0;
3767 end
3768end
3769
3770
3771-- ===========================================================================
3772-- UI Event
3773-- Called whenever the application regains focus.
3774-- ===========================================================================
3775function OnAppRegainedFocusHandler()
3776 ClearAllCachedInputState();
3777 ProcessPan(m_edgePanX,m_edgePanY);
3778end
3779
3780
3781-- ===========================================================================
3782-- UI Event
3783-- Called whenever the application loses focus.
3784-- ===========================================================================
3785function OnAppLostFocusHandler()
3786 ClearAllCachedInputState();
3787 ProcessPan(0,0);
3788end
3789
3790-- ===========================================================================
3791-- UI Event
3792-- ===========================================================================
3793function LateInitialize()
3794
3795 g_isTouchEnabled = Options.GetAppOption("UI", "IsTouchScreenEnabled") ~= 0;
3796
3797 -- Input assignments.
3798
3799 -- Default handlers:
3800 DefaultMessageHandler[KeyEvents.KeyDown] = OnDefaultKeyDown;
3801 DefaultMessageHandler[KeyEvents.KeyUp] = OnDefaultKeyUp;
3802 DefaultMessageHandler[MouseEvents.LButtonDown] = OnMouseStart;
3803 DefaultMessageHandler[MouseEvents.LButtonUp] = OnMouseEnd;
3804 DefaultMessageHandler[MouseEvents.MouseMove] = OnMouseMove;
3805 DefaultMessageHandler[MouseEvents.RButtonUp] = OnDefaultChangeToSelectionMode;
3806 DefaultMessageHandler[MouseEvents.PointerUp] = OnDefaultChangeToSelectionMode;
3807 DefaultMessageHandler[MouseEvents.MouseWheel] = OnMouseWheelZoom;
3808 DefaultMessageHandler[MouseEvents.MButtonDown] = OnMouseSelectionSnapToPlot;
3809
3810 -- Interface Mode ENTERING :
3811 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Air_Attack;
3812 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Debug;
3813 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_CityManagement;
3814 InterfaceModeMessageHandler[InterfaceModeTypes.CINEMATIC] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Cinematic;
3815 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_WMD_Strike;
3816 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_ICBM_Strike;
3817 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_CoastalRaid;
3818 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_BuildingPlacement; -- StrategicView_MapPlacement.lua
3819 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_CityRangeAttack;
3820 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Deploy;
3821 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_DistrictPlacement; -- StrategicView_MapPlacement.lua
3822 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][INTERFACEMODE_ENTER] = OnInterfaceModeChange_DistrictRangeAttack;
3823 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitFormArmy;
3824 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitFormCorps;
3825 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitAirlift;
3826 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MakeTradeRoute;
3827 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_TeleportToCity;
3828 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MoveTo;
3829 InterfaceModeMessageHandler[InterfaceModeTypes.NATURAL_WONDER] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Cinematic; -- DEPRECATED mode
3830 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitRangeAttack;
3831 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_ReBase;
3832 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Selection;
3833 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MoveTo;
3834 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_PlaceMapPin;
3835 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_WBSelectPlot;
3836 InterfaceModeMessageHandler[InterfaceModeTypes.SPY_CHOOSE_MISSION] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_SpyChooseMission;
3837 InterfaceModeMessageHandler[InterfaceModeTypes.SPY_TRAVEL_TO_CITY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_SpyTravelToCity;
3838
3839
3840 -- Interface Mode LEAVING (optional):
3841 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_BuildingPlacement; -- StrategicView_MapPlacement.lua
3842 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CityManagement;
3843 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_DistrictPlacement; -- StrategicView_MapPlacement.lua
3844 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_LEAVE] = OnInterfaceModeChange_MoveToLeave;
3845 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitRangeAttack;
3846 InterfaceModeMessageHandler[InterfaceModeTypes.CINEMATIC] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Cinematic;
3847 InterfaceModeMessageHandler[InterfaceModeTypes.NATURAL_WONDER] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Cinematic; -- DEPRECATED mode
3848 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CityRangeAttack;
3849 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_DistrictRangeAttack;
3850 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Air_Attack;
3851 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_WMD_Strike;
3852 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_ICBM_Strike;
3853 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CoastalRaid;
3854 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Deploy;
3855 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_ReBase;
3856 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_TeleportToCity;
3857 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitFormCorps;
3858 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitFormArmy;
3859 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitAirlift;
3860
3861 -- Keyboard Events (all happen on up!)
3862 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3863 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3864 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3865 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3866 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3867 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3868 InterfaceModeMessageHandler[InterfaceModeTypes.NATURAL_WONDER] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3869 InterfaceModeMessageHandler[InterfaceModeTypes.CINEMATIC] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3870 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3871 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3872 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3873 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3874 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3875 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3876 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3877 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3878 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3879 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3880 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3881 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3882
3883
3884 -- Mouse Events
3885 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.LButtonUp] = OnMouseDebugEnd;
3886 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.RButtonUp] = OnDebugCancelPlacement;
3887 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.LButtonUp] = OnMouseSelectionEnd;
3888 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.RButtonDown] = OnMouseSelectionUnitMoveStart;
3889 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.RButtonUp] = OnMouseSelectionUnitMoveEnd;
3890 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.MButtonDown] = OnMouseSelectionSnapToPlot;
3891 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.MouseMove] = OnMouseSelectionMove;
3892 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.LButtonDoubleClick] = OnSelectionDoubleTap;
3893 InterfaceModeMessageHandler[InterfaceModeTypes.VIEW_MODAL_LENS] [MouseEvents.LButtonUp] = OnMouseSelectionEnd;
3894 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.LButtonUp] = OnMouseMakeTradeRouteEnd;
3895 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.MButtonDown] = OnMouseMakeTradeRouteSnapToPlot;
3896 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.LButtonUp] = OnMouseTeleportToCityEnd;
3897 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.MButtonDown] = OnMouseTeleportToCitySnapToPlot;
3898 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.LButtonUp] = OnMouseDistrictPlacementEnd;
3899 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.RButtonUp] = OnMouseDistrictPlacementCancel;
3900 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.MouseMove] = OnMouseDistrictPlacementMove;
3901 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.LButtonDown] = OnMouseMoveToStart;
3902 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.LButtonUp] = OnMouseMoveToEnd;
3903 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.MouseMove] = OnMouseMoveToUpdate;
3904 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.RButtonUp] = OnMouseMoveToCancel;
3905 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.LButtonUp] = OnMouseUnitRangeAttack;
3906 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3907 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3908 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.LButtonUp] = DistrictRangeAttack;
3909 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.LButtonUp] = OnMouseBuildingPlacementEnd;
3910 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.RButtonUp] = OnMouseBuildingPlacementCancel;
3911 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.MouseMove] = OnMouseBuildingPlacementMove;
3912 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.LButtonUp] = CityRangeAttack;
3913 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3914 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [MouseEvents.LButtonUp] = FormCorps;
3915 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [MouseEvents.LButtonUp] = FormArmy;
3916 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [MouseEvents.LButtonUp] = OnMouseAirliftEnd;
3917 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [MouseEvents.LButtonUp] = UnitAirAttack;
3918 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.LButtonUp] = OnWMDStrikeEnd;
3919 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3920 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.LButtonUp] = OnICBMStrikeEnd;
3921 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3922 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [MouseEvents.LButtonUp] = OnMouseDeployEnd;
3923 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [MouseEvents.LButtonUp] = OnMouseRebaseEnd;
3924 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [MouseEvents.LButtonUp] = CoastalRaid;
3925 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [MouseEvents.LButtonUp] = PlaceMapPin;
3926 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.LButtonUp] = OnMouseEnd_WBSelectPlot;
3927 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.RButtonUp] = OnRButtonUp_WBSelectPlot;
3928 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.RButtonDown] = OnRButtonDown_WBSelectPlot;
3929 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.MouseMove] = OnMouseMove_WBSelectPlot;
3930
3931 -- Touch Events (if a touch system)
3932 if g_isTouchEnabled then
3933 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.PointerDown] = OnTouchStart;
3934 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3935 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.PointerUp] = OnTouchDebugEnd;
3936 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerDown] = OnTouchSelectionStart;
3937 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerUpdate] = OnTouchSelectionUpdate;
3938 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerUp] = OnTouchSelectionEnd;
3939 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerDown] = OnTouchStart;
3940 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3941 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerUp] = OnTouchTradeRouteEnd;
3942 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerDown] = OnTouchStart;
3943 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3944 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerUp] = OnTouchTeleportToCityEnd;
3945 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerDown] = OnTouchStart;
3946 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3947 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerUp] = OnTouchDistrictPlacementEnd;
3948 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerDown] = OnTouchMoveToStart;
3949 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerUpdate] = OnTouchMoveToUpdate;
3950 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerUp] = OnTouchMoveToEnd;
3951 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerDown] = OnTouchStart;
3952 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3953 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerUp] = OnTouchBuildingPlacementEnd;
3954 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.PointerUp] = CityRangeAttack;
3955 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.PointerUp] = DistrictRangeAttack;
3956 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [MouseEvents.PointerUp] = FormArmy;
3957 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [MouseEvents.PointerUp] = FormCorps;
3958 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [MouseEvents.PointerUp] = Airlift;
3959 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.PointerUp] = OnTouchUnitRangeAttack;
3960 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [MouseEvents.PointerUp] = UnitAirAttack;
3961 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.PointerUp] = OnWMDStrikeEnd;
3962 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.PointerUp] = OnICBMStrikeEnd;
3963 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [MouseEvents.PointerUp] = AirUnitDeploy;
3964 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [MouseEvents.PointerUp] = AirUnitReBase;
3965 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [MouseEvents.PointerUp] = CoastalRaid;
3966 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [MouseEvents.PointerUp] = PlaceMapPin;
3967 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [MouseEvents.PointerUp] = OnDoNothing;
3968 end
3969
3970
3971 -- ===== EVENTS =====
3972
3973 -- Game Engine Events
3974 Events.CityMadePurchase.Add( OnCityMadePurchase_StrategicView_MapPlacement );
3975 Events.CycleUnitSelectionRequest.Add( OnCycleUnitSelectionRequest );
3976 Events.InputActionTriggered.Add( OnInputActionTriggered );
3977 Events.InterfaceModeChanged.Add(OnInterfaceModeChanged);
3978 Events.MultiplayerGameLastPlayer.Add(OnMultiplayerGameLastPlayer);
3979 Events.MultiplayerGameAbandoned.Add(OnMultiplayerGameAbandoned);
3980 Events.MatchEndTurnComplete.Add(OnMatchEndTurnComplete);
3981 Events.UnitSelectionChanged.Add( OnUnitSelectionChanged );
3982 Events.UnitCommandStarted.Add( OnUnitCommandStarted );
3983
3984 -- LUA Events
3985 LuaEvents.Tutorial_ConstrainMovement.Add( OnTutorial_ConstrainMovement );
3986 LuaEvents.Tutorial_DisableMapDrag.Add( OnTutorial_DisableMapDrag );
3987 LuaEvents.Tutorial_DisableMapSelect.Add( OnTutorial_DisableMapSelect );
3988 LuaEvents.Tutorial_DisableMapCancel.Add( OnTutorial_DisableMapCancel );
3989
3990 LuaEvents.Tutorial_AddUnitHexRestriction.Add( OnTutorial_AddUnitHexRestriction );
3991 LuaEvents.Tutorial_RemoveUnitHexRestriction.Add( OnTutorial_RemoveUnitHexRestriction );
3992 LuaEvents.Tutorial_ClearAllHexMoveRestrictions.Add( OnTutorial_ClearAllUnitHexRestrictions );
3993
3994 LuaEvents.Tutorial_AddUnitMoveRestriction.Add( OnTutorial_AddUnitMoveRestriction );
3995 LuaEvents.Tutorial_RemoveUnitMoveRestrictions.Add( OnTutorial_RemoveUnitMoveRestrictions );
3996
3997 LuaEvents.InGameTopOptionsMenu_Show.Add(OnBlockInput);
3998 LuaEvents.InGameTopOptionsMenu_Close.Add(OnUnblockInput);
3999
4000 LuaEvents.DiploScene_SceneClosed.Add(OnUnblockInput);
4001 LuaEvents.DiploScene_SceneOpened.Add(OnBlockInput);
4002
4003end
4004
4005-- ===========================================================================
4006-- Load all static information as well as display information for the
4007-- current local player.
4008-- ===========================================================================
4009function OnInit( isReload:boolean )
4010 LateInitialize();
4011end
4012
4013
4014-- ===========================================================================
4015-- UI Event
4016-- ===========================================================================
4017function OnShutdown()
4018 -- Clean up events
4019 Events.CycleUnitSelectionRequest.Remove( OnCycleUnitSelectionRequest );
4020 Events.InterfaceModeChanged.Remove( OnInterfaceModeChanged );
4021
4022 LuaEvents.Tutorial_ConstrainMovement.Remove( OnTutorial_ConstrainMovement );
4023 LuaEvents.Tutorial_DisableMapDrag.Remove( OnTutorial_DisableMapDrag );
4024 LuaEvents.Tutorial_DisableMapSelect.Remove( OnTutorial_DisableMapSelect );
4025end
4026
4027-- ===========================================================================
4028-- Hotkey Event
4029-- ===========================================================================
4030function OnInputActionTriggered( actionId )
4031 if actionId == m_actionHotkeyToggleGrid then
4032 LuaEvents.MinimapPanel_ToggleGrid();
4033 LuaEvents.MinimapPanel_RefreshMinimapOptions();
4034 UI.PlaySound("Play_UI_Click");
4035
4036 elseif actionId == m_actionHotkeyToggleRes then
4037 if UserConfiguration.ShowMapResources() then
4038 UserConfiguration.ShowMapResources( false );
4039 else
4040 UserConfiguration.ShowMapResources( true );
4041 end
4042 UI.PlaySound("Play_UI_Click");
4043 LuaEvents.MinimapPanel_RefreshMinimapOptions();
4044
4045 elseif actionId == m_actionHotkeyToggleYield then
4046 if UserConfiguration.ShowMapYield() then -- yield already visible, hide
4047 LuaEvents.MinimapPanel_HideYieldIcons();
4048 UserConfiguration.ShowMapYield( false );
4049 else
4050 LuaEvents.MinimapPanel_ShowYieldIcons();
4051 UserConfiguration.ShowMapYield( true );
4052 end
4053
4054 LuaEvents.MinimapPanel_RefreshMinimapOptions();
4055 UI.PlaySound("Play_UI_Click");
4056
4057 elseif actionId == m_actionHotkeyPrevUnit then
4058 UI.SelectPrevReadyUnit();
4059 UI.PlaySound("Play_UI_Click");
4060
4061 elseif actionId == m_actionHotkeyNextUnit then
4062 UI.SelectNextReadyUnit();
4063 UI.PlaySound("Play_UI_Click");
4064
4065 elseif actionId == m_actionHotkeyPrevCity then
4066 LuaEvents.CQUI_GoPrevCity();
4067 UI.PlaySound("Play_UI_Click");
4068
4069 elseif actionId == m_actionHotkeyNextCity then
4070 LuaEvents.CQUI_GoNextCity();
4071 UI.PlaySound("Play_UI_Click");
4072
4073 elseif actionId == m_actionHotkeyCapitalCity then
4074 local capital;
4075 local ePlayer = Game.GetLocalPlayer();
4076 local player = Players[ePlayer];
4077 if(player) then
4078 local cities = player:GetCities();
4079 for i, city in cities:Members() do
4080 if(city:IsCapital()) then
4081 capital = city;
4082 break;
4083 end
4084 end
4085 end
4086
4087 if(capital) then
4088 UI.SelectNextCity(capital);
4089 UI.PlaySound("Play_UI_Click");
4090 end
4091 elseif actionId == m_actionHotkeyOnlinePause then
4092 if GameConfiguration.IsNetworkMultiplayer() then
4093 TogglePause();
4094 end
4095 end
4096end
4097
4098-- Alt-F4 in some situations can cause m_isALTDown to be stuck on after you click "Cancel", so clear it here.
4099function OnUserRequestClose()
4100 m_isALTDown = false;
4101end
4102
4103-- called when Hot Seat changes players
4104function OnLocalPlayerChanged()
4105 ClearMovementPath();
4106end
4107
4108-- ===========================================================================
4109-- INCLUDES
4110-- Other handlers & helpers that may utilze functionality defined above.
4111-- ===========================================================================
4112
4113include ("StrategicView_MapPlacement"); -- handlers for: BUILDING_PLACEMENT, DISTRICT_PLACEMENT
4114include ("StrategicView_DebugSupport"); -- the Debug interface mode
4115
4116
4117-- ===========================================================================
4118-- Assign callbacks
4119-- ===========================================================================
4120function Initialize()
4121
4122 -- UI Events
4123 ContextPtr:SetInitHandler( OnInit );
4124 ContextPtr:SetInputHandler( OnInputHandler, true );
4125 ContextPtr:SetShutdown( OnShutdown );
4126 ContextPtr:SetRefreshHandler( OnRefresh );
4127 ContextPtr:SetAppRegainedFocusHandler( OnAppRegainedFocusHandler );
4128 ContextPtr:SetAppLostFocusHandler( OnAppLostFocusHandler );
4129 Events.UserRequestClose.Add( OnUserRequestClose );
4130 Events.LocalPlayerChanged.Add( OnLocalPlayerChanged );
4131
4132 -- CQUI Events
4133 LuaEvents.CQUI_WorldInput_CityviewEnable.Add( function() CQUI_cityview = true; end );
4134 LuaEvents.CQUI_WorldInput_CityviewDisable.Add( function() CQUI_cityview = false; end );
4135 LuaEvents.CQUI_showUnitPath.Add(RealizeMovementPath);
4136 LuaEvents.CQUI_clearUnitPath.Add(ClearMovementPath);
4137
4138 Controls.DebugStuff:SetHide(not m_isDebuging);
4139 -- Popup setup
4140 m_kConfirmWarDialog = PopupDialogInGame:new( "ConfirmWarPopup" );
4141
4142end
4143Initialize();