Skip to content

Commit

Permalink
Merge pull request #4907 from Gliese852/safe-hyperspace
Browse files Browse the repository at this point in the history
No more crashes when hyperjumping
  • Loading branch information
Webster Sheets authored Sep 9, 2020
2 parents a839eca + 5490eb5 commit ca6d23a
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 106 deletions.
2 changes: 1 addition & 1 deletion data/libs/Equipment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ HyperdriveType.HyperjumpTo = function (self, ship, destination)
return ship:InitiateHyperjumpTo(destination, warmup_time, duration, sounds), fuel_use, duration
end

HyperdriveType.OnEnterHyperspace = function (self, ship)
HyperdriveType.OnLeaveHyperspace = function (self, ship)
if ship:hasprop('nextJumpFuelUse') then
local amount = ship.nextJumpFuelUse
ship:RemoveEquip(self.fuel, amount)
Expand Down
6 changes: 1 addition & 5 deletions data/libs/Ship.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1015,12 +1015,9 @@ local onEnterSystem = function (ship)
end
end
end
end

local onLeaveSystem = function (ship)
local engine = ship:GetEquip("engine", 1)
if engine then
engine:OnEnterHyperspace(ship)
engine:OnLeaveHyperspace(ship)
end
end

Expand All @@ -1036,7 +1033,6 @@ local onShipDestroyed = function (ship, attacker)
end

Event.Register("onEnterSystem", onEnterSystem)
Event.Register("onLeaveSystem", onLeaveSystem)
Event.Register("onShipDestroyed", onShipDestroyed)
Event.Register("onGameStart", onGameStart)
Serializer:Register("ShipClass", serialize, unserialize)
Expand Down
165 changes: 85 additions & 80 deletions data/pigui/modules/hyperjump-planner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,27 @@ local function showInfo()
local total_duration = 0
local total_distance = 0

local start = current_path
-- Tally up totals for the entire jump plan
for _,jump in pairs(hyperjump_route) do
local status, distance, fuel, duration = player:GetHyperspaceDetails(start, jump.path)

total_fuel = total_fuel + fuel
total_duration = total_duration + duration
total_distance = total_distance + distance

start = jump.path
end

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)
-- we can only have the current path in normal space
if current_path then
local start = current_path
-- Tally up totals for the entire jump plan
for _,jump in pairs(hyperjump_route) do
local status, distance, fuel, duration = player:GetHyperspaceDetails(start, jump.path)

total_fuel = total_fuel + fuel
total_duration = total_duration + duration
total_distance = total_distance + distance

start = jump.path
end

if ui.selectable(current_system.name .. " (" .. current_path.sectorX .. ", " .. current_path.sectorY .. ", " .. current_path.sectorZ ..")") then
sectorView:SwitchToPath(current_path)
end
else -- no current path => we are hyperjumping => no current system
ui.text("---")
end

textIcon(icons.route_destination, lui.FINAL_TARGET)
Expand Down Expand Up @@ -184,84 +189,84 @@ 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
function()
sectorView:AddToRoute(map_selected_path)
updateHyperspaceTarget()
selected_jump = #hyperjump_route
end)
ui.sameLine()

mainButton(icons.current_line, lui.REMOVE_JUMP,
function()
local new_route = {}
local new_count = 0
if selected_jump then
sectorView:RemoveRouteItem(selected_jump)
end
updateHyperspaceTarget()
function()
local new_route = {}
local new_count = 0
if selected_jump then
sectorView:RemoveRouteItem(selected_jump)
end
updateHyperspaceTarget()
end)
ui.sameLine()

mainButton(icons.current_periapsis, lui.MOVE_UP,
function()
if selected_jump then
if sectorView:MoveRouteItemUp(selected_jump) then
selected_jump = selected_jump - 1
end
function()
if selected_jump then
if sectorView:MoveRouteItemUp(selected_jump) then
selected_jump = selected_jump - 1
end
updateHyperspaceTarget()
end
updateHyperspaceTarget()
end)
ui.sameLine()

mainButton(icons.current_apoapsis, lui.MOVE_DOWN,
function()
if selected_jump then
if sectorView:MoveRouteItemDown(selected_jump) then
selected_jump = selected_jump + 1
end
function()
if selected_jump then
if sectorView:MoveRouteItemDown(selected_jump) then
selected_jump = selected_jump + 1
end
updateHyperspaceTarget()
end
updateHyperspaceTarget()
end)
ui.sameLine()

mainButton(icons.retrograde_thin, lui.CLEAR_ROUTE,
function()
sectorView:ClearRoute()
updateHyperspaceTarget()
function()
sectorView:ClearRoute()
updateHyperspaceTarget()
end)
ui.sameLine()

mainButton(icons.hyperspace, lui.AUTO_ROUTE,
function()
local result = sectorView:AutoRoute()
if result == "NO_DRIVE" then
mb.OK(lui.NO_DRIVE)
elseif result == "NO_VALID_ROUTE" then
mb.OK(lui.NO_VALID_ROUTE)
end
updateHyperspaceTarget()
function()
local result = sectorView:AutoRoute()
if result == "NO_DRIVE" then
mb.OK(lui.NO_DRIVE)
elseif result == "NO_VALID_ROUTE" then
mb.OK(lui.NO_VALID_ROUTE)
end
updateHyperspaceTarget()
end)
ui.sameLine()

mainButton(icons.search_lens, lui.CENTER_ON_SYSTEM,
function()
if selected_jump then
sectorView:GotoSystemPath(hyperjump_route[selected_jump].path)
end
function()
if selected_jump then
sectorView:GotoSystemPath(hyperjump_route[selected_jump].path)
end
end)

ui.separator()

local clicked
ui.child("routelist", function()
for jumpIndex, jump in pairs(hyperjump_route) do
ui.withStyleColors({["Text"] = jump.color},
for jumpIndex, jump in pairs(hyperjump_route) do
ui.withStyleColors({["Text"] = jump.color},
function()
if ui.selectable(jump.textLine, jumpIndex == selected_jump) then
clicked = jumpIndex
end
end)
end -- for
end)
end -- for
end --function
)

Expand All @@ -288,13 +293,13 @@ function hyperJumpPlanner.updateInRoute(path)
end

local function showHyperJumpPlannerWindow()
textIcon(icons.route)
ui.sameLine()
ui.text(lui.HYPERJUMP_ROUTE)
ui.separator()
showInfo()
ui.separator()
showJumpRoute()
textIcon(icons.route)
ui.sameLine()
ui.text(lui.HYPERJUMP_ROUTE)
ui.separator()
showInfo()
ui.separator()
showJumpRoute()
end -- showHyperJumpPlannerWindow

function hyperJumpPlanner.Dummy()
Expand Down Expand Up @@ -332,17 +337,17 @@ end
function hyperJumpPlanner.display()
player = Game.player
if not textIconSize then
textIconSize = ui.calcTextSize("H")
textIconSize.x = textIconSize.y -- make square
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
current_path = current_system.path
current_fuel = player:CountEquip(fuel_type,"cargo")
map_selected_path = sectorView:GetSelectedSystemPath()
route_jumps = sectorView:GetRouteSize()
showHyperJumpPlannerWindow()
local drive = table.unpack(player:GetEquip("engine")) or nil
local fuel_type = drive and drive.fuel or Equipment.cargo.hydrogen
current_system = Game.system -- will be nil during the hyperjump
current_path = Game.system and current_system.path -- will be nil during the hyperjump
current_fuel = player:CountEquip(fuel_type,"cargo")
map_selected_path = sectorView:GetSelectedSystemPath()
route_jumps = sectorView:GetRouteSize()
showHyperJumpPlannerWindow()
end -- hyperJumpPlanner.display

function hyperJumpPlanner.setSectorView(sv)
Expand All @@ -356,14 +361,14 @@ function hyperJumpPlanner.onShipEquipmentChanged(ship, equipment)
end

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
if ship:IsPlayer() and remove_first_if_current then
if route_jumps > 0 and hyperjump_route[1].path:IsSameSystem(Game.system.path) then
sectorView:RemoveRouteItem(1)
end
-- 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
if ship:IsPlayer() and remove_first_if_current then
if route_jumps > 0 and hyperjump_route[1].path:IsSameSystem(Game.system.path) then
sectorView:RemoveRouteItem(1)
end
end
updateHyperspaceTarget()
end

Expand Down
2 changes: 1 addition & 1 deletion data/pigui/modules/system-view-ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ local hideSystemViewWindows = false
local function displaySystemViewUI()
player = Game.player
local current_view = Game.CurrentView()
if current_view == "system" and not Game.InHyperspace() then
if current_view == "system" 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
Expand Down
33 changes: 33 additions & 0 deletions src/AnimationCurves.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#define ANIMATIONCURVES_H

#include "FloatComparison.h"
#include "Pi.h"
#include <cmath>

namespace AnimationCurves {

Expand All @@ -26,6 +28,37 @@ namespace AnimationCurves {
if (newDelta * delta < 0) cur = target;
}

// easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
// p should go from 0.0 to 1.0
inline float InOutQuadraticEasing(float p)
{
float m = p - 1.0;
float t = p * 2.0;
if (t < 1)
return p * t;
else
return 1.0 - m * m * 2.0;
}

// easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
// p should go from 0.0 to 1.0
inline float InOutCubicEasing(float p)
{
float m = p - 1.0;
float t = p * 2.0;
if (t < 1)
return p * t * t;
else
return 1.0 + m * m * m * 4.0;
}

// easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
// p should go from 0.0 to 1.0
inline float InOutSineEasing(float p)
{
return 0.5 * (1.0 - std::cos(p * M_PI));
}

} // namespace AnimationCurves

#endif
8 changes: 8 additions & 0 deletions src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,14 @@ void Game::TimeStep(float step)
if (Pi::game->GetTime() >= m_hyperspaceEndTime) {
SwitchToNormalSpace();
m_player->EnterSystem();
// event "onEnterSystem(player)" is in the event queue after p_player->EnterSystem()
// in this callback, for example, fuel is reduced
// but event handling has already passed, and will only be in the next frame
// it turns out that we are already in the system, but the fuel has not yet been reduced
// and then the drawing of the views will go, and inconsistencies may occur,
// for example, the sphere of the hyperjump range will be too large
// so we forcefully call event handling again
LuaEvent::Emit();
RequestTimeAccel(TIMEACCEL_1X);
} else
m_hyperspaceProgress += step;
Expand Down
Loading

0 comments on commit ca6d23a

Please sign in to comment.