Skip to main content
Skip to main content

IngameMapElement

IngameMapElement

Description

In-game map element. Controls input on the map in the in-game menu with objectives, vehicles, etc. The actual map rendering is deferred to the map component of the current mission. The map reference and terrain size must be set during mission initialization via the setIngameMap() and setTerrainSize() methods.

Parent

GuiElement

Functions

addCursorDeadzone

Description

Add a dead zone wherein the map will not react to cursor inputs. Used this to designate areas where other controls should receive cursor input which would otherwise be used up by the map (e.g. in full-screen mode in the map overview screen in-game). The deadzones will also restrict cursor movement.

Definition

addCursorDeadzone()

Arguments

anyscreenX
anyscreenY
anywidth
anyheight

Code

function IngameMapElement:addCursorDeadzone(screenX, screenY, width, height)
table.insert( self.cursorDeadzones, { screenX, screenY, width, height } )
end

checkAndResetMouse

Description

Check if mouse input was active before a bound input was triggered and queue a reset of the mouse state for the next frame. Mouse input continuously sets the mouse input flag (self.useMouse) but does not receive any events when the mouse is inert. Therefore we need to set and reset the state each frame to make sure we can seamlessly switch between mouse and gamepad input on the map element while at the same time preventing any player bindings from interfering with the custom mouse input logic of this class.

Definition

checkAndResetMouse()

Code

function IngameMapElement:checkAndResetMouse()
local useMouse = self.useMouse
if useMouse then
self.resetMouseNextFrame = true
end

return useMouse
end

clearCursorDeadzones

Description

Clear cursor dead zones.

Definition

clearCursorDeadzones()

Code

function IngameMapElement:clearCursorDeadzones()
self.cursorDeadzones = { }
end

copyAttributes

Description

Definition

copyAttributes()

Arguments

anysrc

Code

function IngameMapElement:copyAttributes(src)
IngameMapElement:superClass().copyAttributes( self , src)

self.mapZoom = src.mapZoom
self.mapAlpha = src.mapAlpha
self.cursorId = src.cursorId
self.limitMapWidth = src.limitMapWidth
self.limitCursorMovement = src.limitCursorMovement
self.onDrawPreIngameMapCallback = src.onDrawPreIngameMapCallback
self.onDrawPostIngameMapCallback = src.onDrawPostIngameMapCallback
self.onDrawPostIngameMapHotspotsCallback = src.onDrawPostIngameMapHotspotsCallback
self.onClickHotspotCallback = src.onClickHotspotCallback
self.onClickMapCallback = src.onClickMapCallback
end

delete

Description

Definition

delete()

Code

function IngameMapElement:delete()
GuiOverlay.deleteOverlay( self.overlay)
self.ingameMap = nil

IngameMapElement:superClass().delete( self )
end

draw

Description

Definition

draw()

Arguments

anyclipX1
anyclipY1
anyclipX2
anyclipY2

Code

function IngameMapElement:draw(clipX1, clipY1, clipX2, clipY2)
self:raiseCallback( "onDrawPreIngameMapCallback" , self , self.ingameMap)
self.ingameMap:drawMapOnly()
self:raiseCallback( "onDrawPostIngameMapCallback" , self , self.ingameMap)

self.ingameMap:drawHotspotsOnly()

self:raiseCallback( "onDrawPostIngameMapHotspotsCallback" , self , self.ingameMap)
IngameMapElement:superClass().draw( self , clipX1, clipY1, clipX2, clipY2)
end

getLocalPointerTarget

Description

Definition

getLocalPointerTarget()

Code

function IngameMapElement:getLocalPointerTarget()
if self.useMouse then
return self:getLocalPosition( self.lastInputPosX[ self.lastInputIndex], self.lastInputPosY[ self.lastInputIndex])
elseif self.cursorElement then
local posX = self.cursorElement.absPosition[ 1 ] + self.cursorElement.size[ 1 ] * 0.5
local posY = self.cursorElement.absPosition[ 2 ] + self.cursorElement.size[ 2 ] * 0.5

return self:getLocalPosition(posX, posY)
end

return 0 , 0
end

getLocalPosition

Description

Definition

getLocalPosition()

Arguments

anyposX
anyposY

Code

function IngameMapElement:getLocalPosition(posX, posY)
local width, height = self.ingameMap.fullScreenLayout:getMapSize()
local offX, offY = self.ingameMap.fullScreenLayout:getMapPosition()

-- offset with map poisition, then conver to 0-1 and adjust for minimap being doubled in size
-- from actual map.
local x, y

if Platform.isMobile then
x = (posX - offX) / width
y = (posY - offY) / height
else
x = ((posX - offX) / width - 0.25 ) * 2
y = ((posY - offY) / height - 0.25 ) * 2
end

return x, y
end

isInputInDeadzones

Description

Check if a cursor position is within one of the stored deadzones.

Definition

isInputInDeadzones()

Arguments

anyinputScreenX
anyinputScreenY

Code

function IngameMapElement:isInputInDeadzones(inputScreenX, inputScreenY)
for _, zone in pairs( self.cursorDeadzones) do
if GuiUtils.checkOverlayOverlap(inputScreenX, inputScreenY, zone[ 1 ], zone[ 2 ], zone[ 3 ], zone[ 4 ]) then
return true
end
end

return false
end

isPointVisible

Description

Definition

isPointVisible()

Arguments

anyx
anyz

Code

function IngameMapElement:isPointVisible(x, z)
end

loadFromXML

Description

Definition

loadFromXML()

Arguments

anyxmlFile
anykey

Code

function IngameMapElement:loadFromXML(xmlFile, key)
IngameMapElement:superClass().loadFromXML( self , xmlFile, key)

self.cursorId = getXMLString(xmlFile, key .. "#cursorId" )
self.mapAlpha = getXMLFloat(xmlFile, key .. "#mapAlpha" ) or self.mapAlpha
self.limitMapWidth = Utils.getNoNil(getXMLBool(xmlFile, key .. "#limitMapWidth" ), self.limitMapWidth)
self.limitCursorMovement = Utils.getNoNil(getXMLBool(xmlFile, key .. "#limitCursorMovement" ), self.limitCursorMovement)

self:addCallback(xmlFile, key .. "#onDrawPreIngameMap" , "onDrawPreIngameMapCallback" )
self:addCallback(xmlFile, key .. "#onDrawPostIngameMap" , "onDrawPostIngameMapCallback" )
self:addCallback(xmlFile, key .. "#onDrawPostIngameMapHotspots" , "onDrawPostIngameMapHotspotsCallback" )
self:addCallback(xmlFile, key .. "#onClickHotspot" , "onClickHotspotCallback" )
self:addCallback(xmlFile, key .. "#onClickMap" , "onClickMapCallback" )
end

loadProfile

Description

Definition

loadProfile()

Arguments

anyprofile
anyapplyProfile

Code

function IngameMapElement:loadProfile(profile, applyProfile)
IngameMapElement:superClass().loadProfile( self , profile, applyProfile)

self.mapAlpha = profile:getNumber( "mapAlpha" , self.mapAlpha)
self.limitMapWidth = profile:getBool( "limitMapWidth" , self.limitMapWidth)
self.limitCursorMovement = profile:getBool( "limitCursorMovement" , self.limitCursorMovement)
end

localToWorldPos

Description

Definition

localToWorldPos()

Arguments

anylocalPosX
anylocalPosY

Code

function IngameMapElement:localToWorldPos(localPosX, localPosY)
local worldPosX = localPosX * self.terrainSize
local worldPosZ = - localPosY * self.terrainSize

-- move world positions to range -1024 to 1024 on a 2k map
worldPosX = worldPosX - self.terrainSize * 0.5
worldPosZ = worldPosZ + self.terrainSize * 0.5

return worldPosX, worldPosZ
end

mouseEvent

Description

Custom mouse event handling for the in-game map. Directly handles zoom, click and drag events on the map. See input events and IngameMapElement:checkAndResetMouse() for the state checking code required to bypass player mouse input bindings.

Definition

mouseEvent()

Arguments

anyposX
anyposY
anyisDown
anyisUp
anybutton
anyeventUsed

Code

function IngameMapElement:mouseEvent(posX, posY, isDown, isUp, button, eventUsed)
if self:getIsActive() then
eventUsed = IngameMapElement:superClass().mouseEvent( self , posX, posY, isDown, isUp, button, eventUsed)
self.lastInputIndex = 0
local index = 0

if not GS_IS_CONSOLE_VERSION and(isDown or isUp or posX ~ = self.lastInputPosX[index] or posY ~ = self.lastInputPosY[index]) then
self.useMouse = true

if self.cursorElement then
self.cursorElement:setVisible( false )
end
self.isCursorActive = false
end

-- On mobile we have touch input.Touch does not give us a position until there is a touch.
-- This means on the first touch-begin, the lastMousePos is wrong and has a big offset.
-- We set it when the touch begins so it becomes a drag action
if Platform.isMobile and self.useMouse then
if isDown then
self.lastInputPosX[index] = posX
self.lastInputPosY[index] = posY
end
end

if not eventUsed then
if isDown and button = = Input.MOUSE_BUTTON_LEFT and not self:isInputInDeadzones(posX, posY) then
eventUsed = true
if not self.inputDown then
self.inputDown = true
end
end
end

if self.inputDown and self.lastInputPosX[index] ~ = nil then
local distX = self.lastInputPosX[index] - posX
local distY = posY - self.lastInputPosY[index]

if self.isFixedHorizontal then
distX = 0
end

if math.abs(distX) > self.minDragDistanceX or math.abs(distY) > self.minDragDistanceY then
local factorX = - distX
local factorY = distY

self:moveCenter(factorX, factorY)

self.hasDragged = true
end
end

if isUp and button = = Input.MOUSE_BUTTON_LEFT then
if not eventUsed and self.inputDown and not self.hasDragged then
local localX, localY = self:getLocalPosition(posX, posY)

-- save state locally to avoid issues if activating/deactivating selection in the onClickMap callback
local isHotspotSelectionActive = self.isHotspotSelectionActive

self:onClickMap(localX, localY)

if isHotspotSelectionActive then
-- Trigger hot spot selection after map clicking because it's the more specific event
self:selectHotspotAt(posX, posY)
end

eventUsed = true
end

self.inputDown = false
self.hasDragged = false
end

self.lastInputPosX[index] = posX
self.lastInputPosY[index] = posY
end

return eventUsed
end

moveCenter

Description

Move center of the map

Definition

moveCenter()

Arguments

anyx
anyy

Code

function IngameMapElement:moveCenter(x, y)
local width, height = self.ingameMap.fullScreenLayout:getMapSize()

if Platform.isMobile then
local maxCenterOffsetX = (width - self.ingameMap.fullScreenLayout.width) * 0.5
local maxCenterOffsetY = (height - 1 ) * 0.5

self.mapCenterX = math.clamp( self.mapCenterX + x, self.originalMapCenterX - maxCenterOffsetX, self.originalMapCenterX + maxCenterOffsetX)
self.mapCenterY = math.clamp( self.mapCenterY + y, self.originalMapCenterY - maxCenterOffsetY, self.originalMapCenterY + maxCenterOffsetY)
else
self.mapCenterX = math.clamp( self.mapCenterX + x, width * - 0.5 + self.originalMapCenterX, width * 0.5 + self.originalMapCenterX)

if self.limitCursorMovement then
local minValue = ( self.absPosition[ 2 ] + self.absSize[ 2 ]) - height * 0.5
local maxValue = self.absPosition[ 2 ] + height * 0.5
self.mapCenterY = math.clamp( self.mapCenterY + y, minValue, maxValue)
else
self.mapCenterY = math.clamp( self.mapCenterY + y, height * - 0.5 + self.originalMapCenterY, height * 0.5 + self.originalMapCenterY)
end
end

self.ingameMap.fullScreenLayout:setMapCenter( self.mapCenterX, self.mapCenterY)
end

new

Description

Definition

new()

Arguments

anytarget
anycustom_mt

Code

function IngameMapElement.new(target, custom_mt)
local self = GuiElement.new(target, custom_mt or IngameMapElement _mt)

self.ingameMap = nil

-- cursor
self.cursorId = nil

self.inputMode = GS_INPUT_HELP_MODE_GAMEPAD

-- map attributes
self.terrainSize = 0
self.mapAlpha = 1
self.zoomMin = 1
self.zoomMax = 8
self.zoomDefault = Platform.ingameMap.zoomDefault

self.mapCenterX = 0.5
self.mapCenterY = 0.5

self.mapZoom = self.zoomDefault

-- horizontal cursor input since last frame
self.accumHorizontalInput = 0
-- vertical cursor input since last frame
self.accumVerticalInput = 0
-- zoom input since last frame
self.accumZoomInput = 0
-- mouse input flag to override potential double binding on cursor movement
self.useMouse = false
-- reset flag for mouse input flag to avoid catching input in the current frame
self.resetMouseNextFrame = false
-- screen space rectangle definitions {x, y, w, h} where the cursor/mouse should not go and react to input
self.cursorDeadzones = { }

self.limitMapWidth = false
self.limitCursorMovement = false
self.mapMovementLocked = false

self.zoomSpeedFactor = Platform.ingameMap.zoomSpeedFactor
---Minimum mouse movement distance in pixels before dragging is started.Used to distinguish between drags and clicks.
self.dragStartDistance = Platform.ingameMap.dragStartDistance

self.minDragDistanceX = self.dragStartDistance * g_pixelSizeX
self.minDragDistanceY = self.dragStartDistance * g_pixelSizeY
self.hasDragged = false -- drag state flag to avoid triggering a click event on a dragging mouse up

self.minimalHotspotSize = getNormalizedScreenValues( 9 , 1 )

self.isHotspotSelectionActive = true
self.isCursorAvailable = true

self.cursorOffsetX = 0
self.cursorOffsetY = 0

self.originalMapCenterX = 0.5
self.originalMapCenterY = 0.5

self.isPinching = false

self.isTouchPickingRotation = false

self.lastInputPosX = { }
self.lastInputPosY = { }
self.lastInputIndex = 0

return self
end

onAccept

Description

Event function for gamepad cursor accept input bound to InputAction.INGAMEMAP_ACCEPT.

Definition

onAccept()

Code

function IngameMapElement:onAccept()
if self.cursorElement then
local cursorElement = self.cursorElement
local posX, posY = cursorElement.absPosition[ 1 ] + cursorElement.size[ 1 ] * 0.5 , cursorElement.absPosition[ 2 ] + cursorElement.size[ 2 ] * 0.5
local localX, localY = self:getLocalPointerTarget()

-- save state locally to avoid issues if activating/deactivating selection in the onClickMap callback
local isHotspotSelectionActive = self.isHotspotSelectionActive

self:onClickMap(localX, localY)

if isHotspotSelectionActive then
-- trigger hot spot selection after map clicking because it's the more specific event
self:selectHotspotAt(posX, posY)
end
end
end

onClickMap

Description

Definition

onClickMap()

Arguments

anylocalPosX
anylocalPosY

Code

function IngameMapElement:onClickMap(localPosX, localPosY)
local worldPosX, worldPosZ = self:localToWorldPos(localPosX, localPosY)

self:raiseCallback( "onClickMapCallback" , self , worldPosX, worldPosZ)
end

onClose

Description

Definition

onClose()

Code

function IngameMapElement:onClose()
IngameMapElement:superClass().onClose( self )

self:removeActionEvents()

self.ingameMap:setFullscreen( false )
end

onGuiSetupFinished

Description

Definition

onGuiSetupFinished()

Code

function IngameMapElement:onGuiSetupFinished()
IngameMapElement:superClass().onGuiSetupFinished( self )

if self.cursorId ~ = nil then
if self.target[ self.cursorId] ~ = nil then
self.cursorElement = self.target[ self.cursorId]
else
printWarning( "Warning:CursorId '" .. self.cursorId .. "' not found for '" .. self.target.name .. "'!" )
end
end
end

onHorizontalCursorInput

Description

Event function for horizontal cursor input bound to InputAction.AXIS_LOOK_LEFTRIGHT_VEHICLE.

Definition

onHorizontalCursorInput()

Arguments

any_
anyinputValue

Code

function IngameMapElement:onHorizontalCursorInput(_, inputValue)
if not self:checkAndResetMouse() and not self.isFixedHorizontal then
self.accumHorizontalInput = self.accumHorizontalInput + inputValue

if math.abs(inputValue) > 0.05 then
g_inGameMenu.pageMapOverview.lastInputTime = g_ time
end
end
end

onOpen

Description

Definition

onOpen()

Code

function IngameMapElement:onOpen()
IngameMapElement:superClass().onOpen( self )

if self.cursorElement ~ = nil then
self.cursorElement:setVisible( false )
end
self.isCursorActive = false

if self.largestSize = = nil then
self.largestSize = self.size
end

self.ingameMap:setFullscreen( true )

if Platform.ingameMap.resetZoomOnOpen then
self:zoom( 0 )
end
end

onPinchEvent

Description

Event function for map zoom input triggered by pinching via touch input.

Definition

onPinchEvent(float offset, pinchCenterX x, pinchCenterY y, float distance)

Arguments

floatoffsetoffset between new distance and distance of last pinch event
pinchCenterXxposition of the center point of the pinch
pinchCenterYyposition of the center point of the pinch
floatdistancedistance between both touch positions

Code

function IngameMapElement:onPinchEvent(offset, pinchCenterX, pinchCenterY, distance)
self.oldCursorX = self.cursorElement.absPosition[ 1 ]
self.oldCursorY = self.cursorElement.absPosition[ 2 ]
self.cursorElement.absPosition[ 1 ] = pinchCenterX
self.cursorElement.absPosition[ 2 ] = pinchCenterY

self.accumZoomInput = self.accumZoomInput + offset * 100

self.isPinching = true
end

onVerticalCursorInput

Description

Event function for vertical cursor input bound to InputAction.AXIS_LOOK_UPDOWN_VEHICLE.

Definition

onVerticalCursorInput()

Arguments

any_
anyinputValue

Code

function IngameMapElement:onVerticalCursorInput(_, inputValue)
if not self:checkAndResetMouse() then
self.accumVerticalInput = self.accumVerticalInput + inputValue

if math.abs(inputValue) > 0.05 then
g_inGameMenu.pageMapOverview.lastInputTime = g_ time
end
end
end

onZoomInput

Description

Event function for map zoom input bound to InputAction.AXIS_ACCELERATE_VEHICLE and InputAction.AXIS_BRAKE_VEHICLE.

Definition

onZoomInput(inputValue Zoom, direction Zoom, )

Arguments

inputValueZoominput value
directionZoominput sign value, 1 for zoom in, -1 for zoom out
anydirection

Code

function IngameMapElement:onZoomInput(_, inputValue, direction)
if not self:isInputInDeadzones(g_lastMousePosX, g_lastMousePosY) or not self.useMouse then
self.accumZoomInput = self.accumZoomInput - direction * inputValue
end
end

panToHotspot

Description

Pan to a hotpspot, if possible the hotspot will end up at the center of the screen, or if it is near the map border it will be centered as much as possible

Definition

panToHotspot(hotspot the, )

Arguments

hotspotthehotspot that gets centered
anyextraOffsetX

Code

function IngameMapElement:panToHotspot(hotspot, extraOffsetX)
if hotspot ~ = nil then
if Platform.isMobile then
local hotspotX, hotspotY = self:worldToScreenPos(hotspot:getWorldPosition())
local cursorOffsetX = - hotspotX + self.mapCenterX + self.originalMapCenterX
local cursorOffsetY = - hotspotY + self.mapCenterY + self.originalMapCenterY

self.cursorOffsetX = cursorOffsetX - self.mapCenterX
self.cursorOffsetY = cursorOffsetY - self.mapCenterY
else
local ingameMap = self.ingameMap
local hotspotX, hotspotY = hotspot:getWorldPosition()
local objectX = (hotspotX + ingameMap.worldCenterOffsetX) / ingameMap.worldSizeX * ingameMap.mapExtensionScaleFactor + ingameMap.mapExtensionOffsetX
local objectZ = (hotspotY + ingameMap.worldCenterOffsetZ) / ingameMap.worldSizeZ * ingameMap.mapExtensionScaleFactor + ingameMap.mapExtensionOffsetZ
hotspotX, hotspotY = ingameMap.layout:getMapObjectPosition(objectX, objectZ, 0 , 0 )

local offsetX = self.originalMapCenterX - hotspotX
local offsetY = self.originalMapCenterY - hotspotY
self:moveCenter(offsetX, offsetY)
end
end
end

registerActionEvents

Description

Register non-GUI input action events.

Definition

registerActionEvents()

Code

function IngameMapElement:registerActionEvents()
g_inputBinding:registerActionEvent(InputAction.AXIS_MAP_SCROLL_LEFT_RIGHT, self , self.onHorizontalCursorInput, false , false , true , true )
g_inputBinding:registerActionEvent(InputAction.AXIS_MAP_SCROLL_UP_DOWN, self , self.onVerticalCursorInput, false , false , true , true )
g_inputBinding:registerActionEvent(InputAction.INGAMEMAP_ACCEPT, self , self.onAccept, false , true , false , true )
g_inputBinding:registerActionEvent(InputAction.AXIS_MAP_ZOOM_OUT, self , self.onZoomInput, false , false , true , true , - 1 ) -- -1 = = zoom out
g_inputBinding:registerActionEvent(InputAction.AXIS_MAP_ZOOM_IN, self , self.onZoomInput, false , false , true , true , 1 ) -- 1 = = zoom in

if g_touchHandler ~ = nil then
self.touchListenerPinch = g_touchHandler:registerGestureListener(TouchHandler.GESTURE_PINCH, self.onPinchEvent, self )
end
end

removeActionEvents

Description

Remove non-GUI input action events.

Definition

removeActionEvents()

Code

function IngameMapElement:removeActionEvents()
g_inputBinding:removeActionEventsByTarget( self )

if g_touchHandler ~ = nil then
g_touchHandler:removeGestureListener( self.touchListenerPinch)
end
end

reset

Description

Definition

reset()

Code

function IngameMapElement:reset()
IngameMapElement:superClass().reset( self )

self.mapCenterX = 0.5
self.mapCenterY = 0.5
self.mapZoom = self.zoomDefault

-- self.ingameMap:resetSettings()
end

resetFrameInputState

Description

Definition

resetFrameInputState()

Code

function IngameMapElement:resetFrameInputState()
self.accumZoomInput = 0
self.accumHorizontalInput = 0
self.accumVerticalInput = 0
if self.resetMouseNextFrame then
self.useMouse = false
self.resetMouseNextFrame = false
end

if Platform.isMobile and self.isPinching then
self.cursorElement.absPosition[ 1 ] = self.originalMapCenterX + self.cursorOffsetX
self.cursorElement.absPosition[ 2 ] = self.originalMapCenterY + self.cursorOffsetY

self.isPinching = false
end
end

selectHotspotAt

Description

Definition

selectHotspotAt()

Arguments

anyposX
anyposY

Code

function IngameMapElement:selectHotspotAt(posX, posY)
if self.isHotspotSelectionActive then
self.ingameMap:updateHotspotSorting()
local sortedHotspots = self.ingameMap.hotspotsSorted

if sortedHotspots ~ = nil then
local playerHotspot = self:getPlayerHotspot(sortedHotspots[ true ])
local prioritizePlayerHotspot = not Platform.isMobile or playerHotspot:getVehicle() ~ = nil

if not self:selectHotspotFrom(sortedHotspots[prioritizePlayerHotspot], posX, posY) then
if prioritizePlayerHotspot then
self:selectHotspotFrom(sortedHotspots[ false ], posX, posY)
end
end

return
end

self:selectHotspotFrom( self.ingameMap.hotspots, posX, posY)
end
end

selectHotspotFrom

Description

Definition

selectHotspotFrom()

Arguments

anyhotspots
anyposX
anyposY

Code

function IngameMapElement:selectHotspotFrom(hotspots, posX, posY)
local minDistance = math.huge
local minHotspot
for i = #hotspots, 1 , - 1 do
local hotspot = hotspots[i]

if self.ingameMap.filter[hotspot:getCategory()] and hotspot:getIsVisible() then
local isInRange, distance = hotspot:hasMouseOverlap(posX, posY)
if isInRange then
if minHotspot ~ = nil then
if hotspot:getSortingValue() < minHotspot:getSortingValue() then
if distance < minDistance then
minDistance = distance
minHotspot = hotspot
end
else
minDistance = distance
minHotspot = hotspot
end
else
minDistance = distance
minHotspot = hotspot
end
end
end
end

if minHotspot ~ = nil then
self:raiseCallback( "onClickHotspotCallback" , self , minHotspot)
return true
end

return false
end

setIngameMap

Description

Set the IngameMap reference to use for display.

Definition

setIngameMap()

Arguments

anyingameMap

Code

function IngameMapElement:setIngameMap(ingameMap)
self.ingameMap = ingameMap
if self.limitMapWidth and self.ingameMap ~ = nil then
self.ingameMap.fullScreenLayout:setMapWidth( self.absSize[ 1 ])
end
end

setTerrainSize

Description

Set the current map's terrain size for map display.

Definition

setTerrainSize()

Arguments

anyterrainSize

Code

function IngameMapElement:setTerrainSize(terrainSize)
self.terrainSize = terrainSize
end

touchEvent

Description

Custom touch event handling for the in-game map. Directly handles zoom, click and drag events on the map.

Definition

touchEvent()

Arguments

anyposX
anyposY
anyisDown
anyisUp
anytouchId
anyeventUsed

Code

function IngameMapElement:touchEvent(posX, posY, isDown, isUp, touchId, eventUsed)
if self:getIsActive() then
eventUsed = IngameMapElement:superClass().mouseEvent( self , posX, posY, isDown, isUp, touchId, eventUsed)
self.lastInputIndex = touchId

if isDown or isUp or posX ~ = self.lastInputPosX[touchId] or posY ~ = self.lastInputPosY[touchId] then
if self.cursorElement then
self.cursorElement:setVisible( false )
end
self.isCursorActive = false
end

-- On mobile we have touch input.Touch does not give us a position until there is a touch.
-- This means on the first touch-begin, the lastMousePos is wrong and has a big offset.
-- We set it when the touch begins so it becomes a drag action
if isDown then
self.lastInputPosX[touchId] = posX
self.lastInputPosY[touchId] = posY
end

if not eventUsed then
if isDown and not self:isInputInDeadzones(posX, posY) then
eventUsed = true
if not self.inputDown then
self.inputDown = true
end
end
end

if self.inputDown and self.lastInputPosX[touchId] ~ = nil then
local distX = self.lastInputPosX[touchId] - posX
local distY = posY - self.lastInputPosY[touchId]

if self.isFixedHorizontal then
distX = 0
end

if self.isTouchPickingRotation then
local aiButton = self.target.buttonConfirmAITarget
local clickInButton = GuiUtils.checkOverlayOverlap(posX, posY, aiButton.absPosition[ 1 ], aiButton.absPosition[ 2 ], aiButton.size[ 1 ], aiButton.size[ 2 ])

if not clickInButton then
local localX, localY = self:getLocalPosition(posX, posY)
self:onClickMap(localX, localY)
end
else
if math.abs(distX) > self.minDragDistanceX or math.abs(distY) > self.minDragDistanceY then
local factorX = - distX
local factorY = distY

self:moveCenter(factorX, factorY)

self.hasDragged = true
end
end
end

if isUp then
if not eventUsed and self.inputDown and not self.hasDragged then
local localX, localY = self:getLocalPosition(posX, posY)

-- save state locally to avoid issues if activating/deactivating selection in the onClickMap callback
local isHotspotSelectionActive = self.isHotspotSelectionActive

self:onClickMap(localX, localY)

if isHotspotSelectionActive then
-- Trigger hot spot selection after map clicking because it's the more specific event
self:selectHotspotAt(posX, posY)
end

eventUsed = true
end

self.inputDown = false
self.hasDragged = false
end

self.lastInputPosX[touchId] = posX
self.lastInputPosY[touchId] = posY
end

return eventUsed
end

update

Description

Definition

update()

Arguments

anydt

Code

function IngameMapElement:update(dt)
IngameMapElement:superClass().update( self , dt)

self.inputMode = g_inputBinding:getLastInputMode()

if not g_gui:getIsDialogVisible() then
if not self.alreadyClosed then
local zoomFactor = self.accumZoomInput
if not self.isPinching then
zoomFactor = math.clamp(zoomFactor, - 1 , 1 )
end

if zoomFactor ~ = 0 then
self:zoom(zoomFactor * - 0.015 * dt)
end

if self.cursorElement ~ = nil then
self.isCursorActive = self.inputMode = = GS_INPUT_HELP_MODE_GAMEPAD
self.cursorElement:setVisible( self.isCursorAvailable and self.isCursorActive)
self:updateCursor( self.accumHorizontalInput, - self.accumVerticalInput, dt)
self.useMouse = false
end
end
end

self:resetFrameInputState()
end

updateCursor

Description

Definition

updateCursor()

Arguments

anydeltaX
anydeltaY
anydt

Code

function IngameMapElement:updateCursor(deltaX, deltaY, dt)
if self.cursorElement ~ = nil then
local speed = IngameMapElement.CURSOR_SPEED_FACTOR

local diffX = deltaX * speed * dt / g_screenAspectRatio
local diffY = deltaY * speed * dt

if Platform.isMobile or self.mapMovementLocked then
diffX = diffX - self.cursorOffsetX
diffY = diffY - self.cursorOffsetY

local oldX = self.mapCenterX
local oldY = self.mapCenterY

if not self.mapMovementLocked then
self:moveCenter( - diffX, - diffY)
end

local newX = self.mapCenterX
local newY = self.mapCenterY

local cursorSize = self.cursorElement.absSize
local _, width = self.ingameMap.fullScreenLayout:getMapSize()

self.cursorOffsetX = oldX - newX - diffX
self.cursorOffsetX = math.max( math.min( self.cursorOffsetX, width * 0.5 - cursorSize[ 1 ] * 0.5 ), - width * 0.5 + cursorSize[ 1 ] * 0.5 )
self.cursorOffsetY = oldY - newY - diffY
self.cursorOffsetY = math.max( math.min( self.cursorOffsetY, 0.5 - cursorSize[ 2 ] * 0.5 ), - 0.5 + cursorSize[ 2 ] * 0.5 )

if not Platform.isMobile and self.mapMovementLocked then
local maxOffset = 250
self.cursorOffsetX = math.clamp( self.cursorOffsetX, - maxOffset * g_pixelSizeScaledX, maxOffset * g_pixelSizeScaledX)
self.cursorOffsetY = math.clamp( self.cursorOffsetY, - maxOffset * g_pixelSizeScaledY, maxOffset * g_pixelSizeScaledY)
end

local cursor = self.cursorElement

cursor.absPosition[ 1 ] = self.originalMapCenterX - self.cursorOffsetX - cursor.absSize[ 1 ] * 0.5
cursor.absPosition[ 2 ] = self.originalMapCenterY - self.cursorOffsetY - cursor.absSize[ 2 ] * 0.5
else
self:moveCenter( - diffX, - diffY)
end
end
end

zoom

Description

Definition

zoom(zoomTarget if, )

Arguments

zoomTargetifset, instead of zooming with predefined speed, map will instantly zoom in to that zoom level
anyzoomTarget

Code

function IngameMapElement:zoom(direction, zoomTarget)
-- No zooming if plaform does not support it
if not Platform.ingameMap.canZoom then
return
end

-- Find the location pointed at by the cursor so we can zoom towards it
local targetX, targetZ = self:localToWorldPos( self:getLocalPointerTarget())

local width, height = self.ingameMap.fullScreenLayout:getMapSize()

-- Zoom by a set factor, or instantly to specified level if zoomTarget is set
local oldZoom = self.mapZoom
local speed = self.zoomSpeedFactor * direction * width -- multiply by size to mimic a constant scroll

if zoomTarget ~ = nil then
self.mapZoom = math.clamp(zoomTarget, self.zoomMin, self.zoomMax)
else
self.mapZoom = math.clamp( self.mapZoom + speed, self.zoomMin, self.zoomMax)
end

self.ingameMap.fullScreenLayout:setMapZoom( self.mapZoom)

-- Size depends on zoom, center bounds depend on size.So clamp the center
self:moveCenter( 0 , 0 )

-- Do not change focus position if we did not change zoom
if oldZoom ~ = self.mapZoom then
-- Find the location the mouseis pointing at now
local newTargetX, newTargetZ = self:localToWorldPos( self:getLocalPointerTarget())

-- Above location is wrong.We want it to point at the same location as before, so find the different for moving
local diffX, diffZ = newTargetX - targetX, newTargetZ - targetZ

-- The diff is in world coordinates.Transform it to screenspace.
local dx, dy = diffX / self.terrainSize * 0.5 * width, - diffZ / self.terrainSize * 0.5 * height

self.cursorOffsetX = self.cursorOffsetX + dx
self.cursorOffsetY = self.cursorOffsetY + dy

local mapLayout = self.ingameMap.fullScreenLayout

local centerX, centerY = mapLayout.mapCenterX, mapLayout.mapCenterY

self:moveCenter(dx, dy)

local newCenterX, newCenterY = mapLayout.mapCenterX, mapLayout.mapCenterY

if direction < 0 then
self.cursorOffsetX = self.cursorOffsetX - newCenterX + centerX + dx
self.cursorOffsetY = self.cursorOffsetY - newCenterY + centerY + dy
end
end
end