diff --git a/data/lang/core/en.json b/data/lang/core/en.json index adc4c9ddcf8..ea4867e1dfd 100644 --- a/data/lang/core/en.json +++ b/data/lang/core/en.json @@ -699,6 +699,22 @@ "description" : "Short for latitude", "message" : "Lat:" }, + "LATITUDE_NORTH_ABBREV" : { + "description" : "Abbreviation letter for latitude 'north'", + "message" : "N" + }, + "LATITUDE_SOUTH_ABBREV" : { + "description" : "Abbreviation letter for latitude 'south'", + "message" : "S" + }, + "LONGITUDE_EAST_ABBREV" : { + "description" : "Abbreviation letter for longitude 'east'", + "message" : "E" + }, + "LONGITUDE_WEST_ABBREV" : { + "description" : "Abbreviation letter for latitude 'west'", + "message" : "W" + }, "LEGAL_CURRENT_SYSTEM" : { "description" : "Short (tooltip) description of commodity (singular) status in the system the player is currently in", "message" : "Legal (current system):" diff --git a/data/lang/ui-core/en.json b/data/lang/ui-core/en.json index 5feb359f62f..b8417119574 100644 --- a/data/lang/ui-core/en.json +++ b/data/lang/ui-core/en.json @@ -439,6 +439,30 @@ "description" : "Game settings option: for graphics resolution", "message" : "High" }, + "HUD_FORWARD_GUN_TEMPERATURE" : { + "description": "Tooltip: Forward Gun Temperature.", + "message": "Forward Gun Temperature" + }, + "HUD_BACKWARD_GUN_TEMPERATURE" : { + "description": "Tooltip: Backward Gun Temperature.", + "message": "Backward Gun Temperature" + }, + "HUD_ATMOSPHERIC_PRESSURE" : { + "description": "Tooltip: Atmospheric Pressure.", + "message": "Atmospheric Pressure" + }, + "HUD_HULL_TEMPERATURE" : { + "description": "Tooltip: Hull Temperature.", + "message": "Hull Temperature" + }, + "HUD_HULL_STRENGTH" : { + "description": "Tooltip: Hull Strength.", + "message": "Hull Strength" + }, + "HUD_SHIELD_STRENGTH" : { + "description": "Tooltip: Shield Strength.", + "message": "Shield Strength" + }, "HUD_SPEED_RELATIVE_TO_TARGET" : { "description": "Tooltip: The speed relative to the target.", "message": "The speed relative to the target" diff --git a/data/pigui/game.lua b/data/pigui/game.lua index 57fb8deb488..c571d9f7238 100644 --- a/data/pigui/game.lua +++ b/data/pigui/game.lua @@ -774,6 +774,7 @@ ui.registerHandler( else displayOnScreenObjects() displayReticule() + ui.displayPlayerGauges() callModules("game") end else diff --git a/data/pigui/modules/gauges.lua b/data/pigui/modules/gauges.lua new file mode 100644 index 00000000000..5b808a8f27b --- /dev/null +++ b/data/pigui/modules/gauges.lua @@ -0,0 +1,63 @@ +local Engine = import('Engine') +local Game = import('Game') +local ui = import('pigui/pigui.lua') +local Vector = import('Vector') +local Color = import('Color') +local Lang = import("Lang") +local lc = Lang.GetResource("core"); +local lui = Lang.GetResource("ui-core"); +local utils = import("utils") +local Event = import("Event") + +local pionillium = ui.fonts.pionillium +local pionicons = ui.fonts.pionicons +local colors = ui.theme.colors +local icons = ui.theme.icons + + +function addGauge(priority, valueFun, unit, format, min, max, icon, color, tooltip) + ui.registerGauge(function() + local v = valueFun() + return { value = v, unit = unit, format = format, min = min, max = max, icon = icon, color = color, tooltip = tooltip } + end + , priority) +end + +addGauge(0, function () + local t = Game.player:GetGunTemperature(0) * 100 + if t and t > 0 then + return t + else + return nil + end + end, '%', '%i', 0, 100, icons.forward, colors.gaugeWeapon, lui.HUD_FORWARD_GUN_TEMPERATURE) +addGauge(1, function () + local t = Game.player:GetGunTemperature(1) * 100 + if t and t > 0 then + return t + else + return nil + end + end, '%', '%i', 0, 100, icons.backward, colors.gaugeWeapon, lui.HUD_BACKWARD_GUN_TEMPERATURE) +addGauge(2, function () + local frame = Game.player.frameBody + if frame then + local pressure, density = frame:GetAtmosphericState() + return pressure + else + return nil + end + end, + 'atm', '%.2f', 0, 15, icons.pressure, colors.gaugePressure, lui.HUD_ATMOSPHERIC_PRESSURE) +addGauge(3, function () + local t = Game.player:GetHullTemperature() * 100 + if t and t > 0 then + return t + else + return nil + end + end, '%', '%i', 0, 100, icons.temperature, colors.gaugeTemperature, lui.HUD_HULL_TEMPERATURE) +addGauge(4, function () return Game.player:GetHullPercent() end, '%', '%i', 0, 100, icons.hull, colors.gaugeHull, lui.HUD_HULL_STRENGTH) +addGauge(5, function () return Game.player:GetShieldsPercent() end, '%', '%i', 0, 100, icons.shield, colors.gaugeShield, lui.HUD_SHIELD_STRENGTH) + +return {} diff --git a/data/pigui/modules/planetary-info.lua b/data/pigui/modules/planetary-info.lua new file mode 100644 index 00000000000..6cba54cf996 --- /dev/null +++ b/data/pigui/modules/planetary-info.lua @@ -0,0 +1,50 @@ +local Engine = import('Engine') +local Game = import('Game') +local ui = import('pigui/pigui.lua') +local Vector = import('Vector') +local Color = import('Color') +local Lang = import("Lang") +local lc = Lang.GetResource("core"); +local lui = Lang.GetResource("ui-core"); +local utils = import("utils") +local Event = import("Event") + +local player = nil +local pionillium = ui.fonts.pionillium +local pionicons = ui.fonts.pionicons +local colors = ui.theme.colors +local icons = ui.theme.icons + +local iconSize = Vector(16,16) + +local function displayPlanetaryInfo() + local player = Game.player + local alt, vspd, latitude, longitude = player:GetGPS() + if latitude and longitude and alt and vspd then + ui.setNextWindowSize(Vector(140,120), "Always") + ui.window("PlanetaryInfo", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus"}, + function() + ui.withFont(pionillium.medium.name, pionillium.medium.size, function() + ui.icon(icons.altitude, iconSize, colors.reticuleCircle) + ui.sameLine() + local altitude,altitude_unit = ui.Format.Distance(alt) + ui.text(altitude .. altitude_unit) + ui.icon(icons.normal, iconSize, colors.reticuleCircle) + ui.sameLine() + local speed,speed_unit = ui.Format.Distance(vspd) + ui.text(speed .. speed_unit) + ui.icon(icons.latitude, iconSize, colors.reticuleCircle) + ui.sameLine() + ui.text(ui.Format.Latitude(latitude)) + ui.icon(icons.longitude, iconSize, colors.reticuleCircle) + ui.sameLine() + ui.text(ui.Format.Longitude(longitude)) + + end) + end) + end +end + +ui.registerModule("game", displayPlanetaryInfo) + +return {} diff --git a/data/pigui/modules/time-window.lua b/data/pigui/modules/time-window.lua index b3850132fd6..9d166b2edba 100644 --- a/data/pigui/modules/time-window.lua +++ b/data/pigui/modules/time-window.lua @@ -49,6 +49,7 @@ local function displayTimeWindow() ui.withFont(pionillium.large.name, pionillium.large.size, function() local text_size = ui.calcTextSize(date) local window_size = Vector(math.max(text_size.x, (button_size.x + frame_padding * 2 + 7) * 6) + 15, text_size.y + button_size.y + frame_padding * 2 + 15) + ui.timeWindowSize = window_size ui.setNextWindowSize(window_size, "Always") ui.setNextWindowPos(Vector(0, ui.screenHeight - window_size.y), "Always") ui.window("Time", {"NoTitleBar", "NoResize", "NoSavedSettings", "NoFocusOnAppearing", "NoBringToFrontOnFocus"}, function() diff --git a/data/pigui/pigui.lua b/data/pigui/pigui.lua index b69c6b5e26b..d185e99ba6d 100644 --- a/data/pigui/pigui.lua +++ b/data/pigui/pigui.lua @@ -27,6 +27,29 @@ local one_over_sqrt_two = 1 / math.sqrt(2) local ui = { } +local defaultTheme = import("themes/default") +ui.theme = defaultTheme + +-- font sizes are correct for 1920x1200 +local font_factor = pigui.screen_height / 1200.0 +ui.fonts = { + -- dummy font, actually renders icons + pionicons = { + small = { name = "icons", size = 16 * font_factor, offset = 14 * font_factor}, + medium = { name = "icons", size = 18 * font_factor, offset = 20 * font_factor}, + large = { name = "icons", size = 22 * font_factor, offset = 28 * font_factor} + }, + pionillium = { + large = { name = "pionillium", size = 30 * font_factor, offset = 24 * font_factor}, + medium = { name = "pionillium", size = 18 * font_factor, offset = 14 * font_factor}, + -- medsmall = { name = "pionillium", size = 15, offset = 12 }, + small = { name = "pionillium", size = 12 * font_factor, offset = 10 * font_factor}, + tiny = { name = "pionillium", size = 8 * font_factor, offset = 7 * font_factor}, + } +} + +ui.anchor = { left = 1, right = 2, center = 3, top = 4, bottom = 5, baseline = 6 } + local function maybeSetTooltip(tooltip) if not Game.player:IsMouseActive() then pigui.SetTooltip(tooltip) @@ -117,6 +140,30 @@ ui.circleSegments = function(radius) end ui.Format = { + Latitude = function(decimal_degrees) + local deg = math.floor(decimal_degrees + 0.5) + local dec = math.abs(decimal_degrees - deg) + local prefix = lc.LATITUDE_NORTH_ABBREV + if deg < 0 then + prefix = lc.LATITUDE_SOUTH_ABBREV + deg = math.abs(deg) + end + local min = dec * 60 + local sec = (min - math.floor(min)) * 60 + return string.format('%s %03i°%02i\'%02i"', prefix, deg, min, sec) + end, + Longitude = function(decimal_degrees) + local deg = math.floor(decimal_degrees + 0.5) + local dec = math.abs(decimal_degrees - deg) + local prefix = lc.LONGITUDE_EAST_ABBREV + if deg < 0 then + prefix = lc.LONGITUDE_WEST_ABBREV + deg = math.abs(deg) + end + local min = dec * 60 + local sec = (min - math.floor(min)) * 60 + return string.format('%s %03i°%02i\'%02i"', prefix, deg, min, sec) + end, Duration = function(duration, elements) -- shown elements items (2 -> wd or dh, 3 -> dhm or hms) local negative = false @@ -218,26 +265,6 @@ ui.pointOnClock = function(center, radius, hours) return Vector(center.x, center.y) + Vector(p.x * math.cos(a) - p.y * math.sin(a), p.y * math.cos(a) + p.x * math.sin(a)) end --- font sizes are correct for 1920x1200 -local font_factor = pigui.screen_height / 1200.0 -ui.fonts = { - -- dummy font, actually renders icons - pionicons = { - small = { name = "icons", size = 16 * font_factor, offset = 14 * font_factor}, - medium = { name = "icons", size = 18 * font_factor, offset = 20 * font_factor}, - large = { name = "icons", size = 22 * font_factor, offset = 28 * font_factor} - }, - pionillium = { - large = { name = "pionillium", size = 30 * font_factor, offset = 24 * font_factor}, - medium = { name = "pionillium", size = 18 * font_factor, offset = 14 * font_factor}, - -- medsmall = { name = "pionillium", size = 15, offset = 12 }, - small = { name = "pionillium", size = 12 * font_factor, offset = 10 * font_factor}, - tiny = { name = "pionillium", size = 8 * font_factor, offset = 7 * font_factor}, - } -} - -ui.anchor = { left = 1, right = 2, center = 3, top = 4, bottom = 5, baseline = 6 } - ui.calcTextAlignment = function(pos, size, anchor_horizontal, anchor_vertical) local position = Vector(pos.x, pos.y) if anchor_horizontal == ui.anchor.left or anchor_horizontal == nil then @@ -274,7 +301,7 @@ ui.addIcon = function(position, icon, color, size, anchor_horizontal, anchor_ver else pigui.AddImage(ui.icons_texture, pos, pos + Vector(size, size), uv0, uv1, color) end - if tooltip and not pigui.IsMouseHoveringAnyWindow() and tooltip ~= "" then + if tooltip and (pigui.IsMouseHoveringWindow() or not pigui.IsMouseHoveringAnyWindow()) and tooltip ~= "" then if pigui.IsMouseHoveringRect(pos, pos + size, true) then maybeSetTooltip(tooltip) end @@ -364,7 +391,7 @@ ui.addStyledText = function(position, anchor_horizontal, anchor_vertical, text, pigui.AddText(position, color, text) -- pigui.AddQuad(position, position + Vector(size.x, 0), position + Vector(size.x, size.y), position + Vector(0, size.y), colors.red, 1.0) end) - if tooltip and not pigui.IsMouseHoveringAnyWindow() and tooltip ~= "" then + if tooltip and (pigui.IsMouseHoveringWindow() or not pigui.IsMouseHoveringAnyWindow()) and tooltip ~= "" then if pigui.IsMouseHoveringRect(position, position + size, true) then maybeSetTooltip(tooltip) end @@ -448,13 +475,79 @@ ui.coloredSelectedIconButton = function(icon, size, is_selected, frame_padding, end return res end + +local gauge_show_percent = true +ui.gauge_height = 25 +ui.gauge_width = 275 + +ui.gauge = function(position, value, unit, format, minimum, maximum, icon, color, tooltip) + local percent = (value - minimum) / (maximum - minimum) + local offset = 60 + local uiPos = position + ui.withFont(ui.fonts.pionillium.medium.name, ui.fonts.pionillium.medium.size, function() + ui.addLine(uiPos, uiPos + Vector(ui.gauge_width, 0), ui.theme.colors.gaugeBackground, ui.gauge_height) + if gauge_show_percent then + local one_hundred = ui.calcTextSize("100") + uiPos = uiPos + Vector(one_hundred.x * 1.2, 0) -- 1.2 for a bit of slack + ui.addStyledText(uiPos + Vector(0, ui.gauge_height/8), ui.anchor.right, ui.anchor.center, string.format("%i", percent * 100), ui.theme.colors.reticuleCircle, ui.fonts.pionillium.medium, tooltip) + end + uiPos = uiPos + Vector(ui.gauge_height * 1.2, 0) + ui.addIcon(uiPos - ui.gauge_height/2, icon, ui.theme.colors.reticuleCircle, ui.gauge_height, ui.anchor.center, ui.anchor.top, tooltip) + local w = (position.x + ui.gauge_width) - uiPos.x + ui.addLine(uiPos, uiPos + Vector(w * percent, 0), color, ui.gauge_height) + ui.addFancyText(uiPos + Vector(ui.gauge_height/2, -ui.gauge_height/6), ui.anchor.left, ui.anchor.top, { + { text=string.format(format, value), color=ui.theme.colors.reticuleCircle, font=ui.fonts.pionillium.small, tooltip=tooltip }, + { text=unit, color=ui.theme.colors.reticuleCircleDark, font=ui.fonts.pionillium.small, tooltip=tooltip }}, + ui.theme.colors.gaugeBackground) + end) + +end + +local gauges = {} + +ui.registerGauge = function(fun, priority) + table.insert(gauges, {fun = fun, priority = priority}) + table.sort(gauges, function(a,b) return a.priority < b.priority end) +end + +ui.displayPlayerGauges = function() + local gauge_stretch = 1.4 + local current_view = Game.CurrentView() + local c = 0 + for k,v in pairs(gauges) do + local g = v.fun() + if g and g.value then + c = c + 1 + end + end + c = c + 0.1 + if current_view == "world" then + ui.setNextWindowSize(Vector(ui.gauge_width, ui.gauge_height * c * gauge_stretch), "Always") + local tws = ui.timeWindowSize + if not tws then + tws = Vector(0, 100) + end + tws = tws + Vector(0, 30) -- extra offset + ui.setNextWindowPos(Vector(5, ui.screenHeight - tws.y - ui.gauge_height * c * gauge_stretch), "Always") + ui.window("PlayerGauges", {"NoTitleBar", "NoResize", "NoFocusOnAppearing", "NoBringToFrontOnFocus"}, + function() + local uiPos = ui.getWindowPos() + Vector(0, ui.gauge_height) + for k,v in pairs(gauges) do + local g = v.fun() + if g and g.value then + ui.gauge(uiPos, g.value, g.unit, g.format, g.min, g.max, g.icon, g.color, g.tooltip) + uiPos = uiPos + Vector(0, ui.gauge_height * gauge_stretch) + end + end + end) + end +end + ui.loadTextureFromSVG = function(a, b, c) return pigui:LoadTextureFromSVG(a, b, c) end ui.dataDirPath = pigui.DataDirPath ui.addImage = pigui.AddImage -local defaultTheme = import("themes/default") -ui.theme = defaultTheme local modules = {} diff --git a/data/pigui/themes/default.lua b/data/pigui/themes/default.lua index e238a87b28a..cca2346772a 100644 --- a/data/pigui/themes/default.lua +++ b/data/pigui/themes/default.lua @@ -32,6 +32,12 @@ theme.colors = { buttonBlue = Color(150, 150, 200, 255), white = Color(255,255,255,255), grey = Color(120,120,120,255), + gaugeBackground = Color(40, 40, 70), + gaugePressure = Color(150,150,230), + gaugeTemperature = Color(200,0,0), + gaugeShield = Color(150,150,230), + gaugeHull = Color(230,230,230), + gaugeWeapon = Color(255,165, 0), } theme.icons = { diff --git a/src/FixedGuns.cpp b/src/FixedGuns.cpp index 6c32452a811..6f1e13ed922 100644 --- a/src/FixedGuns.cpp +++ b/src/FixedGuns.cpp @@ -85,7 +85,7 @@ void FixedGuns::InitGun( SceneGraph::Model *m, const char *tag, int num) m_gun[num].pos = trans.GetTranslate(); m_gun[num].dir = trans.GetOrient().VectorZ(); } else { - Output("WARNING: tag %s not found for gun %i\n", tag, num); + // Output("WARNING: tag %s not found for gun %i\n", tag, num); // XXX deprecated m_gun[num].pos = (num==Guns::GUN_FRONT) ? vector3f(0,0,0) : vector3f(0,0,0); m_gun[num].dir = (num==Guns::GUN_REAR) ? vector3f(0,0,-1) : vector3f(0,0,1); @@ -133,12 +133,12 @@ bool FixedGuns::Fire( int num, Body* b ) { if (!m_gun_present[num]) return false; if (!m_is_firing[num]) return false; - Output("Firing gun %i, present\n", num); - Output(" is firing\n"); + // Output("Firing gun %i, present\n", num); + // Output(" is firing\n"); if (m_recharge_stat[num]>0) return false; - Output(" recharge stat <= 0\n"); + // Output(" recharge stat <= 0\n"); if (m_temperature_stat[num] > 1.0) return false; - Output(" temperature stat <= 1.0\n"); + // Output(" temperature stat <= 1.0\n"); const vector3d dir = b->GetOrient() * vector3d(m_gun[num].dir); const vector3d pos = b->GetOrient() * vector3d(m_gun[num].pos) + b->GetPosition(); diff --git a/src/LuaBody.cpp b/src/LuaBody.cpp index 05c0aecf2a0..56a1e9c5644 100644 --- a/src/LuaBody.cpp +++ b/src/LuaBody.cpp @@ -684,6 +684,22 @@ static int l_body_get_projected_screen_position(lua_State *l) return pushOnScreenPositionDirection(l, p); } +static int l_body_get_atmospheric_state(lua_State *l) { + Body *b = LuaObject
::CheckFromLua(1); + // const SystemBody *sb = b->GetSystemBody(); + vector3d pos = Pi::player->GetPosition(); + double center_dist = pos.Length(); + if (b->IsType(Object::PLANET)) { + double pressure, density; + static_cast