Guest User

Worldinput.lua

a guest
Oct 23rd, 2016
414
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 133.87 KB | None | 0 0
  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.  
  15. include("PopupDialogSupport.lua");
  16. -- More interface-specific includes before the initialization
  17.  
  18.  
  19.  
  20. -- ===========================================================================
  21. --  Debug
  22. -- ===========================================================================
  23.  
  24. local m_isDebuging              :boolean = false;   -- Turn on local debug systems
  25.  
  26. -- ===========================================================================
  27. --  CONSTANTS
  28. -- ===========================================================================
  29.  
  30. local INTERFACEMODE_ENTER       :string = "InterfaceModeEnter";
  31. local INTERFACEMODE_LEAVE       :string = "InterfaceModeLeave";
  32. local NORMALIZED_DRAG_THRESHOLD :number = 0.035;            -- How much movement to kick off a drag
  33. local MOUSE_SCALAR              :number = 6.0;
  34. local PAN_SPEED                 :number = 1;
  35. local ZOOM_SPEED                :number = 0.1;
  36. local 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. -- ===========================================================================
  43. InterfaceModeMessageHandler =
  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.  
  82. local showMapResources:boolean = not UserConfiguration.ShowMapResources();
  83. local showMapYield:boolean = not UserConfiguration.ShowMapYield();
  84. local DefaultMessageHandler     :table  = {};
  85. local m_actionHotkeyToggleGrid  :number = Input.GetActionId("ToggleGrid");      --  Hot Key Handling
  86. local m_actionHotkeyOnlinePause :number = Input.GetActionId("OnlinePause");     --  Hot Key Handling
  87. local m_kTouchesDownInWorld     :table  = {};       -- Tracks "down" touches that occurred in this context.
  88. local m_isTouchEnabled          :boolean= false;
  89. local m_isALTDown               :boolean= false;
  90. local m_isMouseButtonLDown      :boolean= false;
  91. local m_isMouseButtonMDown      :boolean= false;
  92. local m_isMouseButtonRDown      :boolean= false;
  93. local m_isMouseDownInWorld      :boolean= false;    -- Did mouse-down start here (true), or in some other UI context?
  94. local m_isMouseDragging         :boolean= false;
  95. local m_isTouchDragging         :boolean= false;
  96. local m_isTouchZooming          :boolean= false;
  97. local m_isTouchPathing          :boolean= false;
  98. local m_isDoubleTapping         :boolean= false;
  99. local m_touchCount              :number = 0;        -- # of touches currently occuring
  100. local m_touchStartPlotX         :number = -1;
  101. local m_touchStartPlotY         :number = -1;
  102. local m_touchTotalNum           :number = 0;        -- # of multiple touches that occurred
  103. local m_mapZoomStart            :number = 0;
  104. local m_dragStartWorldX         :number = 0;
  105. local m_dragStartWorldY         :number = 0;
  106. local m_dragStartFocusWorldX    :number = 0;
  107. local m_dragStartFocusWorldY    :number = 0;
  108. local m_dragStartX              :number = 0;        -- Mouse or virtual mouse (of average touch points) X
  109. local m_dragStartY              :number = 0;        -- Mouse or virtual mouse (of average touch points) Y
  110. local m_dragX                   :number = 0;   
  111. local m_dragY                   :number = 0;
  112. local m_edgePanX                :number = 0;
  113. local m_edgePanY                :number = 0;
  114. local m_constrainToPlotID       :number = 0;
  115. local ms_bGridOn                :boolean= true;
  116. local m_isMapDragDisabled       :boolean = false;
  117. local m_isCancelDisabled        :boolean = false;   -- Is a cancelable action (e.g., right-click for district placement) been disabled?
  118. local m_debugTrace              :table = {};        -- debug
  119. local m_cachedPathUnit          :table;
  120. local m_cachedPathPlotId        :number;
  121. local m_previousTurnsCount      :number = 0;
  122. local m_kConfirmWarDialog       :table;
  123. local m_targetPlots             :table;
  124. local m_focusedTargetPlot       :number = -1;
  125. local m_WBMouseOverPlot         :number = -1;
  126. local m_kTutorialPermittedHexes         :table = nil;       -- Which hexes are permitted for selection by the tutorial (nil if disabled)
  127. local m_kTutorialUnitHexRestrictions    :table = nil;       -- Any restrictions on where units can move.  (Key=UnitType, Value={restricted plotIds})
  128. local 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)
  129. local 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. -- ===========================================================================
  144. function trace( msg:string )    m_debugTrace[table.count(m_debugTrace)+1] = msg;    end
  145. function dump()                 print("DebugTrace: "..table.concat(m_debugTrace));  end
  146. function clear()                m_debugTrace = {};                                  end
  147.  
  148.  
  149.  
  150. -- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
  151. --
  152. --                                      OPERATIONS
  153. --
  154. -- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
  155.  
  156.  
  157. -- ===========================================================================
  158. --  Empty function (to override default)
  159. -- ===========================================================================
  160. function OnDoNothing()
  161. end
  162.  
  163.  
  164. -- ===========================================================================
  165. --  Pan camera
  166. -- ===========================================================================
  167. function 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 );
  180. end
  181.  
  182.  
  183. -- ===========================================================================
  184. --  Input conditions are set for edge camera panning
  185. -- ===========================================================================
  186. function IsAbleToEdgePan()
  187.     return UserConfiguration.IsEdgePanEnabled() or ( (UI.GetInterfaceMode() == InterfaceModeTypes.SELECTION) and m_isMouseButtonRDown );
  188. end
  189.  
  190.  
  191. -- ===========================================================================
  192. --  Have world camera focus on a plot
  193. --  plotId, the plot # to look at
  194. -- ===========================================================================
  195. function SnapToPlot( plotId:number )
  196.     if (Map.IsPlot(plotId)) then
  197.         local plot = Map.GetPlotByIndex(plotId);
  198.         UI.LookAtPlot( plot );
  199.     end
  200. end
  201.  
  202. -- ===========================================================================
  203. function IsCancelAllowed()
  204.     return (not m_isCancelDisabled);
  205. end
  206.  
  207. -- ===========================================================================
  208. --  Perform a camera zoom based on the native 2-finger gesture
  209. -- ===========================================================================
  210. function 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
  236. end
  237.  
  238. -- ===========================================================================
  239. function 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;
  254. end
  255.  
  256. -- ===========================================================================
  257. function 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
  292. end
  293.  
  294. -- ===========================================================================
  295. --  Selects a unit but firsts deselect any current unit, thereby forcing
  296. --  a cache refresh.
  297. -- ===========================================================================
  298. function SelectUnit( kUnit:table ) 
  299.     UI.DeselectUnit(kUnit);
  300.     UI.SelectUnit(kUnit);
  301. end
  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. -- ===========================================================================
  308. function 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;
  316. end
  317.  
  318. -- ===========================================================================
  319. --  Selects the unit or city at the plot passed in.
  320. -- ===========================================================================
  321. function 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;
  369. end
  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. -- ===========================================================================
  376. function 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;  
  381. end
  382.  
  383. -- ===========================================================================
  384. --  Setup to start dragging the map.
  385. -- ===========================================================================
  386. function 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();
  393. end
  394.  
  395. -- ===========================================================================
  396. --  Drag (or spin) the camera based new position
  397. -- ===========================================================================
  398. function 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;
  423. end
  424.  
  425. -- ===========================================================================
  426. --  Reset drag variables for next go around.
  427. -- ===========================================================================
  428. function 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;   
  440. end
  441.  
  442.  
  443. -- ===========================================================================
  444. --  True if a given unit type is allowed to move to a plot.
  445. -- ===========================================================================
  446. function 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;
  456. end
  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. -- ===========================================================================
  463. function 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 );
  470. end
  471.  
  472. -- ===========================================================================
  473. --  RETURNS true if the plot is considered a bad move for a unit.
  474. --          Also returns the plotId (if bad)
  475. -- ===========================================================================
  476. function 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;
  524. end
  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. -- ===========================================================================
  532. function 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
  542. end
  543.  
  544. -- ===========================================================================
  545. --  LUA Event
  546. -- ===========================================================================
  547. function 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
  571. end
  572.  
  573. -- ===========================================================================
  574. --  LUA Event
  575. -- ===========================================================================
  576. function OnTutorial_ClearAllUnitHexRestrictions()
  577.     m_kTutorialUnitHexRestrictions = nil;
  578. end
  579.  
  580.  
  581. -- ===========================================================================
  582. --  LUA Event
  583. --  Prevent a unit type from being selected.
  584. -- ===========================================================================
  585. function 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;
  594. end
  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. -- ===========================================================================
  602. function 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
  613. end
  614.  
  615.  
  616. -- ===========================================================================
  617. -- Perform a movement path operation (if there is a selected unit).
  618. -- ===========================================================================
  619. function 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
  638. end
  639.  
  640. -- ===========================================================================
  641. function UnitMovementCancel()
  642.     ClearMovementPath();
  643.     UILens.SetActive("Default");
  644. end
  645.  
  646. -- ===========================================================================
  647. --  Unit Range Attack
  648. -- ===========================================================================
  649. function 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);
  669. end
  670.  
  671. -- ===========================================================================
  672. --  Clear the visual representation (and cache) of the movement path
  673. -- ===========================================================================
  674. function 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;
  680. end
  681.  
  682. -- ===========================================================================
  683. function ClearRangeAttackDragging()
  684.     local bWasDragging:boolean = m_isMouseDragging;
  685.     OnMouseEnd( pInputStruct );
  686.     return bWasDragging;
  687. end
  688.  
  689. -- ===========================================================================
  690. --  Update the 3D displayed path for a unit.
  691. -- ===========================================================================
  692. function 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
  914. end
  915.  
  916. -- ===========================================================================
  917. -- ===========================================================================
  918. function 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;
  968. end
  969.  
  970.  
  971. -- ===========================================================================
  972. -- ===========================================================================
  973. function 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;
  1015. end
  1016.  
  1017.  
  1018. -- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
  1019. --
  1020. --                                      INPUT STATE
  1021. --
  1022. -- .,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,.,;/^`'^\:,
  1023.  
  1024.  
  1025. -- ===========================================================================
  1026. function OnDefaultKeyDown( pInputStruct:table )
  1027.     local uiKey         :number = pInputStruct:GetKey();
  1028.     return DefaultKeyDownHandler( uiKey ); 
  1029. end
  1030.  
  1031. -- ===========================================================================
  1032. function OnDefaultKeyUp( pInputStruct:table )
  1033.     local uiKey         :number = pInputStruct:GetKey();
  1034.     return DefaultKeyUpHandler( uiKey );   
  1035. end
  1036.  
  1037. -- ===========================================================================
  1038. --  Placing a building, wonder, or district; ESC to leave
  1039. -- ===========================================================================
  1040. function 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 );   
  1047. end
  1048.  
  1049.  
  1050. -- ===========================================================================
  1051. function TogglePause()
  1052.     local localPlayerID = Network.GetLocalPlayerID();
  1053.     local localPlayerConfig = PlayerConfigurations[localPlayerID];
  1054.     local newPause = not localPlayerConfig:GetWantsPause();
  1055.     localPlayerConfig:SetWantsPause(newPause);
  1056.     Network.BroadcastPlayerInfo();
  1057. end
  1058.  
  1059. -- ===========================================================================
  1060. function OnDefaultChangeToSelectionMode( pInputStruct )
  1061.     UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
  1062. end
  1063.  
  1064. -- ===========================================================================
  1065. function 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.  
  1084. end
  1085.  
  1086. -- ===========================================================================
  1087. function 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;
  1099. end
  1100.  
  1101. -- ===========================================================================
  1102. function OnInterfaceModeChange_Debug( eNewMode:number )
  1103.     UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
  1104. end
  1105.  
  1106.  
  1107. -- ===========================================================================
  1108. function OnInterfaceModeEnter_CityManagement( eNewMode:number )
  1109.     UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);   
  1110.     UILens.SetActive("CityManagement");
  1111. end
  1112.  
  1113. -- ===========================================================================
  1114. function OnInterfaceModeLeave_CityManagement( eNewMode:number )
  1115.     UIManager:SetUICursor(CursorTypes.NORMAL);
  1116.     UILens.SetActive("Default");
  1117. end
  1118.  
  1119.  
  1120. -- ===========================================================================
  1121. function 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;
  1136. end
  1137.  
  1138. -- ===========================================================================
  1139. function 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;
  1168. end
  1169.  
  1170. -- ===========================================================================
  1171. function OnMouseSelectionUnitMoveStart( pInputStruct:table )
  1172.     m_isMouseDownInWorld = true;
  1173.     return true;
  1174. end
  1175.  
  1176. -- ===========================================================================
  1177. function 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;
  1193. end
  1194.  
  1195. -- ===========================================================================
  1196. function OnMouseSelectionSnapToPlot( pInputStruct:table )
  1197.     local plotId :number= UI.GetCursorPlotID();
  1198.     SnapToPlot( plotId );
  1199. end
  1200.  
  1201. -- ===========================================================================
  1202. function 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;
  1221. end
  1222.  
  1223.  
  1224. -- ===========================================================================
  1225. --  Common way for mouse to function with a press start.
  1226. -- ===========================================================================
  1227. function OnMouseStart( pInputStruct:table )
  1228.     ReadyForDragMap();
  1229.     m_isMouseDownInWorld = true;
  1230.     return true;
  1231. end
  1232.  
  1233. -- ===========================================================================
  1234. function 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;
  1243. end
  1244.  
  1245. -- ===========================================================================
  1246. --  Zoom
  1247. -- ===========================================================================
  1248. function 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;
  1263. end
  1264.  
  1265. -- ===========================================================================
  1266. --  Either Mouse Double-Click or Touch Double-Tap
  1267. -- ===========================================================================
  1268. function 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;
  1283. end
  1284.  
  1285. -- ===========================================================================
  1286. function 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;
  1299. end
  1300.  
  1301. -- ===========================================================================
  1302. function OnMouseMakeTradeRouteSnapToPlot( pInputStruct:table )
  1303.     local plotId :number= UI.GetCursorPlotID();
  1304.     SnapToPlot( plotId );
  1305. end
  1306.  
  1307. -- ===========================================================================
  1308. function 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;
  1318. end
  1319.  
  1320. -- ===========================================================================
  1321. function OnMouseTeleportToCitySnapToPlot( pInputStruct:table )
  1322.     local plotId :number= UI.GetCursorPlotID();
  1323.     SnapToPlot( plotId );
  1324. end
  1325.  
  1326. -- ===========================================================================
  1327. function 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;
  1339. end
  1340.  
  1341. -- ===========================================================================
  1342. function OnMouseBuildingPlacementCancel( pInputStruct:table )
  1343.     if IsCancelAllowed() then
  1344.         ExitPlacementMode( true );
  1345.     end
  1346. end
  1347.  
  1348. -- ===========================================================================
  1349. function OnMouseBuildingPlacementMove( pInputStruct:table)
  1350.     OnMouseMove( pInputStruct );
  1351.     RealizeCurrentPlaceDistrictOrWonderPlot();
  1352. end
  1353.  
  1354. -- ===========================================================================
  1355. function 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;
  1367. end
  1368.  
  1369. -- ===========================================================================
  1370. function OnMouseDistrictPlacementCancel( pInputStruct:table )
  1371.     if IsCancelAllowed() then
  1372.         ExitPlacementMode( true );
  1373.     end
  1374. end
  1375.  
  1376. -- ===========================================================================
  1377. function OnMouseDistrictPlacementMove( pInputStruct:table)
  1378.     OnMouseMove( pInputStruct );
  1379.     RealizeCurrentPlaceDistrictOrWonderPlot();
  1380. end
  1381.  
  1382. -- ===========================================================================
  1383. function 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;
  1393. end
  1394.  
  1395. -- ===========================================================================
  1396. function 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;
  1425. end
  1426.  
  1427. -- ===========================================================================
  1428. function OnMouseMoveToStart( pInputStruct:table )  
  1429.     ReadyForDragMap();
  1430.     m_isMouseDownInWorld = true;
  1431.     return true;
  1432. end
  1433.  
  1434. -- ===========================================================================
  1435. function 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;
  1451. end
  1452.  
  1453. -- ===========================================================================
  1454. function 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;
  1472. end
  1473.  
  1474. -- ===========================================================================
  1475. function OnMouseMoveToCancel( pInputStruct:table )
  1476.     UnitMovementCancel();
  1477.     UI.SetInterfaceMode( InterfaceModeTypes.SELECTION );
  1478.     return true;
  1479. end
  1480.  
  1481.  
  1482. -- ===========================================================================
  1483. --  Start touch, until release or move, do not take action.
  1484. -- ===========================================================================
  1485. function 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;
  1508. end
  1509.  
  1510.  
  1511. -- ===========================================================================
  1512. function 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;
  1537. end
  1538.  
  1539. -- ===========================================================================
  1540. function 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;
  1585. end
  1586.  
  1587. -- ===========================================================================
  1588. --  Common start for touch
  1589. -- ===========================================================================
  1590. function 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;
  1602. end
  1603.  
  1604. -- ===========================================================================
  1605. --  Common update for touch
  1606. -- ===========================================================================
  1607. function 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;
  1626. end
  1627.  
  1628.  
  1629. -- ===========================================================================
  1630. function 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;
  1653. end
  1654.  
  1655. -- ===========================================================================
  1656. function 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;
  1676. end
  1677.  
  1678. -- ===========================================================================
  1679. function OnTouchDistrictPlacementEnd( pInputStruct:table )
  1680.     ConfirmPlaceDistrict(pInputStruct);
  1681. end
  1682.  
  1683. -- ===========================================================================
  1684. function OnTouchBuildingPlacementEnd( pInputStruct:table )
  1685.     ConfirmPlaceWonder(pInputStruct);
  1686. end
  1687.  
  1688. -- ===========================================================================
  1689. function OnTouchMoveToStart( pInputStruct:table )
  1690.     return true;
  1691. end
  1692.  
  1693. -- ===========================================================================
  1694. function 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;
  1706. end
  1707.  
  1708. -- ===========================================================================
  1709. function 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;
  1732. end
  1733.  
  1734. -- ===========================================================================
  1735. function OnTouchUnitRangeAttack( pInputStruct:table )
  1736.     local plotID:number = UI.GetCursorPlotID();
  1737.     if (Map.IsPlot(plotID)) then
  1738.         UnitRangeAttack( plotID );
  1739.     end
  1740.     return true;
  1741. end
  1742.  
  1743.  
  1744. -------------------------------------------------------------------------------
  1745. function 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
  1779. end
  1780.  
  1781. -------------------------------------------------------------------------------
  1782. function OnInterfaceModeLeave_UnitRangeAttack(eNewMode)
  1783.     UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
  1784. end
  1785.  
  1786. -- ===========================================================================
  1787. --  Code related to the Unit Air Attack interface mode
  1788. -- ===========================================================================
  1789. function 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;
  1806. end
  1807. -------------------------------------------------------------------------------
  1808. function 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
  1831. end
  1832.  
  1833. ---------------------------------------------------------------------------------
  1834. function OnInterfaceModeLeave_Air_Attack( eNewMode:number )
  1835.     UIManager:SetUICursor(CursorTypes.NORMAL);
  1836.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
  1837.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
  1838. end
  1839.  
  1840. -- ===========================================================================
  1841. --  Code related to the WMD Strike interface mode
  1842. -- ===========================================================================
  1843. function 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;
  1877. end
  1878. -------------------------------------------------------------------------------
  1879. function 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
  1888. end
  1889. -------------------------------------------------------------------------------
  1890. function 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
  1924. end
  1925.  
  1926. -------------------------------------------------------------------------------
  1927. function OnInterfaceModeLeave_WMD_Strike( eNewMode:number )
  1928.     UIManager:SetUICursor(CursorTypes.NORMAL);
  1929.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
  1930.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
  1931. end
  1932.  
  1933. -- ===========================================================================
  1934. --  Code related to the ICBM Strike interface mode
  1935. -- ===========================================================================
  1936. function 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
  1972. end
  1973. -------------------------------------------------------------------------------
  1974. function 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
  1985. end
  1986. -------------------------------------------------------------------------------
  1987. function 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
  2029. end
  2030.  
  2031. ---------------------------------------------------------------------------------
  2032. function OnInterfaceModeLeave_ICBM_Strike( eNewMode:number )
  2033.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2034.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
  2035.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
  2036. end
  2037.  
  2038. -- ===========================================================================
  2039. --  Code related to the Coastal Raid interface mode
  2040. -- ===========================================================================
  2041. function 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;
  2058. end
  2059. -------------------------------------------------------------------------------
  2060. function 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
  2080. end
  2081.  
  2082. ---------------------------------------------------------------------------------
  2083. function OnInterfaceModeLeave_CoastalRaid( eNewMode:number )
  2084.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2085.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_ATTACK );
  2086.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_ATTACK );
  2087. end
  2088.  
  2089. -- ===========================================================================
  2090. --  Code related to the Unit Air Deploy interface mode
  2091. -- ===========================================================================
  2092. function 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;
  2104. end
  2105. -------------------------------------------------------------------------------
  2106. function 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;
  2123. end
  2124. -------------------------------------------------------------------------------
  2125. function 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
  2148. end
  2149.  
  2150. ---------------------------------------------------------------------------------
  2151. function OnInterfaceModeLeave_Deploy( eNewMode:number )
  2152.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2153.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
  2154.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
  2155. end
  2156.  
  2157. -- ===========================================================================
  2158. --  Code related to the Unit Air Re-Base interface mode
  2159. -- ===========================================================================
  2160. function 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;
  2172. end
  2173. -------------------------------------------------------------------------------
  2174. function 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;
  2191. end
  2192. -------------------------------------------------------------------------------
  2193. function 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
  2214. end
  2215.  
  2216. ---------------------------------------------------------------------------------
  2217. function OnInterfaceModeLeave_ReBase( eNewMode:number )
  2218.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2219.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
  2220.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
  2221. end
  2222.  
  2223. -- ===========================================================================
  2224. --  Code related to the Place Map Pin interface mode
  2225. -- ===========================================================================
  2226. function 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;
  2234. end
  2235.  
  2236. ------------------------------------------------------------------------------------------------
  2237. -- Code related to the City and District Range Attack interface mode
  2238. ------------------------------------------------------------------------------------------------
  2239. function 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;
  2260. end
  2261.  
  2262. -------------------------------------------------------------------------------
  2263. function 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
  2300. end
  2301.  
  2302. -------------------------------------------------------------------------------
  2303. function OnInterfaceModeLeave_CityRangeAttack(eNewMode)
  2304.     UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
  2305. end
  2306.  
  2307. -------------------------------------------------------------------------------
  2308. function 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;
  2329. end
  2330. -------------------------------------------------------------------------------
  2331. function 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
  2368. end
  2369.  
  2370. -------------------------------------------------------------------------------
  2371. function OnInterfaceModeLeave_DistrictRangeAttack(eNewMode)
  2372.     UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
  2373. end
  2374.  
  2375. -------------------------------------------------------------------------------
  2376. function OnInterfaceModeLeave_WMDRangeAttack(eNewMode)
  2377.     UILens.ClearLayerHexes( LensLayers.ATTACK_RANGE );
  2378. end
  2379.  
  2380. ------------------------------------------------------------------------------------------------
  2381. -- Code related to the Unit's Make Trade Route interface mode
  2382. -- Some input is handled separately, by TradePanel.lua
  2383. ------------------------------------------------------------------------------------------------
  2384. function OnInterfaceModeChange_MakeTradeRoute(eNewMode)
  2385.     UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
  2386. end
  2387.  
  2388. ------------------------------------------------------------------------------------------------
  2389. -- Code related to the Unit's 'Teleport to City' mode
  2390. ------------------------------------------------------------------------------------------------
  2391. function 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;
  2410. end
  2411. -------------------------------------------------------------------------------
  2412. function 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
  2434. end
  2435.  
  2436. ---------------------------------------------------------------------------------
  2437. function OnInterfaceModeLeave_TeleportToCity( eNewMode:number )
  2438.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2439.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
  2440.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
  2441. end
  2442.  
  2443. -- =============================================================================================
  2444. function OnInterfaceModeChange_MoveTo( eNewMode:number )
  2445.     m_cachedPathUnit    = nil;
  2446.     m_cachedPathPlotId  = -1 ;
  2447.     RealizeMovementPath();
  2448. end
  2449.  
  2450. -- =============================================================================================
  2451. function OnInterfaceModeChange_MoveToLeave( eOldMode:number )
  2452.     ClearMovementPath();
  2453.     UILens.SetActive("Default");
  2454. end
  2455.  
  2456. -- =============================================================================================
  2457. function OnInterfaceModeChange_PlaceMapPin( eNewMode:number )
  2458.     UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
  2459. end
  2460.  
  2461. ------------------------------------------------------------------------------------------------
  2462. -- Code related to the World Builder's Select Plot Mode
  2463. ------------------------------------------------------------------------------------------------
  2464.  
  2465. -- =============================================================================================
  2466. function OnInterfaceModeChange_WBSelectPlot()
  2467.     m_WBMouseOverPlot = -1;
  2468. end
  2469.  
  2470. -- =============================================================================================
  2471. function OnInterfaceModeChange_SpyChooseMission()
  2472.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2473.     UILens.SetActive("Default");
  2474. end
  2475.  
  2476. -- =============================================================================================
  2477. function OnInterfaceModeChange_SpyTravelToCity()
  2478.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2479.     UILens.SetActive("Default");
  2480.  
  2481. end
  2482.  
  2483. function OnInterfaceModeChange_NaturalWonder()
  2484.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2485.     UI.SetFixedTiltMode( true );
  2486. end
  2487.  
  2488. -- ===========================================================================
  2489. function OnInterfaceModeLeave_NaturalWonder( eNewMode:number )
  2490.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2491.     UI.SetFixedTiltMode( false );
  2492.     OnCycleUnitSelectionRequest();
  2493. end
  2494.  
  2495. -- ===========================================================================
  2496. function 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;
  2511. end
  2512.  
  2513. -- ===========================================================================
  2514. function OnRButtonUp_WBSelectPlot( pInputStruct )
  2515.     if (Map.IsPlot(UI.GetCursorPlotID())) then
  2516.         LuaEvents.WorldInput_WBSelectPlot(UI.GetCursorPlotID(), UI.GetCursorNearestPlotEdge(), false);
  2517.     end
  2518.     return true;
  2519. end
  2520.  
  2521. -- ===========================================================================
  2522. function 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();
  2536. end
  2537.  
  2538. ------------------------------------------------------------------------------------------------
  2539. -- Code related to the Unit's 'Form Corps' mode
  2540. ------------------------------------------------------------------------------------------------
  2541. function 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;
  2559. end
  2560.  
  2561. ------------------------------------------------------------------------------------------------
  2562. function 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
  2579. end
  2580.  
  2581. --------------------------------------------------------------------------------------------------
  2582. function OnInterfaceModeLeave_UnitFormCorps( eNewMode:number )
  2583.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2584.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_PLACEMENT );
  2585.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_PLACEMENT );
  2586. end
  2587.  
  2588. ------------------------------------------------------------------------------------------------
  2589. -- Code related to the Unit's 'Form Army' mode
  2590. ------------------------------------------------------------------------------------------------
  2591. function 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;
  2610. end
  2611.  
  2612. ------------------------------------------------------------------------------------------------
  2613. function 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
  2630. end
  2631.  
  2632. --------------------------------------------------------------------------------------------------
  2633. function OnInterfaceModeLeave_UnitFormArmy( eNewMode:number )
  2634.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2635.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_PLACEMENT );
  2636.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_PLACEMENT );
  2637. end
  2638.  
  2639. ------------------------------------------------------------------------------------------------
  2640. -- Code related to the Unit's 'Airlift' mode
  2641. ------------------------------------------------------------------------------------------------
  2642. function 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;
  2654. end
  2655. ------------------------------------------------------------------------------------------------
  2656. function 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;
  2673. end
  2674. ------------------------------------------------------------------------------------------------
  2675. function 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
  2693. end
  2694. --------------------------------------------------------------------------------------------------
  2695. function OnInterfaceModeLeave_UnitAirlift( eNewMode:number )
  2696.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2697.     UILens.ToggleLayerOff( LensLayers.HEX_COLORING_MOVEMENT );
  2698.     UILens.ClearLayerHexes( LensLayers.HEX_COLORING_MOVEMENT );
  2699. end
  2700.  
  2701.  
  2702. -- ===========================================================================
  2703. function OnInterfaceModeChange_Selection(eNewMode)
  2704.     UIManager:SetUICursor(CursorTypes.NORMAL);
  2705.     UILens.SetActive("Default");
  2706. end
  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. -- ===========================================================================
  2723. function 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
  2737. end
  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. -- ===========================================================================
  2745. function 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
  2769. end
  2770.  
  2771. -- ===========================================================================
  2772. --  ENGINE Event
  2773. -- ===========================================================================
  2774. function 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;
  2781. end
  2782.  
  2783. function 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
  2797. end
  2798.  
  2799. -- ===========================================================================
  2800. --  ENGINE Event
  2801. -- ===========================================================================
  2802. function 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
  2829. end
  2830.  
  2831. -- ===========================================================================
  2832. --  LUA Event
  2833. -- ===========================================================================
  2834. function OnTutorial_ConstrainMovement( plotID:number )
  2835.     m_constrainToPlotID = plotID;
  2836. end
  2837.  
  2838. -- ===========================================================================
  2839. --  LUA Event
  2840. --  Effectively turns on/off ability to drag pan the map.
  2841. -- ===========================================================================
  2842. function OnTutorial_DisableMapDrag( isDisabled:boolean )
  2843.     m_isMapDragDisabled = isDisabled;
  2844. end
  2845.  
  2846. -- ===========================================================================
  2847. --  LUA Event
  2848. --  Turns off canceling an event via a cancel action
  2849. --  (e.g., right click for district placement)
  2850. -- ===========================================================================
  2851. function OnTutorial_DisableMapCancel( isDisabled:boolean )
  2852.     m_isCancelDisabled = isDisabled;
  2853. end
  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. -- ===========================================================================
  2861. function 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
  2868. end
  2869.  
  2870. -- ===========================================================================
  2871. --  TEST
  2872. -- ===========================================================================
  2873. function 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;
  2891. end
  2892.  
  2893.  
  2894. -- ===========================================================================
  2895. --  Related to edge-panning.
  2896. -- ===========================================================================
  2897. function OnMouseBeginPanLeft() 
  2898.     if IsAbleToEdgePan() then
  2899.         m_edgePanX = -PAN_SPEED;
  2900.         ProcessPan(m_edgePanX,m_edgePanY);
  2901.     end
  2902. end
  2903. function OnMouseStopPanLeft()  
  2904.     if not ( m_edgePanX == 0.0 ) then
  2905.         m_edgePanX = 0.0;
  2906.         ProcessPan(m_edgePanX,m_edgePanY);
  2907.     end
  2908. end
  2909. function OnMouseBeginPanRight()
  2910.     if IsAbleToEdgePan() then
  2911.         m_edgePanX = PAN_SPEED;
  2912.         ProcessPan(m_edgePanX,m_edgePanY);
  2913.     end
  2914. end
  2915. function OnMouseStopPanRight()  
  2916.     if not ( m_edgePanX == 0.0 ) then
  2917.         m_edgePanX = 0;
  2918.         ProcessPan(m_edgePanX,m_edgePanY);
  2919.     end
  2920. end
  2921. function OnMouseBeginPanUp()   
  2922.     if IsAbleToEdgePan() then
  2923.         m_edgePanY = PAN_SPEED;
  2924.         ProcessPan(m_edgePanX,m_edgePanY);
  2925.     end
  2926. end
  2927. function OnMouseStopPanUp()    
  2928.     if not ( m_edgePanY == 0.0 ) then
  2929.         m_edgePanY = 0;
  2930.         ProcessPan(m_edgePanX,m_edgePanY);
  2931.     end
  2932. end
  2933. function OnMouseBeginPanDown() 
  2934.     if IsAbleToEdgePan() then
  2935.         m_edgePanY = -PAN_SPEED;
  2936.         ProcessPan(m_edgePanX,m_edgePanY);
  2937.     end
  2938. end
  2939. function OnMouseStopPanDown()  
  2940.     if not ( m_edgePanY == 0.0 ) then
  2941.         m_edgePanY = 0;
  2942.         ProcessPan(m_edgePanX,m_edgePanY);
  2943.     end
  2944. end
  2945.  
  2946.  
  2947. -- ===========================================================================
  2948. --  UI Event
  2949. --  Input Event Processing
  2950. -- ===========================================================================
  2951. function 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;
  3057. end
  3058.  
  3059.  
  3060. -- ===========================================================================
  3061. --  UI Event
  3062. --  Per-frame (e.g., expensive) event.
  3063. -- ===========================================================================
  3064. function 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
  3071. end
  3072.  
  3073.  
  3074. -- ===========================================================================
  3075. -- 
  3076. -- ===========================================================================
  3077. function 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;
  3108. end
  3109.  
  3110.  
  3111. -- ===========================================================================
  3112. --  UI Event
  3113. --  Called whenever the application regains focus.
  3114. -- ===========================================================================
  3115. function OnAppRegainedFocusHandler()
  3116.     ClearAllCachedInputState();
  3117.     ProcessPan(m_edgePanX,m_edgePanY);
  3118. end
  3119.  
  3120.  
  3121. -- ===========================================================================
  3122. --  UI Event
  3123. --  Called whenever the application loses focus.
  3124. -- ===========================================================================
  3125. function OnAppLostFocusHandler()
  3126.     ClearAllCachedInputState();
  3127.     ProcessPan(0,0);
  3128. end
  3129.  
  3130.  
  3131. -- ===========================================================================
  3132. --  UI Event
  3133. -- ===========================================================================
  3134. function 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 );
  3142. end
  3143.  
  3144. -- ===========================================================================
  3145. --  Hotkey Event
  3146. -- ===========================================================================
  3147. function 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
  3159. end
  3160.  
  3161. -- ===========================================================================
  3162. --  INCLUDES
  3163. --  Other handlers & helpers that may utilze functionality defined in here
  3164. -- ===========================================================================
  3165.  
  3166. include ("StrategicView_MapPlacement"); -- handlers for: BUILDING_PLACEMENT, DISTRICT_PLACEMENT
  3167. include ("StrategicView_DebugSupport"); -- the Debug interface mode
  3168.  
  3169.  
  3170. -- ===========================================================================
  3171. --  Assign callbacks
  3172. -- ===========================================================================
  3173. function 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" );
  3370. end
  3371. Initialize();
Add Comment
Please, Sign In to add comment