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