· 9 years ago · Nov 06, 2016, 09:08 PM
1-- ===========================================================================
2-- World Input
3-- Copyright 2015-2016, Firaxis Games
4--
5-- Handle input that occurs within the 3D world.
6--
7-- In-file functions are organized in 3 areas:
8-- 1) "Operation" functions, occur agnostic of the input device
9-- 2) "Input State" functions, handle input base on up/down/update/or
10-- another state of the input device.
11-- 3) Event listening, mapping, and pre-processing
12--
13-- ===========================================================================
14
15include("PopupDialogSupport.lua");
16-- More interface-specific includes before the initialization
17
18
19
20-- ===========================================================================
21-- Debug
22-- ===========================================================================
23
24local m_isDebuging :boolean = false; -- Turn on local debug systems
25
26-- ===========================================================================
27-- CONSTANTS
28-- ===========================================================================
29
30local INTERFACEMODE_ENTER :string = "InterfaceModeEnter";
31local INTERFACEMODE_LEAVE :string = "InterfaceModeLeave";
32local NORMALIZED_DRAG_THRESHOLD :number = 0.035; -- How much movement to kick off a drag
33local MOUSE_SCALAR :number = 6.0;
34local PAN_SPEED :number = 1;
35local ZOOM_SPEED :number = 0.1;
36local DOUBLETAP_THRESHHOLD :number = 2;
37
38
39-- ===========================================================================
40-- Table of tables of functions for each interface mode & event the mode handles
41-- (Must be defined before support functions in includes.)
42-- ===========================================================================
43InterfaceModeMessageHandler =
44{
45 [InterfaceModeTypes.DEBUG] = {},
46 [InterfaceModeTypes.SELECTION] = {},
47 [InterfaceModeTypes.MOVE_TO] = {},
48 [InterfaceModeTypes.ROUTE_TO] = {},
49 [InterfaceModeTypes.ATTACK] = {},
50 [InterfaceModeTypes.RANGE_ATTACK] = {},
51 [InterfaceModeTypes.CITY_RANGE_ATTACK] = {},
52 [InterfaceModeTypes.DISTRICT_RANGE_ATTACK] = {},
53 [InterfaceModeTypes.AIR_ATTACK] = {},
54 [InterfaceModeTypes.WMD_STRIKE] = {},
55 [InterfaceModeTypes.ICBM_STRIKE] = {},
56 [InterfaceModeTypes.EMBARK] = {},
57 [InterfaceModeTypes.DISEMBARK] = {},
58 [InterfaceModeTypes.DEPLOY] = {},
59 [InterfaceModeTypes.REBASE] = {},
60 [InterfaceModeTypes.BUILDING_PLACEMENT] = {},
61 [InterfaceModeTypes.DISTRICT_PLACEMENT] = {},
62 [InterfaceModeTypes.MAKE_TRADE_ROUTE] = {},
63 [InterfaceModeTypes.TELEPORT_TO_CITY] = {},
64 [InterfaceModeTypes.FORM_CORPS] = {},
65 [InterfaceModeTypes.FORM_ARMY] = {},
66 [InterfaceModeTypes.AIRLIFT] = {},
67 [InterfaceModeTypes.COASTAL_RAID] = {},
68 [InterfaceModeTypes.PLACE_MAP_PIN] = {},
69 [InterfaceModeTypes.CITY_MANAGEMENT] = {},
70 [InterfaceModeTypes.WB_SELECT_PLOT] = {},
71 [InterfaceModeTypes.SPY_CHOOSE_MISSION] = {},
72 [InterfaceModeTypes.SPY_TRAVEL_TO_CITY] = {},
73 [InterfaceModeTypes.NATURAL_WONDER] = {},
74 [InterfaceModeTypes.VIEW_MODAL_LENS] = {}
75}
76
77
78-- ===========================================================================
79-- MEMBERS
80-- ===========================================================================
81
82local DefaultMessageHandler :table = {};
83local m_actionHotkeyToggleGrid :number = Input.GetActionId("ToggleGrid"); -- Hot Key Handling
84local m_actionHotkeyOnlinePause :number = Input.GetActionId("OnlinePause"); -- Hot Key Handling
85local m_kTouchesDownInWorld :table = {}; -- Tracks "down" touches that occurred in this context.
86local m_isTouchEnabled :boolean= false;
87local m_isALTDown :boolean= false;
88local m_isMouseButtonLDown :boolean= false;
89local m_isMouseButtonMDown :boolean= false;
90local m_isMouseButtonRDown :boolean= false;
91local m_isMouseDownInWorld :boolean= false; -- Did mouse-down start here (true), or in some other UI context?
92local m_isMouseDragging :boolean= false;
93local m_isTouchDragging :boolean= false;
94local m_isTouchZooming :boolean= false;
95local m_isTouchPathing :boolean= false;
96local m_isDoubleTapping :boolean= false;
97local m_touchCount :number = 0; -- # of touches currently occuring
98local m_touchStartPlotX :number = -1;
99local m_touchStartPlotY :number = -1;
100local m_touchTotalNum :number = 0; -- # of multiple touches that occurred
101local m_mapZoomStart :number = 0;
102local m_dragStartWorldX :number = 0;
103local m_dragStartWorldY :number = 0;
104local m_dragStartFocusWorldX :number = 0;
105local m_dragStartFocusWorldY :number = 0;
106local m_dragStartX :number = 0; -- Mouse or virtual mouse (of average touch points) X
107local m_dragStartY :number = 0; -- Mouse or virtual mouse (of average touch points) Y
108local m_dragX :number = 0;
109local m_dragY :number = 0;
110local m_edgePanX :number = 0;
111local m_edgePanY :number = 0;
112local m_constrainToPlotID :number = 0;
113local ms_bGridOn :boolean= true;
114local m_isMapDragDisabled :boolean = false;
115local m_isCancelDisabled :boolean = false; -- Is a cancelable action (e.g., right-click for district placement) been disabled?
116local m_debugTrace :table = {}; -- debug
117local m_cachedPathUnit :table;
118local m_cachedPathPlotId :number;
119local m_previousTurnsCount :number = 0;
120local m_kConfirmWarDialog :table;
121local m_targetPlots :table;
122local m_focusedTargetPlot :number = -1;
123local m_WBMouseOverPlot :number = -1;
124local m_kTutorialPermittedHexes :table = nil; -- Which hexes are permitted for selection by the tutorial (nil if disabled)
125local m_kTutorialUnitHexRestrictions :table = nil; -- Any restrictions on where units can move. (Key=UnitType, Value={restricted plotIds})
126local 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)
127local m_kTutorialUnitMoveRestrictions :table = nil; -- Restrictions for moving (anywhere) of a selected unit type.
128
129
130-- ===========================================================================
131-- FUNCTIONS
132-- ===========================================================================
133
134
135-- ===========================================================================
136-- DEBUG:
137-- trace(msg) Add a trace message to be output later (to prevent stalling
138-- game while looking at per-frame input).
139-- dump() Send to output all the collected traces
140-- clear() Empties trace buffer
141-- ===========================================================================
142function trace( msg:string ) m_debugTrace[table.count(m_debugTrace)+1] = msg; end
143function dump() print("DebugTrace: "..table.concat(m_debugTrace)); end
144function clear() m_debugTrace = {}; end
145
146
147
148-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
149--
150-- OPERATIONS
151--
152-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
153
154
155-- ===========================================================================
156-- Empty function (to override default)
157-- ===========================================================================
158function OnDoNothing()
159end
160
161
162-- ===========================================================================
163-- Pan camera
164-- ===========================================================================
165function ProcessPan( panX :number, panY :number )
166
167 if( panY == 0.0 ) then
168 if( m_isUPpressed ) then panY = panY + PAN_SPEED; end
169 if( m_isDOWNpressed) then panY = panY - PAN_SPEED; end
170 end
171
172 if( panX == 0.0 ) then
173 if( m_isRIGHTpressed ) then panX = panX + PAN_SPEED; end
174 if( m_isLEFTpressed ) then panX = panX - PAN_SPEED; end
175 end
176
177 UI.PanMap( panX, panY );
178end
179
180
181-- ===========================================================================
182-- Input conditions are set for edge camera panning
183-- ===========================================================================
184function IsAbleToEdgePan()
185 return UserConfiguration.IsEdgePanEnabled() or ( (UI.GetInterfaceMode() == InterfaceModeTypes.SELECTION) and m_isMouseButtonRDown );
186end
187
188
189-- ===========================================================================
190-- Have world camera focus on a plot
191-- plotId, the plot # to look at
192-- ===========================================================================
193function SnapToPlot( plotId:number )
194 if (Map.IsPlot(plotId)) then
195 local plot = Map.GetPlotByIndex(plotId);
196 UI.LookAtPlot( plot );
197 end
198end
199
200-- ===========================================================================
201function IsCancelAllowed()
202 return (not m_isCancelDisabled);
203end
204
205-- ===========================================================================
206-- Perform a camera zoom based on the native 2-finger gesture
207-- ===========================================================================
208function RealizeTouchGestureZoom()
209 if TouchManager:IsInGesture(Gestures.Stretching) then
210 local fDistance:number = TouchManager:GetGestureDistance(Gestures.Stretching);
211 local normalizedX :number, normalizedY:number = UIManager:GetNormalizedMousePos();
212
213 -- If zooming just started, get the starting zoom level.
214 if not m_isTouchZooming then
215 m_mapZoomStart = UI.GetMapZoom();
216 m_isTouchZooming = true;
217 end
218
219 local fZoomDelta:number = - (fDistance * 0.5);
220 local fZoom:number = m_mapZoomStart + fZoomDelta; -- Adjust the zoom level. This speed scalar should be put into the UI configuration.
221
222 if( fZoomDelta < 0.0 ) then
223 --UI.SetMapZoom( fZoom, normalizedX, normalizedY );
224 UI.SetMapZoom( fZoom, 0.0, 0.0 );
225 else
226 --UI.SetMapZoom( fZoom, normalizedX, normalizedY );
227 UI.SetMapZoom( fZoom, 0.0, 0.0 );
228 end
229
230 --LuaEvents.WorldInput_TouchPlotTooltipHide(); -- Once this gestures starts, stop and plot tooltip
231 else
232 m_isTouchZooming = false;
233 end
234end
235
236-- ===========================================================================
237function GetCurrentlySelectUnitIndex( unitList:table, ePlayer:number )
238 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
239 local iCount :number = 0; -- # of units in the list owned by the player
240 for i, pUnit in ipairs(unitList) do
241 -- Owned by the local player?
242 if (pUnit:GetOwner() == ePlayer) then
243 -- Already selected?
244 if UI.IsUnitSelected(pUnit) then
245 iSelectedUnit = iCount;
246 end
247 iCount = iCount + 1;
248 end
249 end
250
251 return iSelectedUnit;
252end
253
254-- ===========================================================================
255function SelectNextUnit(unitList:table, iCurrentlySelectedUnit:number, ePlayer:number, bWrap:boolean)
256 if iCurrentlySelectedUnit == -1 then
257 -- Nothing selected yet
258 for i, pUnit in ipairs(unitList) do
259 -- Owned by the player?
260 if (pUnit:GetOwner() == ePlayer) then
261 SelectUnit(pUnit);
262 end
263 end
264 else
265 local bSelected = false;
266 local iCount = 0; -- number of units in the list owned by the player
267 for i, pUnit in ipairs(unitList) do
268 -- Owned by the player?
269 if (pUnit:GetOwner() == ePlayer) then
270 if (iCount > iCurrentlySelectedUnit) then
271 SelectUnit(pUnit);
272 bSelected = true;
273 break;
274 end
275 iCount = iCount + 1;
276 end
277 end
278
279 if not bSelected and bWrap then
280 -- Either the input was wrong or we wrapped, go back and select the first one.
281 for i, pUnit in ipairs(unitList) do
282 -- Owned by the player?
283 if (pUnit:GetOwner() == ePlayer) then
284 SelectUnit(pUnit);
285 break;
286 end
287 end
288 end
289 end
290end
291
292-- ===========================================================================
293-- Selects a unit but firsts deselect any current unit, thereby forcing
294-- a cache refresh.
295-- ===========================================================================
296function SelectUnit( kUnit:table )
297 UI.DeselectUnit(kUnit);
298 UI.SelectUnit(kUnit);
299end
300
301-- ===========================================================================
302-- Returns if a specific plot is allowed to be selected.
303-- This is generally always true except when the tutorial is running to lock
304-- down some (or all) of the plots.
305-- ===========================================================================
306function IsSelectionAllowedAt( plotId:number )
307 if m_kTutorialPermittedHexes == nil then return true; end
308 for i,allowedId:number in ipairs( m_kTutorialPermittedHexes ) do
309 if allowedId == plotId then
310 return true;
311 end
312 end
313 return false;
314end
315
316-- ===========================================================================
317-- Selects the unit or city at the plot passed in.
318-- ===========================================================================
319function SelectInPlot( plotX:number, plotY:number )
320
321 local kUnitList :table = Units.GetUnitsInPlotLayerID( plotX, plotY, MapLayers.ANY );
322 local tryCity :boolean= false;
323 local eLocalPlayer :number = Game.GetLocalPlayer();
324 local pCity :table = Cities.GetCityInPlot( plotX, plotY );
325 if pCity ~= nil then
326 if (pCity:GetOwner() ~= eLocalPlayer) then
327 pCity = nil;
328 end
329 end
330
331 -- If there are units to try selecting...
332 if table.count(kUnitList) ~= 0 then
333 -- Get any currently selected unit so we can cycle to the next.
334 local iSelected:number = GetCurrentlySelectUnitIndex(kUnitList, eLocalPlayer);
335
336 -- Cycle to the next, or select the first one if nothing was selected and there is no city
337 SelectNextUnit(kUnitList, iSelected, eLocalPlayer, pCity == nil);
338
339 local iNewSelected = GetCurrentlySelectUnitIndex(kUnitList, eLocalPlayer);
340 if (iNewSelected == -1 or (iNewSelected == iSelected and pCity ~= nil)) then
341 -- No valid units to select
342 UI.DeselectAllUnits();
343 tryCity = true;
344 else
345 if (iNewSelected ~= -1 and iNewSelected ~= iSelected) then
346 local pNewSelectedUnit = UI.GetHeadSelectedUnit();
347 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.
348 -- The user has manually selected a unit, rebuild the selection list from that unit.
349 UI.RebuildSelectionList(pNewSelectedUnit);
350 end
351 end
352 end
353 else
354 UI.DeselectAllUnits();
355 tryCity = true;
356 end
357
358 if tryCity then
359 if pCity ~= nil then
360 UI.SelectCity(pCity);
361 end
362 -- No else, as this would be the case when click on a city banner,
363 -- and so the CityBannerManager will handle the selection.
364 end
365
366 return true;
367end
368
369-- ===========================================================================
370-- Has the player moved a down mouse or touch enough that a drag should be
371-- considered?
372-- RETURNS: true if a drag is occurring.
373-- ===========================================================================
374function IsDragThreshholdMet()
375 local normalizedX :number, normalizedY:number = UIManager:GetNormalizedMousePos();
376 return
377 math.abs(normalizedX - m_dragStartX) > NORMALIZED_DRAG_THRESHOLD or
378 math.abs(normalizedY - m_dragStartY) > NORMALIZED_DRAG_THRESHOLD;
379end
380
381-- ===========================================================================
382-- Setup to start dragging the map.
383-- ===========================================================================
384function ReadyForDragMap()
385 m_dragStartX, m_dragStartY = UIManager:GetNormalizedMousePos();
386 m_dragStartFocusWorldX, m_dragStartFocusWorldY = UI.GetMapLookAtWorldTarget();
387 m_dragStartWorldX, m_dragStartWorldY = UI.GetWorldFromNormalizedScreenPos_NoWrap( m_dragStartX, m_dragStartY );
388 m_dragX = m_dragStartX;
389 m_dragY = m_dragStartY;
390 LuaEvents.WorldInput_DragMapBegin();
391end
392
393-- ===========================================================================
394-- Drag (or spin) the camera based new position
395-- ===========================================================================
396function UpdateDragMap()
397
398 -- Obtain either the actual mouse position, or for touch, the virtualized
399 -- mouse position based on the "average" of all touches:
400 local x:number, y:number= UIManager:GetNormalizedMousePos();
401 local dx:number = m_dragX - x;
402 local dy:number = m_dragY - y;
403
404 -- Early out if no change:
405 -- Need m_drag... checks or snap to 0,0 can occur.
406 if (dx==0 and dy==0) or (m_dragStartWorldX==0 and m_dragStartFocusWorldX==0) then
407 return;
408 end
409 if m_isMapDragDisabled then
410 return;
411 end
412
413 if m_isALTDown then
414 UI.SpinMap( m_dragStartX - x, m_dragStartY - y );
415 else
416 UI.DragMap( x, y, m_dragStartWorldX, m_dragStartWorldY, m_dragStartFocusWorldX, m_dragStartFocusWorldY );
417 end
418
419 m_dragX = x;
420 m_dragY = y;
421end
422
423-- ===========================================================================
424-- Reset drag variables for next go around.
425-- ===========================================================================
426function EndDragMap()
427 UI.SpinMap( 0.0, 0.0 );
428
429 LuaEvents.WorldInput_DragMapEnd();
430 m_dragX = 0;
431 m_dragY = 0;
432 m_dragStartX = 0;
433 m_dragStartY = 0;
434 m_dragStartFocusWorldX = 0;
435 m_dragStartFocusWorldY = 0;
436 m_dragStartWorldX = 0;
437 m_dragStartWorldY = 0;
438end
439
440
441-- ===========================================================================
442-- True if a given unit type is allowed to move to a plot.
443-- ===========================================================================
444function IsUnitTypeAllowedToMoveToPlot( unitType:string, plotId:number )
445 if m_kTutorialUnitHexRestrictions == nil then return true; end
446 if m_kTutorialUnitHexRestrictions[unitType] ~= nil then
447 for _,restrictedPlotId:number in ipairs(m_kTutorialUnitHexRestrictions[unitType]) do
448 if plotId == restrictedPlotId then
449 return false; -- Found in restricted list, nope, permission denied to move.
450 end
451 end
452 end
453 return true;
454end
455
456-- ===========================================================================
457-- Returns true if a unit can move to a particular plot.
458-- This is after the pathfinder may have returned that it's okay, but another
459-- system (such as the tutorial) has locked it down.
460-- ===========================================================================
461function IsUnitAllowedToMoveToCursorPlot( pUnit:table )
462 if m_kTutorialUnitHexRestrictions == nil then return true; end
463 if m_isPlotFlaggedRestricted then return false; end -- Previous call to check path showed player ending on hex that was restricted.
464
465 local unitType :string = GameInfo.Units[pUnit:GetUnitType()].UnitType;
466 local plotId :number = UI.GetCursorPlotID();
467 return (not m_isPlotFlaggedRestricted) and IsUnitTypeAllowedToMoveToPlot( unitType, plotId );
468end
469
470-- ===========================================================================
471-- RETURNS true if the plot is considered a bad move for a unit.
472-- Also returns the plotId (if bad)
473-- ===========================================================================
474function IsPlotPathRestrictedForUnit( kPlotPath:table, kTurnsList:table, pUnit:table )
475 local endPlotId:number = kPlotPath[table.count(kPlotPath)];
476 if m_constrainToPlotID ~= 0 and endPlotId ~= m_constrainToPlotID then
477 return true, m_constrainToPlotID;
478 end
479
480 local unitType:string = GameInfo.Units[pUnit:GetUnitType()].UnitType;
481
482 -- Is the unit type just not allowed to be moved at all.
483 if m_kTutorialUnitMoveRestrictions ~= nil and m_kTutorialUnitMoveRestrictions[unitType] ~= nil then
484 return true, -1;
485 end
486
487 -- Is path traveling through a restricted plot?
488 -- Ignore the first plot, as a unit may be on a restricted plot and the
489 -- goal is just to get it off of it (and never come back.)
490 if m_kTutorialUnitHexRestrictions ~= nil then
491 if m_kTutorialUnitHexRestrictions[unitType] ~= nil then
492 local lastTurn :number = 1;
493 local lastRestrictedPlot:number = -1;
494 for i,plotId in ipairs(kPlotPath) do
495 -- Past the first plot
496 if i > 1 then
497 if kTurnsList[i] == lastTurn then
498 lastRestrictedPlot = -1; -- Same turn? Reset and previously found restricitions (unit is passing through)
499 if (not IsUnitTypeAllowedToMoveToPlot( unitType, plotId )) then
500 lastTurn = kTurnsList[i];
501 lastRestrictedPlot = plotId;
502 end
503 else
504 if lastRestrictedPlot ~= -1 then
505 return true, lastRestrictedPlot;
506 end
507 if (not IsUnitTypeAllowedToMoveToPlot( unitType, plotId )) then
508 lastTurn = kTurnsList[i];
509 lastRestrictedPlot = plotId;
510 end
511 end
512 end
513 end
514 if lastRestrictedPlot ~= -1 then
515 return true, lastRestrictedPlot;
516 end
517 end
518 end
519
520 m_isPlotFlaggedRestricted = false;
521 return false;
522end
523
524
525-- ===========================================================================
526-- LUA Event
527-- Add plot(s) to the restriction list; units of a certain type may not
528-- move to there.
529-- ===========================================================================
530function OnTutorial_AddUnitHexRestriction( unitType:string, kPlotIds:table )
531 if m_kTutorialUnitHexRestrictions == nil then
532 m_kTutorialUnitHexRestrictions = {};
533 end
534 if m_kTutorialUnitHexRestrictions[unitType] == nil then
535 m_kTutorialUnitHexRestrictions[unitType] = {};
536 end
537 for _,plotId:number in ipairs(kPlotIds) do
538 table.insert(m_kTutorialUnitHexRestrictions[unitType], plotId );
539 end
540end
541
542-- ===========================================================================
543-- LUA Event
544-- ===========================================================================
545function OnTutorial_RemoveUnitHexRestriction( unitType:string, kPlotIds:table )
546 if m_kTutorialUnitHexRestrictions == nil then
547 UI.DataError("Cannot RemoveUnitHexRestriction( "..unitType.." ...) as no restrictions are set.");
548 return;
549 end
550 if m_kTutorialUnitHexRestrictions[unitType] == nil then
551 UI.DataError("Cannot RemoveUnitHexRestriction( "..unitType.." ...) as a restriction for that unit type is not set.");
552 return;
553 end
554
555 -- Remove all the items in the restriction list based on what was passed in.
556 for _,plotId in ipairs( kPlotIds ) do
557 local isRemoved:boolean = false;
558 for i=#m_kTutorialUnitHexRestrictions[unitType],1,-1 do
559 if m_kTutorialUnitHexRestrictions[unitType][i] == plotId then
560 table.remove( m_kTutorialUnitHexRestrictions[unitType], i);
561 isRemoved = true;
562 break;
563 end
564 end
565 if (not isRemoved) then
566 UI.DataError("Cannot remove restriction for the plot "..tostring(plotId)..", it wasn't found in the list for unit "..unitType);
567 end
568 end
569end
570
571-- ===========================================================================
572-- LUA Event
573-- ===========================================================================
574function OnTutorial_ClearAllUnitHexRestrictions()
575 m_kTutorialUnitHexRestrictions = nil;
576end
577
578
579-- ===========================================================================
580-- LUA Event
581-- Prevent a unit type from being selected.
582-- ===========================================================================
583function OnTutorial_AddUnitMoveRestriction( unitType:string )
584 if m_kTutorialUnitMoveRestrictions == nil then
585 m_kTutorialUnitMoveRestrictions = {};
586 end
587 if m_kTutorialUnitMoveRestrictions[unitType] then
588 UI.DataError("Setting tutorial WorldInput unit selection for '"..unitType.."' but it's already set to restricted!");
589 end
590
591 m_kTutorialUnitMoveRestrictions[unitType] = true;
592end
593
594
595-- ===========================================================================
596-- LUA Event
597-- optionalUnitType The unit to remove from the restriction list or nil
598-- to completely clear the list.
599-- ===========================================================================
600function OnTutorial_RemoveUnitMoveRestrictions( optionalUnitType:string )
601 -- No arg, clear all...
602 if optionalUnitType == nil then
603 m_kTutorialUnitMoveRestrictions = nil;
604 else
605 -- Clear a specific type from restriction list.
606 if m_kTutorialUnitMoveRestrictions[optionalUnitType] == nil then
607 UI.DataError("Tutorial did not reset WorldInput selection for the unit type '"..optionalUnitType.."' since it's not in the restriction list.");
608 end
609 m_kTutorialUnitMoveRestrictions[optionalUnitType] = nil;
610 end
611end
612
613
614-- ===========================================================================
615-- Perform a movement path operation (if there is a selected unit).
616-- ===========================================================================
617function MoveUnitToCursorPlot( pUnit:table )
618
619 -- Clear any paths set for moving the unit and ensure any raised lens
620 -- due to the selection, is turned off.
621 ClearMovementPath();
622 UILens.SetActive("Default");
623
624 local plotID:number = UI.GetCursorPlotID();
625 if (not Map.IsPlot(plotID)) then
626 return;
627 end
628
629 if (m_constrainToPlotID == 0 or plotID == m_constrainToPlotID) and not GameInfo.Units[pUnit:GetUnitType()].IgnoreMoves then
630 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
631 if m_previousTurnsCount >= 1 then
632 UI.PlaySound("UI_Move_Confirm");
633 end
634 MoveUnitToPlot( pUnit, plotX, plotY );
635 end
636end
637
638-- ===========================================================================
639function UnitMovementCancel()
640 ClearMovementPath();
641 UILens.SetActive("Default");
642end
643
644-- ===========================================================================
645-- Unit Range Attack
646-- ===========================================================================
647function UnitRangeAttack( plotID:number )
648 local plot :table = Map.GetPlotByIndex(plotID);
649 local tParameters :table = {};
650 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
651 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
652
653 local pSelectedUnit :table = UI.GetHeadSelectedUnit();
654 if pSelectedUnit == nil then
655 UI.DataError("A UnitRangeAttack( "..tostring(plotID).." ) was attempted but there is no selected unit.");
656 return;
657 end
658
659 if UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.RANGE_ATTACK, nil, tParameters) then
660 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.RANGE_ATTACK, tParameters);
661 else
662 -- LClicking on an empty hex, deselect unit.
663 UI.DeselectUnit( pSelectedUnit );
664 end
665 -- Always leave ranged attack mode after interaction.
666 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
667end
668
669-- ===========================================================================
670-- Clear the visual representation (and cache) of the movement path
671-- ===========================================================================
672function ClearMovementPath()
673 UILens.ClearLayerHexes( LensLayers.MOVEMENT_PATH );
674 UILens.ClearLayerHexes( LensLayers.NUMBERS );
675 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
676 m_cachedPathUnit = nil;
677 m_cachedPathPlotId = -1;
678end
679
680-- ===========================================================================
681function ClearRangeAttackDragging()
682 local bWasDragging:boolean = m_isMouseDragging;
683 OnMouseEnd( pInputStruct );
684 return bWasDragging;
685end
686
687-- ===========================================================================
688-- Update the 3D displayed path for a unit.
689-- ===========================================================================
690function RealizeMovementPath()
691
692 if not UI.IsMovementPathOn() or UI.IsGameCoreBusy() then
693 return;
694 end
695
696 -- Bail if no selected unit.
697 local kUnit :table = UI.GetHeadSelectedUnit();
698 if kUnit == nil then
699 UILens.SetActive("Default");
700 m_cachedPathUnit = nil;
701 m_cachedPathPlotId = -1;
702 return;
703 end
704
705 -- Bail if unit is not a type that allows movement.
706 if GameInfo.Units[kUnit:GetUnitType()].IgnoreMoves then
707 return;
708 end
709
710 -- Bail if end plot is not determined.
711 local endPlotId :number = UI.GetCursorPlotID();
712 if (not Map.IsPlot(endPlotId)) then
713 return;
714 end
715
716 -- Only update if a new unit or new plot from the previous update.
717 if m_cachedPathUnit ~= kUnit or m_cachedPathPlotId ~= endPlotId then
718 UILens.ClearLayerHexes( LensLayers.MOVEMENT_PATH );
719 UILens.ClearLayerHexes( LensLayers.NUMBERS );
720 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
721 if m_cachedPathPlotId ~= -1 then
722 UILens.UnFocusHex( LensLayers.ATTACK_RANGE, m_cachedPathPlotId );
723 end
724
725 m_cachedPathUnit = kUnit;
726 m_cachedPathPlotId = endPlotId;
727
728
729 -- Obtain ordered list of plots.
730 local turnsList : table;
731 local obstacles : table;
732 local variations : table = {}; -- 2 to 3 values
733 local pathPlots : table = {};
734 local eLocalPlayer : number = Game.GetLocalPlayer();
735
736 --check for unit position swap first
737 local startPlotId :number = Map.GetPlot(kUnit:GetX(),kUnit:GetY()):GetIndex();
738 if startPlotId ~= endPlotId then
739 local plot :table = Map.GetPlotByIndex(endPlotId);
740 local tParameters :table = {};
741 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
742 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
743 if ( UnitManager.CanStartOperation( kUnit, UnitOperationTypes.SWAP_UNITS, nil, tParameters) ) then
744 lensNameBase = "MovementGood";
745 if not UILens.IsLensActive(lensNameBase) then
746 UILens.SetActive(lensNameBase);
747 end
748 table.insert(pathPlots, startPlotId);
749 table.insert(pathPlots, endPlotId);
750 table.insert(variations, {lensNameBase.."_Destination",startPlotId} );
751 table.insert(variations, {lensNameBase.."_Counter", startPlotId} ); -- show counter pip
752 UI.AddNumberToPath( 1, startPlotId);
753 table.insert(variations, {lensNameBase.."_Destination",endPlotId} );
754 table.insert(variations, {lensNameBase.."_Counter", endPlotId} ); -- show counter pip
755 UI.AddNumberToPath( 1, endPlotId);
756 UILens.SetLayerHexesPath(LensLayers.MOVEMENT_PATH, eLocalPlayer, pathPlots, variations);
757 return;
758 end
759 end
760
761 pathPlots, turnsList, obstacles = UnitManager.GetMoveToPath( kUnit, endPlotId );
762
763 if table.count(pathPlots) > 1 then
764 -- Start and end art "variations" when drawing path
765 local startHexId:number = pathPlots[1];
766 local endHexId :number = pathPlots[table.count(pathPlots)];
767
768 -- Check if our desired "movement" is actually a ranged attack. Early out if so.
769 local isImplicitRangedAttack :boolean = false;
770
771 local pResults = UnitManager.GetOperationTargets(kUnit, UnitOperationTypes.RANGE_ATTACK );
772 local pAllPlots = pResults[UnitOperationResults.PLOTS];
773 if pAllPlots ~= nil then
774 for i, modifier in ipairs( pResults[UnitOperationResults.MODIFIERS] ) do
775 if modifier == UnitOperationResults.MODIFIER_IS_TARGET then
776 if pAllPlots[i] == endPlotId then
777 isImplicitRangedAttack = true;
778 break;
779 end
780 end
781 end
782 end
783
784 if isImplicitRangedAttack then
785 -- Unit can apparently perform a ranged attack on that hex. Show the arrow!
786 local kVariations:table = {};
787 local kEmpty:table = {};
788 table.insert(kVariations, {"EmptyVariant", startHexId, endHexId} );
789 UILens.SetLayerHexesArea(LensLayers.ATTACK_RANGE, eLocalPlayer, kEmpty, kVariations);
790
791 -- Focus must be called AFTER the attack range variants are set.
792 UILens.FocusHex( LensLayers.ATTACK_RANGE, endHexId );
793 return; -- We're done here. Do not show a movement path.
794 end
795
796 -- Any plots of path in Fog Of War or midfog?
797 local isPathInFog:boolean = false;
798 local pPlayerVis :table = PlayersVisibility[eLocalPlayer];
799 if pPlayerVis ~= nil then
800 for _,plotIds in pairs(pathPlots) do
801 isPathInFog = not pPlayerVis:IsVisible(plotIds);
802 if isPathInFog then
803 break;
804 end
805 end
806 end
807
808 -- If any plots are in Fog Of War (FOW) then switch to the FOW movement lens.
809 local lensNameBase :string = "MovementGood";
810 local movePostfix :string = "";
811 local isPathHaveRestriction,restrictedPlotId = IsPlotPathRestrictedForUnit( pathPlots, turnsList, kUnit );
812
813 if isPathHaveRestriction then
814 lensNameBase = "MovementBad";
815 m_isPlotFlaggedRestricted = true;
816 if restrictedPlotId ~= nil and restrictedPlotId ~= -1 then
817 table.insert(variations, {"MovementBad_Destination", restrictedPlotId} );
818 end
819 elseif isPathInFog then
820 lensNameBase = "MovementFOW";
821 movePostfix = "_FOW";
822 end
823 -- Turn on lens.
824 if not UILens.IsLensActive(lensNameBase) then
825 UILens.SetActive(lensNameBase);
826 end
827
828 -- is there an enemy unit at the end?
829 local bIsEnemyAtEnd:boolean = false;
830 local endPlot :table = Map.GetPlotByIndex(endPlotId);
831 if( endPlot ~= nil ) then
832 local unitList = Units.GetUnitsInPlotLayerID( endPlot:GetX(), endPlot:GetY(), MapLayers.ANY );
833 for i, pUnit in ipairs(unitList) do
834 if( eLocalPlayer ~= pUnit:GetOwner() and pPlayerVis ~= nil and pPlayerVis:IsVisible(endPlot:GetX(), endPlot:GetY()) and pPlayerVis:IsUnitVisible(pUnit) ) then
835 bIsEnemyAtEnd = true;
836 end
837 end
838 end
839
840 -- Hide the destination indicator only if the attack is guaranteed this turn.
841 -- Regular movements and attacks planned for later turns still get the indicator.
842 table.insert(variations, {lensNameBase.."_Origin",startHexId} );
843 local nTurnCount :number = turnsList[table.count( turnsList )];
844 if not bIsEnemyAtEnd or nTurnCount > 1 then
845 table.insert(variations, {lensNameBase.."_Destination",endHexId} );
846 end
847
848 -- Since turnsList are matched against plots, this should be the same # as above.
849 if table.count(turnsList) > 1 then
850
851 -- Track any "holes" in the path.
852 local pathHole:table = {};
853 for i=1,table.count(pathPlots),1 do
854 pathHole[i] = true;
855 end
856
857 local lastTurn:number = 1;
858 for i,value in pairs(turnsList) do
859
860 -- If a new turn entry exists, or it's the very last entry of the path... show turn INFO.
861 if value > lastTurn then
862 if i > 1 then
863 table.insert(variations, {lensNameBase.."_Counter", pathPlots[i-1]} ); -- show counter pip
864 UI.AddNumberToPath( lastTurn, pathPlots[i-1] );
865 pathHole[i-1]=false;
866 end
867 lastTurn = value;
868 end
869 if i == table.count(turnsList) and i > 1 then
870 table.insert(variations, {lensNameBase.."_Counter", pathPlots[i]} ); -- show counter pip
871 UI.AddNumberToPath( lastTurn, pathPlots[i] );
872 if lastTurn == 2 then
873 if m_previousTurnsCount == 1 then
874 UI.PlaySound("UI_Multi_Turn_Movement_Alert");
875 end
876 end
877 m_previousTurnsCount = lastTurn;
878 pathHole[i]=false;
879 end
880 end
881
882 -- Any obstacles? (e.g., rivers)
883 local plotIndex:number = 1;
884 for i,value in pairs(obstacles) do
885 while( pathPlots[plotIndex] ~= value ) do plotIndex = plotIndex + 1; end -- Get ID to use for river's next plot
886 table.insert(variations, {lensNameBase.."_Minus", value, pathPlots[plotIndex+1]} );
887 end
888
889 -- Any variations not filled in earlier (holes), are filled in with Pips
890 for i,isHole in pairs(pathHole) do
891 if isHole then
892 table.insert(variations, {lensNameBase.."_Pip", pathPlots[i]} ); -- non-counter pip
893 end
894 end
895 end
896
897 else
898 -- No path; is it a bad path or is the player have the cursor on the same hex as the unit?
899 local startPlotId :number = Map.GetPlot(kUnit:GetX(),kUnit:GetY()):GetIndex();
900 if startPlotId ~= endPlotId then
901 if not UILens.IsLensActive("MovementBad") then
902 UILens.SetActive("MovementBad");
903 lensNameBase = "MovementBad";
904 end
905 table.insert(pathPlots, endPlotId);
906 table.insert(variations, {"MovementBad_Destination", endPlotId} );
907 end
908 end
909
910 UILens.SetLayerHexesPath(LensLayers.MOVEMENT_PATH, eLocalPlayer, pathPlots, variations);
911 end
912end
913
914-- ===========================================================================
915-- ===========================================================================
916function DefaultKeyDownHandler( uiKey:number )
917 local keyPanChanged :boolean = false;
918 if uiKey == Keys.VK_ALT then
919 if m_isALTDown == false then
920 m_isALTDown = true;
921 EndDragMap();
922 ReadyForDragMap();
923 end
924 end
925 if( uiKey == Keys.VK_UP ) then
926 keyPanChanged = true;
927 m_isUPpressed = true;
928 end
929 if( uiKey == Keys.VK_RIGHT ) then
930 keyPanChanged = true;
931 m_isRIGHTpressed = true;
932 end
933 if( uiKey == Keys.VK_DOWN ) then
934 keyPanChanged = true;
935 m_isDOWNpressed = true;
936 end
937 if( uiKey == Keys.VK_LEFT ) then
938 keyPanChanged = true;
939 m_isLEFTpressed = true;
940 end
941 if( keyPanChanged == true ) then
942 ProcessPan(m_edgePanX,m_edgePanY);
943 end
944 return false;
945end
946
947-- ===========================================================================
948-- ===========================================================================
949function DefaultKeyUpHandler( uiKey:number )
950
951 local keyPanChanged :boolean = false;
952 if uiKey == Keys.VK_ALT then
953 if m_isALTDown == true then
954 m_isALTDown = false;
955 EndDragMap();
956 ReadyForDragMap();
957 end
958 end
959
960 if( uiKey == Keys.VK_UP ) then
961 m_isUPpressed = false;
962 keyPanChanged = true;
963 end
964 if( uiKey == Keys.VK_RIGHT ) then
965 m_isRIGHTpressed = false;
966 keyPanChanged = true;
967 end
968 if( uiKey == Keys.VK_DOWN ) then
969 m_isDOWNpressed = false;
970 keyPanChanged = true;
971 end
972 if( uiKey == Keys.VK_LEFT ) then
973 m_isLEFTpressed = false;
974 keyPanChanged = true;
975 end
976 if( keyPanChanged == true ) then
977 ProcessPan(m_edgePanX,m_edgePanY);
978 end
979
980 if( uiKey == Keys.VK_ADD or uiKey == Keys.VK_SUBTRACT ) then
981 local oldZoom = UI.GetMapZoom();
982 if( uiKey == Keys.VK_ADD ) then
983 UI.SetMapZoom( oldZoom - ZOOM_SPEED, 0.0, 0.0 );
984 elseif( uiKey == Keys.VK_SUBTRACT ) then
985 UI.SetMapZoom( oldZoom + ZOOM_SPEED, 0.0, 0.0 );
986 end
987 return true;
988 end
989
990 return false;
991end
992
993
994-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
995--
996-- INPUT STATE
997--
998-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
999
1000
1001-- ===========================================================================
1002function OnDefaultKeyDown( pInputStruct:table )
1003 local uiKey :number = pInputStruct:GetKey();
1004 return DefaultKeyDownHandler( uiKey );
1005end
1006
1007-- ===========================================================================
1008function OnDefaultKeyUp( pInputStruct:table )
1009 local uiKey :number = pInputStruct:GetKey();
1010 return DefaultKeyUpHandler( uiKey );
1011end
1012
1013-- ===========================================================================
1014-- Placing a building, wonder, or district; ESC to leave
1015-- ===========================================================================
1016function OnPlacementKeyUp( pInputStruct:table )
1017 local uiKey :number = pInputStruct:GetKey();
1018 if uiKey == Keys.VK_ESCAPE then
1019 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1020 return true;
1021 end
1022 return DefaultKeyUpHandler( uiKey );
1023end
1024
1025
1026-- ===========================================================================
1027function TogglePause()
1028 local localPlayerID = Network.GetLocalPlayerID();
1029 local localPlayerConfig = PlayerConfigurations[localPlayerID];
1030 local newPause = not localPlayerConfig:GetWantsPause();
1031 localPlayerConfig:SetWantsPause(newPause);
1032 Network.BroadcastPlayerInfo();
1033end
1034
1035-- ===========================================================================
1036function OnDefaultChangeToSelectionMode( pInputStruct )
1037 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1038end
1039
1040-- ===========================================================================
1041function OnMouseDebugEnd( pInputStruct:table )
1042 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1043 -- is in the plot the mouse is currently at.
1044 if m_isMouseDragging then
1045 print("Stopping drag");
1046 m_isMouseDragging = false;
1047
1048 else
1049 print("Debug placing!!!");
1050 local plotID:number = UI.GetCursorPlotID();
1051 if (Map.IsPlot(plotID)) then
1052 local edge = UI.GetCursorNearestPlotEdge();
1053 DebugPlacement( plotID, edge );
1054 end
1055 end
1056 EndDragMap(); -- Reset any dragging
1057 m_isMouseDownInWorld = false;
1058 return true;
1059
1060end
1061
1062-- ===========================================================================
1063function OnDebugCancelPlacement( pInputStruct )
1064 local plotID:number = UI.GetCursorPlotID();
1065 if (Map.IsPlot(plotID)) then
1066 local edge = UI.GetCursorNearestPlotEdge();
1067 local plot:table = Map.GetPlotByIndex(plotID);
1068 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
1069 worldX, worldY, worldZ = UI.GetWorldFromNormalizedScreenPos(normalizedX, normalizedY);
1070
1071 -- Communicate this to the TunerMapPanel handler
1072 LuaEvents.TunerMapRButtonDown(plot:GetX(), plot:GetY(), worldX, worldY, worldZ, edge);
1073 end
1074 return true;
1075end
1076
1077-- ===========================================================================
1078function OnInterfaceModeChange_Debug( eNewMode:number )
1079 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1080end
1081
1082
1083-- ===========================================================================
1084function OnInterfaceModeEnter_CityManagement( eNewMode:number )
1085 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1086 UILens.SetActive("CityManagement");
1087end
1088
1089-- ===========================================================================
1090function OnInterfaceModeLeave_CityManagement( eNewMode:number )
1091 UIManager:SetUICursor(CursorTypes.NORMAL);
1092 UILens.SetActive("Default");
1093end
1094
1095
1096-- ===========================================================================
1097function OnMouseSelectionEnd( pInputStruct:table )
1098 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1099 -- is in the plot the mouse is currently at.
1100 if m_isMouseDragging then
1101 m_isMouseDragging = false;
1102 else
1103 -- If something (such as the tutorial) hasn't disabled mouse deslecting.
1104 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1105 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
1106 SelectInPlot( plotX, plotY );
1107 end
1108 end
1109 EndDragMap(); -- Reset any dragging
1110 m_isMouseDownInWorld = false;
1111 return true;
1112end
1113
1114-- ===========================================================================
1115function OnMouseSelectionMove( pInputStruct:table )
1116
1117 if not m_isMouseDownInWorld then
1118 return false;
1119 end
1120
1121 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
1122 if m_isMouseDragging then
1123 UpdateDragMap();
1124 return true;
1125 else
1126 if m_isMouseButtonLDown then
1127 -- A mouse button is down but isn't currently marked for "dragging",
1128 -- do some maths to see if this is actually a drag state.
1129 if not m_isMouseDragging then
1130 m_isMouseDragging = IsDragThreshholdMet();
1131 end
1132 end
1133
1134 local playerID :number = Game.GetLocalPlayer();
1135 if playerID == -1 or (not Players[playerID]:IsTurnActive()) then
1136 return false;
1137 end
1138
1139 if m_isMouseButtonRDown then
1140 RealizeMovementPath();
1141 end
1142 end
1143 return false;
1144end
1145
1146-- ===========================================================================
1147function OnMouseSelectionUnitMoveStart( pInputStruct:table )
1148 m_isMouseDownInWorld = true;
1149 return true;
1150end
1151
1152-- ===========================================================================
1153function OnMouseSelectionUnitMoveEnd( pInputStruct:table )
1154 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1155 if pSelectedUnit ~= nil then
1156 local playerID :number = Game.GetLocalPlayer();
1157 if playerID ~= -1 and Players[playerID]:IsTurnActive() then
1158 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1159 MoveUnitToCursorPlot( pSelectedUnit );
1160 else
1161 UnitMovementCancel();
1162 end
1163 end
1164 else
1165 UnitMovementCancel();
1166 end
1167 m_isMouseDownInWorld = false;
1168 return true;
1169end
1170
1171-- ===========================================================================
1172function OnMouseSelectionSnapToPlot( pInputStruct:table )
1173 local plotId :number= UI.GetCursorPlotID();
1174 SnapToPlot( plotId );
1175end
1176
1177-- ===========================================================================
1178function OnMouseMove( pInputStruct:table )
1179
1180 if not m_isMouseDownInWorld then
1181 return false;
1182 end
1183
1184 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
1185 if m_isMouseDragging then
1186 UpdateDragMap();
1187 return true;
1188 else
1189 if m_isMouseButtonLDown then
1190 -- A mouse button is down but isn't currently marked for "dragging".
1191 if not m_isMouseDragging then
1192 m_isMouseDragging = IsDragThreshholdMet();
1193 end
1194 end
1195 end
1196 return false;
1197end
1198
1199
1200-- ===========================================================================
1201-- Common way for mouse to function with a press start.
1202-- ===========================================================================
1203function OnMouseStart( pInputStruct:table )
1204 ReadyForDragMap();
1205 m_isMouseDownInWorld = true;
1206 return true;
1207end
1208
1209-- ===========================================================================
1210function OnMouseEnd( pInputStruct:table )
1211 -- If a drag was occurring, end it; otherwise attempt selection of whatever
1212 -- is in the plot the mouse is currently at.
1213 if m_isMouseDragging then
1214 m_isMouseDragging = false;
1215 end
1216 EndDragMap(); -- Reset any dragging
1217 m_isMouseDownInWorld = false;
1218 return true;
1219end
1220
1221-- ===========================================================================
1222-- Zoom
1223-- ===========================================================================
1224function OnMouseWheelZoom( pInputStruct:table )
1225 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.
1226 local normalizedX :number, normalizedY:number = UIManager:GetNormalizedMousePos();
1227 local oldZoom = UI.GetMapZoom();
1228 local newZoom = oldZoom + wheelValue;
1229
1230 if( wheelValue < 0.0 ) then
1231 --UI.SetMapZoom( newZoom, normalizedX, normalizedY );
1232 UI.SetMapZoom( newZoom, 0.0, 0.0 );
1233 else
1234 --UI.SetMapZoom( newZoom, normalizedX, normalizedY );
1235 UI.SetMapZoom( newZoom, 0.0, 0.0 );
1236 end
1237
1238 return true;
1239end
1240
1241-- ===========================================================================
1242-- Either Mouse Double-Click or Touch Double-Tap
1243-- ===========================================================================
1244function OnSelectionDoubleTap( pInputStruct:table )
1245 -- Determine if mouse or touch...
1246 if m_isMouseDownInWorld then
1247 -- Ignore if mouse.
1248 else
1249 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1250 if pSelectedUnit ~= nil then
1251 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1252 MoveUnitToCursorPlot( pSelectedUnit );
1253 end
1254 m_isDoubleTapping = true;
1255 return true;
1256 end
1257 end
1258 return false;
1259end
1260
1261-- ===========================================================================
1262function OnMouseMakeTradeRouteEnd( pInputStruct:table )
1263 -- If a drag was occurring, end it; otherwise raise event.
1264 if m_isMouseDragging then
1265 m_isMouseDragging = false;
1266 else
1267 local plotId:number = UI.GetCursorPlotID();
1268 if (Map.IsPlot(plotId)) then
1269 LuaEvents.WorldInput_MakeTradeRouteDestination( plotId );
1270 end
1271 end
1272 EndDragMap();
1273 m_isMouseDownInWorld = true;
1274 return true;
1275end
1276
1277-- ===========================================================================
1278function OnMouseMakeTradeRouteSnapToPlot( pInputStruct:table )
1279 local plotId :number= UI.GetCursorPlotID();
1280 SnapToPlot( plotId );
1281end
1282
1283-- ===========================================================================
1284function OnMouseTeleportToCityEnd( pInputStruct:table )
1285 -- If a drag was occurring, end it; otherwise raise event.
1286 if m_isMouseDragging then
1287 m_isMouseDragging = false;
1288 else
1289 TeleportToCity();
1290 end
1291 EndDragMap();
1292 m_isMouseDownInWorld = true;
1293 return true;
1294end
1295
1296-- ===========================================================================
1297function OnMouseTeleportToCitySnapToPlot( pInputStruct:table )
1298 local plotId :number= UI.GetCursorPlotID();
1299 SnapToPlot( plotId );
1300end
1301
1302-- ===========================================================================
1303function OnMouseBuildingPlacementEnd( pInputStruct:table )
1304 -- If a drag was occurring, end it; otherwise raise event.
1305 if m_isMouseDragging then
1306 m_isMouseDragging = false;
1307 else
1308 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1309 ConfirmPlaceWonder(pInputStruct); -- StrategicView_MapPlacement.lua
1310 end
1311 end
1312 EndDragMap();
1313 m_isMouseDownInWorld = false;
1314 return true;
1315end
1316
1317-- ===========================================================================
1318function OnMouseBuildingPlacementCancel( pInputStruct:table )
1319 if IsCancelAllowed() then
1320 ExitPlacementMode( true );
1321 end
1322end
1323
1324-- ===========================================================================
1325function OnMouseBuildingPlacementMove( pInputStruct:table)
1326 OnMouseMove( pInputStruct );
1327 RealizeCurrentPlaceDistrictOrWonderPlot();
1328end
1329
1330-- ===========================================================================
1331function OnMouseDistrictPlacementEnd( pInputStruct:table )
1332 -- If a drag was occurring, end it; otherwise raise event.
1333 if m_isMouseDragging then
1334 m_isMouseDragging = false;
1335 else
1336 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
1337 ConfirmPlaceDistrict(pInputStruct);
1338 end
1339 end
1340 EndDragMap();
1341 m_isMouseDownInWorld = false;
1342 return true;
1343end
1344
1345-- ===========================================================================
1346function OnMouseDistrictPlacementCancel( pInputStruct:table )
1347 if IsCancelAllowed() then
1348 ExitPlacementMode( true );
1349 end
1350end
1351
1352-- ===========================================================================
1353function OnMouseDistrictPlacementMove( pInputStruct:table)
1354 OnMouseMove( pInputStruct );
1355 RealizeCurrentPlaceDistrictOrWonderPlot();
1356end
1357
1358-- ===========================================================================
1359function OnMouseUnitRangeAttack( pInputStruct:table )
1360 if ClearRangeAttackDragging() then
1361 return true;
1362 end
1363
1364 local plotID:number = UI.GetCursorPlotID();
1365 if (Map.IsPlot(plotID)) then
1366 UnitRangeAttack( plotID );
1367 end
1368 return true;
1369end
1370
1371-- ===========================================================================
1372function OnMouseMoveRangeAttack( pInputStruct:table )
1373 OnMouseMove( pInputStruct );
1374
1375 local plotID:number = UI.GetCursorPlotID();
1376
1377 if (Map.IsPlot(plotID)) then
1378 if m_focusedTargetPlot ~= plotID then
1379 if m_focusedTargetPlot ~= -1 then
1380 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
1381 m_focusedTargetPlot = -1;
1382 end
1383
1384 if (m_targetPlots ~= nil) then
1385 local bPlotIsTarget:boolean = false;
1386 for i=1,#m_targetPlots do
1387 if m_targetPlots[i] == plotID then
1388 bPlotIsTarget = true;
1389 break;
1390 end
1391 end
1392
1393 if bPlotIsTarget then
1394 m_focusedTargetPlot = plotID;
1395 UILens.FocusHex(LensLayers.ATTACK_RANGE, plotID);
1396 end
1397 end
1398 end
1399 end
1400 return true;
1401end
1402
1403-- ===========================================================================
1404function OnMouseMoveToStart( pInputStruct:table )
1405 ReadyForDragMap();
1406 m_isMouseDownInWorld = true;
1407 return true;
1408end
1409
1410-- ===========================================================================
1411function OnMouseMoveToEnd( pInputStruct:table )
1412 -- Stop a dragging or kick off a move selection.
1413 if m_isMouseDragging then
1414 m_isMouseDragging = false;
1415 else
1416 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1417 if pSelectedUnit ~= nil and IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1418 MoveUnitToCursorPlot( pSelectedUnit );
1419 else
1420 UnitMovementCancel();
1421 end
1422 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
1423 end
1424 EndDragMap();
1425 m_isMouseDownInWorld = false;
1426 return true;
1427end
1428
1429-- ===========================================================================
1430function OnMouseMoveToUpdate( pInputStruct:table )
1431
1432 if m_isMouseDownInWorld then
1433 -- Check for that player who holds the mouse button dwon, drags and releases it over a UI element.
1434 if m_isMouseDragging then
1435 UpdateDragMap();
1436 else
1437 if m_isMouseButtonLDown then
1438 -- A mouse button is down but isn't currently marked for "dragging",
1439 -- do some maths to see if this is actually a drag state.
1440 if not m_isMouseDragging then
1441 m_isMouseDragging = IsDragThreshholdMet();
1442 end
1443 end
1444 end
1445 end
1446 RealizeMovementPath();
1447 return true;
1448end
1449
1450-- ===========================================================================
1451function OnMouseMoveToCancel( pInputStruct:table )
1452 UnitMovementCancel();
1453 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
1454 return true;
1455end
1456
1457
1458-- ===========================================================================
1459-- Start touch, until release or move, do not take action.
1460-- ===========================================================================
1461function OnTouchSelectionStart( pInputStruct:table )
1462
1463 if m_touchCount > m_touchTotalNum then
1464 m_touchTotalNum = m_touchCount;
1465 end
1466
1467 -- If the first touch then obtain the plot the touch started in.
1468 if m_touchTotalNum == 1 then
1469 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
1470 m_touchStartPlotX, m_touchStartPlotY = UI.GetPlotCoordFromNormalizedScreenPos(normalizedX, normalizedY);
1471
1472 -- Potentially draw path based on if a unit is selected.
1473 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1474 if pSelectedUnit ~= nil and m_touchStartPlotX == pSelectedUnit:GetX() and m_touchStartPlotY == pSelectedUnit:GetY() then
1475 m_isTouchPathing = true;
1476 RealizeMovementPath();
1477 else
1478 -- No unit selected to draw a path, the player is either about to
1479 -- start a drag or is just now selecting a unit.
1480 ReadyForDragMap();
1481 end
1482 end
1483 return true;
1484end
1485
1486
1487-- ===========================================================================
1488function OnTouchSelectionUpdate( pInputStruct:table )
1489
1490 -- Determine maximum # of touches that have occurred.
1491 if m_touchCount > m_touchTotalNum then
1492 m_touchTotalNum = m_touchCount;
1493 end
1494
1495 RealizeTouchGestureZoom();
1496
1497 -- If more than one touch ever occured; take no more actions.
1498 if m_touchTotalNum > 1 then
1499 return true;
1500 end
1501
1502 -- Drawing a path or dragging?
1503 if m_isTouchPathing then
1504 RealizeMovementPath();
1505 else
1506 if m_isTouchDragging then
1507 UpdateDragMap();
1508 else
1509 m_isTouchDragging = IsDragThreshholdMet();
1510 end
1511 end
1512 return true;
1513end
1514
1515-- ===========================================================================
1516function OnTouchSelectionEnd( pInputStruct:table )
1517
1518 -- If last touch in a sequence or double tapping.
1519 if m_touchCount > 0 then
1520 return true;
1521 end
1522
1523 if m_isDoubleTapping then
1524 -- If a double tap just happened, clear out.
1525 m_isDoubleTapping = false;
1526 m_isTouchPathing = false;
1527 m_isTouchDragging = false;
1528 else
1529 -- Moving a unit?
1530 if m_isTouchPathing then
1531 m_isTouchPathing = false;
1532 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1533 if pSelectedUnit ~= nil then
1534 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1535 MoveUnitToCursorPlot( pSelectedUnit );
1536 else
1537 UnitMovementCancel();
1538 end
1539 else
1540 UnitMovementCancel();
1541 end
1542 else
1543 -- Selection or Dragging
1544 if m_isTouchDragging then
1545 m_isTouchDragging = false;
1546 else
1547 local plotX:number, plotY:number = UI.GetCursorPlotCoord();
1548 if plotX == m_touchStartPlotX and plotY == m_touchStartPlotY then
1549 SelectInPlot( plotX, plotY );
1550 end
1551 end
1552 end
1553 end
1554
1555 EndDragMap();
1556 m_touchTotalNum = 0;
1557 m_isTouchZooming = false;
1558 m_touchStartPlotX = -1;
1559 m_touchStartPlotY = -1;
1560 return true;
1561end
1562
1563-- ===========================================================================
1564-- Common start for touch
1565-- ===========================================================================
1566function OnTouchStart( pInputStruct:table )
1567 if m_touchCount > m_touchTotalNum then
1568 m_touchTotalNum = m_touchCount;
1569 end
1570
1571 -- If the first touch then obtain the plot the touch started in.
1572 if m_touchTotalNum == 1 then
1573 local normalizedX, normalizedY = UIManager:GetNormalizedMousePos();
1574 m_touchStartPlotX, m_touchStartPlotY = UI.GetPlotCoordFromNormalizedScreenPos(normalizedX, normalizedY);
1575 ReadyForDragMap();
1576 end
1577 return true;
1578end
1579
1580-- ===========================================================================
1581-- Common update for touch
1582-- ===========================================================================
1583function OnTouchUpdate( pInputStruct:table )
1584 -- Determine maximum # of touches that have occurred.
1585 if m_touchCount > m_touchTotalNum then
1586 m_touchTotalNum = m_touchCount;
1587 end
1588
1589 RealizeTouchGestureZoom();
1590
1591 -- If more than one touch ever occured; take no more actions.
1592 if m_touchTotalNum > 1 then
1593 return true;
1594 end
1595
1596 if m_isTouchDragging then
1597 UpdateDragMap();
1598 else
1599 m_isTouchDragging = IsDragThreshholdMet();
1600 end
1601 return true;
1602end
1603
1604
1605-- ===========================================================================
1606function OnTouchTradeRouteEnd( pInputStruct:table )
1607
1608 -- If last touch in a sequence or double tapping.
1609 if m_touchCount > 0 then
1610 return true;
1611 end
1612
1613 -- Selection or Dragging
1614 if m_isTouchDragging then
1615 m_isTouchDragging = false;
1616 else
1617 local plotId:number = UI.GetCursorPlotID();
1618 if (Map.IsPlot(plotId)) then
1619 LuaEvents.WorldInput_MakeTradeRouteDestination( plotId );
1620 end
1621 end
1622
1623 EndDragMap();
1624 m_touchTotalNum = 0;
1625 m_isTouchZooming = false;
1626 m_touchStartPlotX = -1;
1627 m_touchStartPlotY = -1;
1628 return true;
1629end
1630
1631-- ===========================================================================
1632function OnTouchTeleportToCityEnd( pInputStruct:table )
1633
1634 -- If last touch in a sequence or double tapping.
1635 if m_touchCount > 0 then
1636 return true;
1637 end
1638
1639 -- Selection or Dragging
1640 if m_isTouchDragging then
1641 m_isTouchDragging = false;
1642 else
1643 TeleportToCity();
1644 end
1645
1646 EndDragMap();
1647 m_touchTotalNum = 0;
1648 m_isTouchZooming = false;
1649 m_touchStartPlotX = -1;
1650 m_touchStartPlotY = -1;
1651 return true;
1652end
1653
1654-- ===========================================================================
1655function OnTouchDistrictPlacementEnd( pInputStruct:table )
1656 ConfirmPlaceDistrict(pInputStruct);
1657end
1658
1659-- ===========================================================================
1660function OnTouchBuildingPlacementEnd( pInputStruct:table )
1661 ConfirmPlaceWonder(pInputStruct);
1662end
1663
1664-- ===========================================================================
1665function OnTouchMoveToStart( pInputStruct:table )
1666 return true;
1667end
1668
1669-- ===========================================================================
1670function OnTouchMoveToUpdate( pInputStruct:table )
1671 -- Determine maximum # of touches that have occurred.
1672 if m_touchCount > m_touchTotalNum then
1673 m_touchTotalNum = m_touchCount;
1674 end
1675
1676 if m_touchTotalNum == 1 then
1677 RealizeMovementPath();
1678 else
1679 UnitMovementCancel();
1680 end
1681 return true;
1682end
1683
1684-- ===========================================================================
1685function OnTouchMoveToEnd( pInputStruct:table )
1686 -- If last touch in a sequence or double tapping.
1687 if m_touchCount > 0 then
1688 return true;
1689 end
1690
1691 if m_touchTotalNum == 1 then
1692 local pSelectedUnit:table = UI.GetHeadSelectedUnit();
1693 if IsUnitAllowedToMoveToCursorPlot( pSelectedUnit ) then
1694 MoveUnitToCursorPlot( pSelectedUnit );
1695 else
1696 UnitMovementCancel();
1697 end
1698 else
1699 UnitMovementCancel();
1700 end
1701
1702 m_touchTotalNum = 0;
1703 m_isTouchZooming = false;
1704 m_touchStartPlotX = -1;
1705 m_touchStartPlotY = -1;
1706 UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
1707 return true;
1708end
1709
1710-- ===========================================================================
1711function OnTouchUnitRangeAttack( pInputStruct:table )
1712 local plotID:number = UI.GetCursorPlotID();
1713 if (Map.IsPlot(plotID)) then
1714 UnitRangeAttack( plotID );
1715 end
1716 return true;
1717end
1718
1719
1720-------------------------------------------------------------------------------
1721function OnInterfaceModeChange_UnitRangeAttack(eNewMode)
1722 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1723 local pSelectedUnit = UI.GetHeadSelectedUnit();
1724 if (pSelectedUnit ~= nil) then
1725
1726 if m_focusedTargetPlot ~= -1 then
1727 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
1728 m_focusedTargetPlot = -1;
1729 end
1730
1731 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.RANGE_ATTACK );
1732 local allPlots = tResults[UnitOperationResults.PLOTS];
1733 if (allPlots ~= nil) then
1734 m_targetPlots = {};
1735 for i,modifier in ipairs(tResults[UnitOperationResults.MODIFIERS]) do
1736 if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
1737 table.insert(m_targetPlots, allPlots[i]);
1738 end
1739 end
1740
1741 -- Highlight the plots available to attack
1742 if (table.count(m_targetPlots) ~= 0) then
1743 -- Variation will hold specific targets in range
1744 local kVariations:table = {};
1745 for _,plotId in ipairs(m_targetPlots) do
1746 -- Variant needed to place the attack arc, but we don't want to double-draw the crosshair on the hex.
1747 table.insert(kVariations, {"EmptyVariant", allPlots[1], plotId} );
1748 end
1749 local eLocalPlayer:number = Game.GetLocalPlayer();
1750
1751 UILens.SetLayerHexesArea(LensLayers.ATTACK_RANGE, eLocalPlayer, allPlots, kVariations);
1752 end
1753 end
1754 end
1755end
1756
1757-------------------------------------------------------------------------------
1758function OnInterfaceModeLeave_UnitRangeAttack(eNewMode)
1759 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
1760end
1761
1762-- ===========================================================================
1763-- Code related to the Unit Air Attack interface mode
1764-- ===========================================================================
1765function UnitAirAttack( pInputStruct )
1766 local plotID = UI.GetCursorPlotID();
1767 if (Map.IsPlot(plotID)) then
1768 local plot = Map.GetPlotByIndex(plotID);
1769
1770 local tParameters = {};
1771 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
1772 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
1773
1774 local pSelectedUnit = UI.GetHeadSelectedUnit();
1775 -- Assuming that the operation is AIR_ATTACK. Store this in the InterfaceMode somehow?
1776 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.AIR_ATTACK, nil, tParameters)) then
1777 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.AIR_ATTACK, tParameters);
1778 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1779 end
1780 end
1781 return true;
1782end
1783-------------------------------------------------------------------------------
1784function OnInterfaceModeChange_Air_Attack(eNewMode)
1785 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1786 local pSelectedUnit = UI.GetHeadSelectedUnit();
1787 if (pSelectedUnit ~= nil) then
1788
1789 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.AIR_ATTACK );
1790 local allPlots = tResults[UnitOperationResults.PLOTS];
1791 if (allPlots ~= nil) then
1792 m_targetPlots = {};
1793 for i,modifier in ipairs(tResults[UnitOperationResults.MODIFIERS]) do
1794 if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
1795 table.insert(m_targetPlots, allPlots[i]);
1796 end
1797 end
1798
1799 -- Highlight the plots available to attack
1800 if (table.count(m_targetPlots) ~= 0) then
1801 local eLocalPlayer:number = Game.GetLocalPlayer();
1802 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_ATTACK);
1803 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_ATTACK, eLocalPlayer, m_targetPlots);
1804 end
1805 end
1806 end
1807end
1808
1809---------------------------------------------------------------------------------
1810function OnInterfaceModeLeave_Air_Attack( eNewMode:number )
1811 UIManager:SetUICursor(CursorTypes.NORMAL);
1812 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
1813 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
1814end
1815
1816-- ===========================================================================
1817-- Code related to the WMD Strike interface mode
1818-- ===========================================================================
1819function OnWMDStrikeEnd( pInputStruct )
1820 if ClearRangeAttackDragging() then
1821 return true;
1822 end
1823
1824 local pSelectedUnit = UI.GetHeadSelectedUnit();
1825 if (pSelectedUnit == nil) then
1826 return false;
1827 end
1828
1829 local plotID = UI.GetCursorPlotID();
1830 if (Map.IsPlot(plotID)) then
1831 local plot = Map.GetPlotByIndex(plotID);
1832 local eWMD = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_WMD_TYPE);
1833 local strikeFn = function() WMDStrike(plot, pSelectedUnit, eWMD); end;
1834 local bWillStartWar = CombatManager.IsAttackChangeWarState( pSelectedUnit:GetComponentID(), plot:GetX(), plot:GetY(), eWMD );
1835 if (bWillStartWar) then
1836 local eDefendingPlayer = CombatManager.GetBestDefender( pSelectedUnit:GetComponentID(), plot:GetX(), plot:GetY() );
1837 if (eDefendingPlayer == nil) then
1838 eDefendingPlayer = plot:GetOwner();
1839 end
1840 -- Create the action specific parameters
1841 if (eDefendingPlayer ~= nil and eDefendingPlayer ~= -1) then
1842 LuaEvents.WorldInput_ConfirmWarDialog(pSelectedUnit:GetOwner(), eDefendingPlayer, WarTypes.SURPRISE_WAR, strikeFn);
1843 end
1844 else
1845 local pPopupDialog :table = PopupDialog:new("ConfirmWMDStrike");
1846 pPopupDialog:AddText(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_ARE_YOU_SURE"));
1847 pPopupDialog:AddButton(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_CANCEL"), nil);
1848 pPopupDialog:AddButton(Locale.Lookup("LOC_LAUNCH_WMD_DIALOG_LAUNCH"), strikeFn);
1849 pPopupDialog:Open();
1850 end
1851 end
1852 return true;
1853end
1854-------------------------------------------------------------------------------
1855function WMDStrike( plot, unit, eWMD )
1856 local tParameters = {};
1857 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
1858 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
1859 tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
1860 if (UnitManager.CanStartOperation( unit, UnitOperationTypes.WMD_STRIKE, nil, tParameters)) then
1861 UnitManager.RequestOperation( unit, UnitOperationTypes.WMD_STRIKE, tParameters);
1862 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1863 end
1864end
1865-------------------------------------------------------------------------------
1866function OnInterfaceModeChange_WMD_Strike(eNewMode)
1867 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1868 local pSelectedUnit = UI.GetHeadSelectedUnit();
1869 if (pSelectedUnit ~= nil) then
1870 if m_focusedTargetPlot ~= -1 then
1871 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
1872 m_focusedTargetPlot = -1;
1873 end
1874 local sourcePlot : number = Map.GetPlot(pSelectedUnit:GetX(),pSelectedUnit:GetY()):GetIndex();
1875 local tParameters = {};
1876 local eWMD = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_WMD_TYPE);
1877 tParameters[UnitOperationTypes.PARAM_WMD_TYPE] = eWMD;
1878
1879 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.WMD_STRIKE, tParameters );
1880 local allPlots = tResults[UnitOperationResults.PLOTS];
1881 if (allPlots ~= nil) then
1882 m_targetPlots = {}; -- Used shared list
1883 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
1884 table.insert(m_targetPlots, allPlots[i]);
1885 end
1886
1887 -- Highlight the plots available to attack
1888 if (table.count(m_targetPlots) ~= 0) then
1889 -- Variation will hold specific targets in range
1890 local kVariations:table = {};
1891 for _,plotId in ipairs(m_targetPlots) do
1892 table.insert(kVariations, {"AttackRange_Target", sourcePlot, plotId} );
1893 end
1894 local eLocalPlayer:number = Game.GetLocalPlayer();
1895 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_ATTACK);
1896 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_ATTACK, eLocalPlayer, m_targetPlots, kVariations);
1897 end
1898 end
1899 end
1900end
1901
1902-------------------------------------------------------------------------------
1903function OnInterfaceModeLeave_WMD_Strike( eNewMode:number )
1904 UIManager:SetUICursor(CursorTypes.NORMAL);
1905 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
1906 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
1907end
1908
1909-- ===========================================================================
1910-- Code related to the ICBM Strike interface mode
1911-- ===========================================================================
1912function OnICBMStrikeEnd( pInputStruct )
1913 if ClearRangeAttackDragging() then
1914 return true;
1915 end
1916
1917 local pSelectedCity = UI.GetHeadSelectedCity();
1918 if (pSelectedCity == nil) then
1919 return false;
1920 end
1921
1922 local targetPlotID = UI.GetCursorPlotID();
1923 if (Map.IsPlot(targetPlotID)) then
1924 local targetPlot = Map.GetPlotByIndex(targetPlotID);
1925 local eWMD = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_WMD_TYPE);
1926 local sourcePlotX = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_X0);
1927 local sourcePlotY = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_Y0);
1928 local strikeFn = function() ICBMStrike(pSelectedCity, sourcePlotX, sourcePlotY, targetPlot, eWMD); end;
1929 --PlayersVisibility[ pSelectedCity:GetOwner() ]:IsVisible(targetPlot:GetX(), targetPlot:GetY())
1930 local bWillStartWar = CombatManager.IsAttackChangeWarState( pSelectedCity:GetComponentID(), targetPlot:GetX(), targetPlot:GetY(), eWMD );
1931 if (bWillStartWar) then
1932 local eDefendingPlayer = CombatManager.GetBestDefender( pSelectedCity:GetComponentID(), targetPlot:GetX(), targetPlot:GetY() );
1933 if (eDefendingPlayer == nil) then
1934 eDefendingPlayer = targetPlot:GetOwner();
1935 end
1936 -- Create the action specific parameters
1937 if (eDefendingPlayer ~= nil and eDefendingPlayer ~= -1) then
1938 LuaEvents.WorldInput_ConfirmWarDialog(pSelectedCity:GetOwner(), eDefendingPlayer, WarTypes.SURPRISE_WAR, strikeFn );
1939 end
1940 else
1941 local pPopupDialog :table = PopupDialog:new("ConfirmICBMStrike");
1942 pPopupDialog:AddText(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_ARE_YOU_SURE"));
1943 pPopupDialog:AddButton(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_CANCEL"), nil);
1944 pPopupDialog:AddButton(Locale.Lookup("LOC_LAUNCH_ICBM_DIALOG_LAUNCH"), strikeFn);
1945 pPopupDialog:Open();
1946 end
1947 end
1948end
1949-------------------------------------------------------------------------------
1950function ICBMStrike( fromCity, sourcePlotX, sourcePlotY, targetPlot, eWMD )
1951 local tParameters = {};
1952 tParameters[CityCommandTypes.PARAM_X0] = sourcePlotX;
1953 tParameters[CityCommandTypes.PARAM_Y0] = sourcePlotY;
1954 tParameters[CityCommandTypes.PARAM_X1] = targetPlot:GetX();
1955 tParameters[CityCommandTypes.PARAM_Y1] = targetPlot:GetY();
1956 tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;
1957 if (CityManager.CanStartCommand( fromCity, CityCommandTypes.WMD_STRIKE, tParameters)) then
1958 CityManager.RequestCommand( fromCity, CityCommandTypes.WMD_STRIKE, tParameters);
1959 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
1960 end
1961end
1962-------------------------------------------------------------------------------
1963function OnInterfaceModeChange_ICBM_Strike(eNewMode)
1964 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
1965 local pCity = UI.GetHeadSelectedCity();
1966
1967 if (pCity ~= nil) then
1968 if m_focusedTargetPlot ~= -1 then
1969 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
1970 m_focusedTargetPlot = -1;
1971 end
1972 local eWMD = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_WMD_TYPE);
1973 local iSourceLocX = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_X0);
1974 local iSourceLocY = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_Y0);
1975
1976 local tParameters = {};
1977 tParameters[CityCommandTypes.PARAM_WMD_TYPE] = eWMD;
1978 tParameters[CityCommandTypes.PARAM_X0] = iSourceLocX;
1979 tParameters[CityCommandTypes.PARAM_Y0] = iSourceLocY;
1980
1981 local sourcePlot : number = Map.GetPlot(iSourceLocX,iSourceLocY):GetIndex();
1982
1983 local tResults = CityManager.GetCommandTargets(pCity, CityCommandTypes.WMD_STRIKE, tParameters);
1984 local allPlots = tResults[CityCommandResults.PLOTS];
1985 if (allPlots ~= nil) then
1986 m_targetPlots = {}; -- Use shared list so other functions know our targets
1987 for i,modifier in ipairs(tResults[CityCommandResults.PLOTS]) do
1988 table.insert(m_targetPlots, allPlots[i]);
1989 end
1990
1991 -- Highlight the plots available to attack
1992 if (table.count(m_targetPlots) ~= 0) then
1993 local kVariations:table = {};
1994 for _,plotId in ipairs(m_targetPlots) do
1995 table.insert(kVariations, {"AttackRange_Target", sourcePlot , plotId} );
1996 end
1997 local eLocalPlayer:number = Game.GetLocalPlayer();
1998 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_ATTACK);
1999 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_ATTACK, eLocalPlayer, m_targetPlots, kVariations);
2000 end
2001 else
2002 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2003 end
2004 end
2005end
2006
2007---------------------------------------------------------------------------------
2008function OnInterfaceModeLeave_ICBM_Strike( eNewMode:number )
2009 UIManager:SetUICursor(CursorTypes.NORMAL);
2010 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
2011 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
2012end
2013
2014-- ===========================================================================
2015-- Code related to the Coastal Raid interface mode
2016-- ===========================================================================
2017function CoastalRaid( pInputStruct )
2018 local plotID = UI.GetCursorPlotID();
2019 if (Map.IsPlot(plotID)) then
2020 local plot = Map.GetPlotByIndex(plotID);
2021
2022 local tParameters = {};
2023 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2024 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2025
2026 local pSelectedUnit = UI.GetHeadSelectedUnit();
2027
2028 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.COASTAL_RAID, nil, tParameters)) then
2029 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.COASTAL_RAID, tParameters);
2030 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2031 end
2032 end
2033 return true;
2034end
2035-------------------------------------------------------------------------------
2036function OnInterfaceModeChange_CoastalRaid(eNewMode)
2037 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2038 local pSelectedUnit = UI.GetHeadSelectedUnit();
2039 if (pSelectedUnit ~= nil) then
2040 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.COASTAL_RAID );
2041 local allPlots = tResults[UnitOperationResults.PLOTS];
2042 if (allPlots ~= nil) then
2043 m_targetPlots = {};
2044 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2045 table.insert(m_targetPlots, allPlots[i]);
2046 end
2047
2048 -- Highlight the plots available to attack
2049 if (table.count(m_targetPlots) ~= 0) then
2050 local eLocalPlayer:number = Game.GetLocalPlayer();
2051 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_ATTACK);
2052 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_ATTACK, eLocalPlayer, m_targetPlots);
2053 end
2054 end
2055 end
2056end
2057
2058---------------------------------------------------------------------------------
2059function OnInterfaceModeLeave_CoastalRaid( eNewMode:number )
2060 UIManager:SetUICursor(CursorTypes.NORMAL);
2061 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
2062 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
2063end
2064
2065-- ===========================================================================
2066-- Code related to the Unit Air Deploy interface mode
2067-- ===========================================================================
2068function OnMouseDeployEnd( pInputStruct )
2069 -- If a drag was occurring, end it; otherwise raise event.
2070 if m_isMouseDragging then
2071 m_isMouseDragging = false;
2072 else
2073 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
2074 AirUnitDeploy(pInputStruct);
2075 end
2076 end
2077 EndDragMap();
2078 m_isMouseDownInWorld = false;
2079 return true;
2080end
2081-------------------------------------------------------------------------------
2082function AirUnitDeploy( pInputStruct )
2083 local plotID = UI.GetCursorPlotID();
2084 if (Map.IsPlot(plotID)) then
2085 local plot = Map.GetPlotByIndex(plotID);
2086
2087 local tParameters = {};
2088 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2089 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2090
2091 local pSelectedUnit = UI.GetHeadSelectedUnit();
2092 -- Assuming that the operation is DEPLOY. Store this in the InterfaceMode somehow?
2093 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.DEPLOY, nil, tParameters)) then
2094 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.DEPLOY, tParameters);
2095 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2096 end
2097 end
2098 return true;
2099end
2100-------------------------------------------------------------------------------
2101function OnInterfaceModeChange_Deploy(eNewMode)
2102 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2103 local pSelectedUnit = UI.GetHeadSelectedUnit();
2104 if (pSelectedUnit ~= nil) then
2105
2106 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.DEPLOY );
2107 local allPlots = tResults[UnitOperationResults.PLOTS];
2108 if (allPlots ~= nil) then
2109 m_targetPlots = {};
2110 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2111 --if(modifier == UnitOperationResults.MODIFIER_IS_TARGET) then
2112 table.insert(m_targetPlots, allPlots[i]);
2113 --end
2114 end
2115
2116 -- Highlight the plots available to deploy to
2117 if (table.count(m_targetPlots) ~= 0) then
2118 local eLocalPlayer:number = Game.GetLocalPlayer();
2119 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_MOVEMENT);
2120 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_MOVEMENT, eLocalPlayer, m_targetPlots);
2121 end
2122 end
2123 end
2124end
2125
2126---------------------------------------------------------------------------------
2127function OnInterfaceModeLeave_Deploy( eNewMode:number )
2128 UIManager:SetUICursor(CursorTypes.NORMAL);
2129 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
2130 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
2131end
2132
2133-- ===========================================================================
2134-- Code related to the Unit Air Re-Base interface mode
2135-- ===========================================================================
2136function OnMouseRebaseEnd( pInputStruct )
2137 -- If a drag was occurring, end it; otherwise raise event.
2138 if m_isMouseDragging then
2139 m_isMouseDragging = false;
2140 else
2141 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
2142 AirUnitReBase(pInputStruct);
2143 end
2144 end
2145 EndDragMap();
2146 m_isMouseDownInWorld = false;
2147 return true;
2148end
2149-------------------------------------------------------------------------------
2150function AirUnitReBase( pInputStruct )
2151 local plotID = UI.GetCursorPlotID();
2152 if (Map.IsPlot(plotID)) then
2153 local plot = Map.GetPlotByIndex(plotID);
2154
2155 local tParameters = {};
2156 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2157 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2158
2159 local pSelectedUnit = UI.GetHeadSelectedUnit();
2160 -- Assuming that the operation is DEPLOY. Store this in the InterfaceMode somehow?
2161 if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.REBASE, nil, tParameters)) then
2162 UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.REBASE, tParameters);
2163 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2164 end
2165 end
2166 return true;
2167end
2168-------------------------------------------------------------------------------
2169function OnInterfaceModeChange_ReBase(eNewMode)
2170 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2171 local pSelectedUnit = UI.GetHeadSelectedUnit();
2172 if (pSelectedUnit ~= nil) then
2173
2174 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, UnitOperationTypes.REBASE );
2175 local allPlots = tResults[UnitOperationResults.PLOTS];
2176 if (allPlots ~= nil) then
2177 m_targetPlots = {};
2178 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2179 table.insert(m_targetPlots, allPlots[i]);
2180 end
2181
2182 -- Highlight the plots available to deploy to
2183 if (table.count(m_targetPlots) ~= 0) then
2184 local eLocalPlayer:number = Game.GetLocalPlayer();
2185 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_MOVEMENT);
2186 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_MOVEMENT, eLocalPlayer, m_targetPlots);
2187 end
2188 end
2189 end
2190end
2191
2192---------------------------------------------------------------------------------
2193function OnInterfaceModeLeave_ReBase( eNewMode:number )
2194 UIManager:SetUICursor(CursorTypes.NORMAL);
2195 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
2196 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
2197end
2198
2199-- ===========================================================================
2200-- Code related to the Place Map Pin interface mode
2201-- ===========================================================================
2202function PlaceMapPin()
2203 local plotId = UI.GetCursorPlotID();
2204 if (Map.IsPlot(plotId)) then
2205 local kPlot = Map.GetPlotByIndex(plotId);
2206 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION); -- Revert to default interface mode.
2207 LuaEvents.MapPinPopup_RequestMapPin(kPlot:GetX(), kPlot:GetY());
2208 end
2209 return true;
2210end
2211
2212------------------------------------------------------------------------------------------------
2213-- Code related to the City and District Range Attack interface mode
2214------------------------------------------------------------------------------------------------
2215function CityRangeAttack( pInputStruct )
2216 if ClearRangeAttackDragging() then
2217 return true;
2218 end
2219
2220 local plotID = UI.GetCursorPlotID();
2221 if (Map.IsPlot(plotID)) then
2222 local plot = Map.GetPlotByIndex(plotID);
2223
2224 local tParameters = {};
2225 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2226 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2227
2228 local pSelectedCity = UI.GetHeadSelectedCity();
2229 -- Assuming that the command is RANGE_ATTACK. Store this in the InterfaceMode somehow?
2230 if (CityManager.CanStartCommand( pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters)) then
2231 CityManager.RequestCommand( pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters);
2232 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2233 end
2234 end
2235 return true;
2236end
2237
2238-------------------------------------------------------------------------------
2239function OnInterfaceModeChange_CityRangeAttack(eNewMode)
2240 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2241 local pSelectedCity = UI.GetHeadSelectedCity();
2242 if (pSelectedCity ~= nil) then
2243
2244 if m_focusedTargetPlot ~= -1 then
2245 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
2246 m_focusedTargetPlot = -1;
2247 end
2248
2249 local tParameters = {};
2250 tParameters[CityCommandTypes.PARAM_RANGED_ATTACK] = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_RANGED_ATTACK);
2251
2252 local tResults = CityManager.GetCommandTargets(pSelectedCity, CityCommandTypes.RANGE_ATTACK, tParameters );
2253 local allPlots = tResults[CityCommandResults.PLOTS];
2254 if (allPlots ~= nil) then
2255 m_targetPlots = {};
2256 for i,modifier in ipairs(tResults[CityCommandResults.MODIFIERS]) do
2257 if(modifier == CityCommandResults.MODIFIER_IS_TARGET) then
2258 table.insert(m_targetPlots, allPlots[i]);
2259 end
2260 end
2261
2262 -- Highlight the plots available to attack
2263 if (table.count(m_targetPlots) ~= 0) then
2264 -- Variation will hold specific targets in range
2265 local kVariations:table = {};
2266 for _,plotId in ipairs(m_targetPlots) do
2267 table.insert(kVariations, {"AttackRange_Target", allPlots[1], plotId} );
2268 end
2269 local eLocalPlayer:number = Game.GetLocalPlayer();
2270
2271 UILens.SetLayerHexesArea(LensLayers.ATTACK_RANGE, eLocalPlayer, allPlots, kVariations);
2272
2273 end
2274 end
2275 end
2276end
2277
2278-------------------------------------------------------------------------------
2279function OnInterfaceModeLeave_CityRangeAttack(eNewMode)
2280 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
2281end
2282
2283-------------------------------------------------------------------------------
2284function DistrictRangeAttack( pInputStruct )
2285 if ClearRangeAttackDragging() then
2286 return true;
2287 end
2288
2289 local plotID = UI.GetCursorPlotID();
2290 if (Map.IsPlot(plotID)) then
2291 local plot = Map.GetPlotByIndex(plotID);
2292
2293 local tParameters = {};
2294 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2295 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2296
2297 local pSelectedDistrict = UI.GetHeadSelectedDistrict();
2298 -- Assuming that the command is RANGE_ATTACK. Store this in the InterfaceMode somehow?
2299 if (CityManager.CanStartCommand( pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters)) then
2300 CityManager.RequestCommand( pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters);
2301 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2302 end
2303 end
2304 return true;
2305end
2306-------------------------------------------------------------------------------
2307function OnInterfaceModeChange_DistrictRangeAttack(eNewMode)
2308 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2309 local pSelectedDistrict = UI.GetHeadSelectedDistrict();
2310 if (pSelectedDistrict ~= nil) then
2311
2312 if m_focusedTargetPlot ~= -1 then
2313 UILens.UnFocusHex(LensLayers.ATTACK_RANGE, m_focusedTargetPlot);
2314 m_focusedTargetPlot = -1;
2315 end
2316
2317 local tParameters = {};
2318 tParameters[CityCommandTypes.PARAM_RANGED_ATTACK] = UI.GetInterfaceModeParameter(CityCommandTypes.PARAM_RANGED_ATTACK);
2319
2320 local tResults :table = CityManager.GetCommandTargets(pSelectedDistrict, CityCommandTypes.RANGE_ATTACK, tParameters );
2321 local allPlots :table = tResults[CityCommandResults.PLOTS];
2322 if (allPlots ~= nil) then
2323 m_targetPlots = {};
2324 for i,modifier in ipairs(tResults[CityCommandResults.MODIFIERS]) do
2325 if(modifier == CityCommandResults.MODIFIER_IS_TARGET) then
2326 table.insert(m_targetPlots, allPlots[i]);
2327 end
2328 end
2329
2330 -- Highlight the plots available to attack
2331 if (table.count(m_targetPlots) ~= 0) then
2332 -- Variation will hold specific targets in range
2333 local kVariations:table = {};
2334 for _,plotId in ipairs(m_targetPlots) do
2335 table.insert(kVariations, {"AttackRange_Target", allPlots[1], plotId} );
2336 end
2337 local eLocalPlayer:number = Game.GetLocalPlayer();
2338
2339 UILens.SetLayerHexesArea(LensLayers.ATTACK_RANGE, eLocalPlayer, allPlots, kVariations);
2340
2341 end
2342 end
2343 end
2344end
2345
2346-------------------------------------------------------------------------------
2347function OnInterfaceModeLeave_DistrictRangeAttack(eNewMode)
2348 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
2349end
2350
2351-------------------------------------------------------------------------------
2352function OnInterfaceModeLeave_WMDRangeAttack(eNewMode)
2353 UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
2354end
2355
2356------------------------------------------------------------------------------------------------
2357-- Code related to the Unit's Make Trade Route interface mode
2358-- Some input is handled separately, by TradePanel.lua
2359------------------------------------------------------------------------------------------------
2360function OnInterfaceModeChange_MakeTradeRoute(eNewMode)
2361 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2362end
2363
2364------------------------------------------------------------------------------------------------
2365-- Code related to the Unit's 'Teleport to City' mode
2366------------------------------------------------------------------------------------------------
2367function TeleportToCity()
2368 local plotID = UI.GetCursorPlotID();
2369 if (Map.IsPlot(plotID)) then
2370 local plot = Map.GetPlotByIndex(plotID);
2371
2372 local tParameters = {};
2373 tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
2374 tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
2375
2376 local eOperation = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_OPERATION_TYPE);
2377
2378 local pSelectedUnit = UI.GetHeadSelectedUnit();
2379 if (UnitManager.CanStartOperation( pSelectedUnit, eOperation, nil, tParameters)) then
2380 UnitManager.RequestOperation( pSelectedUnit, eOperation, tParameters);
2381 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2382 UI.PlaySound("Unit_Relocate");
2383 end
2384 end
2385 return true;
2386end
2387-------------------------------------------------------------------------------
2388function OnInterfaceModeChange_TeleportToCity(eNewMode)
2389 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2390 local pSelectedUnit = UI.GetHeadSelectedUnit();
2391 if (pSelectedUnit ~= nil) then
2392
2393 local eOperation = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_OPERATION_TYPE);
2394 local tResults = UnitManager.GetOperationTargets(pSelectedUnit, eOperation );
2395 local allPlots = tResults[UnitOperationResults.PLOTS];
2396 if (allPlots ~= nil) then
2397 m_targetPlots = {};
2398 for i,modifier in ipairs(tResults[UnitOperationResults.PLOTS]) do
2399 table.insert(m_targetPlots, allPlots[i]);
2400 end
2401
2402 -- Highlight the plots available to deploy to
2403 if (table.count(m_targetPlots) ~= 0) then
2404 local eLocalPlayer:number = Game.GetLocalPlayer();
2405 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_MOVEMENT);
2406 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_MOVEMENT, eLocalPlayer, m_targetPlots);
2407 end
2408 end
2409 end
2410end
2411
2412---------------------------------------------------------------------------------
2413function OnInterfaceModeLeave_TeleportToCity( eNewMode:number )
2414 UIManager:SetUICursor(CursorTypes.NORMAL);
2415 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
2416 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
2417end
2418
2419-- =============================================================================================
2420function OnInterfaceModeChange_MoveTo( eNewMode:number )
2421 m_cachedPathUnit = nil;
2422 m_cachedPathPlotId = -1 ;
2423 RealizeMovementPath();
2424end
2425
2426-- =============================================================================================
2427function OnInterfaceModeChange_MoveToLeave( eOldMode:number )
2428 ClearMovementPath();
2429 UILens.SetActive("Default");
2430end
2431
2432-- =============================================================================================
2433function OnInterfaceModeChange_PlaceMapPin( eNewMode:number )
2434 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2435end
2436
2437------------------------------------------------------------------------------------------------
2438-- Code related to the World Builder's Select Plot Mode
2439------------------------------------------------------------------------------------------------
2440
2441-- =============================================================================================
2442function OnInterfaceModeChange_WBSelectPlot()
2443 m_WBMouseOverPlot = -1;
2444end
2445
2446-- =============================================================================================
2447function OnInterfaceModeChange_SpyChooseMission()
2448 UIManager:SetUICursor(CursorTypes.NORMAL);
2449 UILens.SetActive("Default");
2450end
2451
2452-- =============================================================================================
2453function OnInterfaceModeChange_SpyTravelToCity()
2454 UIManager:SetUICursor(CursorTypes.NORMAL);
2455 UILens.SetActive("Default");
2456
2457end
2458
2459function OnInterfaceModeChange_NaturalWonder()
2460 UIManager:SetUICursor(CursorTypes.NORMAL);
2461 UI.SetFixedTiltMode( true );
2462end
2463
2464-- ===========================================================================
2465function OnInterfaceModeLeave_NaturalWonder( eNewMode:number )
2466 UIManager:SetUICursor(CursorTypes.NORMAL);
2467 UI.SetFixedTiltMode( false );
2468 OnCycleUnitSelectionRequest();
2469end
2470
2471-- ===========================================================================
2472function OnMouseEnd_WBSelectPlot( pInputStruct:table )
2473 -- If a drag was occurring, end it; otherwise attempt selection of whatever
2474 -- is in the plot the mouse is currently at.
2475 if m_isMouseDragging then
2476 print("Stopping drag");
2477 m_isMouseDragging = false;
2478 else
2479 print("World Builder Placement");
2480 if (Map.IsPlot(UI.GetCursorPlotID())) then
2481 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), true);
2482 end
2483 end
2484 EndDragMap(); -- Reset any dragging
2485 m_isMouseDownInWorld = false;
2486 return true;
2487end
2488
2489-- ===========================================================================
2490function OnRButtonUp_WBSelectPlot( pInputStruct )
2491 if (Map.IsPlot(UI.GetCursorPlotID())) then
2492 LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), false);
2493 end
2494 return true;
2495end
2496
2497-- ===========================================================================
2498function OnMouseMove_WBSelectPlot( pInputStruct )
2499
2500 -- Check to see if the plot the mouse is over has changed
2501 if not m_isMouseDragging then
2502 local mouseOverPlot = UI.GetCursorPlotID();
2503 if (Map.IsPlot(mouseOverPlot)) then
2504 if mouseOverPlot ~= m_WBMouseOverPlot then
2505 m_WBMouseOverPlot = mouseOverPlot;
2506 LuaEvents.WorldInput_WBMouseOverPlot(mouseOverPlot);
2507 end
2508 end
2509 end
2510
2511 return OnMouseMove();
2512end
2513
2514------------------------------------------------------------------------------------------------
2515-- Code related to the Unit's 'Form Corps' mode
2516------------------------------------------------------------------------------------------------
2517function FormCorps( pInputStruct )
2518 local plotID = UI.GetCursorPlotID();
2519 if (Map.IsPlot(plotID)) then
2520 local plot = Map.GetPlotByIndex(plotID);
2521 local unitList = Units.GetUnitsInPlotLayerID( plot:GetX(), plot:GetY(), MapLayers.ANY );
2522 local pSelectedUnit = UI.GetHeadSelectedUnit();
2523
2524 local tParameters :table = {};
2525 for i, pUnit in ipairs(unitList) do
2526 tParameters[UnitCommandTypes.PARAM_UNIT_PLAYER] = pUnit:GetOwner();
2527 tParameters[UnitCommandTypes.PARAM_UNIT_ID] = pUnit:GetID();
2528 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.FORM_CORPS, tParameters)) then
2529 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.FORM_CORPS, tParameters);
2530 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2531 end
2532 end
2533 end
2534 return true;
2535end
2536
2537------------------------------------------------------------------------------------------------
2538function OnInterfaceModeChange_UnitFormCorps(eNewMode)
2539 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2540 local pSelectedUnit = UI.GetHeadSelectedUnit();
2541 local player = pSelectedUnit:GetOwner();
2542 local tResults = UnitManager.GetCommandTargets( pSelectedUnit, UnitCommandTypes.FORM_CORPS );
2543 if (tResults[UnitCommandResults.UNITS] ~= nil and #tResults[UnitCommandResults.UNITS] ~= 0) then
2544 local tUnits = tResults[UnitCommandResults.UNITS];
2545 local unitPlots :table = {};
2546 m_targetPlots = {};
2547 for i, unitComponentID in ipairs(tUnits) do
2548 local unit = Players[player]:GetUnits():FindID(unitComponentID.id);
2549 table.insert(unitPlots, Map.GetPlotIndex(unit:GetX(), unit:GetY()));
2550 end
2551 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_PLACEMENT);
2552 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_PLACEMENT, player, unitPlots);
2553 m_targetPlots = unitPlots;
2554 end
2555end
2556
2557--------------------------------------------------------------------------------------------------
2558function OnInterfaceModeLeave_UnitFormCorps( eNewMode:number )
2559 UIManager:SetUICursor(CursorTypes.NORMAL);
2560 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_PLACEMENT );
2561 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_PLACEMENT );
2562end
2563
2564------------------------------------------------------------------------------------------------
2565-- Code related to the Unit's 'Form Army' mode
2566------------------------------------------------------------------------------------------------
2567function FormArmy( pInputStruct )
2568 local plotID = UI.GetCursorPlotID();
2569 if (Map.IsPlot(plotID)) then
2570 local plot = Map.GetPlotByIndex(plotID);
2571 local unitList = Units.GetUnitsInPlotLayerID( plot:GetX(), plot:GetY(), MapLayers.ANY );
2572 local pSelectedUnit = UI.GetHeadSelectedUnit();
2573
2574 local tParameters :table = {};
2575 for i, pUnit in ipairs(unitList) do
2576 tParameters[UnitCommandTypes.PARAM_UNIT_PLAYER] = pUnit:GetOwner();
2577 tParameters[UnitCommandTypes.PARAM_UNIT_ID] = pUnit:GetID();
2578 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.FORM_ARMY, tParameters)) then
2579 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.FORM_ARMY, tParameters);
2580 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2581 end
2582 end
2583 end
2584
2585 return true;
2586end
2587
2588------------------------------------------------------------------------------------------------
2589function OnInterfaceModeChange_UnitFormArmy(eNewMode)
2590 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2591 local pSelectedUnit = UI.GetHeadSelectedUnit();
2592 local player = pSelectedUnit:GetOwner();
2593 local tResults = UnitManager.GetCommandTargets( pSelectedUnit, UnitCommandTypes.FORM_ARMY );
2594 if (tResults[UnitCommandResults.UNITS] ~= nil and #tResults[UnitCommandResults.UNITS] ~= 0) then
2595 local tUnits = tResults[UnitCommandResults.UNITS];
2596 local unitPlots :table = {};
2597 m_targetPlots = {};
2598 for i, unitComponentID in ipairs(tUnits) do
2599 local unit = Players[player]:GetUnits():FindID(unitComponentID.id);
2600 table.insert(unitPlots, Map.GetPlotIndex(unit:GetX(), unit:GetY()));
2601 end
2602 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_PLACEMENT);
2603 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_PLACEMENT, player, unitPlots);
2604 m_targetPlots = unitPlots;
2605 end
2606end
2607
2608--------------------------------------------------------------------------------------------------
2609function OnInterfaceModeLeave_UnitFormArmy( eNewMode:number )
2610 UIManager:SetUICursor(CursorTypes.NORMAL);
2611 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_PLACEMENT );
2612 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_PLACEMENT );
2613end
2614
2615------------------------------------------------------------------------------------------------
2616-- Code related to the Unit's 'Airlift' mode
2617------------------------------------------------------------------------------------------------
2618function OnMouseAirliftEnd( pInputStruct )
2619 -- If a drag was occurring, end it; otherwise raise event.
2620 if m_isMouseDragging then
2621 m_isMouseDragging = false;
2622 else
2623 if IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
2624 UnitAirlift(pInputStruct);
2625 end
2626 end
2627 EndDragMap();
2628 m_isMouseDownInWorld = false;
2629 return true;
2630end
2631------------------------------------------------------------------------------------------------
2632function UnitAirlift( pInputStruct )
2633 local plotID = UI.GetCursorPlotID();
2634 if (Map.IsPlot(plotID)) then
2635 local plot = Map.GetPlotByIndex(plotID);
2636
2637 local tParameters = {};
2638 tParameters[UnitCommandTypes.PARAM_X] = plot:GetX();
2639 tParameters[UnitCommandTypes.PARAM_Y] = plot:GetY();
2640
2641 local pSelectedUnit = UI.GetHeadSelectedUnit();
2642 -- Assuming that the operation is AIRLIFT. Store this in the InterfaceMode somehow?
2643 if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.AIRLIFT, nil, tParameters)) then
2644 UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.AIRLIFT, tParameters);
2645 UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
2646 end
2647 end
2648 return true;
2649end
2650------------------------------------------------------------------------------------------------
2651function OnInterfaceModeChange_UnitAirlift(eNewMode)
2652 UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
2653 local pSelectedUnit = UI.GetHeadSelectedUnit();
2654 local tResults = UnitManager.GetCommandTargets(pSelectedUnit, UnitCommandTypes.AIRLIFT );
2655 local allPlots = tResults[UnitCommandResults.PLOTS];
2656 if (allPlots ~= nil) then
2657 m_targetPlots = {};
2658 for i,modifier in ipairs(tResults[UnitCommandResults.PLOTS]) do
2659 table.insert(m_targetPlots, allPlots[i]);
2660 end
2661
2662 -- Highlight the plots available to airlift to
2663 if (table.count(m_targetPlots) ~= 0) then
2664 local eLocalPlayer:number = Game.GetLocalPlayer();
2665 UILens.ToggleLayerOn(LensLayers.HEX_COLORING_MOVEMENT);
2666 UILens.SetLayerHexesArea(LensLayers.HEX_COLORING_MOVEMENT, eLocalPlayer, m_targetPlots);
2667 end
2668 end
2669end
2670--------------------------------------------------------------------------------------------------
2671function OnInterfaceModeLeave_UnitAirlift( eNewMode:number )
2672 UIManager:SetUICursor(CursorTypes.NORMAL);
2673 UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
2674 UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
2675end
2676
2677
2678-- ===========================================================================
2679function OnInterfaceModeChange_Selection(eNewMode)
2680 UIManager:SetUICursor(CursorTypes.NORMAL);
2681 UILens.SetActive("Default");
2682end
2683
2684
2685
2686-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
2687--
2688-- EVENT MAPPINGS, PRE-PROCESSING & HANDLING
2689--
2690-- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
2691
2692
2693-- ===========================================================================
2694-- ENGINE Event
2695-- Will only be called once the animation from the previous player is
2696-- complete or will be skipped if a player has no selection or explicitly
2697-- selected another unit/city.
2698-- ===========================================================================
2699function OnCycleUnitSelectionRequest()
2700
2701 -- If the right button is (still) down, do not select a new unit otherwise
2702 -- a long path may be created if there is a long camera pan.
2703 --if m_isMouseButtonRDown then
2704 -- return;
2705 --end
2706
2707 if(UI.GetInterfaceMode() ~= InterfaceModeTypes.NATURAL_WONDER or m_isMouseButtonRDown) then
2708 -- Auto-advance selection to the next unit.
2709 if not UI.SelectNextReadyUnit() then
2710 UI.DeselectAllUnits();
2711 end
2712 end
2713end
2714
2715
2716-- ===========================================================================
2717-- ENGINE Event
2718-- eOldMode, mode the engine was formally in
2719-- eNewMode, new mode the engine has just changed to
2720-- ===========================================================================
2721function OnInterfaceModeChanged( eOldMode:number, eNewMode:number )
2722
2723 -- Optional: function run before a mode is exited.
2724 local pOldModeHandler :table = InterfaceModeMessageHandler[eOldMode];
2725 if pOldModeHandler then
2726 local pModeLeaveFunc :ifunction = pOldModeHandler[INTERFACEMODE_LEAVE];
2727 if pModeLeaveFunc ~= nil then
2728 pModeLeaveFunc(eOldMode);
2729 end
2730 end
2731
2732 -- Required: function to setup next interface mode in world input
2733 local pNewModeHandler :table = InterfaceModeMessageHandler[eNewMode];
2734 if pNewModeHandler then
2735 local pModeChangeFunc :ifunction = pNewModeHandler[INTERFACEMODE_ENTER];
2736 if pModeChangeFunc ~= nil then
2737 pModeChangeFunc(eNewMode);
2738 end
2739 else
2740 local msg:string = string.format("Change requested an unhandled interface mode of value '0x%x'. (Previous mode '0x%x')",eNewMode,eOldMode);
2741 print(msg);
2742 UIManager:SetUICursor(CursorTypes.NORMAL);
2743 UILens.SetActive("Default");
2744 end
2745end
2746
2747-- ===========================================================================
2748-- ENGINE Event
2749-- ===========================================================================
2750function IsEndGameMenuShown()
2751 local endGameShown = false;
2752 local endGameContext = ContextPtr:LookUpControl("/InGame/EndGameMenu");
2753 if(endGameContext) then
2754 endGameShown = not endGameContext:IsHidden();
2755 end
2756 return endGameShown;
2757end
2758
2759function OnMultiplayerGameLastPlayer()
2760 -- Only show the last player popup in multiplayer games where the session is a going concern
2761 if(GameConfiguration.IsNetworkMultiplayer()
2762 and not Network.IsSessionInCloseState()
2763 -- suppress popup when the end game screen is up.
2764 -- 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
2765 and not IsEndGameMenuShown()) then
2766 local lastPlayerStr = Locale.Lookup( "TXT_KEY_MP_LAST_PLAYER" );
2767 local okStr = Locale.Lookup( "LOC_OK_BUTTON" );
2768 local pPopupDialog :table = PopupDialog:new("LastPlayer");
2769 pPopupDialog:AddText(lastPlayerStr);
2770 pPopupDialog:AddButton(okStr, nil );
2771 pPopupDialog:Open();
2772 end
2773end
2774
2775-- ===========================================================================
2776-- ENGINE Event
2777-- ===========================================================================
2778function OnMultiplayerGameAbandoned(eReason)
2779 if(GameConfiguration.IsNetworkMultiplayer()) then
2780 local errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_CONNECTION_LOST" );
2781 local exitStr = Locale.Lookup( "LOC_GAME_MENU_EXIT_TO_MAIN" );
2782
2783 -- Select error message based on KickReason.
2784 -- Not all of these should be possible while in game but we include them anyway.
2785 if (eReason == KickReason.KICK_HOST) then
2786 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_KICKED" );
2787 elseif (eReason == KickReason.KICK_NO_HOST) then
2788 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_HOST_LOSTED" );
2789 elseif (eReason == KickReason.KICK_NO_ROOM) then
2790 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_ROOM_FULL" );
2791 elseif (eReason == KickReason.KICK_VERSION_MISMATCH) then
2792 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_VERSION_MISMATCH" );
2793 elseif (eReason == KickReason.KICK_MOD_ERROR) then
2794 errorStr = Locale.Lookup( "LOC_GAME_ABANDONED_MOD_ERROR" );
2795 end
2796
2797 local pPopupDialog :table = PopupDialog:new("PlayerKicked");
2798 pPopupDialog:AddText(errorStr);
2799 pPopupDialog:AddButton(exitStr,
2800 function()
2801 Events.ExitToMainMenu();
2802 end);
2803 pPopupDialog:Open();
2804 end
2805end
2806
2807-- ===========================================================================
2808-- LUA Event
2809-- ===========================================================================
2810function OnTutorial_ConstrainMovement( plotID:number )
2811 m_constrainToPlotID = plotID;
2812end
2813
2814-- ===========================================================================
2815-- LUA Event
2816-- Effectively turns on/off ability to drag pan the map.
2817-- ===========================================================================
2818function OnTutorial_DisableMapDrag( isDisabled:boolean )
2819 m_isMapDragDisabled = isDisabled;
2820end
2821
2822-- ===========================================================================
2823-- LUA Event
2824-- Turns off canceling an event via a cancel action
2825-- (e.g., right click for district placement)
2826-- ===========================================================================
2827function OnTutorial_DisableMapCancel( isDisabled:boolean )
2828 m_isCancelDisabled = isDisabled;
2829end
2830
2831-- ===========================================================================
2832-- LUA Event
2833-- Effectively turns on/off ability to deselect unit.
2834-- exceptionHexIds (optional) a list of hex Ids that are still permitted to
2835-- be selected even in this state.
2836-- ===========================================================================
2837function OnTutorial_DisableMapSelect( isDisabled:boolean, kExceptionHexIds:table )
2838 if isDisabled then
2839 -- Set to either an empty table or the table of exception Ids if one was passed in.
2840 m_kTutorialPermittedHexes = (kExceptionHexIds ~= nil) and kExceptionHexIds or {};
2841 else
2842 m_kTutorialPermittedHexes = nil; -- Disabling
2843 end
2844end
2845
2846-- ===========================================================================
2847-- TEST
2848-- ===========================================================================
2849function Test()
2850 if (UI.GetHeadSelectedUnit() == nil) then
2851 print("Need head unit!");
2852 return false;
2853 end
2854 local kUnit :table = UI.GetHeadSelectedUnit();
2855-- local startPlotId :table = Map.GetPlot(sx, sy);
2856-- local endPlotId :number = UI.GetCursorPlotID();
2857
2858 local plots:table = UnitManager.GetReachableZonesOfControl( kUnit );
2859 if plots == nil then
2860 print("NIL plots return");
2861 else
2862 for k,v in pairs(plots) do
2863 print("LENSTest Plot: " .. tostring(k) .. " = " .. tostring(v) );
2864 end
2865 end
2866 return true;
2867end
2868
2869
2870-- ===========================================================================
2871-- Related to edge-panning.
2872-- ===========================================================================
2873function OnMouseBeginPanLeft()
2874 if IsAbleToEdgePan() then
2875 m_edgePanX = -PAN_SPEED;
2876 ProcessPan(m_edgePanX,m_edgePanY);
2877 end
2878end
2879function OnMouseStopPanLeft()
2880 if not ( m_edgePanX == 0.0 ) then
2881 m_edgePanX = 0.0;
2882 ProcessPan(m_edgePanX,m_edgePanY);
2883 end
2884end
2885function OnMouseBeginPanRight()
2886 if IsAbleToEdgePan() then
2887 m_edgePanX = PAN_SPEED;
2888 ProcessPan(m_edgePanX,m_edgePanY);
2889 end
2890end
2891function OnMouseStopPanRight()
2892 if not ( m_edgePanX == 0.0 ) then
2893 m_edgePanX = 0;
2894 ProcessPan(m_edgePanX,m_edgePanY);
2895 end
2896end
2897function OnMouseBeginPanUp()
2898 if IsAbleToEdgePan() then
2899 m_edgePanY = PAN_SPEED;
2900 ProcessPan(m_edgePanX,m_edgePanY);
2901 end
2902end
2903function OnMouseStopPanUp()
2904 if not ( m_edgePanY == 0.0 ) then
2905 m_edgePanY = 0;
2906 ProcessPan(m_edgePanX,m_edgePanY);
2907 end
2908end
2909function OnMouseBeginPanDown()
2910 if IsAbleToEdgePan() then
2911 m_edgePanY = -PAN_SPEED;
2912 ProcessPan(m_edgePanX,m_edgePanY);
2913 end
2914end
2915function OnMouseStopPanDown()
2916 if not ( m_edgePanY == 0.0 ) then
2917 m_edgePanY = 0;
2918 ProcessPan(m_edgePanX,m_edgePanY);
2919 end
2920end
2921
2922
2923-- ===========================================================================
2924-- UI Event
2925-- Input Event Processing
2926-- ===========================================================================
2927function OnInputHandler( pInputStruct:table )
2928
2929 local uiMsg :number = pInputStruct:GetMessageType();
2930 local mode :number = UI.GetInterfaceMode();
2931
2932 if uiMsg == MouseEvents.PointerLeave then
2933 ClearAllCachedInputState();
2934 ProcessPan(0,0);
2935 return;
2936 end
2937
2938
2939 -- DEBUG: T for Test (remove eventually; or at least comment out)
2940 --if pInputStruct:GetKey() == Keys.T and pInputStruct:IsControlDown() and pInputStruct:IsShiftDown() then
2941 if pInputStruct:GetKey() == Keys.T and pInputStruct:IsAltDown() and pInputStruct:IsControlDown() then
2942 return Test(); --??TRON
2943 end
2944
2945 -- Set internal represenation of inputs.
2946 m_isMouseButtonLDown = pInputStruct:IsLButtonDown();
2947 m_isMouseButtonRDown = pInputStruct:IsRButtonDown();
2948 m_isMouseButtonMDown = pInputStruct:IsMButtonDown();
2949
2950 -- Prevent "sticky" button down issues where a mouse release occurs else-where in UI so this context is unaware.
2951 m_isMouseDownInWorld = m_isMouseButtonLDown or m_isMouseButtonRDown or m_isMouseButtonMDown;
2952
2953 -- TODO: Below is test showing endPlot is not updating fast enough via event system
2954 -- (even with ImmediatePublish) and a direct/alternative way into the pathfinder
2955 -- needs to be added. Remove once new update paradigm is added. --??TRON debug:
2956 --local endPlotId :number = UI.GetCursorPlotID();
2957 --print("endPlotId, ",endPlotId,uiMsg);
2958
2959 -- Only except touch "up" or "move", if a mouse "down" occurred in the world.
2960 if m_isTouchEnabled then
2961 m_touchCount = TouchManager:GetTouchPointCount();
2962
2963 -- Show touch ID in squares
2964 if m_isDebuging then
2965 local kTouchIds:table = {};
2966 if m_touchCount > 0 then
2967 Controls.a1:SetToBeginning();
2968 Controls.a1:Play();
2969 local index:number = next(m_kTouchesDownInWorld,nil);
2970 table.insert(kTouchIds, index);
2971 if m_touchCount > 1 then
2972 Controls.a2:SetToBeginning();
2973 Controls.a2:Play();
2974 index = next(m_kTouchesDownInWorld,index);
2975 table.insert(kTouchIds, index);
2976 if m_touchCount > 2 then
2977 Controls.a3:SetToBeginning();
2978 Controls.a3:Play();
2979 index = next(m_kTouchesDownInWorld,index);
2980 table.insert(kTouchIds, index);
2981 end
2982 end
2983 end
2984 table.sort(kTouchIds);
2985 if m_touchCount > 0 then Controls.t1:SetText(tostring(kTouchIds[1])); end
2986 if m_touchCount > 1 then Controls.t2:SetText(tostring(kTouchIds[2])); end
2987 if m_touchCount > 2 then Controls.t3:SetText(tostring(kTouchIds[3])); end
2988 end
2989
2990 if uiMsg == MouseEvents.PointerUpdate then
2991 if m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] == nil then
2992 return false; -- Touch "down" did not occur in this context; ignore related touch sequence input.
2993 end
2994 elseif uiMsg == MouseEvents.PointerUp then
2995 -- Stop plot tool tippin' if more or less than 2 digits
2996 if m_touchCount < 2 then
2997 LuaEvents.WorldInput_TouchPlotTooltipHide();
2998 end
2999 if m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] == nil then
3000 return false; -- Touch "down" did not occur in this context; ignore related touch sequence input.
3001 end
3002 m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] = nil;
3003 elseif uiMsg == MouseEvents.PointerDown then
3004 m_kTouchesDownInWorld[ pInputStruct:GetTouchID() ] = true;
3005 -- If the 2nd touch occurs in the world (first one doesn't) then use it
3006 -- like a mouse for plot tool tips.
3007 if m_touchCount == 2 then
3008 LuaEvents.WorldInput_TouchPlotTooltipShow( pInputStruct:GetTouchID() );
3009 end
3010 end
3011 end
3012
3013 local isHandled:boolean = false;
3014
3015 -- Get the handler for the mode
3016 local modeHandler = InterfaceModeMessageHandler[mode];
3017
3018 -- Is it valid and is able to handle this message?
3019 if modeHandler and modeHandler[uiMsg] then
3020 isHandled = modeHandler[uiMsg]( pInputStruct );
3021 elseif DefaultMessageHandler[uiMsg] then
3022 isHandled = DefaultMessageHandler[uiMsg]( pInputStruct );
3023 end
3024
3025 -- Do this after the handler has completed as it may be making decisions based on if mouse dragging occurred.
3026 if not m_isMouseDownInWorld and m_isMouseDragging then
3027 --print("Forced mouse dragging false!");
3028 m_isMouseDragging = false; -- No mouse down, no dragging is occuring!
3029 end
3030
3031
3032 return isHandled;
3033end
3034
3035
3036-- ===========================================================================
3037-- UI Event
3038-- Per-frame (e.g., expensive) event.
3039-- ===========================================================================
3040function OnRefresh()
3041 -- If there is a panning delta, and screen can pan, do the pan and request
3042 -- this is refreshed again.
3043 --if (m_edgePanX ~= 0 or m_edgePanY ~= 0) and IsAbleToEdgePan() then
3044 -- RealizePan();
3045 -- ContextPtr:RequestRefresh()
3046 --end
3047end
3048
3049
3050-- ===========================================================================
3051--
3052-- ===========================================================================
3053function ClearAllCachedInputState()
3054 m_isALTDown = false;
3055 m_isUPpressed = false;
3056 m_isDOWNpressed = false;
3057 m_isLEFTpressed = false;
3058 m_isRIGHTpressed = false;
3059
3060 m_isDoubleTapping = false;
3061 m_isMouseDownInWorld= false;
3062 m_isMouseButtonLDown= false;
3063 m_isMouseButtonMDown= false;
3064 m_isMouseButtonRDown= false;
3065 m_isMouseDragging = false;
3066 m_isTouchDragging = false;
3067 m_isTouchZooming = false;
3068 m_isTouchPathing = false;
3069 m_mapZoomStart = 0;
3070 m_dragStartFocusWorldX = 0;
3071 m_dragStartFocusWorldY = 0;
3072 m_dragStartWorldX = 0;
3073 m_dragStartWorldY = 0;
3074 m_dragStartX = 0;
3075 m_dragStartY = 0;
3076 m_dragX = 0;
3077 m_dragY = 0;
3078 m_edgePanX = 0.0;
3079 m_edgePanY = 0.0;
3080 m_touchTotalNum = 0;
3081 m_touchStartPlotX = -1;
3082 m_touchStartPlotY = -1;
3083 ms_bGridOn = true;
3084end
3085
3086
3087-- ===========================================================================
3088-- UI Event
3089-- Called whenever the application regains focus.
3090-- ===========================================================================
3091function OnAppRegainedFocusHandler()
3092 ClearAllCachedInputState();
3093 ProcessPan(m_edgePanX,m_edgePanY);
3094end
3095
3096
3097-- ===========================================================================
3098-- UI Event
3099-- Called whenever the application loses focus.
3100-- ===========================================================================
3101function OnAppLostFocusHandler()
3102 ClearAllCachedInputState();
3103 ProcessPan(0,0);
3104end
3105
3106
3107-- ===========================================================================
3108-- UI Event
3109-- ===========================================================================
3110function OnShutdown()
3111 -- Clean up events
3112 Events.CycleUnitSelectionRequest.Remove( OnCycleUnitSelectionRequest );
3113 Events.InterfaceModeChanged.Remove( OnInterfaceModeChanged );
3114
3115 LuaEvents.Tutorial_ConstrainMovement.Remove( OnTutorial_ConstrainMovement );
3116 LuaEvents.Tutorial_DisableMapDrag.Remove( OnTutorial_DisableMapDrag );
3117 LuaEvents.Tutorial_DisableMapSelect.Remove( OnTutorial_DisableMapSelect );
3118end
3119
3120-- ===========================================================================
3121-- Hotkey Event
3122-- ===========================================================================
3123function OnInputActionTriggered( actionId )
3124 if actionId == m_actionHotkeyToggleGrid then
3125 -- TODO: query if already on (or will get out of sync with button presses!)
3126 ms_bGridOn = not ms_bGridOn;
3127 UI.ToggleGrid( ms_bGridOn );
3128 end
3129
3130 if actionId == m_actionHotkeyOnlinePause then
3131 if GameConfiguration.IsNetworkMultiplayer() then
3132 TogglePause();
3133 end
3134 end
3135end
3136
3137-- ===========================================================================
3138-- INCLUDES
3139-- Other handlers & helpers that may utilze functionality defined in here
3140-- ===========================================================================
3141
3142include ("StrategicView_MapPlacement"); -- handlers for: BUILDING_PLACEMENT, DISTRICT_PLACEMENT
3143include ("StrategicView_DebugSupport"); -- the Debug interface mode
3144
3145
3146-- ===========================================================================
3147-- Assign callbacks
3148-- ===========================================================================
3149function Initialize()
3150
3151 m_isTouchEnabled = Options.GetAppOption("UI", "IsTouchScreenEnabled") ~= 0;
3152
3153 -- Input assignments.
3154
3155 -- Default handlers:
3156 DefaultMessageHandler[KeyEvents.KeyDown] = OnDefaultKeyDown;
3157 DefaultMessageHandler[KeyEvents.KeyUp] = OnDefaultKeyUp;
3158 DefaultMessageHandler[MouseEvents.LButtonDown] = OnMouseStart;
3159 DefaultMessageHandler[MouseEvents.LButtonUp] = OnMouseEnd;
3160 DefaultMessageHandler[MouseEvents.MouseMove] = OnMouseMove;
3161 DefaultMessageHandler[MouseEvents.RButtonUp] = OnDefaultChangeToSelectionMode;
3162 DefaultMessageHandler[MouseEvents.PointerUp] = OnDefaultChangeToSelectionMode;
3163 DefaultMessageHandler[MouseEvents.MouseWheel] = OnMouseWheelZoom;
3164
3165 -- Interface Mode ENTERING :
3166 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Air_Attack;
3167 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Debug;
3168 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_CityManagement;
3169 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_WMD_Strike;
3170 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_ICBM_Strike;
3171 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_CoastalRaid;
3172 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_BuildingPlacement; -- StrategicView_MapPlacement.lua
3173 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_CityRangeAttack;
3174 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Deploy;
3175 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [INTERFACEMODE_ENTER] = OnInterfaceModeEnter_DistrictPlacement; -- StrategicView_MapPlacement.lua
3176 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][INTERFACEMODE_ENTER] = OnInterfaceModeChange_DistrictRangeAttack;
3177 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitFormArmy;
3178 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitFormCorps;
3179 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitAirlift;
3180 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MakeTradeRoute;
3181 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_TeleportToCity;
3182 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MoveTo;
3183 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_UnitRangeAttack;
3184 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_ReBase;
3185 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_Selection;
3186 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_MoveTo;
3187 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_PlaceMapPin;
3188 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_WBSelectPlot;
3189 InterfaceModeMessageHandler[InterfaceModeTypes.SPY_CHOOSE_MISSION] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_SpyChooseMission;
3190 InterfaceModeMessageHandler[InterfaceModeTypes.SPY_TRAVEL_TO_CITY] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_SpyTravelToCity;
3191 InterfaceModeMessageHandler[InterfaceModeTypes.NATURAL_WONDER] [INTERFACEMODE_ENTER] = OnInterfaceModeChange_NaturalWonder;
3192
3193 -- Interface Mode LEAVING (optional):
3194 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_BuildingPlacement; -- StrategicView_MapPlacement.lua
3195 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CityManagement;
3196 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_DistrictPlacement; -- StrategicView_MapPlacement.lua
3197 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [INTERFACEMODE_LEAVE] = OnInterfaceModeChange_MoveToLeave;
3198 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitRangeAttack;
3199 InterfaceModeMessageHandler[InterfaceModeTypes.NATURAL_WONDER] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_NaturalWonder;
3200 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CityRangeAttack;
3201 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_DistrictRangeAttack;
3202 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_WMDRangeAttack;
3203 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_WMDRangeAttack;
3204 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Air_Attack;
3205 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_WMD_Strike;
3206 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_ICBM_Strike;
3207 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_CoastalRaid;
3208 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_Deploy;
3209 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_ReBase;
3210 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_TeleportToCity;
3211 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitFormCorps;
3212 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitFormArmy;
3213 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_UnitAirlift;
3214
3215 -- Keyboard Events (all happen on up!)
3216 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3217 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [KeyEvents.KeyUp] = OnPlacementKeyUp;
3218
3219
3220 -- Mouse Events
3221 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.LButtonUp] = OnMouseDebugEnd;
3222 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.RButtonUp] = OnDebugCancelPlacement;
3223 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.LButtonUp] = OnMouseSelectionEnd;
3224 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.RButtonDown] = OnMouseSelectionUnitMoveStart;
3225 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.RButtonUp] = OnMouseSelectionUnitMoveEnd;
3226 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.MButtonDown] = OnMouseSelectionSnapToPlot;
3227 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.MouseMove] = OnMouseSelectionMove;
3228 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.LButtonDoubleClick] = OnSelectionDoubleTap;
3229 InterfaceModeMessageHandler[InterfaceModeTypes.VIEW_MODAL_LENS] [MouseEvents.LButtonUp] = OnMouseSelectionEnd;
3230 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.LButtonUp] = OnMouseMakeTradeRouteEnd;
3231 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.MButtonDown] = OnMouseMakeTradeRouteSnapToPlot;
3232 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.LButtonUp] = OnMouseTeleportToCityEnd;
3233 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.MButtonDown] = OnMouseTeleportToCitySnapToPlot;
3234 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.LButtonUp] = OnMouseDistrictPlacementEnd;
3235 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.RButtonUp] = OnMouseDistrictPlacementCancel;
3236 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.MouseMove] = OnMouseDistrictPlacementMove;
3237 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.LButtonDown] = OnMouseMoveToStart;
3238 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.LButtonUp] = OnMouseMoveToEnd;
3239 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.MouseMove] = OnMouseMoveToUpdate;
3240 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.RButtonUp] = OnMouseMoveToCancel;
3241 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.LButtonUp] = OnMouseUnitRangeAttack;
3242 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3243 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3244 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.LButtonUp] = DistrictRangeAttack;
3245 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.LButtonUp] = OnMouseBuildingPlacementEnd;
3246 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.RButtonUp] = OnMouseBuildingPlacementCancel;
3247 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.MouseMove] = OnMouseBuildingPlacementMove;
3248 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.LButtonUp] = CityRangeAttack;
3249 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3250 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [MouseEvents.LButtonUp] = FormCorps;
3251 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [MouseEvents.LButtonUp] = FormArmy;
3252 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [MouseEvents.LButtonUp] = OnMouseAirliftEnd;
3253 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [MouseEvents.LButtonUp] = UnitAirAttack;
3254 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.LButtonUp] = OnWMDStrikeEnd;
3255 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3256 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.LButtonUp] = OnICBMStrikeEnd;
3257 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.MouseMove] = OnMouseMoveRangeAttack;
3258 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [MouseEvents.LButtonUp] = OnMouseDeployEnd;
3259 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [MouseEvents.LButtonUp] = OnMouseRebaseEnd;
3260 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [MouseEvents.LButtonUp] = CoastalRaid;
3261 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [MouseEvents.LButtonUp] = PlaceMapPin;
3262 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.LButtonUp] = OnMouseEnd_WBSelectPlot;
3263 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.RButtonUp] = OnRButtonUp_WBSelectPlot;
3264 InterfaceModeMessageHandler[InterfaceModeTypes.WB_SELECT_PLOT] [MouseEvents.MouseMove] = OnMouseMove_WBSelectPlot;
3265
3266 -- Touch Events (if a touch system)
3267 if m_isTouchEnabled then
3268 InterfaceModeMessageHandler[InterfaceModeTypes.DEBUG] [MouseEvents.PointerUp] = DebugPlacement;
3269 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerDown] = OnTouchSelectionStart;
3270 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerUpdate] = OnTouchSelectionUpdate;
3271 InterfaceModeMessageHandler[InterfaceModeTypes.SELECTION] [MouseEvents.PointerUp] = OnTouchSelectionEnd;
3272 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerDown] = OnTouchStart;
3273 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3274 InterfaceModeMessageHandler[InterfaceModeTypes.MAKE_TRADE_ROUTE] [MouseEvents.PointerUp] = OnTouchTradeRouteEnd;
3275 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerDown] = OnTouchStart;
3276 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3277 InterfaceModeMessageHandler[InterfaceModeTypes.TELEPORT_TO_CITY] [MouseEvents.PointerUp] = OnTouchTeleportToCityEnd;
3278 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerDown] = OnTouchStart;
3279 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3280 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_PLACEMENT] [MouseEvents.PointerUp] = OnTouchDistrictPlacementEnd;
3281 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerDown] = OnTouchMoveToStart;
3282 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerUpdate] = OnTouchMoveToUpdate;
3283 InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_TO] [MouseEvents.PointerUp] = OnTouchMoveToEnd;
3284 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerDown] = OnTouchStart;
3285 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerUpdate] = OnTouchUpdate;
3286 InterfaceModeMessageHandler[InterfaceModeTypes.BUILDING_PLACEMENT] [MouseEvents.PointerUp] = OnTouchBuildingPlacementEnd;
3287 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_RANGE_ATTACK] [MouseEvents.PointerUp] = CityRangeAttack;
3288 InterfaceModeMessageHandler[InterfaceModeTypes.DISTRICT_RANGE_ATTACK][MouseEvents.PointerUp] = DistrictRangeAttack;
3289 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_ARMY] [MouseEvents.PointerUp] = FormArmy;
3290 InterfaceModeMessageHandler[InterfaceModeTypes.FORM_CORPS] [MouseEvents.PointerUp] = FormCorps;
3291 InterfaceModeMessageHandler[InterfaceModeTypes.AIRLIFT] [MouseEvents.PointerUp] = Airlift;
3292 InterfaceModeMessageHandler[InterfaceModeTypes.RANGE_ATTACK] [MouseEvents.PointerUp] = UnitRangeAttack;
3293 InterfaceModeMessageHandler[InterfaceModeTypes.AIR_ATTACK] [MouseEvents.PointerUp] = UnitAirAttack;
3294 InterfaceModeMessageHandler[InterfaceModeTypes.WMD_STRIKE] [MouseEvents.PointerUp] = OnWMDStrikeEnd;
3295 InterfaceModeMessageHandler[InterfaceModeTypes.ICBM_STRIKE] [MouseEvents.PointerUp] = OnICBMStrikeEnd;
3296 InterfaceModeMessageHandler[InterfaceModeTypes.DEPLOY] [MouseEvents.PointerUp] = AirUnitDeploy;
3297 InterfaceModeMessageHandler[InterfaceModeTypes.REBASE] [MouseEvents.PointerUp] = AirUnitReBase;
3298 InterfaceModeMessageHandler[InterfaceModeTypes.COASTAL_RAID] [MouseEvents.PointerUp] = CoastalRaid;
3299 InterfaceModeMessageHandler[InterfaceModeTypes.PLACE_MAP_PIN] [MouseEvents.PointerUp] = PlaceMapPin;
3300 InterfaceModeMessageHandler[InterfaceModeTypes.CITY_MANAGEMENT] [MouseEvents.PointerUp] = OnDoNothing;
3301 end
3302
3303
3304 -- ===== EVENTS =====
3305
3306 -- Game Engine Events
3307 Events.CityMadePurchase.Add( OnCityMadePurchase_StrategicView_MapPlacement );
3308 Events.CycleUnitSelectionRequest.Add( OnCycleUnitSelectionRequest );
3309 Events.InputActionTriggered.Add( OnInputActionTriggered );
3310 Events.InterfaceModeChanged.Add(OnInterfaceModeChanged);
3311 Events.MultiplayerGameLastPlayer.Add(OnMultiplayerGameLastPlayer);
3312 Events.MultiplayerGameAbandoned.Add(OnMultiplayerGameAbandoned);
3313
3314 -- LUA Events
3315 LuaEvents.Tutorial_ConstrainMovement.Add( OnTutorial_ConstrainMovement );
3316 LuaEvents.Tutorial_DisableMapDrag.Add( OnTutorial_DisableMapDrag );
3317 LuaEvents.Tutorial_DisableMapSelect.Add( OnTutorial_DisableMapSelect );
3318 LuaEvents.Tutorial_DisableMapCancel.Add( OnTutorial_DisableMapCancel );
3319
3320 LuaEvents.Tutorial_AddUnitHexRestriction.Add( OnTutorial_AddUnitHexRestriction );
3321 LuaEvents.Tutorial_RemoveUnitHexRestriction.Add( OnTutorial_RemoveUnitHexRestriction );
3322 LuaEvents.Tutorial_ClearAllHexMoveRestrictions.Add( OnTutorial_ClearAllUnitHexRestrictions );
3323
3324 LuaEvents.Tutorial_AddUnitMoveRestriction.Add( OnTutorial_AddUnitMoveRestriction );
3325 LuaEvents.Tutorial_RemoveUnitMoveRestrictions.Add( OnTutorial_RemoveUnitMoveRestrictions );
3326
3327
3328 -- UI Events
3329 Controls.LeftScreenEdge:RegisterMouseEnterCallback( OnMouseBeginPanLeft );
3330 Controls.LeftScreenEdge:RegisterMouseExitCallback( OnMouseStopPanLeft );
3331 Controls.RightScreenEdge:RegisterMouseEnterCallback( OnMouseBeginPanRight );
3332 Controls.RightScreenEdge:RegisterMouseExitCallback( OnMouseStopPanRight );
3333 Controls.TopScreenEdge:RegisterMouseEnterCallback( OnMouseBeginPanUp );
3334 Controls.TopScreenEdge:RegisterMouseExitCallback( OnMouseStopPanUp );
3335 Controls.BottomScreenEdge:RegisterMouseEnterCallback( OnMouseBeginPanDown );
3336 Controls.BottomScreenEdge:RegisterMouseExitCallback( OnMouseStopPanDown );
3337 ContextPtr:SetInputHandler( OnInputHandler, true );
3338 ContextPtr:SetRefreshHandler( OnRefresh );
3339 ContextPtr:SetAppRegainedFocusHandler( OnAppRegainedFocusHandler );
3340 ContextPtr:SetAppLostFocusHandler( OnAppLostFocusHandler );
3341 ContextPtr:SetShutdown( OnShutdown );
3342
3343 Controls.DebugStuff:SetHide(not m_isDebuging);
3344 -- Popup setup
3345 m_kConfirmWarDialog = PopupDialog:new( "ConfirmWarPopup" );
3346end
3347Initialize();