Merge pull request #4821 from Gliese852/ecraven-systemview-squashed

Move the System Map to PiGUI (#4821)
master
Webster Sheets 2020-04-04 15:53:12 -04:00 committed by GitHub
commit 8e31d169ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1643 additions and 762 deletions

View File

@ -16,7 +16,7 @@
viewBox="0 0 3628.3465 3628.3464"
id="svg4446"
version="1.1"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="icons.svg">
<defs
id="defs4448">
@ -881,16 +881,16 @@
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.1767767"
inkscape:cx="1429.7092"
inkscape:cy="1859.5164"
inkscape:zoom="0.25000001"
inkscape:cx="2379.8651"
inkscape:cy="2002.5917"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1850"
inkscape:window-height="1057"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-width="1853"
inkscape:window-height="1016"
inkscape:window-x="67"
inkscape:window-y="27"
inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true"
@ -943,7 +943,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -9014,5 +9014,29 @@
id="rect7847"
style="fill:none;stroke:none;stroke-width:10.69061661;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:10.69061666, 21.38123329;stroke-dashoffset:0" />
</g>
<g
inkscape:label="rotate_view"
transform="translate(-4762.2048,1133.8583)"
id="g2225">
<rect
style="opacity:1;fill:none;fill-opacity:1;stroke:none;stroke-width:21.25984192;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.5151515"
id="rect2223"
width="226.77151"
height="226.77162"
x="8163.7798"
y="-2575.9844" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:14.17322826;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
d="m 8203.6641,-2505.9607 -28.4385,-0.4182 49.7674,65.2412 56.877,-63.5684 -35.9663,-0.8364 c 0,0 8.0177,-38.3618 43.3419,-41.9946 28.4386,4.1822 18.5537,47.4314 18.5537,47.4314 0,0 7.1096,-5.4369 17.9831,-5.0187 10.8736,0.4183 15.8922,11.9192 15.8922,11.9192 0,0 4.182,-23.2109 -4.1822,-37.8484 -8.3642,-14.6374 -28.4385,-31.7841 -53.5313,-30.5295 -25.0928,1.2547 -44.3307,4.1821 -62.3138,23.8382 -14.6375,18.8196 -17.9832,31.7842 -17.9832,31.7842 z"
id="path2227"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccc" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:14.17322826;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
d="m 8234.8718,-2421.3714 50.2389,63.6822 0.3823,-35.7724 c 40.2329,6.163 71.2869,1.8276 85.669,-13.457 14.3821,-15.2847 15.0115,-40.8195 5.6423,-57.6389 -9.3693,-16.8194 -32.0947,-21.798 -32.0947,-21.798 0,0 6.1707,10.9709 6.3568,20.8718 0.1827,9.7237 -10.2431,16.3492 -10.2431,16.3492 0,0 17.5122,1.9115 20.8358,3.4682 3.3236,1.5567 5.762,1.9039 -0.5228,7.4519 -6.2848,5.548 -41.2332,12.4421 -74.9406,2.6361 l 0.8277,-38.7801 z"
id="path2231"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccczzcsczzccc" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 717 KiB

After

Width:  |  Height:  |  Size: 719 KiB

View File

@ -167,6 +167,10 @@
"description": "",
"message": "Cargo scoop attempted. Not enough room in cargo hold."
},
"CENTER": {
"description": "",
"message": "Center"
},
"CH4_ATMOSPHERE": {
"description": "",
"message": "\" Methane atmosphere\""
@ -1091,6 +1095,10 @@
"description": "",
"message": "Orbital starport"
},
"ORBIT_PLANNER": {
"description": "",
"message": "Orbit planner"
},
"OUTDOOR_AGRICULTURAL_WORLD": {
"description": "",
"message": "Outdoor agricultural world."
@ -1323,6 +1331,14 @@
"description": "",
"message": "Semi-major axis"
},
"SET_AS_COMBAT_TARGET": {
"description": "",
"message": "Set as combat target"
},
"SET_AS_TARGET": {
"description": "",
"message": "Set as navigation target"
},
"SET_HYPERSPACE_DESTINATION_TO": {
"description": "",
"message": "Set hyperspace destination to %system"

View File

@ -263,6 +263,10 @@
"description": "Player combat rating",
"message": "Deadly"
},
"DECREASE": {
"description": "Decrease something.",
"message": "Decrease"
},
"DELTA_V": {
"description": "",
"message": "Delta-v"
@ -963,6 +967,10 @@
"description": "For player reputation",
"message": "Incompetent"
},
"INCREASE": {
"description": "Increase something.",
"message": "Increase"
},
"INEXPERIENCED": {
"description": "For player reputation",
"message": "Inexperienced"
@ -1531,6 +1539,10 @@
"description": "",
"message": "Reward"
},
"ROTATE_VIEW": {
"description": "",
"message": "Rotate view"
},
"ROUTE_INFO": {
"description": "For hyperjump planner",
"message": "Route Info"
@ -1627,6 +1639,10 @@
"description": "",
"message": "Ship Repairs"
},
"SHIP_TYPE": {
"description": "",
"message": "Ship Type"
},
"SHIP_VIEWING_WAS_SOLD": {
"description": "",
"message": "The ship you were viewing has been sold"

View File

@ -0,0 +1,516 @@
local Game = require 'Game'
local Engine = require 'Engine'
local Event = require 'Event'
local Lang = require 'Lang'
local ui = require 'pigui'
local Format = require 'Format'
local Input = require 'Input'
local Vector2 = _G.Vector2
local lc = Lang.GetResource("core")
local luc = Lang.GetResource("ui-core")
local player = nil
local colors = ui.theme.colors
local icons = ui.theme.icons
local systemView
local mainButtonSize = ui.rescaleUI(Vector2(32,32), Vector2(1600, 900))
local mainButtonFramePadding = 3
local itemSpacing = Vector2(8, 4) -- couldn't get default from ui
local indicatorSize = Vector2(30 , 30)
local selectedObject -- object, centered in SystemView
local pionillium = ui.fonts.pionillium
local ASTEROID_RADIUS = 1500000 -- rocky planets smaller than this (in meters) are considered an asteroid, not a planet
--load enums Projectable::types and Projectable::bases in one table "Projectable"
local Projectable = {}
for _, key in pairs(Constants.ProjectableTypes) do Projectable[key] = Engine.GetEnumValue("ProjectableTypes", key) end
for _, key in pairs(Constants.ProjectableBases) do Projectable[key] = Engine.GetEnumValue("ProjectableBases", key) end
local svColor = {
BUTTON_BACK = colors.buttonBlue,
BUTTON_INK = colors.white,
COMBAT_TARGET = colors.combatTarget,
GRID = Color(25,25,25),
LAGRANGE = Color(0,214,226),
NAV_TARGET = colors.navTarget,
OBJECT = colors.frame,
PLANNER = Color(0,0,255),
PLANNER_ORBIT = Color(0,0,255),
PLAYER = Color(255,0,0),
PLAYER_ORBIT = Color(255,0,0),
SELECTED_SHIP_ORBIT = Color(0,186,255),
SHIP = colors.frame,
SHIP_ORBIT = Color(0,0,155),
SYSTEMBODY = Color(109,109,134),
SYSTEMBODY_ICON = colors.frame,
SYSTEMBODY_ORBIT = Color(0,155,0),
SYSTEMNAME_BACK = colors.transparent,
WINDOW_BACK = colors.lightBlackBackground,
UNKNOWN = Color(255,0,255)
}
local onGameStart = function ()
--connect to class SystemView
systemView = Game.systemView
--export several colors to class SystemView (only those which mentioned in the enum SystemViewColorIndex)
for _, key in pairs(Constants.SystemViewColorIndex) do
systemView:SetColor(key, svColor[key])
end
end
local function showDvLine(leftIcon, resetIcon, rightIcon, key, Formatter, leftTooltip, resetTooltip, rightTooltip)
local wheel = function()
if ui.isItemHovered() then
local w = ui.getMouseWheel()
if w ~= 0 then
systemView:TransferPlannerAdd(key, w * 10)
end
end
end
local press = ui.coloredSelectedIconButton(leftIcon, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, leftTooltip)
if press or (key ~= "factor" and ui.isItemActive()) then
systemView:TransferPlannerAdd(key, -10)
end
wheel()
ui.sameLine()
if ui.coloredSelectedIconButton(resetIcon, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, resetTooltip) then
systemView:TransferPlannerReset(key)
end
wheel()
ui.sameLine()
press = ui.coloredSelectedIconButton(rightIcon, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, rightTooltip)
if press or (key ~= "factor" and ui.isItemActive()) then
systemView:TransferPlannerAdd(key, 10)
end
wheel()
ui.sameLine()
local speed, speed_unit = Formatter(systemView:TransferPlannerGet(key))
ui.text(speed .. " " .. speed_unit)
return 0
end
local time_selected_button_icon = icons.time_center
local function timeButton(icon, tooltip, factor)
if ui.coloredSelectedIconButton(icon, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, tooltip) then
time_selected_button_icon = icon
end
local active = ui.isItemActive()
if active then
systemView:AccelerateTime(factor)
end
ui.sameLine()
return active
end
local function loop3items(a, b, c) return { [a] = b, [b] = c, [c] = a } end
local ship_drawing = "SHIPS_OFF"
local show_lagrange = "LAG_OFF"
local show_grid = "GRID_OFF"
local nextShipDrawings = loop3items("SHIPS_OFF", "SHIPS_ON", "SHIPS_ORBITS")
local nextShowLagrange = loop3items("LAG_OFF", "LAG_ICON", "LAG_ICONTEXT")
local nextShowGrid = loop3items("GRID_OFF", "GRID_ON", "GRID_AND_LEGS")
local function calcWindowWidth(buttons)
return (mainButtonSize.y + mainButtonFramePadding * 2) * buttons
+ itemSpacing.x * (buttons + 1)
end
local function calcWindowHeight(buttons, separators, texts)
return
(mainButtonSize.y + mainButtonFramePadding * 2) * buttons
+ separators * itemSpacing.y
+ texts * ui.fonts.pionillium.medium.size
+ (buttons + texts - 1) * itemSpacing.y
+ itemSpacing.x * 2
end
local orbitPlannerWindowPos = Vector2(ui.screenWidth - calcWindowWidth(7), ui.screenHeight - calcWindowHeight(7, 3, 2))
local function showOrbitPlannerWindow()
ui.setNextWindowPos(orbitPlannerWindowPos, "Always")
ui.withStyleColors({["WindowBg"] = svColor.WINDOW_BACK}, function()
ui.window("OrbitPlannerWindow", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "NoSavedSettings", "AlwaysAutoResize"},
function()
ui.text(lc.ORBIT_PLANNER)
ui.separator()
if ui.coloredSelectedIconButton(icons.reset_view, mainButtonSize, showShips, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, lc.RESET_ORIENTATION_AND_ZOOM) then
systemView:SetVisibility("RESET_VIEW")
end
ui.sameLine()
if ui.coloredSelectedIconButton(icons.toggle_grid, mainButtonSize, showShips, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, lc.GRID_DISPLAY_MODE_TOGGLE) then
show_grid = nextShowGrid[show_grid]
systemView:SetVisibility(show_grid);
end
ui.sameLine()
if ui.coloredSelectedIconButton(icons.toggle_ships, mainButtonSize, showShips, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, lc.SHIPS_DISPLAY_MODE_TOGGLE) then
ship_drawing = nextShipDrawings[ship_drawing]
systemView:SetVisibility(ship_drawing);
end
ui.sameLine()
if ui.coloredSelectedIconButton(icons.toggle_lagrange, mainButtonSize, showLagrangePoints, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, lc.L4L5_DISPLAY_MODE_TOGGLE) then
show_lagrange = nextShowLagrange[show_lagrange]
systemView:SetVisibility(show_lagrange);
end
ui.sameLine()
ui.coloredSelectedIconButton(icons.search_lens,mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, luc.ZOOM)
systemView:SetZoomMode(ui.isItemActive())
ui.sameLine()
ui.coloredSelectedIconButton(icons.rotate_view, mainButtonSize, false, mainButtonFramePadding, svColor.BUTTON_BACK, svColor.BUTTON_INK, luc.ROTATE_VIEW)
systemView:SetRotateMode(ui.isItemActive())
ui.separator()
showDvLine(icons.decrease, icons.delta, icons.increase, "factor", function(i) return i, "x" end, luc.DECREASE, lc.PLANNER_RESET_FACTOR, luc.INCREASE)
showDvLine(icons.decrease, icons.clock, icons.increase, "starttime",
function(i)
local now = Game.time
local start = systemView:GetOrbitPlannerStartTime()
if start then
return ui.Format.Duration(math.floor(start - now)), ""
else
return lc.NOW, ""
end
end,
luc.DECREASE, lc.PLANNER_RESET_START, luc.INCREASE)
showDvLine(icons.decrease, icons.orbit_prograde, icons.increase, "prograde", ui.Format.Speed, luc.DECREASE, lc.PLANNER_RESET_PROGRADE, luc.INCREASE)
showDvLine(icons.decrease, icons.orbit_normal, icons.increase, "normal", ui.Format.Speed, luc.DECREASE, lc.PLANNER_RESET_NORMAL, luc.INCREASE)
showDvLine(icons.decrease, icons.orbit_radial, icons.increase, "radial", ui.Format.Speed, luc.DECREASE, lc.PLANNER_RESET_RADIAL, luc.INCREASE)
ui.separator()
local t = systemView:GetOrbitPlannerTime()
ui.text(t and ui.Format.Datetime(t) or lc.NOW)
local r = false
r = timeButton(icons.time_backward_100x, "-10,000,000x",-10000000) or r
r = timeButton(icons.time_backward_10x, "-100,000x", -100000) or r
r = timeButton(icons.time_backward_1x, "-1,000x", -1000) or r
r = timeButton(icons.time_center, lc.NOW, nil) or r
r = timeButton(icons.time_forward_1x, "1,000x", 1000) or r
r = timeButton(icons.time_forward_10x, "100,000x", 100000) or r
r = timeButton(icons.time_forward_100x, "10,000,000x", 10000000) or r
if not r then
if time_selected_button_icon == icons.time_center then
systemView:AccelerateTime(nil)
else
systemView:AccelerateTime(0.0)
end
end
end)
end)
end
local function getBodyIcon(obj)
if obj.type == Projectable.APOAPSIS then return icons.apoapsis
elseif obj.type == Projectable.PERIAPSIS then return icons.periapsis
elseif obj.type == Projectable.L4 then return icons.lagrange_marker
elseif obj.type == Projectable.L5 then return icons.lagrange_marker
elseif obj.base == Projectable.PLAYER or obj.base == Projectable.PLANNER then
local shipClass = obj.ref:GetShipClass()
if icons[shipClass] then
return icons[shipClass]
else
return icons.ship
end
elseif obj.base == Projectable.SYSTEMBODY then
local body = obj.ref
local st = body.superType
local t = body.type
if st == "STARPORT" then
if t == "STARPORT_ORBITAL" then
return icons.spacestation
elseif body.type == "STARPORT_SURFACE" then
return icons.starport
end
elseif st == "GAS_GIANT" then
return icons.gas_giant
elseif st == "STAR" then
return icons.sun
elseif st == "ROCKY_PLANET" then
if body.IsMoon then
return icons.moon
else
if body.radius < ASTEROID_RADIUS then
return icons.asteroid_hollow
else
return icons.rocky_planet
end
end
end -- st
else
-- physical body
local body = obj.ref
if body:IsShip() then
local shipClass = body:GetShipClass()
if icons[shipClass] then
return icons[shipClass]
else
print("system-view-ui.lua: getBodyIcon unknown ship class " .. (shipClass and shipClass or "nil"))
return icons.ship -- TODO: better icon
end
elseif body:IsHyperspaceCloud() then
return icons.hyperspace -- TODO: better icon
elseif body:IsMissile() then
return icons.bullseye -- TODO: better icon
elseif body:IsCargoContainer() then
return icons.rocky_planet -- TODO: better icon
else
print("system-view-ui.lua: getBodyIcon not sure how to process body, supertype: " .. (st and st or "nil") .. ", type: " .. (t and t or "nil"))
--utils.print_r(body)
return icons.ship
end
end
end
local function getLabel(obj)
if obj.type == Projectable.OBJECT then
if obj.base == Projectable.SYSTEMBODY then return obj.ref.name
elseif obj.base == Projectable.PLANNER then return ""
else return obj.ref:GetLabel() end
elseif obj.type == Projectable.L4 and show_lagrange == "LAG_ICONTEXT" then return "L4"
elseif obj.type == Projectable.L5 and show_lagrange == "LAG_ICONTEXT" then return "L5"
else return ""
end
end
local function getColor(obj)
if obj.type == Projectable.OBJECT then
if obj.base == Projectable.SYSTEMBODY then return svColor.SYSTEMBODY_ICON
elseif obj.base == Projectable.SHIP then return svColor.SHIP
elseif obj.base == Projectable.PLAYER then return svColor.PLAYER
elseif obj.base == Projectable.PLANNER then return svColor.PLANNER
else return svColor.OBJECT
end
elseif obj.type == Projectable.APOAPSIS or obj.type == Projectable.PERIAPSIS then
if obj.base == Projectable.SYSTEMBODY then return svColor.SYSTEMBODY_ORBIT
elseif obj.base == Projectable.SHIP then
if obj.ref == selectedObject then return svColor.SELECTED_SHIP_ORBIT
else return svColor.SHIP_ORBIT
end
elseif obj.base == Projectable.PLAYER then return svColor.PLAYER_ORBIT
elseif obj.base == Projectable.PLANNER then return svColor.PLANNER_ORBIT
else return svColor.UNKNOWN -- unknown base
end
elseif obj.type == Projectable.L4 or obj.type == Projectable.L5 then return svColor.LAGRANGE
else return svColor.UNKNOWN
end
end
local function showSystemName()
ui.setNextWindowPos(Vector2(20, 20), "Always")
ui.withStyleColors({["WindowBg"] = svColor.SYSTEMNAME_BACK}, function()
ui.window("SystemName", {"NoTitleBar", "AlwaysAutoResize", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "NoSavedSettings"},
function()
local path = Engine.GetSectorMapSelectedSystemPath()
local starsystem = path:GetStarSystem()
ui.text(starsystem.name .. " (" .. path.sectorX .. ", " .. path.sectorY .. ", " .. path.sectorZ .. ")")
end)
end)
end
-- forked from data/pigui/views/game.lua
local function displayOnScreenObjects()
local navTarget = player:GetNavTarget()
local combatTarget = player:GetCombatTarget()
local should_show_label = ui.shouldShowLabels()
local iconsize = Vector2(18 , 18)
local label_offset = 14 -- enough so that the target rectangle fits
local collapse = iconsize -- size of clusters to be collapsed into single bodies
local click_radius = collapse:length() * 0.5
-- make click_radius sufficiently smaller than the cluster size
-- to prevent overlap of selection regions
local objectCounter = 0
local objects_grouped = systemView:GetProjectedGrouped(collapse, 1e64)
if #objects_grouped == 0 then
ui.setNextWindowPos(Vector2(ui.screenWidth, ui.screenHeight) / 2 - ui.calcTextSize(lc.UNEXPLORED_SYSTEM_NO_SYSTEM_VIEW) / 2, "Always")
ui.withStyleColors({["WindowBg"] = svColor.SYSTEMNAME_BACK}, function()
ui.window("NoSystemView", {"NoTitleBar", "AlwaysAutoResize", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "NoSavedSettings"},
function()
ui.text(lc.UNEXPLORED_SYSTEM_NO_SYSTEM_VIEW);
end)
end)
return
end
for _,group in ipairs(objects_grouped) do
local mainObject = group.mainObject
local mainCoords = Vector2(group.screenCoordinates.x, group.screenCoordinates.y)
-- indicators
local stackedSize = indicatorSize
local stackStep = Vector2(10, 10)
if group.hasPlayer then
ui.addIcon(mainCoords, icons.square, svColor.PLAYER, stackedSize, ui.anchor.center, ui.anchor.center)
stackedSize = stackedSize + stackStep
end
if group.hasNavTarget then
ui.addIcon(mainCoords, icons.square, svColor.NAV_TARGET, stackedSize, ui.anchor.center, ui.anchor.center)
stackedSize = stackedSize + stackStep
end
if group.hasCombatTarget then
ui.addIcon(mainCoords, icons.square, svColor.COMBAT_TARGET, stackedSize, ui.anchor.center, ui.anchor.center)
stackedSize = stackedSize + stackStep
end
if mainObject.type == Projectable.OBJECT and mainObject.base == Projectable.PLANNER then ui.addIcon(mainCoords, icons.square, svColor.PLANNER, indicatorSize, ui.anchor.center, ui.anchor.center) end
ui.addIcon(mainCoords, getBodyIcon(mainObject), getColor(mainObject), iconsize, ui.anchor.center, ui.anchor.center)
if should_show_label then
local label = getLabel(mainObject)
if group.objects then
label = label .. " (" .. #group.objects .. ")"
end
ui.addStyledText(mainCoords + Vector2(label_offset,0), ui.anchor.left, ui.anchor.center, label , getColor(mainObject), pionillium.small)
end
local mp = ui.getMousePos()
if mainObject.type == Projectable.OBJECT and (mainObject.base == Projectable.SYSTEMBODY or mainObject.base == Projectable.SHIP or mainObject.base == Projectable.PLAYER) then
-- mouse release handler for right button
if (mp - mainCoords):length() < click_radius then
if not ui.isAnyWindowHovered() and ui.isMouseReleased(1) then
ui.openPopup("target" .. objectCounter)
end
end
-- make popup
ui.popup("target" .. objectCounter, function()
local isObject = mainObject.type == Projectable.OBJECT
local isSystemBody = isObject and mainObject.base == Projectable.SYSTEMBODY
local isShip = isObject and not isSystemBody and mainObject.ref:IsShip()
ui.text(getLabel(mainObject))
ui.separator()
if ui.selectable(lc.CENTER, false, {}) then
systemView:SetSelectedObject(mainObject.type, mainObject.base, mainObject.ref)
end
if (isShip or isSystemBody and mainObject.ref.physicsBody) and ui.selectable(lc.SET_AS_TARGET, false, {}) then
if isSystemBody then
player:SetNavTarget(mainObject.ref.physicsBody)
else
if combatTarget == mainObject.ref then player:SetCombatTarget(nil) end
player:SetNavTarget(mainObject.ref)
end
end
if isShip and ui.selectable(lc.SET_AS_COMBAT_TARGET, false, {}) then
if navTarget == mainObject.ref then player:SetNavTarget(nil) end
player:SetCombatTarget(mainObject.ref)
end
end)
end
-- mouse release handler for left button
if (mp - mainCoords):length() < click_radius then
if not ui.isAnyWindowHovered() and ui.isMouseReleased(0) and mainObject.type == Projectable.OBJECT then
systemView:SetSelectedObject(mainObject.type, mainObject.base, mainObject.ref)
end
end
objectCounter = objectCounter + 1
end
end
local function tabular(data)
if data and #data > 0 then
ui.columns(2, "Attributes", true)
for _,item in pairs(data) do
if item.value then
ui.text(item.name)
ui.nextColumn()
ui.text(item.value)
ui.nextColumn()
end
end
ui.columns(1, "NoAttributes", false)
end
end
local function showTargetInfoWindow(obj)
if obj.type ~= Projectable.OBJECT or obj.base ~= Projectable.SHIP and obj.base ~= Projectable.SYSTEMBODY then return end
ui.setNextWindowSize(Vector2(ui.screenWidth / 5, 0), "Always")
ui.setNextWindowPos(Vector2(20, (ui.screenHeight / 5) * 2 + 20), "Always")
ui.withStyleColors({["WindowBg"] = svColor.WINDOW_BACK}, function()
ui.window("TargetInfoWindow", {"NoTitleBar", "AlwaysAutoResize", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus", "NoSavedSettings"},
function()
local data
-- system body
if obj.type == Projectable.OBJECT and obj.base == Projectable.SYSTEMBODY then
local systemBody = obj.ref
local name = systemBody.name
local rp = systemBody.rotationPeriod * 24 * 60 * 60
local r = systemBody.radius
local radius = nil
if r and r > 0 then
local v,u = ui.Format.Distance(r)
radius = v .. u
end
local sma = systemBody.semiMajorAxis
local semimajoraxis = nil
if sma and sma > 0 then
local v,u = ui.Format.Distance(sma)
semimajoraxis = v .. u
end
local op = systemBody.orbitPeriod * 24 * 60 * 60
data = {
{ name = lc.NAME_OBJECT,
value = name },
{ name = lc.DAY_LENGTH .. lc.ROTATIONAL_PERIOD,
value = rp > 0 and ui.Format.Duration(rp, 2) or nil },
{ name = lc.RADIUS,
value = radius },
{ name = lc.SEMI_MAJOR_AXIS,
value = semimajoraxis },
{ name = lc.ORBITAL_PERIOD,
value = op and op > 0 and ui.Format.Duration(op, 2) or nil }
}
-- physical body
elseif obj.type == Projectable.OBJECT and obj.ref:IsShip() then
local body = obj.ref
local name = body.label
data = {{ name = lc.NAME_OBJECT, value = name }, }
-- TODO: the advanced target scanner should add additional data here,
-- but we really do not want to hardcode that here. there should be
-- some kind of hook that the target scanner can hook into to display
-- more info here.
-- This is what should be inserted:
table.insert(data, { name = luc.SHIP_TYPE, value = body:GetShipType() })
if player:GetEquipCountOccupied('target_scanner') > 0 or player:GetEquipCountOccupied('advanced_target_scanner') > 0 then
local hd = body:GetEquip("engine", 1)
table.insert(data, { name = lc.HYPERDRIVE, value = hd and hd:GetName() or lc.NO_HYPERDRIVE })
table.insert(data, { name = lc.MASS, value = Format.MassTonnes(body:GetStats().staticMass) })
table.insert(data, { name = lc.CARGO, value = Format.MassTonnes(body:GetStats().usedCargo) })
end
else
data = {}
end
tabular(data)
end)
end)
end
local function displaySystemViewUI()
player = Game.player
local current_view = Game.CurrentView()
if current_view == "system" and not Game.InHyperspace() then
selectedObject = systemView:GetSelectedObject()
displayOnScreenObjects()
ui.withFont(ui.fonts.pionillium.medium.name, ui.fonts.pionillium.medium.size, function()
showOrbitPlannerWindow()
showTargetInfoWindow(selectedObject)
end)
showSystemName()
end
end
Event.Register("onGameStart", onGameStart)
ui.registerModule("game", displaySystemViewUI)
return {}

View File

@ -160,6 +160,7 @@ theme.icons = {
shield = 92,
hull = 93,
temperature = 94,
rotate_view = 95,
-- seventh row
heavy_cargo_shuttle = 96,
medium_cargo_shuttle = 97,

View File

@ -373,8 +373,8 @@ def write_header(enums, fl):
fl.write('#ifndef HX_GEN_ENUM_TABLES\n')
fl.write('#define HX_GEN_ENUM_TABLES\n\n')
write_generation_header(fl)
fl.write('struct EnumItem { const char *name; int value; };\n')
fl.write('struct EnumTable { const char *name; const EnumItem *first; };\n\n')
fl.write('struct EnumItem {\n\tconst char *name;\n\tint value;\n};\n')
fl.write('struct EnumTable {\n\tconst char *name;\n\tconst EnumItem *first;\n};\n\n')
for e in enums:
e.write_c_header(fl)
fl.write('\n')

View File

@ -16,6 +16,7 @@
#include "Player.h"
#include "SpaceStation.h"
#include "Star.h"
#include "SystemView.h"
#include "collider/CollisionContact.h"
#include "collider/CollisionSpace.h"
#include "galaxy/Galaxy.h"
@ -427,7 +428,7 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Planet *planet, vecto
double bestVariation = 1e10; // any high value
matrix3x3d rotNotUnderwaterWithLeastVariation = rot;
vector3d posNotUnderwaterWithLeastVariation = pos;
const double heightVariationCheckThreshold = 0.008; // max variation to radius radius ratio to check for local slope, ganymede is around 0.01
const double heightVariationCheckThreshold = 0.008; // max variation to radius radius ratio to check for local slope, ganymede is around 0.01
const double terrainHeightVariation = planet->GetMaxFeatureRadius(); //in radii
//Output("%s: terrain height variation %f\n", sbody->name.c_str(), terrainHeightVariation);
@ -436,8 +437,8 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Planet *planet, vecto
// points must stay within max height variation to be accepted
// 1. delta should be chosen such that it a distance from the starport center that encloses landing pads for the largest starport
// 2. maxSlope should be set so maxHeightVariation is less than the height of the landing pads
const double delta = 20.0 / radius; // in radii
const double maxSlope = 0.2; // 0.0 to 1.0
const double delta = 20.0 / radius; // in radii
const double maxSlope = 0.2; // 0.0 to 1.0
const double maxHeightVariation = maxSlope * delta * radius; // in m
matrix3x3d rot_ = rot;
@ -1006,6 +1007,7 @@ void Space::UpdateBodies()
rmb->SetFrame(FrameId::Invalid);
for (Body *b : m_bodies)
b->NotifyRemoved(rmb);
if (Pi::GetView()) Pi::game->GetSystemView()->BodyInaccessible(rmb);
m_bodies.remove(rmb);
}
m_removeBodies.clear();
@ -1013,6 +1015,7 @@ void Space::UpdateBodies()
for (Body *killb : m_killBodies) {
for (Body *b : m_bodies)
b->NotifyRemoved(killb);
if (Pi::GetView()) Pi::game->GetSystemView()->BodyInaccessible(killb);
m_bodies.remove(killb);
delete killb;
}
@ -1030,7 +1033,7 @@ static void DebugDumpFrame(FrameId fId, bool details, unsigned int indent)
Frame *f = Frame::GetFrame(fId);
Frame *parent = Frame::GetFrame(f->GetParent());
Output("%.*s%2i) %p (%s)%s\n", indent, space, fId, static_cast<void *>(f), f->GetLabel().c_str(), f->IsRotFrame() ? " [rotating]" : " [non rotating]");
Output("%.*s%2i) %p (%s)%s\n", indent, space, static_cast<int>(fId), static_cast<void *>(f), f->GetLabel().c_str(), f->IsRotFrame() ? " [rotating]" : " [non rotating]");
if (f->GetParent().valid())
Output("%.*s parent %p (%s)\n", indent + 3, space, static_cast<void *>(parent), parent->GetLabel().c_str());
if (f->GetBody())

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,15 @@
#include "graphics/Drawables.h"
#include "matrix4x4.h"
#include "vector3.h"
#include "enum_table.h"
#include "Frame.h"
class StarSystem;
class SystemBody;
class Orbit;
class Ship;
class Game;
class Body;
enum BurnDirection {
PROGRADE,
@ -40,6 +43,7 @@ enum ShowLagrange {
LAG_OFF
};
class TransferPlanner {
public:
TransferPlanner();
@ -51,7 +55,9 @@ public:
void IncreaseFactor(), ResetFactor(), DecreaseFactor();
void AddStartTime(double timeStep);
void ResetStartTime();
double GetFactor() const { return m_factor; }
void AddDv(BurnDirection d, double dv);
double GetDv(BurnDirection d);
void ResetDv(BurnDirection d);
void ResetDv();
std::string printDeltaTime();
@ -69,85 +75,130 @@ private:
double m_startTime;
};
class SystemView : public UIView {
struct Projectable
{
enum types { // <enum name=ProjectableTypes scope='Projectable' public>
NONE = 0, // empty projectable, don't try to get members
OBJECT = 1, // clickable space object, may be without phys.body (other starsystem)
L4 = 2,
L5 = 3,
APOAPSIS = 4,
PERIAPSIS = 5
} type;
enum bases { // <enum name=ProjectableBases scope='Projectable' public>
SYSTEMBODY = 0, // ref class SystemBody, may not have a physical body
BODY = 1, // generic body
SHIP = 2,
PLAYER = 3, // player's ship
PLANNER = 4 // player's ship planned by transfer planner, refers to player's object
} base;
union{
const Body* body;
const SystemBody* sbody;
} ref;
vector3d screenpos; // x,y - screen coordinate, z - in NDC
Projectable(const types t, const bases b, const Body* obj) : type(t), base(b)
{
ref.body = obj;
}
Projectable(const types t, const bases b, const SystemBody* obj) : type(t), base(b)
{
ref.sbody = obj;
}
Projectable() : type(NONE) {}
};
class SystemView : public UIView, public DeleteEmitter {
public:
SystemView(Game *game);
virtual ~SystemView();
virtual void Update();
virtual void Draw3D();
virtual void OnSwitchTo() { Update(); Draw3D(); }
Projectable* GetSelectedObject();
void SetSelectedObject(Projectable::types type, Projectable::bases base, SystemBody *sb);
void SetSelectedObject(Projectable::types type, Projectable::bases base, Body *b);
TransferPlanner* GetTransferPlanner() const { return m_planner; }
double GetOrbitPlannerStartTime() const { return m_planner->GetStartTime(); }
double GetOrbitPlannerTime() const { return m_time; }
void AccelerateTime(float step);
void SetRealTime();
std::vector<Projectable> GetProjected() const { return m_projected; }
void BodyInaccessible(Body *b);
void SetVisibility(std::string param);
void SetZoomMode(bool enable);
void SetRotateMode(bool enable);
double ProjectedSize(double size, vector3d pos);
// all used colors. defined in system-view-ui.lua
enum ColorIndex { // <enum name=SystemViewColorIndex scope='SystemView' public>
GRID = 0,
SYSTEMBODY = 1,
SYSTEMBODY_ORBIT = 2,
PLAYER_ORBIT = 3,
PLANNER_ORBIT = 4,
SELECTED_SHIP_ORBIT = 5,
SHIP_ORBIT = 6
};
Color svColor[7];
void SetColor(ColorIndex color_index, Color* color_value) { svColor[color_index] = *color_value; }
private:
bool m_rotateWithMouseButton = false;
bool m_rotateView = false;
bool m_zoomView = false;
std::vector<Projectable> m_projected;
static const double PICK_OBJECT_RECT_SIZE;
static const Uint16 N_VERTICES_MAX;
void PutOrbit(const Orbit *orb, const vector3d &offset, const Color &color, const double planetRadius = 0.0, const bool showLagrange = false);
const float CAMERA_FOV = 50.f;
const float CAMERA_FOV_RADIANS = CAMERA_FOV / 57.295779f;
matrix4x4f m_cameraSpace;
template <typename RefType>
void PutOrbit(Projectable::bases base, RefType *ref, const Orbit *orb, const vector3d &offset, const Color &color, const double planetRadius = 0.0, const bool showLagrange = false);
void PutBody(const SystemBody *b, const vector3d &offset, const matrix4x4f &trans);
void PutLabel(const SystemBody *b, const vector3d &offset);
void PutSelectionBox(const SystemBody *b, const vector3d &rootPos, const Color &col);
void PutSelectionBox(const vector3d &worldPos, const Color &col);
void GetTransformTo(const SystemBody *b, vector3d &pos);
void OnClickObject(const SystemBody *b);
void OnClickLagrange();
void OnClickAccel(float step);
void OnClickRealt();
void OnIncreaseFactorButtonClick(void), OnResetFactorButtonClick(void), OnDecreaseFactorButtonClick(void);
void OnIncreaseStartTimeButtonClick(void), OnResetStartTimeButtonClick(void), OnDecreaseStartTimeButtonClick(void);
void OnToggleShipsButtonClick(void);
void OnToggleGridButtonClick(void);
void OnToggleL4L5ButtonClick(Gui::MultiStateImageButton *);
void GetTransformTo(Projectable &p, vector3d &pos);
void ResetViewpoint();
void MouseWheel(bool up);
void RefreshShips(void);
void DrawShips(const double t, const vector3d &offset);
void PrepareGrid();
void DrawGrid();
void LabelShip(Ship *s, const vector3d &offset);
void OnClickShip(Ship *s);
template <typename T>
void AddProjected(Projectable::types type, Projectable::bases base, T *ref, vector3d &pos);
template <typename T>
void AddNotProjected(Projectable::types type, Projectable::bases base, T *ref, const vector3d &worldscaledpos);
void CalculateShipPositionAtTime(const Ship *s, Orbit o, double t, vector3d &pos);
void CalculateFramePositionAtTime(FrameId frameId, double t, vector3d &pos);
double GetOrbitTime(double t, const SystemBody* b);
double GetOrbitTime(double t, const Body* b);
Game *m_game;
RefCountedPtr<StarSystem> m_system;
const SystemBody *m_selectedObject;
Projectable m_selectedObject;
std::vector<SystemBody *> m_displayed_sbody;
bool m_unexplored;
ShowLagrange m_showL4L5;
TransferPlanner *m_planner;
std::list<std::pair<Ship *, Orbit>> m_contacts;
Gui::LabelSet *m_shipLabels;
ShipDrawing m_shipDrawing;
GridDrawing m_gridDrawing;
int m_grid_lines;
float m_rot_x, m_rot_z;
float m_rot_x_to, m_rot_z_to;
float m_rot_x, m_rot_y;
float m_rot_x_to, m_rot_y_to;
float m_zoom, m_zoomTo;
int m_animateTransition;
vector3d m_trans;
vector3d m_transTo;
double m_time;
bool m_realtime;
double m_timeStep;
Gui::ImageButton *m_zoomInButton;
Gui::ImageButton *m_zoomOutButton;
Gui::ImageButton *m_toggleShipsButton;
Gui::ImageButton *m_toggleGridButton;
Gui::ImageButton *m_ResetOrientButton;
Gui::MultiStateImageButton *m_toggleL4L5Button;
Gui::ImageButton *m_plannerIncreaseStartTimeButton, *m_plannerResetStartTimeButton, *m_plannerDecreaseStartTimeButton;
Gui::ImageButton *m_plannerIncreaseFactorButton, *m_plannerResetFactorButton, *m_plannerDecreaseFactorButton;
Gui::ImageButton *m_plannerAddProgradeVelButton;
Gui::ImageButton *m_plannerAddRetrogradeVelButton;
Gui::ImageButton *m_plannerAddNormalVelButton;
Gui::ImageButton *m_plannerAddAntiNormalVelButton;
Gui::ImageButton *m_plannerAddRadiallyInVelButton;
Gui::ImageButton *m_plannerAddRadiallyOutVelButton;
Gui::ImageButton *m_plannerZeroProgradeVelButton, *m_plannerZeroNormalVelButton, *m_plannerZeroRadialVelButton;
Gui::Label *m_timePoint;
Gui::Label *m_infoLabel;
Gui::Label *m_infoText;
Gui::Label *m_plannerFactorText, *m_plannerStartTimeText, *m_plannerProgradeDvText, *m_plannerNormalDvText, *m_plannerRadialDvText;
Gui::LabelSet *m_objectLabels;
sigc::connection m_onMouseWheelCon;
std::unique_ptr<Graphics::Drawables::Disk> m_bodyIcon;
std::unique_ptr<Gui::TexturedQuad> m_l4Icon;
std::unique_ptr<Gui::TexturedQuad> m_l5Icon;
std::unique_ptr<Gui::TexturedQuad> m_periapsisIcon;
std::unique_ptr<Gui::TexturedQuad> m_apoapsisIcon;
Graphics::RenderState *m_lineState;
Graphics::Drawables::Lines m_orbits;
Graphics::Drawables::Lines m_selectBox;
@ -157,7 +208,6 @@ private:
std::unique_ptr<Graphics::VertexArray> m_lineVerts;
Graphics::Drawables::Lines m_lines;
};
#endif /* _SYSTEMVIEW_H */

View File

@ -10,15 +10,17 @@
#include "Ship.h"
#include "ShipAICmd.h"
#include "ShipType.h"
#include "SystemView.h"
#include "galaxy/Economy.h"
#include "galaxy/Polit.h"
#include "galaxy/StarSystem.h"
#include "galaxy/SystemBody.h"
#include "gameui/Face.h"
#include "lua/LuaEngine.h"
#include "lua/LuaFileSystem.h"
#include "pigui/Face.h"
#include "scenegraph/Model.h"
#include "ship/PlayerShipController.h"
#include "ship/Propulsion.h"
#include "ship/ShipController.h"
#include "ui/Align.h"
#include "ui/Animation.h"
#include "ui/Event.h"
@ -37,21 +39,6 @@ const struct EnumItem ENUM_ShipAIError[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_DetailLevel[] = {
{ "VERY_LOW", int(LuaEngine::DETAIL_VERY_LOW) },
{ "LOW", int(LuaEngine::DETAIL_LOW) },
{ "MEDIUM", int(LuaEngine::DETAIL_MEDIUM) },
{ "HIGH", int(LuaEngine::DETAIL_HIGH) },
{ "VERY_HIGH", int(LuaEngine::DETAIL_VERY_HIGH) },
{ 0, 0 },
};
const struct EnumItem ENUM_FileSystemRoot[] = {
{ "USER", int(LuaFileSystem::ROOT_USER) },
{ "DATA", int(LuaFileSystem::ROOT_DATA) },
{ 0, 0 },
};
const struct EnumItem ENUM_PhysicsObjectType[] = {
{ "BODY", int(Object::BODY) },
{ "MODELBODY", int(Object::MODELBODY) },
@ -65,52 +52,6 @@ const struct EnumItem ENUM_PhysicsObjectType[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_PolitEcon[] = {
{ "NONE", int(Polit::ECON_NONE) },
{ "VERY_CAPITALIST", int(Polit::ECON_VERY_CAPITALIST) },
{ "CAPITALIST", int(Polit::ECON_CAPITALIST) },
{ "MIXED", int(Polit::ECON_MIXED) },
{ "PLANNED", int(Polit::ECON_PLANNED) },
{ 0, 0 },
};
const struct EnumItem ENUM_PolitGovType[] = {
{ "NONE", int(Polit::GOV_NONE) },
{ "EARTHCOLONIAL", int(Polit::GOV_EARTHCOLONIAL) },
{ "EARTHDEMOC", int(Polit::GOV_EARTHDEMOC) },
{ "EMPIRERULE", int(Polit::GOV_EMPIRERULE) },
{ "CISLIBDEM", int(Polit::GOV_CISLIBDEM) },
{ "CISSOCDEM", int(Polit::GOV_CISSOCDEM) },
{ "LIBDEM", int(Polit::GOV_LIBDEM) },
{ "CORPORATE", int(Polit::GOV_CORPORATE) },
{ "SOCDEM", int(Polit::GOV_SOCDEM) },
{ "EARTHMILDICT", int(Polit::GOV_EARTHMILDICT) },
{ "MILDICT1", int(Polit::GOV_MILDICT1) },
{ "MILDICT2", int(Polit::GOV_MILDICT2) },
{ "EMPIREMILDICT", int(Polit::GOV_EMPIREMILDICT) },
{ "COMMUNIST", int(Polit::GOV_COMMUNIST) },
{ "PLUTOCRATIC", int(Polit::GOV_PLUTOCRATIC) },
{ "DISORDER", int(Polit::GOV_DISORDER) },
{ 0, 0 },
};
const struct EnumItem ENUM_ShipTypeThruster[] = {
{ "REVERSE", int(Thruster::THRUSTER_REVERSE) },
{ "FORWARD", int(Thruster::THRUSTER_FORWARD) },
{ "UP", int(Thruster::THRUSTER_UP) },
{ "DOWN", int(Thruster::THRUSTER_DOWN) },
{ "LEFT", int(Thruster::THRUSTER_LEFT) },
{ "RIGHT", int(Thruster::THRUSTER_RIGHT) },
{ 0, 0 },
};
const struct EnumItem ENUM_PropulsionFuelStatus[] = {
{ "OK", int(Propulsion::FUEL_OK) },
{ "WARNING", int(Propulsion::FUEL_WARNING) },
{ "EMPTY", int(Propulsion::FUEL_EMPTY) },
{ 0, 0 },
};
const struct EnumItem ENUM_ShipFlightState[] = {
{ "FLYING", int(Ship::FLYING) },
{ "DOCKING", int(Ship::DOCKING) },
@ -138,6 +79,7 @@ const struct EnumItem ENUM_ShipAlertStatus[] = {
{ "NONE", int(Ship::ALERT_NONE) },
{ "SHIP_NEARBY", int(Ship::ALERT_SHIP_NEARBY) },
{ "SHIP_FIRING", int(Ship::ALERT_SHIP_FIRING) },
{ "MISSILE_DETECTED", int(Ship::ALERT_MISSILE_DETECTED) },
{ 0, 0 },
};
@ -153,20 +95,6 @@ const struct EnumItem ENUM_ShipAICmdName[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_ShipControllerFlightControlState[] = {
{ "CONTROL_MANUAL", int(FlightControlState::CONTROL_MANUAL) },
{ "CONTROL_FIXSPEED", int(FlightControlState::CONTROL_FIXSPEED) },
{ "CONTROL_FIXHEADING_FORWARD", int(FlightControlState::CONTROL_FIXHEADING_FORWARD) },
{ "CONTROL_FIXHEADING_BACKWARD", int(FlightControlState::CONTROL_FIXHEADING_BACKWARD) },
{ "CONTROL_FIXHEADING_NORMAL", int(FlightControlState::CONTROL_FIXHEADING_NORMAL) },
{ "CONTROL_FIXHEADING_ANTINORMAL", int(FlightControlState::CONTROL_FIXHEADING_ANTINORMAL) },
{ "CONTROL_FIXHEADING_RADIALLY_INWARD", int(FlightControlState::CONTROL_FIXHEADING_RADIALLY_INWARD) },
{ "CONTROL_FIXHEADING_RADIALLY_OUTWARD", int(FlightControlState::CONTROL_FIXHEADING_RADIALLY_OUTWARD) },
{ "CONTROL_FIXHEADING_KILLROT", int(FlightControlState::CONTROL_FIXHEADING_KILLROT) },
{ "CONTROL_AUTOPILOT", int(FlightControlState::CONTROL_AUTOPILOT) },
{ 0, 0 },
};
const struct EnumItem ENUM_DualLaserOrientation[] = {
{ "HORIZONTAL", int(ShipType::DUAL_LASERS_HORIZONTAL) },
{ "VERTICAL", int(ShipType::DUAL_LASERS_VERTICAL) },
@ -181,6 +109,36 @@ const struct EnumItem ENUM_ShipTypeTag[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_ProjectableTypes[] = {
{ "NONE", int(Projectable::NONE) },
{ "OBJECT", int(Projectable::OBJECT) },
{ "L4", int(Projectable::L4) },
{ "L5", int(Projectable::L5) },
{ "APOAPSIS", int(Projectable::APOAPSIS) },
{ "PERIAPSIS", int(Projectable::PERIAPSIS) },
{ 0, 0 },
};
const struct EnumItem ENUM_ProjectableBases[] = {
{ "SYSTEMBODY", int(Projectable::SYSTEMBODY) },
{ "BODY", int(Projectable::BODY) },
{ "SHIP", int(Projectable::SHIP) },
{ "PLAYER", int(Projectable::PLAYER) },
{ "PLANNER", int(Projectable::PLANNER) },
{ 0, 0 },
};
const struct EnumItem ENUM_SystemViewColorIndex[] = {
{ "GRID", int(SystemView::GRID) },
{ "SYSTEMBODY", int(SystemView::SYSTEMBODY) },
{ "SYSTEMBODY_ORBIT", int(SystemView::SYSTEMBODY_ORBIT) },
{ "PLAYER_ORBIT", int(SystemView::PLAYER_ORBIT) },
{ "PLANNER_ORBIT", int(SystemView::PLANNER_ORBIT) },
{ "SELECTED_SHIP_ORBIT", int(SystemView::SELECTED_SHIP_ORBIT) },
{ "SHIP_ORBIT", int(SystemView::SHIP_ORBIT) },
{ 0, 0 },
};
const struct EnumItem ENUM_EconType[] = {
{ "MINING", int(GalacticEconomy::ECON_MINING) },
{ "AGRICULTURE", int(GalacticEconomy::ECON_AGRICULTURE) },
@ -223,6 +181,35 @@ const struct EnumItem ENUM_CommodityType[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_PolitEcon[] = {
{ "NONE", int(Polit::ECON_NONE) },
{ "VERY_CAPITALIST", int(Polit::ECON_VERY_CAPITALIST) },
{ "CAPITALIST", int(Polit::ECON_CAPITALIST) },
{ "MIXED", int(Polit::ECON_MIXED) },
{ "PLANNED", int(Polit::ECON_PLANNED) },
{ 0, 0 },
};
const struct EnumItem ENUM_PolitGovType[] = {
{ "NONE", int(Polit::GOV_NONE) },
{ "EARTHCOLONIAL", int(Polit::GOV_EARTHCOLONIAL) },
{ "EARTHDEMOC", int(Polit::GOV_EARTHDEMOC) },
{ "EMPIRERULE", int(Polit::GOV_EMPIRERULE) },
{ "CISLIBDEM", int(Polit::GOV_CISLIBDEM) },
{ "CISSOCDEM", int(Polit::GOV_CISSOCDEM) },
{ "LIBDEM", int(Polit::GOV_LIBDEM) },
{ "CORPORATE", int(Polit::GOV_CORPORATE) },
{ "SOCDEM", int(Polit::GOV_SOCDEM) },
{ "EARTHMILDICT", int(Polit::GOV_EARTHMILDICT) },
{ "MILDICT1", int(Polit::GOV_MILDICT1) },
{ "MILDICT2", int(Polit::GOV_MILDICT2) },
{ "EMPIREMILDICT", int(Polit::GOV_EMPIREMILDICT) },
{ "COMMUNIST", int(Polit::GOV_COMMUNIST) },
{ "PLUTOCRATIC", int(Polit::GOV_PLUTOCRATIC) },
{ "DISORDER", int(Polit::GOV_DISORDER) },
{ 0, 0 },
};
const struct EnumItem ENUM_BodyType[] = {
{ "GRAVPOINT", int(SystemBody::TYPE_GRAVPOINT) },
{ "BROWN_DWARF", int(SystemBody::TYPE_BROWN_DWARF) },
@ -286,6 +273,29 @@ const struct EnumItem ENUM_GameUIFaceFlags[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_DetailLevel[] = {
{ "VERY_LOW", int(LuaEngine::DETAIL_VERY_LOW) },
{ "LOW", int(LuaEngine::DETAIL_LOW) },
{ "MEDIUM", int(LuaEngine::DETAIL_MEDIUM) },
{ "HIGH", int(LuaEngine::DETAIL_HIGH) },
{ "VERY_HIGH", int(LuaEngine::DETAIL_VERY_HIGH) },
{ 0, 0 },
};
const struct EnumItem ENUM_FileSystemRoot[] = {
{ "USER", int(LuaFileSystem::ROOT_USER) },
{ "DATA", int(LuaFileSystem::ROOT_DATA) },
{ 0, 0 },
};
const struct EnumItem ENUM_PiGUIFaceFlags[] = {
{ "RAND", int(PiGUI::Face::RAND) },
{ "MALE", int(PiGUI::Face::MALE) },
{ "FEMALE", int(PiGUI::Face::FEMALE) },
{ "ARMOUR", int(PiGUI::Face::ARMOUR) },
{ 0, 0 },
};
const struct EnumItem ENUM_ModelDebugFlags[] = {
{ "NONE", int(SceneGraph::Model::DEBUG_NONE) },
{ "BBOX", int(SceneGraph::Model::DEBUG_BBOX) },
@ -296,6 +306,37 @@ const struct EnumItem ENUM_ModelDebugFlags[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_ShipTypeThruster[] = {
{ "REVERSE", int(Thruster::THRUSTER_REVERSE) },
{ "FORWARD", int(Thruster::THRUSTER_FORWARD) },
{ "UP", int(Thruster::THRUSTER_UP) },
{ "DOWN", int(Thruster::THRUSTER_DOWN) },
{ "LEFT", int(Thruster::THRUSTER_LEFT) },
{ "RIGHT", int(Thruster::THRUSTER_RIGHT) },
{ 0, 0 },
};
const struct EnumItem ENUM_PropulsionFuelStatus[] = {
{ "OK", int(Propulsion::FUEL_OK) },
{ "WARNING", int(Propulsion::FUEL_WARNING) },
{ "EMPTY", int(Propulsion::FUEL_EMPTY) },
{ 0, 0 },
};
const struct EnumItem ENUM_ShipControllerFlightControlState[] = {
{ "CONTROL_MANUAL", int(FlightControlState::CONTROL_MANUAL) },
{ "CONTROL_FIXSPEED", int(FlightControlState::CONTROL_FIXSPEED) },
{ "CONTROL_FIXHEADING_FORWARD", int(FlightControlState::CONTROL_FIXHEADING_FORWARD) },
{ "CONTROL_FIXHEADING_BACKWARD", int(FlightControlState::CONTROL_FIXHEADING_BACKWARD) },
{ "CONTROL_FIXHEADING_NORMAL", int(FlightControlState::CONTROL_FIXHEADING_NORMAL) },
{ "CONTROL_FIXHEADING_ANTINORMAL", int(FlightControlState::CONTROL_FIXHEADING_ANTINORMAL) },
{ "CONTROL_FIXHEADING_RADIALLY_INWARD", int(FlightControlState::CONTROL_FIXHEADING_RADIALLY_INWARD) },
{ "CONTROL_FIXHEADING_RADIALLY_OUTWARD", int(FlightControlState::CONTROL_FIXHEADING_RADIALLY_OUTWARD) },
{ "CONTROL_FIXHEADING_KILLROT", int(FlightControlState::CONTROL_FIXHEADING_KILLROT) },
{ "CONTROL_AUTOPILOT", int(FlightControlState::CONTROL_AUTOPILOT) },
{ 0, 0 },
};
const struct EnumItem ENUM_UIAlignDirection[] = {
{ "TOP_LEFT", int(UI::Align::TOP_LEFT) },
{ "TOP", int(UI::Align::TOP) },
@ -479,26 +520,30 @@ const struct EnumItem ENUM_UIFont[] = {
const struct EnumTable ENUM_TABLES[] = {
{ "ShipAIError", ENUM_ShipAIError },
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PhysicsObjectType", ENUM_PhysicsObjectType },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "ShipTypeThruster", ENUM_ShipTypeThruster },
{ "PropulsionFuelStatus", ENUM_PropulsionFuelStatus },
{ "ShipFlightState", ENUM_ShipFlightState },
{ "ShipJumpStatus", ENUM_ShipJumpStatus },
{ "ShipAlertStatus", ENUM_ShipAlertStatus },
{ "ShipAICmdName", ENUM_ShipAICmdName },
{ "ShipControllerFlightControlState", ENUM_ShipControllerFlightControlState },
{ "DualLaserOrientation", ENUM_DualLaserOrientation },
{ "ShipTypeTag", ENUM_ShipTypeTag },
{ "ProjectableTypes", ENUM_ProjectableTypes },
{ "ProjectableBases", ENUM_ProjectableBases },
{ "SystemViewColorIndex", ENUM_SystemViewColorIndex },
{ "EconType", ENUM_EconType },
{ "CommodityType", ENUM_CommodityType },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "BodyType", ENUM_BodyType },
{ "BodySuperType", ENUM_BodySuperType },
{ "GameUIFaceFlags", ENUM_GameUIFaceFlags },
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PiGUIFaceFlags", ENUM_PiGUIFaceFlags },
{ "ModelDebugFlags", ENUM_ModelDebugFlags },
{ "ShipTypeThruster", ENUM_ShipTypeThruster },
{ "PropulsionFuelStatus", ENUM_PropulsionFuelStatus },
{ "ShipControllerFlightControlState", ENUM_ShipControllerFlightControlState },
{ "UIAlignDirection", ENUM_UIAlignDirection },
{ "UIAnimationType", ENUM_UIAnimationType },
{ "UIAnimationEasing", ENUM_UIAnimationEasing },
@ -523,26 +568,30 @@ const struct EnumTable ENUM_TABLES[] = {
const struct EnumTable ENUM_TABLES_PUBLIC[] = {
{ "ShipAIError", ENUM_ShipAIError },
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PhysicsObjectType", ENUM_PhysicsObjectType },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "ShipTypeThruster", ENUM_ShipTypeThruster },
{ "PropulsionFuelStatus", ENUM_PropulsionFuelStatus },
{ "ShipFlightState", ENUM_ShipFlightState },
{ "ShipJumpStatus", ENUM_ShipJumpStatus },
{ "ShipAlertStatus", ENUM_ShipAlertStatus },
{ "ShipAICmdName", ENUM_ShipAICmdName },
{ "ShipControllerFlightControlState", ENUM_ShipControllerFlightControlState },
{ "DualLaserOrientation", ENUM_DualLaserOrientation },
{ "ShipTypeTag", ENUM_ShipTypeTag },
{ "ProjectableTypes", ENUM_ProjectableTypes },
{ "ProjectableBases", ENUM_ProjectableBases },
{ "SystemViewColorIndex", ENUM_SystemViewColorIndex },
{ "EconType", ENUM_EconType },
{ "CommodityType", ENUM_CommodityType },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "BodyType", ENUM_BodyType },
{ "BodySuperType", ENUM_BodySuperType },
{ "GameUIFaceFlags", ENUM_GameUIFaceFlags },
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PiGUIFaceFlags", ENUM_PiGUIFaceFlags },
{ "ModelDebugFlags", ENUM_ModelDebugFlags },
{ "ShipTypeThruster", ENUM_ShipTypeThruster },
{ "PropulsionFuelStatus", ENUM_PropulsionFuelStatus },
{ "ShipControllerFlightControlState", ENUM_ShipControllerFlightControlState },
{ "UIAlignDirection", ENUM_UIAlignDirection },
{ "UIAnimationType", ENUM_UIAnimationType },
{ "UIAnimationEasing", ENUM_UIAnimationEasing },

View File

@ -17,26 +17,30 @@ struct EnumTable {
};
extern const struct EnumItem ENUM_ShipAIError[];
extern const struct EnumItem ENUM_DetailLevel[];
extern const struct EnumItem ENUM_FileSystemRoot[];
extern const struct EnumItem ENUM_PhysicsObjectType[];
extern const struct EnumItem ENUM_PolitEcon[];
extern const struct EnumItem ENUM_PolitGovType[];
extern const struct EnumItem ENUM_ShipTypeThruster[];
extern const struct EnumItem ENUM_PropulsionFuelStatus[];
extern const struct EnumItem ENUM_ShipFlightState[];
extern const struct EnumItem ENUM_ShipJumpStatus[];
extern const struct EnumItem ENUM_ShipAlertStatus[];
extern const struct EnumItem ENUM_ShipAICmdName[];
extern const struct EnumItem ENUM_ShipControllerFlightControlState[];
extern const struct EnumItem ENUM_DualLaserOrientation[];
extern const struct EnumItem ENUM_ShipTypeTag[];
extern const struct EnumItem ENUM_ProjectableTypes[];
extern const struct EnumItem ENUM_ProjectableBases[];
extern const struct EnumItem ENUM_SystemViewColorIndex[];
extern const struct EnumItem ENUM_EconType[];
extern const struct EnumItem ENUM_CommodityType[];
extern const struct EnumItem ENUM_PolitEcon[];
extern const struct EnumItem ENUM_PolitGovType[];
extern const struct EnumItem ENUM_BodyType[];
extern const struct EnumItem ENUM_BodySuperType[];
extern const struct EnumItem ENUM_GameUIFaceFlags[];
extern const struct EnumItem ENUM_DetailLevel[];
extern const struct EnumItem ENUM_FileSystemRoot[];
extern const struct EnumItem ENUM_PiGUIFaceFlags[];
extern const struct EnumItem ENUM_ModelDebugFlags[];
extern const struct EnumItem ENUM_ShipTypeThruster[];
extern const struct EnumItem ENUM_PropulsionFuelStatus[];
extern const struct EnumItem ENUM_ShipControllerFlightControlState[];
extern const struct EnumItem ENUM_UIAlignDirection[];
extern const struct EnumItem ENUM_UIAnimationType[];
extern const struct EnumItem ENUM_UIAnimationEasing[];

View File

@ -31,6 +31,7 @@
#include "Ship.h"
#include "SpaceStation.h"
#include "Star.h"
#include "SystemView.h"
#include "galaxy/StarSystem.h"
#include "gameui/Lua.h"
@ -71,6 +72,7 @@ namespace Lua {
LuaObject<StarSystem>::RegisterClass();
LuaObject<SystemPath>::RegisterClass();
LuaObject<SystemView>::RegisterClass();
LuaObject<SystemBody>::RegisterClass();
LuaObject<Random>::RegisterClass();
LuaObject<Faction>::RegisterClass();

View File

@ -11,6 +11,7 @@
#include "Intro.h"
#include "KeyBindings.h"
#include "Lang.h"
#include "LuaColor.h"
#include "LuaConstants.h"
#include "LuaObject.h"
#include "LuaPiGui.h"
@ -336,6 +337,14 @@ static int l_engine_set_fullscreen(lua_State *l)
return 0;
}
static int l_engine_get_enum_value(lua_State *l)
{
auto enum_name = LuaPull<const char *>(l, 1);
auto enum_tag = LuaPull<const char *>(l, 2);
LuaPush<int>(l, EnumStrings::GetValue(enum_name, enum_tag));
return 1;
}
static int l_engine_get_disable_screenshot_info(lua_State *l)
{
LuaPush<bool>(l, Pi::config->Int("DisableScreenshotInfo") != 0);
@ -1077,7 +1086,7 @@ static int l_engine_get_sector_map_factions(lua_State *l)
lua_setfield(l, -2, "faction");
lua_pushboolean(l, hidden.count(f) == 0);
lua_setfield(l, -2, "visible"); // inner table
lua_settable(l, -3); // outer table
lua_settable(l, -3); // outer table
}
return 1;
}
@ -1195,16 +1204,14 @@ void LuaEngine::Register()
{ "SectorMapMoveRouteItemUp", l_engine_sector_map_move_route_item_up },
{ "SectorMapMoveRouteItemDown", l_engine_sector_map_move_route_item_down },
{ "SectorMapRemoveRouteItem", l_engine_sector_map_remove_route_item },
{ "SectorMapClearRoute", l_engine_sector_map_clear_route },
{ "SectorMapAddToRoute", l_engine_sector_map_add_to_route },
{ "SearchNearbyStarSystemsByName", l_engine_search_nearby_star_systems_by_name },
{ "ShipSpaceToScreenSpace", l_engine_ship_space_to_screen_space },
{ "CameraSpaceToScreenSpace", l_engine_camera_space_to_screen_space },
{ "WorldSpaceToScreenSpace", l_engine_world_space_to_screen_space },
{ "WorldSpaceToShipSpace", l_engine_world_space_to_ship_space },
{ "GetEnumValue", l_engine_get_enum_value },
{ 0, 0 }
};

View File

@ -336,6 +336,28 @@ static int l_game_attr_system(lua_State *l)
return 1;
}
/*
* Attribute: systemView
*
* The <SystemView> object for the system map view class
*
* Availability:
*
* February 2020
*
* Status:
*
* experiment
*/
static int l_game_attr_systemview(lua_State *l)
{
if (!Pi::game)
lua_pushnil(l);
else
LuaObject<SystemView>::PushToLua(Pi::game->GetSystemView());
return 1;
}
/*
* Attribute: time
*
@ -613,7 +635,7 @@ static int l_game_get_hyperspace_travelled_percentage(lua_State *l)
static int l_game_get_parts_from_date_time(lua_State *l)
{
float time = LuaPull<float>(l, 1);
double time = LuaPull<double>(l, 1);
Time::DateTime t(time);
int year, month, day, hour, minute, second;
t.GetDateParts(&year, &month, &day);
@ -662,6 +684,7 @@ void LuaGame::Register()
static const luaL_Reg l_attrs[] = {
{ "player", l_game_attr_player },
{ "system", l_game_attr_system },
{ "systemView", l_game_attr_systemview },
{ "time", l_game_attr_time },
{ "paused", l_game_attr_paused },
{ 0, 0 }

View File

@ -7,6 +7,7 @@
#include "LuaObject.h"
#include "LuaUtils.h"
#include "Pi.h"
#include "SectorView.h"
#include "Space.h"
#include "galaxy/Galaxy.h"
#include "galaxy/StarSystem.h"
@ -655,6 +656,27 @@ static int l_sbody_attr_children(lua_State *l)
return 1;
}
static int l_sbody_attr_is_moon(lua_State *l)
{
LuaPush<bool>(l, LuaObject<SystemBody>::CheckFromLua(1)->IsMoon());
return 1;
}
static int l_sbody_attr_physics_body(lua_State *l)
{
SystemBody *b = LuaObject<SystemBody>::CheckFromLua(1);
Body *physbody = nullptr;
SystemPath headpath = Pi::game->GetSectorView()->GetSelected().SystemOnly();
SystemPath gamepath = Pi::game->GetSpace()->GetStarSystem()->GetPath();
if (headpath == gamepath) {
RefCountedPtr<StarSystem> ss = Pi::game->GetGalaxy()->GetStarSystem(headpath);
SystemPath path = ss->GetPathOf(b);
physbody = Pi::game->GetSpace()->FindBodyForPath(&path);
}
LuaObject<Body>::PushToLua(physbody);
return 1;
}
template <>
const char *LuaObject<SystemBody>::s_type = "SystemBody";
@ -694,6 +716,8 @@ void LuaObject<SystemBody>::RegisterClass()
{ "path", l_sbody_attr_path },
{ "body", l_sbody_attr_body },
{ "children", l_sbody_attr_children },
{ "isMoon", l_sbody_attr_is_moon },
{ "physicsBody", l_sbody_attr_physics_body },
{ 0, 0 }
};

436
src/lua/LuaSystemView.cpp Normal file
View File

@ -0,0 +1,436 @@
// Copyright © 2008-2020 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
#include "EnumStrings.h"
#include "Game.h"
#include "LuaColor.h"
#include "LuaObject.h"
#include "LuaVector.h"
#include "LuaVector2.h"
#include "Pi.h"
#include "Player.h"
#include "SystemView.h"
#include "graphics/Graphics.h"
LuaTable projectable_to_lua_row(Projectable &p, lua_State *l)
{
LuaTable proj_table(l, 0, 3);
proj_table.Set("type", int(p.type));
if (p.type == Projectable::NONE) return proj_table;
proj_table.Set("base", int(p.base));
if (p.base == Projectable::SYSTEMBODY)
proj_table.Set("ref", const_cast<SystemBody *>(p.ref.sbody));
else
proj_table.Set("ref", const_cast<Body *>(p.ref.body));
return proj_table;
}
static int l_systemview_set_color(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
auto color_index = static_cast<SystemView::ColorIndex>(EnumStrings::GetValue("SystemViewColorIndex", LuaPull<const char *>(l, 2)));
auto color_value = LuaColor::CheckFromLua(l, 3);
sv->SetColor(color_index, color_value);
return 0;
}
static int l_systemview_set_selected_object(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
Projectable::types type = static_cast<Projectable::types>(luaL_checkinteger(l, 2));
Projectable::bases base = static_cast<Projectable::bases>(luaL_checkinteger(l, 3));
if (base == Projectable::SYSTEMBODY)
sv->SetSelectedObject(type, base, LuaObject<SystemBody>::CheckFromLua(4));
else
sv->SetSelectedObject(type, base, LuaObject<Body>::CheckFromLua(4));
return 0;
}
bool too_near(const vector3d &a, const vector3d &b, const vector2d &gain)
{
return std::abs(a.x - b.x) < gain.x && std::abs(a.y - b.y) < gain.y
// we dont want to group objects that simply overlap and are located at different distances
// therefore, depth is also taken into account, we have z_NDC (normalized device coordinates)
// in order to make a strict translation of delta z_NDC into delta "pixels", one also needs to know
// the z coordinates in the camera space. I plan to implement this later
// at the moment I just picked up a number that works well (6.0)
&& std::abs(a.z - b.z) * Graphics::GetScreenWidth() * 6.0 < gain.x;
};
/*
* Method: GetProjectedGrouped
*
* Get a table of projected point objects from the SystemView class, having
* previously grouped them.
*
* In the process of rendering the current frame in a SystemView class, an
* array of visible point objects (centers of planets, ships, special points
* of orbits) is created. This function creates a lua table based on this
* array, after grouping them according to certain criteria.
*
* Resulting table:
*
* {
* *** ORBIT ICONS (apoapsis, periapsis) ***
*
* { screenCoordinates: vector2d
* mainObject (see struct Projectable in SystemView.h)
* { type: Projectable::types
* base: Projectable::bases
* ref: SystemBody* or Body*
* }
* objects (if multiple only, main object is duplicated there)
* {
* {type, base, ref}
* {type, base, ref}
* ...
* }
* hasPlayer: boolean
* hasCombatTarget: boolean
* hasNavTarget: boolean
* }
* { screencoordinates, mainobject, ... }
* { screencoordinates, mainobject, ... }
* ...
*
* *** LAGRANGE ICONS ***
* { screenCoordinates, mainObject, ... }
* { screenCoordinates, mainObject, ... }
* ...
*
* *** BODY ICONS (stars, planets, ships) ***
* { screenCoordinates, mainObject, ... }
* { screenCoordinates, mainObject, ... }
* ...
*
* }
*
*
* Availability:
*
* 2020-03
*
* Status:
*
* experimental
*/
static int l_systemview_get_projected_grouped(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
const vector2d gap = LuaPull<vector2d>(l, 2);
std::vector<Projectable> projected = sv->GetProjected();
// types of special object
const int NOT_SPECIAL = -1;
const int SO_PLAYER = 0;
const int SO_COMBATTARGET = 1;
const int SO_NAVTARGET = 2;
const int NUMBER_OF_SO_TYPES = 3;
Projectable *special_object[NUMBER_OF_SO_TYPES] = { nullptr, nullptr, nullptr };
const char *special_object_lua_name[NUMBER_OF_SO_TYPES] = { "hasPlayer", "hasCombatTarget", "hasNavTarget" };
struct GroupInfo {
Projectable m_mainObject;
std::vector<Projectable> m_objects;
bool m_hasSpecialObject[NUMBER_OF_SO_TYPES] = { false, false, false };
GroupInfo(Projectable p) :
m_mainObject(p)
{
m_objects.push_back(p);
}
};
// use forward_list to concatenate
std::vector<GroupInfo> bodyIcons;
std::vector<GroupInfo> orbitIcons;
std::vector<GroupInfo> lagrangeIcons;
const Body *nav_target = Pi::game->GetPlayer()->GetNavTarget();
const Body *combat_target = Pi::game->GetPlayer()->GetCombatTarget();
const Body *player_body = static_cast<Body *>(Pi::game->GetPlayer());
for (Projectable &p : projected) {
// --- icons---
if (p.type == Projectable::APOAPSIS || p.type == Projectable::PERIAPSIS)
// orbit icons - just take all
orbitIcons.push_back(GroupInfo(p));
else if (p.type == Projectable::L4 || p.type == Projectable::L5) {
// lagrange icons - take only those who don't intersect with other lagrange icons
bool intersect = false;
for (GroupInfo &group : lagrangeIcons) {
if (too_near(p.screenpos, group.m_mainObject.screenpos, gap)) {
intersect = true;
break;
}
}
if (!intersect) lagrangeIcons.push_back(GroupInfo(p));
} else {
// --- real objects ---
int object_type = NOT_SPECIAL;
bool inserted = false;
// check if p is special object, and remember it's type
if (p.base == Projectable::SYSTEMBODY) {
if (nav_target && p.ref.sbody == nav_target->GetSystemBody()) object_type = SO_NAVTARGET;
//system body can't be a combat target and can't be a player
} else {
if (nav_target && p.ref.body == nav_target)
object_type = SO_NAVTARGET;
else if (combat_target && p.ref.body == combat_target)
object_type = SO_COMBATTARGET;
else if (p.base == Projectable::PLAYER)
object_type = SO_PLAYER;
}
for (GroupInfo &group : bodyIcons) {
if (too_near(p.screenpos, group.m_mainObject.screenpos, gap)) {
// object inside group boundaries
// special object is not added
// special objects must be added to nearest group, this group could be not nearest
if (object_type == NOT_SPECIAL) {
group.m_objects.push_back(p);
} else
// remember it separately
special_object[object_type] = &p;
inserted = true;
break;
}
}
if (!inserted) {
// object is not inside a group
// special object is nearest to itself, so we remember it as a new group
// create new group
GroupInfo newgroup(p);
if (object_type != NOT_SPECIAL) newgroup.m_hasSpecialObject[object_type] = true;
bodyIcons.push_back(std::move(newgroup));
}
}
} // for (Projectable &p : projected)
// adding overlapping special object to nearest group
for (int object_type = 0; object_type < NUMBER_OF_SO_TYPES; object_type++)
if (special_object[object_type]) {
std::vector<GroupInfo *> touchedGroups;
// first we get all groups, touched this object
for (GroupInfo &group : bodyIcons)
if (too_near(special_object[object_type]->screenpos, group.m_mainObject.screenpos, gap))
// object inside group boundaries: remember this group
touchedGroups.push_back(&group);
//now select the nearest group (if have)
if (touchedGroups.size()) {
GroupInfo *nearest;
double min_length = 1e64;
for (GroupInfo *&g : touchedGroups) {
double this_length = (g->m_mainObject.screenpos - special_object[object_type]->screenpos).Length();
if (this_length < min_length) {
nearest = g;
min_length = this_length;
}
}
nearest->m_hasSpecialObject[object_type] = true;
nearest->m_objects.push_back(*special_object[object_type]);
} else {
//don't touching any group, create a new one
GroupInfo newgroup(*special_object[object_type]);
newgroup.m_hasSpecialObject[object_type] = true;
bodyIcons.push_back(std::move(newgroup));
}
}
//no need to sort, because the bodies are so recorded in good order
//because they are written recursively starting from the root
//body of the system, and ships go after the system bodies
LuaTable result(l, orbitIcons.size() + lagrangeIcons.size() + bodyIcons.size(), 0);
int index = 1;
//the sooner is displayed, the more in the background
// so it goes orbitIcons->lagrangeIcons->bodies
for (auto groups : { orbitIcons, lagrangeIcons, bodyIcons }) {
for (GroupInfo &group : groups) {
LuaTable info_table(l, 0, 6);
info_table.Set("screenCoordinates", group.m_mainObject.screenpos);
info_table.Set("mainObject", projectable_to_lua_row(group.m_mainObject, l));
lua_pop(l, 1);
if (group.m_objects.size() > 1) {
LuaTable objects_table(l, group.m_objects.size(), 0);
int objects_table_index = 1;
for (Projectable &pj : group.m_objects) {
objects_table.Set(objects_table_index++, projectable_to_lua_row(pj, l));
lua_pop(l, 1);
}
info_table.Set("objects", objects_table);
lua_pop(l, 1);
}
for (int object_type = 0; object_type < NUMBER_OF_SO_TYPES; object_type++)
info_table.Set(special_object_lua_name[object_type], group.m_hasSpecialObject[object_type]);
result.Set(index++, info_table);
lua_pop(l, 1);
}
}
LuaPush(l, result);
return 1;
}
static int l_systemview_get_selected_object(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
Projectable *p = sv->GetSelectedObject();
LuaPush(l, projectable_to_lua_row(*p, l));
return 1;
}
static int l_systemview_set_visibility(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
sv->SetVisibility(LuaPull<std::string>(l, 2));
return 0;
}
static int l_systemview_get_orbit_planner_start_time(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
double t = sv->GetOrbitPlannerStartTime();
if (std::fabs(t) < 1.)
lua_pushnil(l);
else
LuaPush<double>(l, t);
return 1;
}
static int l_systemview_get_orbit_planner_time(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
double t = sv->GetOrbitPlannerTime();
LuaPush<double>(l, t);
return 1;
}
static int l_systemview_accelerate_time(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
if (lua_isnil(l, 2))
sv->SetRealTime();
else {
double step = LuaPull<double>(l, 2);
sv->AccelerateTime(step);
}
return 0;
}
static int l_systemview_set_rotate_mode(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
bool b = LuaPull<bool>(l, 2);
sv->SetRotateMode(b);
return 0;
}
static int l_systemview_set_zoom_mode(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
bool b = LuaPull<bool>(l, 2);
sv->SetZoomMode(b);
return 0;
}
static int l_systemview_transfer_planner_get(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
std::string key = LuaPull<std::string>(l, 2);
TransferPlanner *planner = sv->GetTransferPlanner();
if (key == "prograde") {
LuaPush<double>(l, planner->GetDv(BurnDirection::PROGRADE));
} else if (key == "normal") {
LuaPush<double>(l, planner->GetDv(BurnDirection::NORMAL));
} else if (key == "radial") {
LuaPush<double>(l, planner->GetDv(BurnDirection::RADIAL));
} else if (key == "starttime") {
LuaPush<double>(l, planner->GetStartTime());
} else if (key == "factor") {
LuaPush<double>(l, planner->GetFactor() * 10); // factor is shown as "x 10"
} else {
Warning("Unknown transfer planner key %s\n", key.c_str());
lua_pushnil(l);
}
return 1;
}
static int l_systemview_transfer_planner_add(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
std::string key = LuaPull<std::string>(l, 2);
double delta = LuaPull<double>(l, 3);
TransferPlanner *planner = sv->GetTransferPlanner();
if (key == "prograde") {
planner->AddDv(BurnDirection::PROGRADE, delta);
} else if (key == "normal") {
planner->AddDv(BurnDirection::NORMAL, delta);
} else if (key == "radial") {
planner->AddDv(BurnDirection::RADIAL, delta);
} else if (key == "starttime") {
planner->AddStartTime(delta);
} else if (key == "factor") {
if (delta > 0)
planner->IncreaseFactor();
else
planner->DecreaseFactor();
} else {
Warning("Unknown transfer planner key %s\n", key.c_str());
}
return 0;
}
static int l_systemview_transfer_planner_reset(lua_State *l)
{
SystemView *sv = LuaObject<SystemView>::CheckFromLua(1);
std::string key = LuaPull<std::string>(l, 2);
TransferPlanner *planner = sv->GetTransferPlanner();
if (key == "prograde") {
planner->ResetDv(BurnDirection::PROGRADE);
} else if (key == "normal") {
planner->ResetDv(BurnDirection::NORMAL);
} else if (key == "radial") {
planner->ResetDv(BurnDirection::RADIAL);
} else if (key == "starttime") {
planner->ResetStartTime();
} else if (key == "factor") {
planner->ResetFactor();
} else {
Warning("Unknown transfer planner key %s\n", key.c_str());
}
return 0;
}
template <>
const char *LuaObject<SystemView>::s_type = "SystemView";
template <>
void LuaObject<SystemView>::RegisterClass()
{
static const luaL_Reg l_methods[] = {
{ "GetProjectedGrouped", l_systemview_get_projected_grouped },
{ "GetSelectedObject", l_systemview_get_selected_object },
{ "GetOrbitPlannerStartTime", l_systemview_get_orbit_planner_start_time },
{ "GetOrbitPlannerTime", l_systemview_get_orbit_planner_time },
{ "AccelerateTime", l_systemview_accelerate_time },
{ "SetSelectedObject", l_systemview_set_selected_object },
{ "SetVisibility", l_systemview_set_visibility },
{ "SetColor", l_systemview_set_color },
{ "SetRotateMode", l_systemview_set_rotate_mode },
{ "SetZoomMode" , l_systemview_set_zoom_mode },
{ "TransferPlannerAdd", l_systemview_transfer_planner_add },
{ "TransferPlannerGet", l_systemview_transfer_planner_get },
{ "TransferPlannerReset", l_systemview_transfer_planner_reset },
{ NULL, NULL }
};
LuaObjectBase::CreateClass(s_type, nullptr, l_methods, 0, 0);
}

View File

@ -5,8 +5,8 @@
#define PIGUI_FACE_H
#include "FaceParts.h"
#include "SmartPtr.h"
#include "Pi.h"
#include "SmartPtr.h"
#include "graphics/Drawables.h"
#include "graphics/Texture.h"
@ -14,12 +14,12 @@ namespace PiGUI {
class Face : public RefCounted {
public:
Face(FaceParts::FaceDescriptor& face, Uint32 seed = 0);
Face(FaceParts::FaceDescriptor &face, Uint32 seed = 0);
Uint32 GetTextureId();
vector2f GetTextureSize();
enum Flags { // <enum scope='GameUI::Face' name=GameUIFaceFlags public>
enum Flags { // <enum scope='PiGUI::Face' name=PiGUIFaceFlags public>
RAND = 0,
MALE = (1 << 0),
FEMALE = (1 << 1),