diff --git a/data/images/game/minimap/flag0.png b/data/images/game/minimap/flag0.png new file mode 100644 index 00000000..1b80e29d Binary files /dev/null and b/data/images/game/minimap/flag0.png differ diff --git a/data/images/game/minimap/flag1.png b/data/images/game/minimap/flag1.png new file mode 100644 index 00000000..560bf79f Binary files /dev/null and b/data/images/game/minimap/flag1.png differ diff --git a/data/images/game/minimap/flag10.png b/data/images/game/minimap/flag10.png new file mode 100644 index 00000000..866d0790 Binary files /dev/null and b/data/images/game/minimap/flag10.png differ diff --git a/data/images/game/minimap/flag11.png b/data/images/game/minimap/flag11.png new file mode 100644 index 00000000..3c986331 Binary files /dev/null and b/data/images/game/minimap/flag11.png differ diff --git a/data/images/game/minimap/flag12.png b/data/images/game/minimap/flag12.png new file mode 100644 index 00000000..c8f5e701 Binary files /dev/null and b/data/images/game/minimap/flag12.png differ diff --git a/data/images/game/minimap/flag13.png b/data/images/game/minimap/flag13.png new file mode 100644 index 00000000..7cba49e0 Binary files /dev/null and b/data/images/game/minimap/flag13.png differ diff --git a/data/images/game/minimap/flag14.png b/data/images/game/minimap/flag14.png new file mode 100644 index 00000000..688175c4 Binary files /dev/null and b/data/images/game/minimap/flag14.png differ diff --git a/data/images/game/minimap/flag15.png b/data/images/game/minimap/flag15.png new file mode 100644 index 00000000..63ce6bf3 Binary files /dev/null and b/data/images/game/minimap/flag15.png differ diff --git a/data/images/game/minimap/flag16.png b/data/images/game/minimap/flag16.png new file mode 100644 index 00000000..1ffb377c Binary files /dev/null and b/data/images/game/minimap/flag16.png differ diff --git a/data/images/game/minimap/flag17.png b/data/images/game/minimap/flag17.png new file mode 100644 index 00000000..fc9d6920 Binary files /dev/null and b/data/images/game/minimap/flag17.png differ diff --git a/data/images/game/minimap/flag18.png b/data/images/game/minimap/flag18.png new file mode 100644 index 00000000..4000460b Binary files /dev/null and b/data/images/game/minimap/flag18.png differ diff --git a/data/images/game/minimap/flag19.png b/data/images/game/minimap/flag19.png new file mode 100644 index 00000000..8f46613a Binary files /dev/null and b/data/images/game/minimap/flag19.png differ diff --git a/data/images/game/minimap/flag2.png b/data/images/game/minimap/flag2.png new file mode 100644 index 00000000..226eb55f Binary files /dev/null and b/data/images/game/minimap/flag2.png differ diff --git a/data/images/game/minimap/flag3.png b/data/images/game/minimap/flag3.png new file mode 100644 index 00000000..1d7f8ef3 Binary files /dev/null and b/data/images/game/minimap/flag3.png differ diff --git a/data/images/game/minimap/flag4.png b/data/images/game/minimap/flag4.png new file mode 100644 index 00000000..3f53f9d3 Binary files /dev/null and b/data/images/game/minimap/flag4.png differ diff --git a/data/images/game/minimap/flag5.png b/data/images/game/minimap/flag5.png new file mode 100644 index 00000000..8badc697 Binary files /dev/null and b/data/images/game/minimap/flag5.png differ diff --git a/data/images/game/minimap/flag6.png b/data/images/game/minimap/flag6.png new file mode 100644 index 00000000..8b713100 Binary files /dev/null and b/data/images/game/minimap/flag6.png differ diff --git a/data/images/game/minimap/flag7.png b/data/images/game/minimap/flag7.png new file mode 100644 index 00000000..c9d5182b Binary files /dev/null and b/data/images/game/minimap/flag7.png differ diff --git a/data/images/game/minimap/flag8.png b/data/images/game/minimap/flag8.png new file mode 100644 index 00000000..da226e15 Binary files /dev/null and b/data/images/game/minimap/flag8.png differ diff --git a/data/images/game/minimap/flag9.png b/data/images/game/minimap/flag9.png new file mode 100644 index 00000000..7a625e79 Binary files /dev/null and b/data/images/game/minimap/flag9.png differ diff --git a/data/images/game/minimap/mapflags.png b/data/images/game/minimap/mapflags.png deleted file mode 100644 index 7d25b647..00000000 Binary files a/data/images/game/minimap/mapflags.png and /dev/null differ diff --git a/data/styles/30-minimap.otui b/data/styles/30-minimap.otui new file mode 100644 index 00000000..cb6a7440 --- /dev/null +++ b/data/styles/30-minimap.otui @@ -0,0 +1,247 @@ +MinimapFlag < UIWidget + size: 11 11 + anchors.left: parent.left + anchors.top: parent.top + +MinimapFlags < UIWidget + anchors.fill: parent + +MinimapFloorUpButton < Button + size: 20 20 + margin-right: 28 + margin-bottom: 28 + anchors.right: parent.right + anchors.bottom: parent.bottom + icon-source: /images/game/minimap/floor_up + icon-clip: 0 32 16 16 + $pressed: + icon-clip: 0 0 16 16 + $hover !pressed: + icon-clip: 0 16 16 16 + +MinimapFloorDownButton < Button + size: 20 20 + margin-right: 28 + margin-bottom: 4 + anchors.right: parent.right + anchors.bottom: parent.bottom + icon-source: /images/game/minimap/floor_down + icon-clip: 0 32 16 16 + $pressed: + icon-clip: 0 0 16 16 + $hover !pressed: + icon-clip: 0 16 16 16 + +MinimapZoomInButton < Button + text: + + size: 20 20 + margin-right: 4 + margin-bottom: 28 + anchors.right: parent.right + anchors.bottom: parent.bottom + //icon-source: /images/game/minimap/zoom_in + +MinimapZoomOutButton < Button + text: - + size: 20 20 + margin-right: 4 + margin-bottom: 4 + anchors.right: parent.right + anchors.bottom: parent.bottom + //icon-source: /images/game/minimap/zoom_out + +MinimapResetButton < Button + !text: tr('Center') + size: 44 20 + anchors.left: parent.left + anchors.top: parent.top + margin: 4 + +Minimap < UIMinimap + draggable: true + focusable: false + cross: true + @onGeometryChange: self:updateFlags() + + MinimapFlags + id: flags + phantom: true + focusable: false + + MinimapFloorUpButton + id: floorUp + @onClick: self:getParent():floorUp(1) + + MinimapFloorDownButton + id: floorDown + @onClick: self:getParent():floorDown(1) + + MinimapZoomInButton + id: zoomIn + @onClick: self:getParent():zoomIn() + + MinimapZoomOutButton + id: zoomOut + @onClick: self:getParent():zoomOut() + + MinimapResetButton + id: reset + @onClick: self:getParent():reset() + + +// Minimap Flag Create Window + + +MinimapFlagCheckBox < CheckBox + size: 15 15 + margin-left: 2 + image-source: /images/game/minimap/flagcheckbox + image-size: 15 15 + image-border: 3 + icon-source: /images/game/minimap/mapflags + icon-size: 11 11 + icon-offset: 2 4 + anchors.left: prev.right + anchors.top: prev.top + $!checked: + image-clip: 26 0 26 26 + $hover !checked: + image-clip: 78 0 26 26 + $checked: + image-clip: 0 0 26 26 + $hover checked: + image-clip: 52 0 26 26 + +MinimapFlagWindow < MainWindow + !text: tr('Create Map Mark') + size: 196 185 + + Label + !text: tr('Position') .. ':' + text-auto-resize: true + anchors.top: parent.top + anchors.left: parent.left + margin-top: 2 + + Label + id: position + text-auto-resize: true + anchors.top: parent.top + anchors.right: parent.right + margin-top: 2 + + Label + !text: tr('Description') .. ':' + anchors.left: parent.left + anchors.top: prev.bottom + margin-top: 7 + + TextEdit + id: description + margin-top: 3 + anchors.left: parent.left + anchors.top: prev.bottom + width: 158 + + MinimapFlagCheckBox + id: flag0 + icon-source: /images/game/minimap/flag0 + anchors.left: parent.left + anchors.top: prev.bottom + margin-top: 6 + margin-left: 0 + + MinimapFlagCheckBox + id: flag1 + icon-source: /images/game/minimap/flag1 + + MinimapFlagCheckBox + id: flag2 + icon-source: /images/game/minimap/flag2 + + MinimapFlagCheckBox + id: flag3 + icon-source: /images/game/minimap/flag3 + + MinimapFlagCheckBox + id: flag4 + icon-source: /images/game/minimap/flag4 + + MinimapFlagCheckBox + id: flag5 + icon-source: /images/game/minimap/flag5 + + MinimapFlagCheckBox + id: flag6 + icon-source: /images/game/minimap/flag6 + + MinimapFlagCheckBox + id: flag7 + icon-source: /images/game/minimap/flag7 + + MinimapFlagCheckBox + id: flag8 + icon-source: /images/game/minimap/flag8 + + MinimapFlagCheckBox + id: flag9 + icon-source: /images/game/minimap/flag9 + + MinimapFlagCheckBox + id: flag10 + icon-source: /images/game/minimap/flag10 + anchors.left: parent.left + anchors.top: prev.bottom + margin-top: 6 + margin-left: 0 + + MinimapFlagCheckBox + id: flag11 + icon-source: /images/game/minimap/flag11 + + MinimapFlagCheckBox + id: flag12 + icon-source: /images/game/minimap/flag12 + + MinimapFlagCheckBox + id: flag13 + icon-source: /images/game/minimap/flag13 + + MinimapFlagCheckBox + id: flag14 + icon-source: /images/game/minimap/flag14 + + MinimapFlagCheckBox + id: flag15 + icon-source: /images/game/minimap/flag15 + + MinimapFlagCheckBox + id: flag16 + icon-source: /images/game/minimap/flag16 + + MinimapFlagCheckBox + id: flag17 + icon-source: /images/game/minimap/flag17 + + MinimapFlagCheckBox + id: flag18 + icon-source: /images/game/minimap/flag18 + + MinimapFlagCheckBox + id: flag19 + icon-source: /images/game/minimap/flag19 + + Button + id: okButton + !text: tr('Ok') + width: 64 + anchors.right: next.left + anchors.bottom: parent.bottom + margin-right: 10 + + Button + id: cancelButton + !text: tr('Cancel') + width: 64 + anchors.right: parent.right + anchors.bottom: parent.bottom diff --git a/modules/corelib/ui/uiradiogroup.lua b/modules/corelib/ui/uiradiogroup.lua index d0a36902..fbf13784 100644 --- a/modules/corelib/ui/uiradiogroup.lua +++ b/modules/corelib/ui/uiradiogroup.lua @@ -57,4 +57,8 @@ end function UIRadioGroup:getSelectedWidget() return self.selectedWidget -end \ No newline at end of file +end + +function UIRadioGroup:getFirstWidget() + return self.widgets[1] +end diff --git a/modules/game_minimap/minimap.lua b/modules/game_minimap/minimap.lua index 3f2a4d46..726426ad 100644 --- a/modules/game_minimap/minimap.lua +++ b/modules/game_minimap/minimap.lua @@ -1,275 +1,74 @@ -DEFAULT_ZOOM = 0 -MAX_FLOOR_UP = 0 -MAX_FLOOR_DOWN = 15 - -navigating = false minimapWidget = nil minimapButton = nil minimapWindow = nil -otmm = false -flagsPanel = nil -flagWindow = nil -nextFlagId = 0 ---[[ - Known Issue (TODO): - If you move the minimap compass directions and - you change floor it will not update the minimap. -]] -function init() - g_ui.importStyle('flagwindow') - - connect(g_game, { - onGameStart = online, - onGameEnd = offline, - onAddAutomapFlag = addMapFlag, - onRemoveAutomapFlag = removeMapFlag, - }) - connect(LocalPlayer, { onPositionChange = center }) - - g_keyboard.bindKeyDown('Ctrl+M', toggle) +otmm = true +function init() minimapButton = modules.client_topmenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', '/images/topbuttons/minimap', toggle) minimapButton:setOn(true) minimapWindow = g_ui.loadUI('minimap', modules.game_interface.getRightPanel()) minimapWindow:setContentMinimumHeight(64) - --minimapWindow:setContentMaximumHeight(256) minimapWidget = minimapWindow:recursiveGetChildById('minimap') - g_mouse.bindAutoPress(minimapWidget, compassClick, nil, MouseLeftButton) - - minimapWidget.onMouseRelease = onMinimapMouseRelease - minimapWidget.onMouseWheel = onMinimapMouseWheel - flagsPanel = minimapWindow:recursiveGetChildById('flagsPanel') local gameRootPanel = modules.game_interface.getRootPanel() - g_keyboard.bindKeyPress('Alt+Left', function() move(-1,0) end, gameRootPanel) - g_keyboard.bindKeyPress('Alt+Right', function() move(1,0) end, gameRootPanel) - g_keyboard.bindKeyPress('Alt+Up', function() move(0,-1) end, gameRootPanel) - g_keyboard.bindKeyPress('Alt+Down', function() move(0,1) end, gameRootPanel) + g_keyboard.bindKeyPress('Alt+Left', function() minimapWidget:move(-1,0) end, gameRootPanel) + g_keyboard.bindKeyPress('Alt+Right', function() minimapWidget:move(1,0) end, gameRootPanel) + g_keyboard.bindKeyPress('Alt+Up', function() minimapWidget:move(0,-1) end, gameRootPanel) + g_keyboard.bindKeyPress('Alt+Down', function() minimapWidget:move(0,1) end, gameRootPanel) + g_keyboard.bindKeyDown('Ctrl+M', toggle) - reset() minimapWindow:setup() - loadMapFlags() - useOTMM() - + + connect(g_game, { + onGameStart = online, + onGameEnd = offline, + }) + if g_game.isOnline() then - addEvent(function() updateMapFlags() end) + loadMap() end end function terminate() - local gameRootPanel = modules.game_interface.getRootPanel() - g_keyboard.unbindKeyPress('Alt+Left', gameRootPanel) - g_keyboard.unbindKeyPress('Alt+Right', gameRootPanel) - g_keyboard.unbindKeyPress('Alt+Up', gameRootPanel) - g_keyboard.unbindKeyPress('Alt+Down', gameRootPanel) + if g_game.isOnline() then + saveMap() + end disconnect(g_game, { onGameStart = online, onGameEnd = offline, - onAddAutomapFlag = addMapFlag, - onRemoveAutomapFlag = removeMapFlag, }) - disconnect(LocalPlayer, { onPositionChange = center }) - - destroyFlagWindow() - saveMapFlags() - if g_game.isOnline() then - saveMap() - end + local gameRootPanel = modules.game_interface.getRootPanel() + g_keyboard.unbindKeyPress('Alt+Left', gameRootPanel) + g_keyboard.unbindKeyPress('Alt+Right', gameRootPanel) + g_keyboard.unbindKeyPress('Alt+Up', gameRootPanel) + g_keyboard.unbindKeyPress('Alt+Down', gameRootPanel) g_keyboard.unbindKeyDown('Ctrl+M') minimapButton:destroy() minimapWindow:destroy() end -function onFlagMousePress(widget, mousePosition, mouseButton) - if mouseButton == MouseRightButton then - local menu = g_ui.createWidget('PopupMenu') - menu:addOption(tr('Delete mark'), function() - widget:destroy() - end) - menu:display(mousePosition) - elseif mouseButton == MouseLeftButton then - minimapAutoWalk(widget.position) - end - return true -end - -function destroyFlagWindow() - if flagWindow then - flagWindow:destroy() - flagWindow = nil - end -end - -function showFlagDialog(position) - if flagWindow then return end - if not position then return end - flagWindow = g_ui.createWidget('FlagWindow', rootWidget) - - local positionLabel = flagWindow:getChildById('position') - local description = flagWindow:getChildById('description') - local okButton = flagWindow:getChildById('okButton') - local cancelButton = flagWindow:getChildById('cancelButton') - - positionLabel:setText(tr('Position: %i %i %i', position.x, position.y, position.z)) - - flagRadioGroup = UIRadioGroup.create() - local flagCheckbox = {} - for i = 1, 20 do - local checkbox = flagWindow:getChildById('flag' .. i) - table.insert(flagCheckbox, checkbox) - checkbox.icon = i - 1 - flagRadioGroup:addWidget(checkbox) - end - - flagRadioGroup:selectWidget(flagCheckbox[1]) - - cancelButton.onClick = function() - flagRadioGroup:destroy() - flagRadioGroup = nil - destroyFlagWindow() - end - okButton.onClick = function() - addMapFlag(position, flagRadioGroup:getSelectedWidget().icon, description:getText()) - flagRadioGroup:destroy() - flagRadioGroup = nil - destroyFlagWindow() - end -end - -function loadMapFlags() - mapFlags = {} - - local flagSettings = g_settings.getNode('MapFlags') - if flagSettings then - for i = 1, #flagSettings do - local flag = flagSettings[i] - addMapFlag(flag.position, flag.icon, flag.description, flag.id, flag.version) - - if i == #flagSettings then - nextFlagId = flag.id + 1 - end - end - end -end - -function saveMapFlags() - local flagSettings = {} - - for i = 1, flagsPanel:getChildCount() do - local child = flagsPanel:getChildByIndex(i) - - table.insert(flagSettings, { position = child.position, - icon = child.icon, - description = child.description, - id = child.id, - version = child.version }) - end - - g_settings.setNode('MapFlags', flagSettings) -end - -function getFlagIconClip(id) - return (((id)%10)*11) .. ' ' .. ((math.ceil(id/10+0.1)-1)*11) .. ' 11 11' -end - -function addMapFlag(pos, icon, message, flagId, version) - if not (icon >= 0 and icon <= 19) or not pos then - return - end - - version = version or g_game.getProtocolVersion() - -- Check if flag is set for that position - for i = 1, flagsPanel:getChildCount() do - local flag = flagsPanel:getChildByIndex(i) - if flag.position.x == pos.x and flag.position.y == pos.y and flag.position.z == pos.z - and version == flag.version then - return - end - end - - if not flagId then - flagId = nextFlagId - nextFlagId = nextFlagId + 1 - end - - local flagWidget = g_ui.createWidget('FlagWidget', flagsPanel) - flagWidget:setIconClip(getFlagIconClip(icon)) - flagWidget:setId('flag' .. flagId) - flagWidget.position = pos - flagWidget.icon = icon - flagWidget.description = message - if message and message:len() > 0 then - flagWidget:setTooltip(message) - end - flagWidget.id = flagId - flagWidget.version = version - updateMapFlag(flagId) - flagWidget.onMousePress = onFlagMousePress -end - -function removeMapFlag(pos, icon, message) - for i=1, flagsPanel:getChildCount() do - local flag = flagsPanel:getChildByIndex(i) - if flag.position.x == pos.x and flag.position.y == pos.y and flag.position.z == pos.z and flag.icon == icon and flag.description == message then - flag:destroy() - break - end - end -end - -function getMapArea() - return minimapWidget:getPosition( { x = 1 + minimapWidget:getX(), y = 1 + minimapWidget:getY() } ), - minimapWidget:getPosition( { x = -2 + minimapWidget:getWidth() + minimapWidget:getX(), y = -2 + minimapWidget:getHeight() + minimapWidget:getY() } ) -end - -function isFlagVisible(flag, firstPosition, lastPosition) - return flag.version == g_game.getProtocolVersion() and (minimapWidget:getZoom() >= -2 and minimapWidget:getZoom() <= 4) and flag.position.x >= firstPosition.x and flag.position.x <= lastPosition.x and flag.position.y >= firstPosition.y and flag.position.y <= lastPosition.y and flag.position.z == firstPosition.z -end - -function updateMapFlag(id) - local firstPosition, lastPosition = getMapArea() - if not firstPosition or not lastPosition then - return - end - - local flag = flagsPanel:getChildById('flag' .. id) - if isFlagVisible(flag, firstPosition, lastPosition) then - flag:setVisible(true) - flag:setMarginLeft(-5.5 + (minimapWidget:getWidth() / (lastPosition.x - firstPosition.x)) * (flag.position.x - firstPosition.x)) - flag:setMarginTop(-5.5 + (minimapWidget:getHeight() / (lastPosition.y - firstPosition.y)) * (flag.position.y - firstPosition.y)) +function toggle() + if minimapButton:isOn() then + minimapWindow:close() + minimapButton:setOn(false) else - flag:setVisible(false) + minimapWindow:open() + minimapButton:setOn(true) end end -function updateMapFlags() - local firstPosition, lastPosition = getMapArea() - if not firstPosition or not lastPosition then - return - end - - for i=1, flagsPanel:getChildCount() do - local flag = flagsPanel:getChildByIndex(i) - if isFlagVisible(flag, firstPosition, lastPosition) then - flag:setVisible(true) - flag:setMarginLeft(-5.5 + (minimapWidget:getWidth() / (lastPosition.x - firstPosition.x)) * (flag.position.x - firstPosition.x)) - flag:setMarginTop(-5.5 + (minimapWidget:getHeight() / (lastPosition.y - firstPosition.y)) * (flag.position.y - firstPosition.y)) - else - flag:setVisible(false) - end - end +function onMiniWindowClose() + minimapButton:setOn(false) end function online() - reset() loadMap() - - updateMapFlags() + minimapWidget:followLocalPlayer() end function offline() @@ -292,11 +91,11 @@ function loadMap() g_map.loadOtcm(minimapFile) end end + minimapWidget:load() end function saveMap() local protocolVersion = g_game.getProtocolVersion() - if otmm then local minimapFile = '/minimap.otmm' g_minimap.saveOtmm(minimapFile) @@ -304,163 +103,5 @@ function saveMap() local minimapFile = '/minimap_' .. protocolVersion .. '.otcm' g_map.saveOtcm(minimapFile) end -end - -function toggle() - if minimapButton:isOn() then - minimapWindow:close() - minimapButton:setOn(false) - else - minimapWindow:open() - minimapButton:setOn(true) - end -end - -function useOTMM() - otmm = true -end - -function isClickInRange(position, fromPosition, toPosition) - return (position.x >= fromPosition.x and position.y >= fromPosition.y and position.x <= toPosition.x and position.y <= toPosition.y) -end - -function reset(zoom) - if zoom == nil then zoom = true end - local player = g_game.getLocalPlayer() - if not player then return end - minimapWidget:followCreature(player) - if zoom then - minimapWidget:setZoom(DEFAULT_ZOOM) - end -end - -function center() - reset(false) - updateMapFlags() -end - -function compassClick(self, mousePos, mouseButton, elapsed) - if elapsed < 300 then return end - - navigating = true - local px = mousePos.x - self:getX() - local py = mousePos.y - self:getY() - local dx = px - self:getWidth()/2 - local dy = -(py - self:getHeight()/2) - local radius = math.sqrt(dx*dx+dy*dy) - local movex = 0 - local movey = 0 - dx = dx/radius - dy = dy/radius - - local speed = math.ceil((1.0 / minimapWidget:getScale()) * 3) - if dx > 0.5 then movex = speed end - if dx < -0.5 then movex = -speed end - if dy > 0.5 then movey = -speed end - if dy < -0.5 then movey = speed end - - local cameraPos = minimapWidget:getCameraPosition() - local pos = {x = cameraPos.x + movex, y = cameraPos.y + movey, z = cameraPos.z} - minimapWidget:setCameraPosition(pos) - - updateMapFlags() -end - -function move(x,y) - local speed = math.ceil((1.0 / minimapWidget:getScale()) * 3) - local cameraPos = minimapWidget:getCameraPosition() - local pos = {x = cameraPos.x + x*speed, y = cameraPos.y + y*speed, z = cameraPos.z} - minimapWidget:setCameraPosition(pos) - updateMapFlags() -end - -function miniMapZoomIn() - minimapWidget:zoomIn() -end - -function miniMapZoomOut() - minimapWidget:zoomOut() -end - -function minimapFloorUp(floors) - local pos = minimapWidget:getCameraPosition() - pos.z = pos.z - floors - if pos.z > MAX_FLOOR_UP then - minimapWidget:setCameraPosition(pos) - end -end - -function minimapFloorDown(floors) - local pos = minimapWidget:getCameraPosition() - pos.z = pos.z + floors - if pos.z < MAX_FLOOR_DOWN then - minimapWidget:setCameraPosition(pos) - end -end - -function minimapAutoWalk(pos) - local player = g_game.getLocalPlayer() - if not player:autoWalk(pos) then - player.onAutoWalkFail = function() modules.game_textmessage.displayFailureMessage(tr('There is no way.')) end - return false - else - return true - end -end - -function onButtonClick(id) - if id == "zoomIn" then - miniMapZoomIn() - elseif id == "zoomOut" then - miniMapZoomOut() - elseif id == "floorUp" then - minimapFloorUp(1) - elseif id == "floorDown" then - minimapFloorDown(1) - end - - updateMapFlags() -end - -function onMinimapMouseRelease(self, mousePosition, mouseButton) - -- Mapmark menu - local pos = self:getPosition(mousePosition) - if mouseButton == MouseRightButton then - local menu = g_ui.createWidget('PopupMenu') - menu:addOption(tr('Create mark'), function() - local pos = self:getPosition(mousePosition) - if pos then - showFlagDialog(pos) - end - end) - menu:display(mousePosition) - end - - if navigating then - navigating = false - return - end - if pos and mouseButton == MouseLeftButton and self:isPressed() then - minimapAutoWalk(pos) - end - return false -end - -function onMinimapMouseWheel(self, mousePos, direction) - local keyboardModifiers = g_keyboard.getModifiers() - - if direction == MouseWheelUp and keyboardModifiers == KeyboardNoModifier then - miniMapZoomIn() - elseif direction == MouseWheelDown and keyboardModifiers == KeyboardNoModifier then - miniMapZoomOut() - elseif direction == MouseWheelDown and keyboardModifiers == KeyboardCtrlModifier then - minimapFloorUp(1) - elseif direction == MouseWheelUp and keyboardModifiers == KeyboardCtrlModifier then - minimapFloorDown(1) - end - updateMapFlags() -end - -function onMiniWindowClose() - minimapButton:setOn(false) + minimapWidget:save() end diff --git a/modules/game_minimap/minimap.otui b/modules/game_minimap/minimap.otui index bf79d07e..84c72127 100644 --- a/modules/game_minimap/minimap.otui +++ b/modules/game_minimap/minimap.otui @@ -1,39 +1,9 @@ -MapControl < Button - size: 20 20 - icon-clip: 0 32 16 16 - - $pressed: - icon-clip: 0 0 16 16 - - $hover !pressed: - icon-clip: 0 16 16 16 - -FlagWidget < UIWidget - size: 11 11 - icon-clip: 0 0 11 11 - icon-source: /images/game/minimap/mapflags - anchors.left: parent.left - anchors.top: parent.top - -FloorUpControl < MapControl - icon-source: /images/game/minimap/floor_up - -FloorDownControl < MapControl - icon-source: /images/game/minimap/floor_down - -ZoomInControl < MapControl - //image-source: /images/game/minimap/zoom_in - -ZoomOutControl < MapControl - //image-source: /images/game/minimap/zoom_out - MiniWindow id: minimapWindow !text: tr('Minimap') height: 150 icon: /images/topbuttons/minimap @onClose: modules.game_minimap.onMiniWindowClose() - @onGeometryChange: updateMapFlags() &save: true Label @@ -47,60 +17,6 @@ MiniWindow size: 14 14 MiniWindowContents - UIMinimap + Minimap id: minimap anchors.fill: parent - cross: true - - Panel - id: flagsPanel - anchors.fill: minimap - phantom: true - - FloorUpControl - id: floorUp - anchors.right: parent.right - anchors.bottom: parent.bottom - margin-right: 28 - margin-bottom: 28 - enabled: true - @onClick: onButtonClick(self:getId()) - - FloorDownControl - id: floorDown - anchors.right: parent.right - anchors.bottom: parent.bottom - margin-right: 28 - margin-bottom: 4 - enabled: true - @onClick: onButtonClick(self:getId()) - - ZoomInControl - id: zoomIn - text: + - font: terminus-14px-bold - anchors.right: parent.right - anchors.bottom: parent.bottom - margin-right: 4 - margin-bottom: 28 - enabled: true - @onClick: onButtonClick(self:getId()) - - ZoomOutControl - id: zoomOut - text: - - anchors.right: parent.right - anchors.bottom: parent.bottom - margin-right: 4 - margin-bottom: 4 - enabled: true - @onClick: onButtonClick(self:getId()) - - Button - id: reset - !text: tr('Center') - width: 44 - anchors.left: parent.left - anchors.top: parent.top - margin: 4 - @onClick: center() diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index fe536645..1ef13d32 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -1,5 +1,8 @@ -- @docconsts @{ +FloorHigher = 0 +FloorLower = 15 + SkullNone = 0 SkullYellow = 1 SkullGreen = 2 diff --git a/modules/gamelib/ui/uiminimap.lua b/modules/gamelib/ui/uiminimap.lua new file mode 100644 index 00000000..e0bfffa9 --- /dev/null +++ b/modules/gamelib/ui/uiminimap.lua @@ -0,0 +1,280 @@ +function UIMinimap:onSetup() + self.flagWindow = nil + self.flagsWidget = self:getChildById('flags') + self.floorUpWidget = self:getChildById('floorUp') + self.floorDownWidget = self:getChildById('floorDown') + self.zoomInWidget = self:getChildById('zoomIn') + self.zoomOutWidget = self:getChildById('zoomOut') + self.dx = 0 + self.dy = 0 + self.onPositionChange = function() self:followLocalPlayer() end + self.onAddAutomapFlag = function(pos, icon, description) self:addFlag(pos, icon, description) end + self.onRemoveAutomapFlag = function(pos, icon, description) self:addFlag(pos, icon, description) end + connect(g_game, { + onAddAutomapFlag = self.onAddAutomapFlag, + onRemoveAutomapFlag = self.onRemoveAutomapFlag, + }) + connect(LocalPlayer, { onPositionChange = self.onPositionChange }) +end + +function UIMinimap:onDestroy() + disconnect(LocalPlayer, { onPositionChange = self.onPositionChange }) + disconnect(g_game, { + onAddAutomapFlag = self.onAddAutomapFlag, + onRemoveAutomapFlag = self.onRemoveAutomapFlag, + }) + self:destroyFlagWindow() +end + +function UIMinimap:load() + local settings = g_settings.getNode('Minimap') + if settings then + if settings.flags then + for i=1,#settings.flags do + local flag = settings.flags[i] + self:addFlag(flag.position, flag.icon, flag.description) + end + end + self:setZoom(settings.zoom) + end + self:updateFlags() +end + +function UIMinimap:save() + local settings = { flags={} } + local children = self.flagsWidget:getChildren() + for i=1,#children do + local flag = children[i] + table.insert(settings.flags, { + position = flag.pos, + icon = flag.icon, + description = flag.description, + }) + end + settings.zoom = self:getZoom() + g_settings.setNode('Minimap', settings) +end + +function UIMinimap:addFlag(pos, icon, description) + local flag = self:getFlag(pos, icon, description) + if flag then + return + end + + flag = g_ui.createWidget('MinimapFlag', self.flagsWidget) + flag.pos = pos + flag.icon = icon + flag.description = description + flag:setIcon('/images/game/minimap/flag' .. icon) + flag:setTooltip(description) + flag.onMouseRelease = function(widget, pos, button) + if button == MouseRightButton then + local menu = g_ui.createWidget('PopupMenu') + menu:addOption(tr('Delete mark'), function() widget:destroy() end) + menu:display(pos) + return true + end + return false + end + + self:updateFlag(flag) +end + +function UIMinimap:getFlag(pos, icon, description) + local children = self.flagsWidget:getChildren() + for i=1,#children do + local flag = children[i] + if flag.pos.x == pos.x and flag.pos.y == pos.y and flag.pos.z == pos.z and flag.icon == icon and flag.description == description then + return flag + end + end +end + +function UIMinimap:removeFlag(pos, icon, description) + local flag = self:getFlag(pos, icon, description) + if flag then + flag:destroy() + end +end + +function UIMinimap:updateFlag(flag) + local topLeft, bottomRight = self:getArea() + if self:isFlagVisible(flag, topLeft, bottomRight) then + flag:setVisible(true) + flag:setMarginLeft(-5.5 + (self:getWidth() / (bottomRight.x - topLeft.x)) * (flag.pos.x - topLeft.x)) + flag:setMarginTop(-5.5 + (self:getHeight() / (bottomRight.y - topLeft.y)) * (flag.pos.y - topLeft.y)) + else + flag:setVisible(false) + end +end + +function UIMinimap:updateFlags() + local children = self.flagsWidget:getChildren() + for i=1,#children do + self:updateFlag(children[i]) + end +end + +UIMinimap.realZoomIn = UIMinimap.zoomIn +function UIMinimap:zoomIn() + self:realZoomIn() + self:updateFlags() +end + +UIMinimap.realZoomOut = UIMinimap.zoomOut +function UIMinimap:zoomOut() + self:realZoomOut() + self:updateFlags() +end + +function UIMinimap:floorUp(floors) + local pos = self:getCameraPosition() + pos.z = pos.z - floors + if pos.z >= FloorHigher then + self:setCameraPosition(pos) + end + self:updateFlags() +end + +function UIMinimap:floorDown(floors) + local pos = self:getCameraPosition() + pos.z = pos.z + floors + if pos.z <= FloorLower then + self:setCameraPosition(pos) + end + self:updateFlags() +end + +function UIMinimap:followLocalPlayer() + local player = g_game.getLocalPlayer() + self:followCreature(player) + self:updateFlags() +end + +function UIMinimap:reset() + self:followLocalPlayer() + self:setZoom(0) +end + +function UIMinimap:move(x, y) + local topLeft, bottomRight = self:getArea() + self.dx = self.dx + ((bottomRight.x - topLeft.x) / self:getWidth() ) * x + self.dy = self.dy + ((bottomRight.y - topLeft.y) / self:getHeight()) * y + local dx = math.floor(self.dx) + local dy = math.floor(self.dy) + self.dx = self.dx - dx + self.dy = self.dy - dy + + local cameraPos = self:getCameraPosition() + local pos = {x = cameraPos.x - dx, y = cameraPos.y - dy, z = cameraPos.z} + self:setCameraPosition(pos) + self:updateFlags() +end + +function UIMinimap:onMouseWheel(mousePos, direction) + local keyboardModifiers = g_keyboard.getModifiers() + if direction == MouseWheelUp and keyboardModifiers == KeyboardNoModifier then + self:zoomIn() + elseif direction == MouseWheelDown and keyboardModifiers == KeyboardNoModifier then + self:zoomOut() + elseif direction == MouseWheelDown and keyboardModifiers == KeyboardCtrlModifier then + self:floorUp(1) + elseif direction == MouseWheelUp and keyboardModifiers == KeyboardCtrlModifier then + self:floorDown(1) + end + self:updateFlags() +end + +function UIMinimap:onMousePress(pos, button) + if not self:isDragging() then + self.allowNextRelease = true + end +end + +function UIMinimap:onMouseRelease(pos, button) + -- TODO: + --if not self.allowNextRelease then return true end + self.allowNextRelease = false + + local mapPos = self:getPosition(pos) + if not mapPos then return end + + if button == MouseLeftButton then + local player = g_game.getLocalPlayer() + if not player:autoWalk(mapPos) then + player.onAutoWalkFail = function() modules.game_textmessage.displayFailureMessage(tr('There is no way.')) end + end + return true + elseif button == MouseRightButton then + local menu = g_ui.createWidget('PopupMenu') + menu:addOption(tr('Create mark'), function() + self:createFlagWindow(mapPos) + end) + menu:display(pos) + return true + end + return false +end + +function UIMinimap:onDragEnter(pos) + return true +end + +function UIMinimap:onDragMove(pos, moved) + self:move(moved.x, moved.y) + return true +end + +function UIMinimap:onDragLeave(widget, pos) + return true +end + +function UIMinimap:createFlagWindow(pos) + if self.flagWindow then return end + if not pos then return end + + self.flagWindow = g_ui.createWidget('MinimapFlagWindow', rootWidget) + + local positionLabel = self.flagWindow:getChildById('position') + local description = self.flagWindow:getChildById('description') + local okButton = self.flagWindow:getChildById('okButton') + local cancelButton = self.flagWindow:getChildById('cancelButton') + + positionLabel:setText(string.format('%i, %i, %i', pos.x, pos.y, pos.z)) + + local flagRadioGroup = UIRadioGroup.create() + for i=0,19 do + local checkbox = self.flagWindow:getChildById('flag' .. i) + checkbox.icon = i + flagRadioGroup:addWidget(checkbox) + end + + flagRadioGroup:selectWidget(flagRadioGroup:getFirstWidget()) + + okButton.onClick = function() + self:addFlag(pos, flagRadioGroup:getSelectedWidget().icon, description:getText()) + self:destroyFlagWindow() + end + cancelButton.onClick = function() + self:destroyFlagWindow() + end + + self.flagWindow.onDestroy = function() flagRadioGroup:destroy() end +end + +function UIMinimap:destroyFlagWindow() + if self.flagWindow then + self.flagWindow:destroy() + self.flagWindow = nil + end +end + +function UIMinimap:getArea() + local topLeft = self:getPosition({ x = self:getX() + 1, y = self:getY() + 1 }) + local bottomRight = self:getPosition({ x = self:getX() + self:getWidth() - 2, y = self:getY() + self:getHeight() - 2 }) + return topLeft, bottomRight +end + +function UIMinimap:isFlagVisible(flag, topLeft, bottomRight) + return flag.pos.x >= topLeft.x and flag.pos.x <= bottomRight.x and flag.pos.y >= topLeft.y and flag.pos.y <= bottomRight.y and flag.pos.z == topLeft.z +end diff --git a/src/client/tile.h b/src/client/tile.h index e193144c..3eda5ad2 100644 --- a/src/client/tile.h +++ b/src/client/tile.h @@ -51,7 +51,6 @@ enum tileflags_t TILESTATE_TRANSLUECENT_LIGHT = 1 << 23 }; -#pragma pack(push,1) // disable memory alignment class Tile : public LuaObject { public: @@ -131,6 +130,5 @@ private: uint8 m_minimapColor; uint32 m_flags, m_houseId; }; -#pragma pack(pop) #endif