diff --git a/data/libs/ui/NavButton.lua b/data/libs/ui/NavButton.lua index 2eb68ca098b..ce8b51b3ae3 100644 --- a/data/libs/ui/NavButton.lua +++ b/data/libs/ui/NavButton.lua @@ -26,7 +26,7 @@ function NavButton.New (text, target) Game.player:SetNavTarget(Space.GetBody(self.target.bodyIndex)) end elseif not Game.InHyperspace() then - Game.player:SetHyperspaceTarget(self.target:GetStarSystem().path) + Game.sectorView:SwitchToPath(self.target:GetStarSystem().path) -- XXX we should do something useful here -- e.g. switch to the sector map or just beep end diff --git a/data/pigui/libs/chat-form.lua b/data/pigui/libs/chat-form.lua index c87238fe4ab..5a0a16cf3eb 100644 --- a/data/pigui/libs/chat-form.lua +++ b/data/pigui/libs/chat-form.lua @@ -169,7 +169,7 @@ function ChatForm:AddNavButton (target) Game.player:SetNavTarget(Space.GetBody(target.bodyIndex)) end elseif not Game.InHyperspace() then - Game.player:SetHyperspaceTarget(target:GetStarSystem().path) + Game.sectorView:SwitchToPath(target:GetStarSystem().path) ui.playBoinkNoise() end end diff --git a/data/pigui/modules/hyperjump-planner.lua b/data/pigui/modules/hyperjump-planner.lua index eb3dd9d8f44..98d50a0856a 100644 --- a/data/pigui/modules/hyperjump-planner.lua +++ b/data/pigui/modules/hyperjump-planner.lua @@ -17,9 +17,11 @@ local icons = ui.theme.icons local sectorView -local mainButtonSize = Vector2(24,24) * (ui.screenHeight / 1200) +local mainButtonSize = ui.rescaleUI(Vector2(24,24), Vector2(1600, 900)) local mainButtonFramePadding = 3 +local hyperJumpPlanner = {} -- for export + -- hyperjump route stuff local hyperjump_route = {} local route_jumps = 0 @@ -31,17 +33,14 @@ local selected_jump local current_fuel local remove_first_if_current = true local hideHyperJumpPlaner = false +local textIconSize = nil -local function showSettings() - if ui.collapsingHeader(lui.SETTINGS, {"DefaultOpen"}) then - local changed - changed, remove_first_if_current = ui.checkbox(lui.REMOVE_WHEN_COMPLETED, remove_first_if_current) - end -end -- showSettings +local function textIcon(icon, tooltip) + ui.icon(icon, textIconSize, colors.font, tooltip) +end local function showJumpData(start, target, status, distance, fuel, duration, short) - --local color = status == "OK" and colors.white or colors.alertRed -- TODO: dedicated colors? - local color = colors.white + local color = colors.font if short then ui.withStyleColors({["Text"] = color}, function() @@ -86,38 +85,75 @@ local function showInfo() start = jump end - ui.text(lui.CURRENT_SYSTEM .. ": " .. current_system.name .. " (" .. current_path.sectorX .. "," .. current_path.sectorY .. "," .. current_path.sectorZ ..")") - ui.text(lui.FINAL_TARGET) + textIcon(icons.display_navtarget, lui.CURRENT_SYSTEM) + ui.sameLine() + if ui.selectable(current_system.name .. " (" .. current_path.sectorX .. ", " .. current_path.sectorY .. ", " .. current_path.sectorZ ..")") then + sectorView:SwitchToPath(current_path) + end + + textIcon(icons.route_destination, lui.FINAL_TARGET) if route_jumps > 0 then local final_path = hyperjump_route[route_jumps] local final_sys = final_path:GetStarSystem() ui.sameLine() - ui.text(final_sys.name .. " (" .. final_path.sectorX .. "," .. final_path.sectorY .. "," .. final_path.sectorZ .. ")") + if ui.selectable(final_sys.name .. " (" .. final_path.sectorX .. ", " .. final_path.sectorY .. ", " .. final_path.sectorZ .. ")", false, {}) then + sectorView:SwitchToPath(final_path) + end + else + ui.sameLine() + ui.text(lui.ADD_JUMP) end - ui.text(lui.CURRENT_FUEL .. " " .. current_fuel .. lc.UNIT_TONNES) + + textIcon(icons.fuel, lui.REQUIRED_FUEL) + ui.sameLine() + ui.text(total_fuel .. lc.UNIT_TONNES) ui.sameLine() - ui.text(lui.REQUIRED_FUEL .. " " .. total_fuel .. lc.UNIT_TONNES) + ui.text("[") + ui.sameLine() + ui.withStyleVars({ItemSpacing = Vector2(0.0)}, function() + textIcon(icons.hull, lui.CURRENT_FUEL) + ui.sameLine() + ui.text(" : " .. current_fuel .. lc.UNIT_TONNES) + end) + ui.sameLine() + ui.text("]") - ui.text(lui.TOTAL_DURATION .. " " ..ui.Format.Duration(total_duration, 2)) + textIcon(icons.eta, lui.TOTAL_DURATION) ui.sameLine() - ui.text(lui.TOTAL_DISTANCE .. " " ..string.format("%.2f", total_distance) .. lc.UNIT_LY) + ui.text(ui.Format.Duration(total_duration, 2)) + ui.sameLine() + textIcon(icons.route_dist, lui.TOTAL_DISTANCE) + ui.sameLine() + ui.text(string.format("%.2f", total_distance) .. lc.UNIT_LY) end end -- showInfo local function mainButton(icon, tooltip, callback) - local button = ui.coloredSelectedIconButton(icon, mainButtonSize, false, mainButtonFramePadding, colors.buttonBlue, colors.white, tooltip) + local button = ui.coloredSelectedIconButton(icon, mainButtonSize, false, mainButtonFramePadding, colors.buttonBlue, colors.buttonInk, tooltip) if button then callback() end return button end --mainButton +local function updateHyperspaceTarget() + hyperjump_route = sectorView:GetRoute() + if #hyperjump_route > 0 then + -- first waypoint is always the hyperspace target + sectorView:SetHyperspaceTarget(hyperjump_route[1]) + else + sectorView:ResetHyperspaceTarget() + end +end + local function showJumpRoute() if ui.collapsingHeader(lui.ROUTE_JUMPS, {"DefaultOpen"}) then mainButton(icons.forward, lui.ADD_JUMP, function() sectorView:AddToRoute(map_selected_path) + updateHyperspaceTarget() + selected_jump = #hyperjump_route end) ui.sameLine() @@ -128,6 +164,7 @@ local function showJumpRoute() if selected_jump then sectorView:RemoveRouteItem(selected_jump) end + updateHyperspaceTarget() end) ui.sameLine() @@ -138,6 +175,7 @@ local function showJumpRoute() selected_jump = selected_jump - 1 end end + updateHyperspaceTarget() end) ui.sameLine() @@ -148,6 +186,7 @@ local function showJumpRoute() selected_jump = selected_jump + 1 end end + updateHyperspaceTarget() end) ui.sameLine() @@ -155,13 +194,14 @@ local function showJumpRoute() function() sectorView:ClearRoute() selected_jump = nil + updateHyperspaceTarget() end) ui.sameLine() mainButton(icons.hyperspace, lui.AUTO_ROUTE, function() sectorView:AutoRoute() - + updateHyperspaceTarget() end) ui.sameLine() @@ -177,8 +217,9 @@ local function showJumpRoute() local start = current_path local clicked local running_fuel = 0 + ui.child("routelist", function() for jumpIndex, jump in pairs(hyperjump_route) do - local jump_sys = jump:GetStarSystem() + local jump_sys = jump:GetSystemBody() local status, distance, fuel, duration = player:GetHyperspaceDetails(start, jump) local color local remaining_fuel = current_fuel - running_fuel - fuel @@ -189,7 +230,7 @@ local function showJumpRoute() if remaining_fuel < 0 then color = colors.alertRed else - color = colors.white + color = colors.font end end @@ -201,38 +242,80 @@ local function showJumpRoute() end) running_fuel = fuel + running_fuel start = jump - end + end -- for + end --function + ) if clicked then selected_jump = clicked + sectorView:SwitchToPath(hyperjump_route[selected_jump]) end end end -- showJumpPlan - +-- scan the route and if this system is there, but another star is selected, update it in route +function hyperJumpPlanner.updateInRoute(path) + for jumpIndex, jump in pairs(hyperjump_route) do + if jump:IsSameSystem(path) then + selected_jump = jumpIndex + if jump ~= path then + sectorView:UpdateRouteItem(jumpIndex, path) + updateHyperspaceTarget() + end + return + end + end + selected_jump = nil; +end local function showHyperJumpPlannerWindow() - ui.setNextWindowSize(Vector2(ui.screenWidth / 5, (ui.screenHeight / 5) * 2), "Always") - ui.setNextWindowPos(Vector2(ui.screenWidth - ui.screenWidth / 5 - 10, ui.screenHeight - ((ui.screenHeight / 5) * 2) - 10), "Always") - ui.withStyleColors({["WindowBg"] = colors.lightBlackBackground}, function() - ui.window("MapSectorViewHyperJumpPlanner", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus"}, - function() + textIcon(icons.route) + ui.sameLine() ui.text(lui.HYPERJUMP_ROUTE) ui.separator() showInfo() ui.separator() showJumpRoute() - ui.separator() - showSettings() - end) - end) end -- showHyperJumpPlannerWindow -local function displayHyperJumpPlanner() +function hyperJumpPlanner.Dummy() + ui.text("Hyperjump route") + ui.separator() + ui.collapsingHeader("Route info",{"DefaultOpen"}) + ui.text("Current system") + ui.text("Final target") + ui.text("Fuel line") + ui.text("Duration line") + ui.collapsingHeader("Route jumps",{"DefaultOpen"}) + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.sameLine() + mainButton(icons.forward, lui.ADD_JUMP, function() end) + ui.separator() + --reserve 5 route items + ui.text("Route item") + ui.text("Route item") + ui.text("Route item") + ui.text("Route item") + ui.text("Route item") + ui.separator() +end + +function hyperJumpPlanner.display() player = Game.player - local current_view = Game.CurrentView() - - if current_view == "sector" and not Game.InHyperspace() then + if not textIconSize then + textIconSize = ui.calcTextSize("H") + textIconSize.x = textIconSize.y -- make square + end local drive = table.unpack(player:GetEquip("engine")) or nil local fuel_type = drive and drive.fuel or Equipment.cargo.hydrogen current_system = Game.system @@ -241,19 +324,14 @@ local function displayHyperJumpPlanner() map_selected_path = sectorView:GetSelectedSystemPath() hyperjump_route = sectorView:GetRoute() route_jumps = sectorView:GetRouteSize() - if ui.isKeyReleased(ui.keys.tab) then - hideHyperJumpPlaner = not hideHyperJumpPlaner; - end - if not hideHyperJumpPlaner then - showHyperJumpPlannerWindow() - end - end -end -- displayHyperJumpPlanner + showHyperJumpPlannerWindow() +end -- hyperJumpPlanner.display -ui.registerModule("game", displayHyperJumpPlanner) +function hyperJumpPlanner.setSectorView(sv) + sectorView = sv +end -Event.Register("onEnterSystem", - function(ship) +function hyperJumpPlanner.onEnterSystem(ship) -- remove the first jump if it's the current system (and enabled to do so) -- this should be the case if you are following a route and want the route to be -- updated as you make multiple jumps @@ -262,17 +340,7 @@ Event.Register("onEnterSystem", sectorView:RemoveRouteItem(1) end end -end) - -Event.Register("onGameStart", - function() - --connect to the class SectorView - sectorView = Game.sectorView -end) - -Event.Register("onGameEnd", - function(ship) - -- clear the route out so it doesn't show up if the user starts a new game - sectorView:ClearRoute() -end) -return {} + updateHyperspaceTarget() +end + +return hyperJumpPlanner diff --git a/data/pigui/modules/map-sector-view.lua b/data/pigui/modules/map-sector-view.lua index 7f967f8ec12..182de078aad 100644 --- a/data/pigui/modules/map-sector-view.lua +++ b/data/pigui/modules/map-sector-view.lua @@ -6,6 +6,7 @@ local Game = require 'Game' local utils = require 'utils' local Event = require 'Event' local SystemPath = require 'SystemPath' +local hyperJumpPlanner = require 'pigui.modules.hyperjump-planner' local Lang = require 'Lang' local lc = Lang.GetResource("core"); @@ -18,21 +19,84 @@ local colors = ui.theme.colors local icons = ui.theme.icons local hideSectorViewWindows = false -local mainButtonSize = Vector2(32,32) * (ui.screenHeight / 1200) +local mainButtonSize = ui.rescaleUI(Vector2(32,32), Vector2(1600, 900)) local mainButtonFramePadding = 3 -local function mainMenuButton(icon, selected, tooltip, color) - color = color or colors.white - return ui.coloredSelectedIconButton(icon, mainButtonSize, selected, mainButtonFramePadding, colors.buttonBlue, color, tooltip) + +local font = ui.fonts.pionillium.medlarge +local MAX_SEARCH_STRINGS_VISIBLE = 15 +local textIconSize = nil +local edgePadding = nil + +-- all colors, used in this module +local svColor = { + BUTTON_ACTIVE = colors.buttonBlue, + BUTTON_INACTIVE = Color(150, 150, 200, 0), + BUTTON_SEMIACTIVE = Color(150, 150, 200, 80), + BUTTON_INK = colors.white, + FONT = colors.white, + UNKNOWN = Color(255,0,255), + WINDOW_BG = colors.lightBlackBackground +} + +local buttonState = { + [true] = { color = svColor.BUTTON_ACTIVE }, + [false] = { color = svColor.BUTTON_INACTIVE } +} + +local draw_vertical_lines = false +local draw_out_range_labels = false +local draw_uninhabited_labels = true +local automatic_system_selection = true +local lock_hyperspace_target = false + +local function mainMenuButton(icon, tooltip) + return ui.coloredSelectedIconButton(icon, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_ACTIVE, svColor.BUTTON_INK, tooltip) +end + +local function textIcon(icon, tooltip) + ui.icon(icon, textIconSize, svColor.FONT, tooltip) end local sectorView local onGameStart = function () - --connect to class SectorView + -- connect to class SectorView sectorView = Game.sectorView + -- connect hyper jump planner to class SectorView + hyperJumpPlanner.setSectorView(sectorView) + -- update visibility states + sectorView:SetAutomaticSystemSelection(automatic_system_selection) + sectorView:SetDrawOutRangeLabels(draw_out_range_labels) + sectorView:SetDrawUninhabitedLabels(draw_uninhabited_labels) + sectorView:SetDrawVerticalLines(draw_vertical_lines) +end + + +local function newWindow(name) + return { + size = Vector2(0.0, 0.0), + pos = Vector2(0.0, 0.0), + visible = true, + name = name, + style_colors = {["WindowBg"] = svColor.WINDOW_BG}, + params = {"NoTitleBar", "AlwaysAutoResize", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "NoSavedSettings"} + } end -local function showSystemInfo(label, current_systempath, systempath, othersystempath) +-- all windows in this view +local Windows = { + current = newWindow("SectorMapCurrentSystem"), -- current system string + hjPlanner = newWindow("HyperJumpPlanner"), -- hyper jump planner + systemInfo = newWindow("SectorMapSystemInfo"), -- selected system information + searchBar = newWindow("SectorMapSearchBar"), + edgeButtons = newWindow("SectorMapEdgeButtons"), + factions = newWindow("SectorMapFactions") +} + +function Windows.systemInfo.Show() + local label = lc.SELECTED_SYSTEM + local current_systempath = sectorView:GetCurrentSystemPath() + local systempath = sectorView:GetSelectedSystemPath() if systempath then local starsystem = systempath:GetStarSystem() local clicked = false @@ -40,9 +104,21 @@ local function showSystemInfo(label, current_systempath, systempath, othersystem local jumpData = "" if not current_systempath:IsSameSystem(systempath) then local jumpStatus, distance, fuelRequired, duration = player:GetHyperspaceDetails(current_systempath, systempath) - jumpData = "\n" .. jumpStatus .. " " .. string.format("%.2f", distance) .. lc.UNIT_LY .. " " .. fuelRequired .. lc.UNIT_TONNES .. " " .. ui.Format.Duration(duration, 2) + jumpData = jumpStatus .. " " .. string.format("%.2f", distance) .. lc.UNIT_LY .. " " .. fuelRequired .. lc.UNIT_TONNES .. " " .. ui.Format.Duration(duration, 2) end - if ui.collapsingHeader(label .. ': ' .. starsystem.name .. ' ' .. jumpData .. " (" .. math.floor(systempath.sectorX) .. ", " .. math.floor(systempath.sectorY) .. ", " .. math.floor(systempath.sectorZ) .. ")", { "DefaultOpen" }) then + textIcon(icons.info) + ui.sameLine() + ui.text(starsystem.name .. " (" .. math.floor(systempath.sectorX) .. ", " .. math.floor(systempath.sectorY) .. ", " .. math.floor(systempath.sectorZ) .. ")") + if not sectorView:IsCenteredOn(systempath) then + -- add button to center on the object + ui.sameLine() + if ui.coloredSelectedIconButton(icons.maneuver, textIconSize, false, 0, svColor.WINDOW_BG, svColor.FONT, lui.CENTER_ON_SYSTEM) then + sectorView:GotoSystemPath(systempath) + end + end + ui.separator() + ui.text(jumpData) + ui.separator() local stars = starsystem:GetStars() for _,star in pairs(stars) do if ui.selectable(star.name, star.path == systempath, {}) then @@ -50,9 +126,16 @@ local function showSystemInfo(label, current_systempath, systempath, othersystem end end if clicked then - sectorView:SetSelected(clicked) - sectorView:GotoSystemPath(clicked) + sectorView:SwitchToPath(clicked) end + + -- check if the selected star has changed + if systempath ~= prevSystemPath then + -- if so, check the route, and update there if necessary + hyperJumpPlanner.updateInRoute(systempath) + prevSystemPath = systempath + end + local numstars = starsystem.numberOfStars local numstarstext = "" if numstars == 4 then @@ -68,27 +151,46 @@ local function showSystemInfo(label, current_systempath, systempath, othersystem if next(starsystem.other_names) ~= nil then ui.text(table.concat(starsystem.other_names, ", ")) end - ui.text(starsystem.shortDescription) - if othersystempath and not othersystempath:IsSameSystem(systempath) then - local otherstarsystem = othersystempath:GetStarSystem() - local jumpStatus, distance, fuelRequired, duration = player:GetHyperspaceDetails(systempath, othersystempath) - ui.text('Relative to ' .. otherstarsystem.name .. ': ' .. jumpStatus .. " " .. string.format("%.2f", distance) .. lc.UNIT_LY .. " " .. fuelRequired .. lc.UNIT_TONNES .. " " .. ui.Format.Duration(duration, 2)) - end - end - end) - end + ui.pushTextWrapPos(ui.getContentRegion().x) + ui.textWrapped(starsystem.shortDescription) + ui.popTextWrapPos() + end) + end +end + +function Windows.systemInfo.Dummy() + textIcon(icons.sun) + ui.sameLine() + ui.text("Selected system") + ui.separator() + ui.text("Distance") + ui.selectable("Star 1", false, {}) + ui.selectable("Star 2", false, {}) + ui.selectable("Star 3", false, {}) + ui.selectable("Star 4", false, {}) + ui.text("Three\nline\ndescription") + -- let's count a row of 6 buttons so that it is as in the system map + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() + mainMenuButton(icons.reset_view, "DUMMY") + ui.sameLine() end +local prevSystemPath = nil + local search_text = "" -local draw_vertical_lines = false -local draw_out_range_labels = false -local draw_uninhabited_labels = true -local automatic_system_selection = true -local lock_hyperspace_target = false -local initialized local function showSettings() - if ui.collapsingHeader("Settings", { "DefaultOpen" }) then local changed changed, draw_vertical_lines = ui.checkbox(lc.DRAW_VERTICAL_LINES, draw_vertical_lines) if changed then @@ -106,6 +208,34 @@ local function showSettings() if changed then sectorView:SetAutomaticSystemSelection(automatic_system_selection) end + -- end +end + +function Windows.edgeButtons.Show() + -- view control buttons + if mainMenuButton(icons.reset_view, lc.RESET_ORIENTATION_AND_ZOOM) then + sectorView:ResetView() + end + mainMenuButton(icons.rotate_view, lui.ROTATE_VIEW) + sectorView:SetRotateMode(ui.isItemActive()) + mainMenuButton(icons.search_lens, lui.ZOOM) + sectorView:SetZoomMode(ui.isItemActive()) + ui.text("") + -- settings buttons + if mainMenuButton(icons.settings, lui.SETTINGS) then + ui.openPopup("sectorViewLabelSettings") + end + ui.popup("sectorViewLabelSettings", function() + showSettings() + end) + if ui.coloredSelectedIconButton(icons.shield_other, mainButtonSize, false, mainButtonFramePadding, buttonState[Windows.factions.visible].color, svColor.BUTTON_INK, "Factions") then + Windows.factions.visible = not Windows.factions.visible + end + if ui.coloredSelectedIconButton(icons.info, mainButtonSize, false, mainButtonFramePadding, buttonState[Windows.systemInfo.visible].color, svColor.BUTTON_INK, lc.OBJECT_INFO) then + Windows.systemInfo.visible = not Windows.systemInfo.visible + end + if ui.coloredSelectedIconButton(icons.route, mainButtonSize, false, mainButtonFramePadding, buttonState[Windows.hjPlanner.visible].color, svColor.BUTTON_INK, lui.HYPERJUMP_ROUTE) then + Windows.hjPlanner.visible = not Windows.hjPlanner.visible end end @@ -131,7 +261,7 @@ local function getHyperspaceDetails(path) return it.jumpStatus, it.distance, it.fuelRequired, it.duration end -local function showSearch() +function Windows.searchBar.Show() ui.text(lc.SEARCH) search_text, changed = ui.inputText("", search_text, {}) if search_text ~= "" then @@ -159,65 +289,40 @@ local function showSearch() local system = item.path:GetStarSystem() local label = system.name label = label .. ' (' .. lui[item.jumpStatus] .. "), " .. string.format("%.2f", item.distance) .. lc.UNIT_LY .. ", " .. item.fuelRequired .. lc.UNIT_TONNES .. ", " .. ui.Format.Duration(item.duration, 2) - if ui.selectable(label, false, {}) then - sectorView:SetSelected(item.path) - sectorView.GotoSystemPath(item.path) + sectorView:SwitchToPath(item.path) end end end) end + -- calulating window size for next frame to fit some search results + Windows.searchBar.size.y = Windows.searchBar.emptyHeight + math.min(#systempaths, MAX_SEARCH_STRINGS_VISIBLE) * ui.calcTextSize("ONE LINE").y end + else + -- calulating window size for the next frame for no search results + Windows.searchBar.size.y = Windows.searchBar.emptyHeight end end -local function showInfoWindow() - ui.withStyleColors({["WindowBg"] = colors.lightBlackBackground}, function() - ui.window("MapSectorViewInfo", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "HorizontalScrollbar"}, - function() - ui.text(string.format("%.2f", sectorView:GetZoomLevel()) .. lc.UNIT_LY) - ui.sameLine() - local zoom_in = mainMenuButton(icons.zoom_in, false, "Zoom in") - if zoom_in or ui.isItemActive() then - sectorView:ZoomIn() - end - ui.sameLine() - local zoom_out = mainMenuButton(icons.zoom_out, false, "Zoom out") - if zoom_out or ui.isItemActive() then - sectorView:ZoomOut() - end - ui.separator() - local sector = sectorView:GetCenterSector() - local distance = sectorView:GetCenterDistance() - ui.text("Sector (" .. math.floor(sector.x) .. ", " .. math.floor(sector.y) .. ", " .. math.floor(sector.z) .. "), Distance " .. string.format("%.2f", distance) .. lc.UNIT_LY) - ui.separator() - local current = sectorView:GetCurrentSystemPath() - local selected = sectorView:GetSelectedSystemPath() - local hyperspaceTarget = sectorView:GetHyperspaceTargetSystemPath() - - showSystemInfo(lc.CURRENT_SYSTEM, current, current) - ui.separator() - showSystemInfo(lc.HYPERSPACE_TARGET, current, hyperspaceTarget, selected) - local changed, lht = ui.checkbox(lock_hyperspace_target and lc.LOCKED or lc.FOLLOWING_SELECTION, lock_hyperspace_target) - lock_hyperspace_target = lht - if changed then - sectorView:SetLockHyperspaceTarget(lock_hyperspace_target) - end - ui.separator() - showSystemInfo(lc.SELECTED_SYSTEM, current, selected) - ui.separator() - showSettings() - ui.separator() - showSearch() - end) - end) +function Windows.searchBar.Dummy() + ui.text("***************") + ui.inputText("", "", {}) + ui.text("***************") end -local function showFactionLegendWindow() - ui.setNextWindowSize(Vector2(ui.screenWidth / 5, ui.screenHeight / 5), "Always") - ui.setNextWindowPos(Vector2(ui.screenWidth - ui.screenWidth / 5 - 10, 10) , "Always") - ui.window("MapSectorViewFactions", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus"}, - function() +function Windows.current.Show() + local path = sectorView:GetCurrentSystemPath() + local starsystem = path:GetStarSystem() + textIcon(icons.display_navtarget) + ui.sameLine() + if ui.selectable(' ' .. starsystem.name .. " (" .. path.sectorX .. ", " .. path.sectorY .. ", " .. path.sectorZ .. ")") then + sectorView:SwitchToPath(path) + end +end + +function Windows.factions.Show() + textIcon(icons.shield) + ui.sameLine() ui.text("Factions") local factions = sectorView:GetFactions() for _,f in pairs(factions) do @@ -229,28 +334,75 @@ local function showFactionLegendWindow() sectorView:SetFactionVisible(f.faction, value) end end - end) end +Windows.hjPlanner.Show = hyperJumpPlanner.display +Windows.hjPlanner.Dummy = hyperJumpPlanner.Dummy + +local function showWindow(w) + ui.setNextWindowSize(w.size, "Always") + ui.setNextWindowPos(w.pos, "Always") + ui.withStyleColors(w.style_colors, function() ui.window(w.name, w.params, w.Show) end) +end + +local dummyFrames = 3 + local function displaySectorViewWindow() - if not initialized then - sectorView:SetAutomaticSystemSelection(automatic_system_selection) - sectorView:SetDrawOutRangeLabels(draw_out_range_labels) - sectorView:SetDrawUninhabitedLabels(draw_uninhabited_labels) - sectorView:SetDrawVerticalLines(draw_vertical_lines) - initialized = true - end player = Game.player - local current_view = Game.CurrentView() - if current_view == "sector" then - ui.setNextWindowSize(Vector2(ui.screenWidth / 5, ui.screenHeight / 3 * 2.1), "Always") - ui.setNextWindowPos(Vector2(10, 10) , "Always") - if ui.isKeyReleased(ui.keys.tab) then - hideSectorViewWindows = not hideSectorViewWindows; - end - if not hideSectorViewWindows then - showInfoWindow() - showFactionLegendWindow() + if Game.CurrentView() == "sector" then + if dummyFrames > 0 then -- do it a few frames, because imgui need a few frames to make the correct window size + + -- first, doing some one-time actions here + -- calculating in-text icon size for used font size + if not textIconSize then + ui.withFont(font, function() + textIconSize = ui.calcTextSize("H") + textIconSize.x = textIconSize.y -- make square + end) + edgePadding = textIconSize + end + + -- measuring windows (or dummies) + ui.withFont(font, function() + for _,w in pairs(Windows) do + ui.setNextWindowPos(Vector2(ui.screenWidth, 0.0), "Always") + ui.window(w.name, w.params, function() + if w.Dummy then w.Dummy() + else w.Show() + end + w.size = ui.getWindowSize() + end) + end + end) + + -- make final calculations on the last non-working frame + if dummyFrames == 1 then + -- resizing, aligning windows - static + Windows.current.pos = edgePadding + Windows.current.size.x = 0 -- adaptive width + Windows.hjPlanner.size.x = math.max(Windows.hjPlanner.size.x, Windows.systemInfo.size.x - Windows.edgeButtons.size.x) + Windows.hjPlanner.pos = Vector2(ui.screenWidth - Windows.edgeButtons.size.x, ui.screenHeight - edgePadding.y) - Windows.hjPlanner.size + Windows.systemInfo.pos = Windows.hjPlanner.pos - Vector2(0, Windows.systemInfo.size.y) + Windows.systemInfo.size = Vector2(Windows.hjPlanner.size.x, 0) -- adaptive height + Windows.searchBar.pos = Windows.current.pos + Windows.current.size + Windows.searchBar.emptyHeight = Windows.searchBar.size.y + Windows.edgeButtons.pos = Vector2(ui.screenWidth - Windows.edgeButtons.size.x, ui.screenHeight / 2 - Windows.edgeButtons.size.y / 2) -- center-right + Windows.factions.pos = Vector2(Windows.systemInfo.pos.x, Windows.current.pos.y) + Windows.factions.size = Vector2(ui.screenWidth - Windows.factions.pos.x - edgePadding.x, 0.0) + end + dummyFrames = dummyFrames - 1 + else + if ui.isKeyReleased(ui.keys.tab) then + hideSectorViewWindows = not hideSectorViewWindows; + end + if not hideSectorViewWindows then + -- display all windows + ui.withFont(font, function() + for _,w in pairs(Windows) do + if w.visible then showWindow(w) end + end + end) + end end end end @@ -260,5 +412,15 @@ Event.Register("onGameStart", onGameStart) Event.Register("onLeaveSystem", function() hyperspaceDetailsCache = {} end) +-- events moved from hyperJumpPlanner +Event.Register("onGameEnd", + function(ship) + -- clear the route out so it doesn't show up if the user starts a new game + sectorView:ClearRoute() +end) +Event.Register("onEnterSystem", + function(ship) + hyperJumpPlanner.onEnterSystem(ship) +end) return {} diff --git a/src/SectorView.cpp b/src/SectorView.cpp index 7f33e58629e..da3cf9e6abc 100644 --- a/src/SectorView.cpp +++ b/src/SectorView.cpp @@ -291,7 +291,7 @@ void SectorView::FloatHyperspaceTarget() void SectorView::ResetHyperspaceTarget() { SystemPath old = m_hyperspaceTarget; - m_hyperspaceTarget = m_selected; + m_hyperspaceTarget = Pi::game->GetSpace()->GetStarSystem()->GetStars()[0]->GetPath(); FloatHyperspaceTarget(); if (!old.IsSameSystem(m_hyperspaceTarget)) { @@ -323,16 +323,34 @@ void SectorView::GotoSystem(const SystemPath &path) } } -void SectorView::SetSelected(const SystemPath &path) +bool SectorView::IsCenteredOn(const SystemPath &path) { - m_selected = path; + RefCountedPtr ps = GetCached(path); + const vector3f &p = ps->m_systems[path.systemIndex].GetPosition(); + vector3f diff = vector3f( + fabs(m_pos.x - path.sectorX - p.x / Sector::SIZE), + fabs(m_pos.y - path.sectorY - p.y / Sector::SIZE), + fabs(m_pos.z - path.sectorZ - p.z / Sector::SIZE)); + return ((diff.x < 0.005f && diff.y < 0.005f && diff.z < 0.005f)); +} - if (m_matchTargetToSelection && m_selected != m_current) { - m_hyperspaceTarget = m_selected; - onHyperspaceTargetChanged.emit(); +void SectorView::SetSelected(const SystemPath &path) +{ + if (path.IsBodyPath()) + m_selected = path; + else if (path.IsSystemPath()) { + RefCountedPtr system = m_galaxy->GetStarSystem(path); + m_selected = system->GetStars()[CheckIndexInRoute(path)]->GetPath(); } } +void SectorView::SwitchToPath(const SystemPath &path) +{ + SetSelected(path); + if (m_automaticSystemSelection) + GotoSystem(path); +} + void SectorView::SwapSelectedHyperspaceTarget() { SystemPath tmpTarget = GetHyperspaceTarget(); @@ -341,33 +359,26 @@ void SectorView::SwapSelectedHyperspaceTarget() GotoSystem(tmpTarget); } else { RefCountedPtr system = m_galaxy->GetStarSystem(tmpTarget); - SetSelected(system->GetStars()[0]->GetPath()); + SetSelected(system->GetStars()[CheckIndexInRoute(tmpTarget)]->GetPath()); } } void SectorView::OnClickSystem(const SystemPath &path) { - if (path.IsSameSystem(m_selected)) { - RefCountedPtr system = m_galaxy->GetStarSystem(path); - if (system->GetNumStars() > 1 && m_selected.IsBodyPath()) { - unsigned i; - for (i = 0; i < system->GetNumStars(); ++i) - if (system->GetStars()[i]->GetPath() == m_selected) break; - if (i >= system->GetNumStars() - 1) - SetSelected(system->GetStars()[0]->GetPath()); - else - SetSelected(system->GetStars()[i + 1]->GetPath()); - } else { - SetSelected(system->GetStars()[0]->GetPath()); - } - } else { - if (m_automaticSystemSelection) { - GotoSystem(path); - } else { - RefCountedPtr system = m_galaxy->GetStarSystem(path); - SetSelected(system->GetStars()[0]->GetPath()); + SwitchToPath(path); +} + +// check the route, maybe this system is there, then we'll take star number from there +// if single system, bodyindex = 0; if multisystem, bodyindex = (0 or 1),2 ... +int SectorView::CheckIndexInRoute(const SystemPath &path) +{ + for (auto &p : m_route) + if (p.IsSameSystem(path)) { + if (p.bodyIndex > 0) + return p.bodyIndex - 1; + return 0; } - } + return 0; } void SectorView::PutSystemLabels(RefCountedPtr sec, const vector3f &origin, int drawRadius) @@ -568,6 +579,11 @@ bool SectorView::MoveRouteItemDown(const std::vector::size_type elem return true; } +void SectorView::UpdateRouteItem(const std::vector::size_type element, const SystemPath &path) +{ + m_route[element] = path; +} + void SectorView::AddToRoute(const SystemPath &path) { m_route.push_back(path); @@ -717,7 +733,7 @@ void SectorView::AutoRoute(const SystemPath &start, const SystemPath &target, st outRoute.reserve(nodes.size()); // Build the route, in reverse starting with the target while (u != 0) { - outRoute.push_back(nodes[u]); + outRoute.push_back(m_galaxy->GetStarSystem(nodes[u])->GetStars()[0]->GetPath()); u = path_prev[u]; } std::reverse(std::begin(outRoute), std::end(outRoute)); @@ -802,9 +818,10 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const if (toCentreOfView.Length() > OUTER_RADIUS) continue; const bool bIsCurrentSystem = i->IsSameSystem(m_current); + const bool bInRoute = std::find_if(m_route.begin(), m_route.end(), [i](const SystemPath &a) -> bool { return i->IsSameSystem(a); }) != m_route.end(); // if the system is the current system or target we can't skip it - bool can_skip = !i->IsSameSystem(m_selected) && !i->IsSameSystem(m_hyperspaceTarget) && !bIsCurrentSystem; + bool can_skip = !i->IsSameSystem(m_selected) && !i->IsSameSystem(m_hyperspaceTarget) && !bIsCurrentSystem && !bInRoute; // if the system belongs to a faction we've chosen to temporarily hide // then skip it if we can @@ -863,29 +880,24 @@ void SectorView::DrawNearSector(const int sx, const int sy, const int sz, const } if (i->IsSameSystem(m_selected)) { - if (m_selected != m_current) { + if (m_selected != m_current && !bInRoute) { m_selectedLine.SetStart(vector3f(0.f, 0.f, 0.f)); m_selectedLine.SetEnd(playerAbsPos - sysAbsPos); m_selectedLine.Draw(m_renderer, m_solidState); - } else { } - if (m_selected != m_hyperspaceTarget) { - RefCountedPtr hyperSec = GetCached(m_hyperspaceTarget); + + if (m_route.size() > 0) { + const SystemPath &routeBack = m_route.back(); + if (!bInRoute) { + RefCountedPtr backSec = GetCached(routeBack); const vector3f hyperAbsPos = - Sector::SIZE * vector3f(m_hyperspaceTarget.sectorX, m_hyperspaceTarget.sectorY, m_hyperspaceTarget.sectorZ) + hyperSec->m_systems[m_hyperspaceTarget.systemIndex].GetPosition(); + Sector::SIZE * vector3f(routeBack.sectorX, routeBack.sectorY, routeBack.sectorZ) + backSec->m_systems[routeBack.systemIndex].GetPosition(); if (m_selected != m_current) { m_secondLine.SetStart(vector3f(0.f, 0.f, 0.f)); m_secondLine.SetEnd(hyperAbsPos - sysAbsPos); m_secondLine.Draw(m_renderer, m_solidState); } - - if (m_hyperspaceTarget != m_current) { - // FIXME: Draw when drawing hyperjump target or current system - m_jumpLine.SetStart(hyperAbsPos - sysAbsPos); - m_jumpLine.SetEnd(playerAbsPos - sysAbsPos); - m_jumpLine.Draw(m_renderer, m_solidState); - } - } else { + } } } @@ -1104,13 +1116,24 @@ void SectorView::Update() if (KeyBindings::mapViewRotateDown.IsActive()) m_rotXMovingTo += 0.5f * moveSpeed; } - if (Pi::input->MouseButtonState(SDL_BUTTON_RIGHT)) { + // to capture mouse when button was pressed and release when released + if (Pi::input->MouseButtonState(SDL_BUTTON_MIDDLE) != m_rotateWithMouseButton) { + m_rotateWithMouseButton = !m_rotateWithMouseButton; + Pi::input->SetCapturingMouse(m_rotateWithMouseButton); + } + + if (m_rotateWithMouseButton || m_rotateView) { int motion[2]; Pi::input->GetMouseMotion(motion); - m_rotXMovingTo += 0.2f * float(motion[1]); m_rotZMovingTo += 0.2f * float(motion[0]); } + else if (m_zoomView) { + Pi::input->SetCapturingMouse(true); + int motion[2]; + Pi::input->GetMouseMotion(motion); + m_zoomMovingTo += ZOOM_SPEED * 0.002f * motion[1]; + } m_rotXMovingTo = Clamp(m_rotXMovingTo, -170.0f, -10.0f); @@ -1169,7 +1192,7 @@ void SectorView::Update() if (!m_selected.IsSameSystem(new_selected)) { RefCountedPtr system = m_galaxy->GetStarSystem(new_selected); - SetSelected(system->GetStars()[0]->GetPath()); + SetSelected(system->GetStars()[CheckIndexInRoute(new_selected)]->GetPath()); } } } @@ -1331,3 +1354,27 @@ void SectorView::SetFactionVisible(const Faction *faction, bool visible) m_hiddenFactions.insert(faction); m_toggledFaction = true; } + +void SectorView::SetZoomMode(bool enable) +{ + if (enable != m_zoomView) { + Pi::input->SetCapturingMouse(enable); + m_zoomView = enable; + if (m_zoomView) m_rotateView = false; + } +} + +void SectorView::SetRotateMode(bool enable) { + if (enable != m_rotateView) { + Pi::input->SetCapturingMouse(enable); + m_rotateView = enable; + if (m_rotateView) m_zoomView = false; + } +} + +void SectorView::ResetView() { + GotoSystem(m_current); + m_rotXMovingTo = m_rotXDefault; + m_rotZMovingTo = m_rotZDefault; + m_zoomMovingTo = m_zoomDefault; +} diff --git a/src/SectorView.h b/src/SectorView.h index 66fe945d200..717722ccb64 100644 --- a/src/SectorView.h +++ b/src/SectorView.h @@ -33,7 +33,7 @@ class SectorView : public UIView, public DeleteEmitter { vector3f GetPosition() const { return m_pos; } SystemPath GetCurrent() const { return m_current; } SystemPath GetSelected() const { return m_selected; } - void SetSelected(const SystemPath &path); + void SwitchToPath(const SystemPath &path); SystemPath GetHyperspaceTarget() const { return m_hyperspaceTarget; } void SetHyperspaceTarget(const SystemPath &path); void FloatHyperspaceTarget(); @@ -45,6 +45,7 @@ class SectorView : public UIView, public DeleteEmitter { void GotoSelectedSystem() { GotoSystem(m_selected); } void GotoHyperspaceTarget() { GotoSystem(m_hyperspaceTarget); } void SwapSelectedHyperspaceTarget(); + bool IsCenteredOn(const SystemPath &path); virtual void SaveToJson(Json &jsonObj); sigc::signal onHyperspaceTargetChanged; @@ -62,10 +63,14 @@ class SectorView : public UIView, public DeleteEmitter { const std::set &GetVisibleFactions() { return m_visibleFactions; } const std::set &GetHiddenFactions() { return m_hiddenFactions; } void SetFactionVisible(const Faction *faction, bool visible); + void SetZoomMode(bool enable); + void SetRotateMode(bool enable); + void ResetView(); // HyperJump Route Planner bool MoveRouteItemUp(const std::vector::size_type element); bool MoveRouteItemDown(const std::vector::size_type element); + void UpdateRouteItem(const std::vector::size_type element, const SystemPath &path); void AddToRoute(const SystemPath &path); bool RemoveRouteItem(const std::vector::size_type element); void ClearRoute(); @@ -106,9 +111,11 @@ class SectorView : public UIView, public DeleteEmitter { void AddStarBillboard(const matrix4x4f &modelview, const vector3f &pos, const Color &col, float size); void OnClickSystem(const SystemPath &path); + int CheckIndexInRoute(const SystemPath &path); RefCountedPtr GetCached(const SystemPath &loc) { return m_sectorCache->GetCached(loc); } void ShrinkCache(); + void SetSelected(const SystemPath &path); void MouseWheel(bool up); void OnKeyPressed(SDL_Keysym *keysym); @@ -132,6 +139,10 @@ class SectorView : public UIView, public DeleteEmitter { float m_zoomClamped; float m_zoomMovingTo; + bool m_rotateWithMouseButton = false; + bool m_rotateView = false; + bool m_zoomView = false; + SystemPath m_hyperspaceTarget; bool m_matchTargetToSelection; bool m_automaticSystemSelection; diff --git a/src/SystemInfoView.cpp b/src/SystemInfoView.cpp index f2a3f7a6195..b99653b9112 100644 --- a/src/SystemInfoView.cpp +++ b/src/SystemInfoView.cpp @@ -12,8 +12,8 @@ #include "StringF.h" #include "galaxy/Factions.h" #include "galaxy/Galaxy.h" -#include "galaxy/SystemPath.h" #include "galaxy/Polit.h" +#include "galaxy/SystemPath.h" #include "graphics/Drawables.h" #include "graphics/Renderer.h" #include @@ -51,7 +51,7 @@ void SystemInfoView::OnBodySelected(SystemBody *b) if (body != 0) Pi::player->SetNavTarget(body); } else if (b->GetSuperType() == SystemBody::SUPERTYPE_STAR) { // We allow hyperjump to any star of the system - m_game->GetSectorView()->SetSelected(path); + m_game->GetSectorView()->SwitchToPath(path); } } @@ -201,12 +201,14 @@ void SystemInfoView::UpdateEconomyTab() for (int i = 1; i < GalacticEconomy::COMMODITY_COUNT; i++) { if (isInList(s->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i))) && s->IsCommodityLegal(GalacticEconomy::Commodity(i))) { - std::string extra = meh; // default color + std::string extra = meh; // default color std::string tooltip = ""; // no tooltip for default if (compareSelectedWithCurrent) { if (isInInterval(hs->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i)))) { - extra = colorInInterval; // change color - tooltip = toolTipInInterval; // describe trade status in current system + // change color + extra = colorInInterval; + // describe trade status in current system + tooltip = toolTipInInterval; } else if (isOther(hs->GetCommodityBasePriceModPercent(GalacticEconomy::Commodity(i)))) { extra = colorOther; tooltip = toolTipOther; @@ -545,8 +547,9 @@ SystemInfoView::RefreshType SystemInfoView::NeedsRefresh() } else { // No body was selected if (m_game->GetSectorView()->GetSelected().IsBodyPath()) - return REFRESH_SELECTED_BODY; // but now we want one, this can only be a star, - // so no check for IsShownInInfoView() needed + // but now we want one, this can only be a star, + // so no check for IsShownInInfoView() needed + return REFRESH_SELECTED_BODY; } } else { Body *navTarget = Pi::player->GetNavTarget(); diff --git a/src/lua/LuaSectorView.cpp b/src/lua/LuaSectorView.cpp index fa54a5ec7ad..a1be838ace5 100644 --- a/src/lua/LuaSectorView.cpp +++ b/src/lua/LuaSectorView.cpp @@ -44,16 +44,21 @@ void LuaObject::RegisterClass() .AddFunction("GetHyperspaceTargetSystemPath", &SectorView::GetHyperspaceTarget) .AddFunction("SetDrawUninhabitedLabels", &SectorView::SetDrawUninhabitedLabels) .AddFunction("AddToRoute", &SectorView::AddToRoute) - .AddFunction("SetSelected", &SectorView::SetSelected) + .AddFunction("SwitchToPath", &SectorView::SwitchToPath) .AddFunction("GotoSectorPath", &SectorView::GotoSector) .AddFunction("GotoSystemPath", &SectorView::GotoSystem) - .AddFunction("GetFactions", - [](lua_State *l, SectorView *sv) -> int { - const std::set visible = sv->GetVisibleFactions(); - const std::set hidden = sv->GetHiddenFactions(); - lua_newtable(l); // outer table - int i = 1; - for (const Faction *f : visible) { + .AddFunction("SetRotateMode", &SectorView::SetRotateMode) + .AddFunction("SetZoomMode", &SectorView::SetZoomMode) + .AddFunction("ResetView", &SectorView::ResetView) + .AddFunction("SetHyperspaceTarget", &SectorView::SetHyperspaceTarget) + .AddFunction("ResetHyperspaceTarget", &SectorView::ResetHyperspaceTarget) + .AddFunction("IsCenteredOn", &SectorView::IsCenteredOn) + .AddFunction("GetFactions", [](lua_State *l, SectorView *sv) -> int { + const std::set visible = sv->GetVisibleFactions(); + const std::set hidden = sv->GetHiddenFactions(); + lua_newtable(l); // outer table + int i = 1; + for (const Faction *f : visible) { lua_pushnumber(l, i++); lua_newtable(l); // inner table LuaObject::PushToLua(const_cast(f)); @@ -61,81 +66,72 @@ void LuaObject::RegisterClass() lua_pushboolean(l, hidden.count(f) == 0); lua_setfield(l, -2, "visible"); // inner table lua_settable(l, -3); // outer table - } - return 1; } - ) - .AddFunction("GetCenterSector", - [](lua_State *l, SectorView *sv) -> int { - LuaPush(l, vector3d(sv->GetCenterSector())); - return 1; - } - ) - .AddFunction("MoveRouteItemUp", - [](lua_State *l, SectorView *sv) -> int { - int element = LuaPull(l, 2); - // lua indexes start at 1 - element -= 1; - bool r = sv->MoveRouteItemUp(element); - LuaPush(l, r); - return 1; - } - ) - .AddFunction("MoveRouteItemDown", - [](lua_State *l, SectorView *sv) -> int { - int element = LuaPull(l, 2); - // lua indexes start at 1 - element -= 1; - bool r = sv->MoveRouteItemDown(element); - LuaPush(l, r); - return 1; - } - ) - .AddFunction("RemoveRouteItem", - [](lua_State *l, SectorView *sv) -> int { - int element = LuaPull(l, 2); - // lua indexes start at 1 - element -= 1; - bool r = sv->RemoveRouteItem(element); - LuaPush(l, r); - return 1; - } - ) - .AddFunction("SearchNearbyStarSystemsByName", - [](lua_State *l, SectorView *sv) -> int { - std::string pattern = LuaPull(l, 2); - std::vector matches = sv->GetNearbyStarSystemsByName(pattern); - int i = 1; - lua_newtable(l); - for (const SystemPath &path : matches) { + return 1; + }) + .AddFunction("GetCenterSector", [](lua_State *l, SectorView *sv) -> int { + LuaPush(l, vector3d(sv->GetCenterSector())); + return 1; + }) + .AddFunction("MoveRouteItemUp", [](lua_State *l, SectorView *sv) -> int { + int element = LuaPull(l, 2); + // lua indexes start at 1 + element -= 1; + bool r = sv->MoveRouteItemUp(element); + LuaPush(l, r); + return 1; + }) + .AddFunction("MoveRouteItemDown", [](lua_State *l, SectorView *sv) -> int { + int element = LuaPull(l, 2); + // lua indexes start at 1 + element -= 1; + bool r = sv->MoveRouteItemDown(element); + LuaPush(l, r); + return 1; + }) + .AddFunction("RemoveRouteItem", [](lua_State *l, SectorView *sv) -> int { + int element = LuaPull(l, 2); + // lua indexes start at 1 + element -= 1; + bool r = sv->RemoveRouteItem(element); + LuaPush(l, r); + return 1; + }) + .AddFunction("UpdateRouteItem", [](lua_State *l, SectorView *sv) -> int { + int element = LuaPull(l, 2) - 1; + SystemPath *path = LuaObject::CheckFromLua(3); + sv->UpdateRouteItem(element, path); + return 0; + }) + .AddFunction("SearchNearbyStarSystemsByName", [](lua_State *l, SectorView *sv) -> int { + std::string pattern = LuaPull(l, 2); + std::vector matches = sv->GetNearbyStarSystemsByName(pattern); + int i = 1; + lua_newtable(l); + for (const SystemPath &path : matches) { lua_pushnumber(l, i++); LuaObject::PushToLua(path); lua_settable(l, -3); - } - return 1; - } - ) - .AddFunction("GetRouteSize", - [](lua_State *l, SectorView *sv) -> int { - std::vector route = sv->GetRoute(); - const int size = route.size(); - LuaPush(l, size); - return 1; } - ) - .AddFunction("AutoRoute", - [](lua_State *l, SectorView *sv) { - SystemPath current_path = sv->GetCurrent(); - SystemPath target_path = sv->GetSelected(); - std::vector route; - sv->AutoRoute(current_path, target_path, route); - sv->ClearRoute(); - for (auto it = route.begin(); it != route.end(); it++) { + return 1; + }) + .AddFunction("GetRouteSize", [](lua_State *l, SectorView *sv) -> int { + std::vector route = sv->GetRoute(); + const int size = route.size(); + LuaPush(l, size); + return 1; + }) + .AddFunction("AutoRoute", [](lua_State *l, SectorView *sv) { + SystemPath current_path = sv->GetCurrent(); + SystemPath target_path = sv->GetSelected(); + std::vector route; + sv->AutoRoute(current_path, target_path, route); + sv->ClearRoute(); + for (auto it = route.begin(); it != route.end(); it++) { sv->AddToRoute(*it); - } - return l_sectorview_get_route(l, sv); } - ) + return l_sectorview_get_route(l, sv); + }) .AddFunction("GetRoute", &l_sectorview_get_route) .StopRecording(); LuaObjectBase::CreateClass(&metaType);