--*********************************************************** --** THE INDIE STONE ** --*********************************************************** require "ISUI/ISPanelJoypad" require "ISUI/Maps/ISMap" require "ISUI/Maps/ISWorldMapSymbols" local FONT_HGT_SMALL = getTextManager():getFontHeight(UIFont.Small) local FONT_HGT_LARGE = getTextManager():getFontHeight(UIFont.Large) local FONT_HGT_HANDWRITTEN = getTextManager():getFontHeight(UIFont.Handwritten) ----- WorldMapOptions = ISCollapsableWindowJoypad:derive("WorldMapOptions") function WorldMapOptions:onTickBox(index, selected, option) option:setValue(selected) end function WorldMapOptions:onCommandEntered(entry, option) option:parse(entry:getText()) end function WorldMapOptions:createChildren() local fontHgt = FONT_HGT_SMALL local entryHgt = fontHgt + 2 * 2 local x = 12 local y = self:titleBarHeight() + 6 local maxWidth = 0 self.doubleBoxes = {} self.tickBoxes = {} self.showAllOptions = false if getDebug() or (isClient() and (getAccessLevel() == "admin")) then self.showAllOptions = true end local texViewIsometric = getTexture("media/textures/worldMap/ViewIsometric.png") local btnSize = texViewIsometric and texViewIsometric:getWidth() or 48 local maxHeight = getCore():getScreenHeight() - 20 - btnSize self.joypadButtonsY = {} self.joypadIndex = 1 self.joypadIndexY = 1 local visibleOptions = self:getVisibleOptions() for i,option in ipairs(visibleOptions) do if option:getType() == "boolean" then local tickBox = ISTickBox:new(x, y, self.width, entryHgt, "", self, self.onTickBox, option) tickBox:initialise() local text = getTextOrNull("IGUI_MapOption_" .. option:getName()) or option:getName() tickBox:addOption(text, option) tickBox:setSelected(1, option:getValue()) tickBox:setWidthToFit() self:addChild(tickBox) maxWidth = math.max(maxWidth, tickBox:getRight()) table.insert(self.tickBoxes, i, tickBox) self:insertNewLineOfButtons(tickBox) y = y + entryHgt + 6 end if option:getType() == "double" then local text = getTextOrNull("IGUI_MapOption_" .. option:getName()) or option:getName() local label = ISLabel:new(x, y, entryHgt, text, 1, 1, 1, 1, UIFont.Small, true) self:addChild(label) local entry = ISTextEntryBox:new("", label:getRight()+4, y, 100, entryHgt) entry.onCommandEntered = function(self) self.parent:onCommandEntered(entry, option) end self:addChild(entry) entry:setOnlyNumbers(true) maxWidth = math.max(maxWidth, entry:getRight()) table.insert(self.doubleBoxes, i, entry) self:insertNewLineOfButtons(entry) y = y + entryHgt + 6 end if y + entryHgt + 6 >= maxHeight then x = x + maxWidth y = self:titleBarHeight() + 6 maxWidth = 0 end end local width = 0 local height = 0 for _,child in pairs(self:getChildren()) do width = math.max(width, child:getRight()) height = math.max(height, child:getBottom()) end self:setWidth(width + 12) self:setHeight(height + self:resizeWidgetHeight()) self.screenHeight = getCore():getScreenHeight() end function WorldMapOptions:getVisibleOptions() local result = {} if self.showAllOptions then for i=1,self.map.mapAPI:getOptionCount() do local option = self.map.mapAPI:getOptionByIndex(i-1) if isClient() or not self:isMultiplayerOption(option:getName()) then table.insert(result, option) end end return result; end local optionNames = {} table.insert(optionNames, "Players") if isClient() then table.insert(optionNames, "RemotePlayers") table.insert(optionNames, "PlayerNames") end table.insert(optionNames, "Symbols") for _,optionName in ipairs(optionNames) do for i=1,self.map.mapAPI:getOptionCount() do local option = self.map.mapAPI:getOptionByIndex(i-1) if optionName == option:getName() then table.insert(result, option) break end end end return result end function WorldMapOptions:isMultiplayerOption(optionName) return optionName == "RemotePlayers" or optionName == "PlayerNames" end function WorldMapOptions:synchUI() local showAllOptions = false if getDebug() or (isClient() and (getAccessLevel() == "admin")) then showAllOptions = true end if showAllOptions ~= self.showAllOptions or self.screenHeight ~= getCore():getScreenHeight() then local children = {} for k,v in pairs(self:getChildren()) do table.insert(children, v) end for _,child in ipairs(children) do self:removeChild(child) end self:createChildren() end local visibleOptions = self:getVisibleOptions() for i,option in ipairs(visibleOptions) do if option:getType() == "boolean" then self.tickBoxes[i]:setSelected(1, option:getValue()) end if option:getType() == "double" then self.doubleBoxes[i]:setText(option:getValueAsString()) end end end function WorldMapOptions:onMouseDownOutside(x, y) if self:isMouseOver() then return -- click in ISTextEntryBox end if self.parent.optionBtn:isMouseOver() then return end self:setVisible(false) if self.joyfocus then setJoypadFocus(joypadData.player, self.parent.buttonPanel) end end function WorldMapOptions:onGainJoypadFocus(joypadData) ISCollapsableWindowJoypad.onGainJoypadFocus(self, joypadData) self:restoreJoypadFocus() end function WorldMapOptions:onJoypadDown(button, joypadData) if button == Joypad.BButton then self:setVisible(false) setJoypadFocus(joypadData.player, self.parent.buttonPanel) return end ISCollapsableWindowJoypad.onJoypadDown(self, button, joypadData) end function WorldMapOptions:new(x, y, width, height, map) local o = ISCollapsableWindowJoypad.new(self, x, y, width, height) o.backgroundColor = {r=0, g=0, b=0, a=1.0} o.resizable = false o.map = map return o end ----- ISWorldMapButtonPanel = ISPanelJoypad:derive("ISWorldMapButtonPanel") function ISWorldMapButtonPanel:render() ISPanelJoypad.render(self) if self.joyfocus then local children = self:getVisibleChildren(self.joypadIndexY) local child = children[self.joypadIndex] if child then self:drawRectBorder(child.x, child.y, child.width, child.height, 0.4, 0.2, 1.0, 1.0); self:drawRectBorder(child.x-1, child.y-1, child.width+2, child.height+2, 0.4, 0.2, 1.0, 1.0); end end end function ISWorldMapButtonPanel:onGainJoypadFocus(joypadData) ISPanelJoypad.onGainJoypadFocus(self, joypadData) self:restoreJoypadFocus() end function ISWorldMapButtonPanel:onLoseJoypadFocus(joypadData) ISPanelJoypad.onLoseJoypadFocus(self, joypadData) self:clearJoypadFocus() end function ISWorldMapButtonPanel:onJoypadDown(button, joypadData) if button == Joypad.BButton or button == Joypad.YButton then setJoypadFocus(joypadData.player, self.parent) return end ISPanelJoypad.onJoypadDown(self, button, joypadData) end function ISWorldMapButtonPanel:new(x, y, width, height) local o = ISPanelJoypad.new(self, x, y, width, height) o:noBackground() return o end ----- ISWorldMap = ISPanelJoypad:derive("ISWorldMap") function ISWorldMap:instantiate() self.javaObject = UIWorldMap.new(self) self.mapAPI = self.javaObject:getAPIv1() self.mapAPI:setMapItem(MapItem.getSingleton()) self.javaObject:setX(self.x) self.javaObject:setY(self.y) self.javaObject:setWidth(self.width) self.javaObject:setHeight(self.height) self.javaObject:setAnchorLeft(self.anchorLeft) self.javaObject:setAnchorRight(self.anchorRight) self.javaObject:setAnchorTop(self.anchorTop) self.javaObject:setAnchorBottom(self.anchorBottom) self.javaObject:setWantKeyEvents(true) self:createChildren() end function ISWorldMap:createChildren() local symbolsWidth = ISWorldMapSymbols.RequiredWidth() self.symbolsUI = ISWorldMapSymbols:new(self.width - 20 - symbolsWidth, 20, symbolsWidth, self.height - 40 * 2, self) self.symbolsUI:initialise() self.symbolsUI:setAnchorLeft(false) self.symbolsUI:setAnchorRight(true) self:addChild(self.symbolsUI) local btnSize = self.texViewIsometric and self.texViewIsometric:getWidth() or 48 local btnCount = 6 if getDebug() then btnCount = btnCount + 1 end self.buttonPanel = ISWorldMapButtonPanel:new(self.width - 20 - (btnSize * btnCount + 20 * (btnCount - 1)), self.height - 20 - btnSize, btnSize * btnCount + 20 * (btnCount - 1), btnSize) self.buttonPanel.anchorLeft = false self.buttonPanel.anchorRight = true self.buttonPanel.anchorTop = false self.buttonPanel.anchorBottom = true self:addChild(self.buttonPanel) local buttons = {} self.closeBtn = ISButton:new(self.buttonPanel.width - btnSize, 0, btnSize, btnSize, "X", self, self.close) self.buttonPanel:addChild(self.closeBtn) table.insert(buttons, 1, self.closeBtn) self.forgetBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "?", self, function(self, button) self:onForget(button) end) self.buttonPanel:addChild(self.forgetBtn) table.insert(buttons, 1, self.forgetBtn) self.symbolsBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "S", self, self.onToggleSymbols) self.buttonPanel:addChild(self.symbolsBtn) table.insert(buttons, 1, self.symbolsBtn) self.centerBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "C", self, self.onCenterOnPlayer) self.buttonPanel:addChild(self.centerBtn) table.insert(buttons, 1, self.centerBtn) self.perspectiveBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "", self, self.onChangePerspective) self.perspectiveBtn:setImage(self.isometric and self.texViewIsometric or self.texViewOrthographic) self.buttonPanel:addChild(self.perspectiveBtn) table.insert(buttons, 1, self.perspectiveBtn) if getDebug() then self.pyramidBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "", self, self.onTogglePyramid) self.pyramidBtn:setImage(self.texViewPyramid) self.buttonPanel:addChild(self.pyramidBtn) table.insert(buttons, 1, self.pyramidBtn) end self.optionBtn = ISButton:new(buttons[1].x - 20 - btnSize, 0, btnSize, btnSize, "OPT", self, self.onChangeOptions) self.buttonPanel:addChild(self.optionBtn) table.insert(buttons, 1, self.optionBtn) self.buttonPanel:insertNewListOfButtons(buttons) self.buttonPanel.joypadIndex = 1 self.buttonPanel.joypadIndexY = 1 end function ISWorldMap:render() getWorld():setDrawWorld(false) local INSET = 0 local w = getCore():getScreenWidth() - INSET * 2 local h = getCore():getScreenHeight() - INSET * 2 if self.width ~= w or self.height ~= h then self:setWidth(w) self:setHeight(h) end self.isometric = self.mapAPI:getBoolean("Isometric") self.perspectiveBtn:setImage(self.isometric and self.texViewIsometric or self.texViewOrthographic) self:updateJoypad() if self.playerNum and ((self.playerNum ~= 0) or (JoypadState.players[self.playerNum+1] ~= nil and not wasMouseActiveMoreRecentlyThanJoypad())) then self:drawTexture(self.cross, self.width/2-12, self.height/2-12, 1, 1,1,1); end if self.joyfocus then local joypadTexture = Joypad.Texture.YButton self:drawTexture(joypadTexture, self.buttonPanel.x - 16 - joypadTexture:getWidth(), self.buttonPanel.y + (self.buttonPanel.height - joypadTexture:getHeight()) / 2, 1, 1, 1, 1) self:renderJoypadPrompt(Joypad.Texture.XButton, getText("IGUI_Map_EditMarkings"), 16, self.height - 16 - 32) if self.symbolsUI.currentTool then self:renderJoypadPrompt(Joypad.Texture.BButton, getText("UI_Cancel"), self.buttonPanel.x - 16 - 32, self.buttonPanel.y - 10 - 32 - 10 - 32) local text = self.symbolsUI:getJoypadAButtonText() if text then self:renderJoypadPrompt(Joypad.Texture.AButton, text, self.buttonPanel.x - 16 - 32, self.buttonPanel.y - 10 - 32) end end self:renderJoypadPrompt(Joypad.Texture.LTrigger, getText("IGUI_Map_ZoomOut"), 16, 16) self:renderJoypadPrompt(Joypad.Texture.RTrigger, getText("IGUI_Map_ZoomIn"), 16, 16 + 48) end ISPanelJoypad.render(self) end function ISWorldMap:renderJoypadPrompt(texture, text, x, y) if not texture then return end local h = 32 self:drawTexture(texture, x, y + (h - texture:getHeight()) / 2, 1, 1, 1, 1) self:drawText(text, x + texture:getWidth() + 10, y + (h - FONT_HGT_LARGE) / 2, 0, 0, 0, 1, UIFont.Large) end function ISWorldMap:onMouseDown(x, y) if self.symbolsUI:onMouseDownMap(x, y) then return true end self.dragging = true self.dragMoved = false self.dragStartX = x self.dragStartY = y self.dragStartCX = self.mapAPI:getCenterWorldX() self.dragStartCY = self.mapAPI:getCenterWorldY() self.dragStartZoomF = self.mapAPI:getZoomF() self.dragStartWorldX = self.mapAPI:uiToWorldX(x, y) self.dragStartWorldY = self.mapAPI:uiToWorldY(x, y) return true end function ISWorldMap:onMouseMove(dx, dy) if self.symbolsUI:onMouseMoveMap(dx, dy) then return true end if self.dragging then local mouseX = self:getMouseX() local mouseY = self:getMouseY() if not self.dragMoved and math.abs(mouseX - self.dragStartX) <= 4 and math.abs(mouseY - self.dragStartY) <= 4 then return end self.dragMoved = true local worldX = self.mapAPI:uiToWorldX(mouseX, mouseY, self.dragStartZoomF, self.dragStartCX, self.dragStartCY) local worldY = self.mapAPI:uiToWorldY(mouseX, mouseY, self.dragStartZoomF, self.dragStartCX, self.dragStartCY) self.mapAPI:centerOn(self.dragStartCX + self.dragStartWorldX - worldX, self.dragStartCY + self.dragStartWorldY - worldY) end return true end function ISWorldMap:onMouseMoveOutside(dx, dy) return self:onMouseMove(dx, dy) end function ISWorldMap:onMouseUp(x, y) self.dragging = false if self.symbolsUI:onMouseUpMap(x, y) then return true end return true end function ISWorldMap:onMouseUpOutside(x, y) self.dragging = false if self.symbolsUI:onMouseUpMap(x, y) then return true end return true end function ISWorldMap:onMouseWheel(del) self.mapAPI:zoomAt(self:getMouseX(), self:getMouseY(), del) return true end function ISWorldMap:onRightMouseDown(x, y) if self.symbolsUI:onRightMouseDownMap(x, y) then return true end return false end function ISWorldMap:onRightMouseUp(x, y) if self.symbolsUI:onRightMouseUpMap(x, y) then return true end if not getDebug() and not (isClient() and (getAccessLevel() == "admin")) then return false end local playerNum = 0 local playerObj = getSpecificPlayer(0) if not playerObj then return end -- Debug in main menu local context = ISContextMenu.get(playerNum, x + self:getAbsoluteX(), y + self:getAbsoluteY()) local option = context:addOption("Show Cell Grid", self, function(self) self:setShowCellGrid(not self.showCellGrid) end) context:setOptionChecked(option, self.showCellGrid) option = context:addOption("Show Tile Grid", self, function(self) self:setShowTileGrid(not self.showTileGrid) end) context:setOptionChecked(option, self.showTileGrid) self.hideUnvisitedAreas = self.mapAPI:getBoolean("HideUnvisited") option = context:addOption("Hide Unvisited Areas", self, function(self) self:setHideUnvisitedAreas(not self.hideUnvisitedAreas) end) context:setOptionChecked(option, self.hideUnvisitedAreas) option = context:addOption("Isometric", self, function(self) self:setIsometric(not self.isometric) end) context:setOptionChecked(option, self.isometric) -- DEV: Apply the style again after reloading ISMapDefinitions.lua option = context:addOption("Reapply Style", self, function(self) MapUtils.initDefaultStyleV1(self) MapUtils.overlayPaper(self) end) local worldX = self.mapAPI:uiToWorldX(x, y) local worldY = self.mapAPI:uiToWorldY(x, y) if getWorld():getMetaGrid():isValidChunk(worldX / 10, worldY / 10) then option = context:addOption("Teleport Here", self, self.onTeleport, worldX, worldY) end return true end function ISWorldMap:onForget() if MainScreen.instance and not MainScreen.instance.inGame then return end if self.forgetUI then self.forgetUI:setVisible(false) self.forgetUI:removeFromUIManager() self.forgetUI = nil return end local modal = ISModalRichText:new(self.width - 40 - 380, self.buttonPanel.y - 40 - 120, 380, 120, getText("IGUI_WorldMap_ConfirmForget"), true, self, self.onConfirmForget, self.playerNum) modal:initialise() modal.prevFocus = self.buttonPanel modal:addToUIManager() modal:setAlwaysOnTop(true) if JoypadState.players[self.playerNum+1] then setJoypadFocus(self.playerNum, modal) end self.forgetUI = modal end function ISWorldMap:onConfirmForget(button) self.forgetUI = nil if button.internal ~= "YES" then return end self.mapAPI:getSymbolsAPI():clear() WorldMapVisited.getInstance():forget() end function ISWorldMap:onToggleSymbols() if self.symbolsUI:isVisible() then self.symbolsUI:undisplay() self.symbolsUI:setVisible(false) else self.symbolsUI:setVisible(true) end end function ISWorldMap:onChangePerspective() self:setIsometric(not self.isometric) end function ISWorldMap:onCenterOnPlayer() if not self.character then self.mapAPI:resetView() return end self.mapAPI:centerOn(self.character:getX(), self.character:getY()) end function ISWorldMap:onTogglePyramid() if self.mapAPI:getBoolean("ImagePyramid") then self.mapAPI:setBoolean("ImagePyramid", false) self.mapAPI:setBoolean("Features", true) else self.mapAPI:setBoolean("ImagePyramid", true) self.mapAPI:setBoolean("Features", false) end end function ISWorldMap:onChangeOptions(button) if self.optionsUI == nil then local ui = WorldMapOptions:new(self.width - 300, button.y - 300, 300, 300, self) self:addChild(ui) ui:setVisible(false) self.optionsUI = ui end if self.optionsUI:isVisible() then self.optionsUI:setVisible(false) return end self.optionsUI:synchUI() self.optionsUI:setX(math.min(self.width - 20 - self.optionsUI.width, button.parent.x + button.x)) self.optionsUI:setY(button.parent.y + button.y - self.optionsUI.height) self.optionsUI:setVisible(true) if JoypadState.players[self.playerNum+1] then setJoypadFocus(self.playerNum, self.optionsUI) end end function ISWorldMap:onTeleport(worldX, worldY) local playerObj = getSpecificPlayer(0) if not playerObj then return end playerObj:setX(worldX) playerObj:setY(worldY) playerObj:setZ(0.0) playerObj:setLx(worldX) playerObj:setLy(worldY) end function ISWorldMap:setHideUnvisitedAreas(hide) self.hideUnvisitedAreas = hide self.mapAPI:setBoolean("HideUnvisited", hide) end function ISWorldMap:setIsometric(iso) self.isometric = iso self.mapAPI:setBoolean("Isometric", iso) end function ISWorldMap:setShowCellGrid(show) self.showCellGrid = show self.mapAPI:setBoolean("CellGrid", show) end function ISWorldMap:setShowTileGrid(show) self.showTileGrid = show self.mapAPI:setBoolean("TileGrid", show) end function ISWorldMap:setShowPlayers(show) self.showPlayers = show self.mapAPI:setBoolean("Players", show) end function ISWorldMap:setShowRemotePlayers(show) self.showRemotePlayers = show self.mapAPI:setBoolean("RemotePlayers", show) end function ISWorldMap:setShowPlayerNames(show) self.showPlayerNames = show self.mapAPI:setBoolean("PlayerNames", show) end function ISWorldMap:close() self:saveSettings() self.symbolsUI:undisplay() if self.forgetUI then self.forgetUI.no:forceClick() end self:setVisible(false) self:removeFromUIManager() if getSpecificPlayer(0) then getWorld():setDrawWorld(true) end for i=1,getNumActivePlayers() do if getSpecificPlayer(i-1) then getSpecificPlayer(i-1):setBlockMovement(false) end end if JoypadState.players[self.playerNum+1] then setJoypadFocus(self.playerNum, nil) end if MainScreen.instance and not MainScreen.instance.inGame then -- Debug in main menu self:setHideUnvisitedAreas(true) ISWorldMap_instance = nil WorldMapVisited.Reset() end if self.character then self.character:playSoundLocal("MapClose") end end function ISWorldMap:isKeyConsumed(key) if key == Keyboard.KEY_ESCAPE or key == getCore():getKey("Toggle UI") then return true end if key == Keyboard.KEY_C then return true end if key == Keyboard.KEY_S then return true end return false end function ISWorldMap:onKeyPress(key) if self.symbolsUI:onKeyPress(key) then return end end function ISWorldMap:onKeyRelease(key) if self.symbolsUI:onKeyRelease(key) then return end if key == Keyboard.KEY_ESCAPE or key == getCore():getKey("Toggle UI") then self:close() end if key == Keyboard.KEY_C then self:onCenterOnPlayer() end if key == Keyboard.KEY_S then self:onToggleSymbols() end --[[ if key == Keyboard.KEY_X then self:close() end --]] end function ISWorldMap:updateJoypad() if self.getJoypadFocus then self.getJoypadFocus = false; if JoypadState.players[self.playerNum+1] then setJoypadFocus(self.playerNum, self) end end local currentTimeMs = getTimestampMs() self.updateMS = self.updateMS or currentTimeMs local dt = currentTimeMs - self.updateMS self.updateMS = currentTimeMs if self.joyfocus == nil then return end local cx = self.mapAPI:getCenterWorldX() local cy = self.mapAPI:getCenterWorldY() if isJoypadLTPressed(self.joyfocus.id, Joypad.LBumper) then if not self.LBumperZoom then self.LBumperZoom = self.mapAPI:getZoomF() end if self.LBumperZoom >= self.mapAPI:getZoomF() then self.LBumperZoom = self.mapAPI:getZoomF() - 1.0 self.mapAPI:zoomAt(self.width / 2, self.height / 2, 2) end else self.LBumperZoom = nil end if isJoypadRTPressed(self.joyfocus.id, Joypad.RBumper) then if not self.RBumperZoom then self.RBumperZoom = self.mapAPI:getZoomF() end if self.RBumperZoom <= self.mapAPI:getZoomF() then self.RBumperZoom = self.mapAPI:getZoomF() + 1.0 self.mapAPI:zoomAt(self.width / 2, self.height / 2, -2) end else self.RBumperZoom = nil end local x = getControllerPovX(self.joyfocus.id); local y = getControllerPovY(self.joyfocus.id); if x == 0 then x = getJoypadMovementAxisX(self.joyfocus.id) if (x > -0.5 and x < 0.5) then x = 0 end end if y == 0 then y = getJoypadMovementAxisY(self.joyfocus.id) if (y > -0.5 and y < 0.5) then y = 0 end end if x ~= 0 then if not self.povXms then self.povXms = currentTimeMs else if currentTimeMs - self.povXms <= 150 then x = 0 end end else self.povXms = nil end if y ~= 0 then if not self.povYms then self.povYms = currentTimeMs else if currentTimeMs - self.povYms <= 150 then y = 0 end end else self.povYms = nil end if self.mapAPI:getBoolean("Isometric") then if x ~= 0 and y ~= 0 then if x > 0 and y > 0 then y = 0 elseif x < 0 and y < 0 then y = 0 else x = 0 end elseif x ~= 0 then y = -x elseif y ~= 0 then x = y end end if x~=0 or y ~= 0 then local scale = self.mapAPI:getWorldScale() local scrollDelta = (dt / 1000) * (500 / scale) local snap = 1 if x < 0 then cx = math.floor((cx + scrollDelta * x) / snap) * snap elseif x > 0 then cx = math.ceil((cx + scrollDelta * x) / snap) * snap end if y < 0 then cy = math.floor((cy + scrollDelta * y) / snap) * snap elseif y > 0 then cy = math.ceil((cy + scrollDelta * y) / snap) * snap end self.mapAPI:centerOn(cx, cy) end end function ISWorldMap:onJoypadDown(button, joypadData) if button == Joypad.AButton then self.symbolsUI:onJoypadDownInMap(button, joypadData) end if button == Joypad.BButton then if self.symbolsUI:onKeyRelease(Keyboard.KEY_ESCAPE) then return end self:close() end if button == Joypad.XButton then if self.symbolsUI:isVisible() then setJoypadFocus(joypadData.player, self.symbolsUI) else self.symbolsUI:setVisible(true) setJoypadFocus(joypadData.player, self.symbolsUI) end end if button == Joypad.YButton then setJoypadFocus(joypadData.player, self.buttonPanel) end end function ISWorldMap:saveSettings() if not MainScreen.instance or not MainScreen.instance.inGame then return end local settings = WorldMapSettings.getInstance() settings:setDouble("WorldMap.CenterX", self.mapAPI:getCenterWorldX()) settings:setDouble("WorldMap.CenterY", self.mapAPI:getCenterWorldY()) settings:setDouble("WorldMap.Zoom", self.mapAPI:getZoomF()) settings:setBoolean("WorldMap.Isometric", self.mapAPI:getBoolean("Isometric")) settings:setBoolean("WorldMap.ShowSymbolsUI", self.symbolsUI:isVisible()) settings:save() end function ISWorldMap:restoreSettings() if not MainScreen.instance or not MainScreen.instance.inGame then return end local settings = WorldMapSettings.getInstance() if settings:getFileVersion() ~= 1 then return end local centerX = settings:getDouble("WorldMap.CenterX", 0.0) local centerY = settings:getDouble("WorldMap.CenterY", 0.0) local zoom = settings:getDouble("WorldMap.Zoom", 0.0) if zoom == 0.0 then return end -- ISMiniMap loaded settings for the first time local isometric = settings:getBoolean("WorldMap.Isometric") local showSymbolsUI = settings:getBoolean("WorldMap.ShowSymbolsUI") self.mapAPI:centerOn(centerX, centerY) self.mapAPI:setZoom(zoom) self.mapAPI:setBoolean("Isometric", isometric) if self.mapAPI:getDataCount() == 0 and self.mapAPI:getImagesCount() > 0 then self.mapAPI:setBoolean("ImagePyramid", true) self.mapAPI:setBoolean("Features", false) end self.symbolsUI:setVisible(showSymbolsUI) end function ISWorldMap:initDataAndStyle() local mapAPI = self.mapAPI if MainScreen.instance.inGame then MapUtils.initDefaultMapData(self) mapAPI:setBoundsFromWorld() self.hideUnvisitedAreas = true else -- TEST in main menu MapUtils.initDirectoryMapData(self, 'media/maps/Muldraugh, KY') mapAPI:setBoundsFromData() local markers = mapAPI:getMarkersAPI() markers:addGridSquareMarker(11342, 6779, 50, 1.0, 1.0, 0.0, 1.0) self.hideUnvisitedAreas = false end MapUtils.initDefaultStyleV1(self) MapUtils.overlayPaper(self) end function ISWorldMap:new(x, y, width, height) local o = ISPanelJoypad.new(self, x, y, width, height) o:noBackground() o.anchorRight = true o.anchorBottom = true o.showCellGrid = false o.showTileGrid = false o.showPlayers = true o.showRemotePlayers = true o.showPlayerNames = true o.hideUnvisitedAreas = false o.isometric = true o.character = nil o.playerNum = character and character:getPlayerNum() or 0 o.cross = getTexture("media/ui/LootableMaps/mapCross.png") o.texViewIsometric = getTexture("media/textures/worldMap/ViewIsometric.png") o.texViewOrthographic = getTexture("media/textures/worldMap/ViewOrtho.png") o.texViewPyramid = getTexture("media/textures/worldMap/ViewPyramid.png") return o end ----- function ISWorldMap.IsAllowed() if getCore():getGameMode() == "Tutorial" then return false end return SandboxVars.Map and (SandboxVars.Map.AllowWorldMap == true) or false end function ISWorldMap.ShowWorldMap(playerNum) if not ISWorldMap.IsAllowed() then return end if not ISWorldMap_instance then local INSET = 0 ISWorldMap_instance = ISWorldMap:new(INSET, INSET, getCore():getScreenWidth() - INSET * 2, getCore():getScreenHeight() - INSET * 2) ISWorldMap_instance:initialise() ISWorldMap_instance:instantiate() -- ISWorldMap_instance:setAlwaysOnTop(true) -- Breaks context menu ISWorldMap_instance.character = getSpecificPlayer(playerNum) ISWorldMap_instance.playerNum = playerNum ISWorldMap_instance.symbolsUI.character = getSpecificPlayer(playerNum) ISWorldMap_instance.symbolsUI.playerNum = playerNum ISWorldMap_instance.symbolsUI:checkInventory() ISWorldMap_instance:initDataAndStyle() ISWorldMap_instance:setHideUnvisitedAreas(ISWorldMap_instance.hideUnvisitedAreas) ISWorldMap_instance:setShowPlayers(ISWorldMap_instance.showPlayers) ISWorldMap_instance:setShowRemotePlayers(ISWorldMap_instance.showRemotePlayers) ISWorldMap_instance:setShowPlayerNames(ISWorldMap_instance.showPlayerNames) ISWorldMap_instance:setShowCellGrid(ISWorldMap_instance.showCellGrid) ISWorldMap_instance:setShowTileGrid(ISWorldMap_instance.showTileGrid) ISWorldMap_instance:setIsometric(ISWorldMap_instance.isometric) ISWorldMap_instance.mapAPI:resetView() if ISWorldMap_instance.character then ISWorldMap_instance.mapAPI:centerOn(ISWorldMap_instance.character:getX(), ISWorldMap_instance.character:getY()) ISWorldMap_instance.mapAPI:setZoom(18.0) end ISWorldMap_instance:restoreSettings() ISWorldMap_instance:addToUIManager() ISWorldMap_instance.getJoypadFocus = true for i=1,getNumActivePlayers() do if getSpecificPlayer(i-1) then getSpecificPlayer(i-1):setBlockMovement(true) end end return end ISWorldMap_instance.character = getSpecificPlayer(playerNum) ISWorldMap_instance.playerNum = playerNum ISWorldMap_instance.symbolsUI.character = getSpecificPlayer(playerNum) ISWorldMap_instance.symbolsUI.playerNum = playerNum ISWorldMap_instance.symbolsUI:checkInventory() ISWorldMap_instance:setVisible(true) ISWorldMap_instance:addToUIManager() ISWorldMap_instance.getJoypadFocus = true if MainScreen.instance.inGame then for i=1,getNumActivePlayers() do if getSpecificPlayer(i-1) then getSpecificPlayer(i-1):setBlockMovement(true) end end else ISWorldMap_instance:setHideUnvisitedAreas(false) end end function ISWorldMap.HideWorldMap(playerNum) if not ISWorldMap.IsAllowed() then return end ISWorldMap_instance:close() end function ISWorldMap.ToggleWorldMap(playerNum) if not ISWorldMap.IsAllowed() then return end -- Forbid showing the map when a splitscreen player has died. if ISPostDeathUI and ISPostDeathUI.instance and #ISPostDeathUI.instance > 0 then return end if ISWorldMap_instance and ISWorldMap_instance:isVisible() then ISWorldMap.HideWorldMap(playerNum) else local playerObj = getSpecificPlayer(playerNum) if playerObj then ISTimedActionQueue.clear(playerObj) ISTimedActionQueue.add(ISReadWorldMap:new(playerObj)) else -- Debug: In the main menu ISWorldMap.ShowWorldMap(playerNum) end end end local KEYSTATE = {} function ISWorldMap.checkKey(key) if key ~= getCore():getKey("Map") then return false end if not ISWorldMap.IsAllowed() then return false end if getCore():getGameMode() == "Tutorial" then return false end if MainScreen.instance and not MainScreen.instance.inGame then -- For debugging the map in the main menu without starting a game. return getDebug() end if UIManager.getSpeedControls() and (UIManager.getSpeedControls():getCurrentGameSpeed() == 0) then return false end local playerObj = getSpecificPlayer(0) if not playerObj or playerObj:isDead() then return false end --[[ local queue = ISTimedActionQueue.queues[playerObj] if queue and #queue.queue > 0 then return false end if getCell():getDrag(0) then return false end --]] return true end function ISWorldMap.onKeyStartPressed(key) if not ISWorldMap.checkKey(key) then return end if MainScreen.instance and not MainScreen.instance.inGame then -- For debugging the map in the main menu without starting a game. return end local radialMenu = getPlayerRadialMenu(0) if getCore():getOptionRadialMenuKeyToggle() and radialMenu:isReallyVisible() then KEYSTATE.radialWasVisible = true radialMenu:removeFromUIManager() return end KEYSTATE.keyPressedMS = getTimestampMs() KEYSTATE.radialWasVisible = false end function ISWorldMap.onKeyKeepPressed(key) if not ISWorldMap.checkKey(key) then return end if MainScreen.instance and not MainScreen.instance.inGame then -- For debugging the map in the main menu without starting a game. return end if KEYSTATE.radialWasVisible then return end if not KEYSTATE.keyPressedMS then return end local playerNum = 0 local radialMenu = getPlayerRadialMenu(playerNum) local delay = 500 if (getTimestampMs() - KEYSTATE.keyPressedMS >= delay) and not radialMenu:isReallyVisible() then radialMenu:clear() radialMenu:addSlice(getText("IGUI_WorldMap_Toggle"), getTexture("media/textures/worldMap/Map_On.png"), ISWorldMap.ToggleWorldMap, playerNum) if getPlayerMiniMap(playerNum) then radialMenu:addSlice(getText("IGUI_MiniMap_Toggle"), getTexture("media/textures/worldMap/Map_On.png"), ISMiniMap.ToggleMiniMap, playerNum) end radialMenu:center() radialMenu:addToUIManager() if JoypadState.players[playerNum+1] then -- menu:setHideWhenButtonReleased(Joypad.RBumper) setJoypadFocus(playerNum, radialMenu) getSpecificPlayer(playerNum):setJoypadIgnoreAimUntilCentered(true) end end end function ISWorldMap.onKeyReleased(key) if not ISWorldMap.checkKey(key) then return end --[[ if not KEYSTATE.keyPressedMS then return end --]] if MainScreen.instance and not MainScreen.instance.inGame then -- For debugging the map in the main menu without starting a game. ISWorldMap.ToggleWorldMap(0) return end local playerNum = 0 local radialMenu = getPlayerRadialMenu(playerNum) if radialMenu:isReallyVisible() or KEYSTATE.radialWasVisible then if not getCore():getOptionRadialMenuKeyToggle() then radialMenu:removeFromUIManager() end return end ISWorldMap.ToggleWorldMap(playerNum) end function ISWorldMap.OnPlayerDeath(playerObj) if ISWorldMap_instance and ISWorldMap_instance:isVisible() then ISWorldMap.HideWorldMap(0) end end Events.OnKeyStartPressed.Add(ISWorldMap.onKeyStartPressed) Events.OnKeyKeepPressed.Add(ISWorldMap.onKeyKeepPressed) Events.OnKeyPressed.Add(ISWorldMap.onKeyReleased) Events.OnPlayerDeath.Add(ISWorldMap.OnPlayerDeath)