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