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