pioneerspacesim/pioneer — pull request #2731 by lwho (2014-02-08 21:47:20+00:00)
Title: Fix "ship:AIFlyTo() cannot be called on a ship in hyperspace"

This fixes #2701 by delaying hyperjumps to the next time step, so that Lua events that already have been queued are delivered before entering hyperspace (like the ```onShipCollided``` which caused the issue in this case). I introduced a new flight state ```JUMPING``` where the ship is still moving, but can not collide anymore.

To test, I used the following patch, that causes launching trade ships to fall back on the spaceport (by prolonging the hyperspace countdown to >10s) and then fast-forwards the hyperspace countdown to 0.001s on collision to enforce jump in the same time step. (Am I happy, that we didn't fix the jumping above ground port, yet ;)).

This patch reproduced the issue without my fix and did not show the issue with the fix.

```diff
diff --git a/src/Ship.cpp b/src/Ship.cpp
index c742b35..62bfb16 100644
--- a/src/Ship.cpp
+++ b/src/Ship.cpp
@@ -443,6 +443,8 @@ bool Ship::OnCollision(Object *b, Uint32 flags, double relVel)
{
LuaEvent::Queue("onShipCollided", this,
b->IsType(Object::CITYONPLANET) ? dynamic_cast(b)->GetPlanet() : dynamic_cast(b));
+ if (IsHyperspaceActive())
+ m_hyperspace.countdown = 0.001; // DEBUG CODE NOT TO BE COMMITTED
}

return DynamicBody::OnCollision(b, flags, relVel);
@@ -655,7 +657,7 @@ Ship::HyperjumpStatus Ship::StartHyperspaceCountdown(const SystemPath &dest)
m_hyperspace.dest = dest;

Equip::Type t = m_equipment.Get(Equip::SLOT_ENGINE);
- m_hyperspace.countdown = 1.0f + Equip::types[t].pval;
+ m_hyperspace.countdown = 10.0f + Equip::types[t].pval; // DEBUG CODE: INCREASED TO 10 SEC. DO NOT COMMIT.
m_hyperspace.now = false;

return Ship::HYPERJUMP_OK;
```