/* * Method: GetDockedWith * * Get the station that the ship is currently docked with * * > station = ship:GetDockedWith() * * Return: * * station - a <SpaceStation> object for the station, or nil if the ship is * not docked * * Availability: * * alpha 10 * * Status: * * stable */ static int l_ship_get_docked_with(lua_State *l) { Ship *s = LuaObject<Ship>::CheckFromLua(1); if (s->GetFlightState() != Ship::DOCKED) return 0; LuaObject<SpaceStation>::PushToLua(s->GetDockedWith()); return 1; }
/* * Method: Undock * * Undock from the station currently docked with * * > success = ship:Undock() * * <Event.onShipUndocked> will be triggered once undocking is complete * * Return: * * success - true if ship is undocking, false if the ship is unable to undock, * probably because another ship is currently undocking * * Availability: * * alpha 10 * * Status: * * stable */ static int l_ship_undock(lua_State *l) { Ship *s = LuaObject<Ship>::CheckFromLua(1); if (!s->GetDockedWith()) luaL_error(l, "Can't undock if not already docked"); bool undocking = s->Undock(); lua_pushboolean(l, undocking); return 1; }
bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel) { if ((flags & 0x10) && (b->IsType(Object::SHIP))) { Ship *s = static_cast<Ship*>(b); matrix4x4d rot; GetRotMatrix(rot); bool canDock = true; int port = -1; for (int i=0; i<MAX_DOCKING_PORTS; i++) { if (m_shipDocking[i].ship == s) { port = i; break; } } if (m_type->dockOneAtATimePlease) { for (int i=0; i<m_type->numDockingPorts; i++) { if (m_shipDocking[i].ship && m_shipDocking[i].stage != 1 && (m_shipDocking[i].stage != m_type->numDockingStages+1)) { canDock = false; break; } } } else { // for non-dockOneAtATimePlease, the ship is expected // to hit the right docking trigger surface for that port if (m_shipDocking[flags&0xf].ship != s) canDock = false; } if (port == -1) canDock = false; // hitting docking area of a station if (canDock) { SpaceStationType::positionOrient_t dport; // why stage 2? Because stage 1 is permission to dock // granted, stage 2 is start of docking animation. PiVerify(m_type->GetDockAnimPositionOrient(port, 2, 0.0f, vector3d(0.0), dport, s)); double speed = s->GetVelocity().Length(); // must be oriented sensibly and have wheels down if (IsGroundStation()) { matrix4x4d shiprot; s->GetRotMatrix(shiprot); matrix4x4d invShipRot = shiprot.InverseOf(); vector3d dockingNormal = rot*dport.yaxis; // check player is sortof sensibly oriented for landing const double dot = vector3d(invShipRot[1], invShipRot[5], invShipRot[9]).Dot(dockingNormal); if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return false; } if ((speed < MAX_LANDING_SPEED) && (!s->GetDockedWith()) && (m_shipDocking[port].stage == 1)) { // if there is more docking port anim to do, // don't set docked yet if (m_type->numDockingStages >= 2) { shipDocking_t &sd = m_shipDocking[port]; sd.ship = s; sd.stage = 2; sd.stagePos = 0; sd.fromPos = rot.InverseOf() * (s->GetPosition() - GetPosition()); matrix4x4d temp; s->GetRotMatrix(temp); sd.fromRot = Quaterniond::FromMatrix4x4(temp); s->Disable(); s->ClearThrusterState(); s->SetFlightState(Ship::DOCKING); } else { s->SetDockedWith(this, port); LuaEvent::Queue("onShipDocked", s, this); } } } return false; } else { return true; } }