void Space::GenBody(SystemBody *sbody, Frame *f) { Body *b = 0; if (sbody->type != SystemBody::TYPE_GRAVPOINT) { if (sbody->GetSuperType() == SystemBody::SUPERTYPE_STAR) { Star *star = new Star(sbody); b = star; } else if ((sbody->type == SystemBody::TYPE_STARPORT_ORBITAL) || (sbody->type == SystemBody::TYPE_STARPORT_SURFACE)) { SpaceStation *ss = new SpaceStation(sbody); b = ss; } else { Planet *planet = new Planet(sbody); b = planet; } b->SetLabel(sbody->name.c_str()); b->SetPosition(vector3d(0,0,0)); AddBody(b); } f = MakeFrameFor(sbody, b, f); for (std::vector<SystemBody*>::iterator i = sbody->children.begin(); i != sbody->children.end(); ++i) { GenBody(*i, f); } }
/* * Function: SpawnShip * * Create a ship and place it somewhere in space. * * > ship = Space.SpawnShip(type, min, max, hyperspace) * * Parameters: * * type - the name of the ship * * min - minimum distance from the system centre (usually the primary star) * to place the ship, in AU * * max - maximum distance to place the ship * * hyperspace - optional table containing hyperspace entry information. If * this is provided the ship will not spawn directly. Instead, * a hyperspace cloud will be created that the ship will exit * from. The table contains two elements, a <SystemPath> for * the system the ship is travelling from, and the due * date/time that the ship should emerge from the cloud. * In this case min and max arguments are ignored. * * Return: * * ship - a <Ship> object for the new ship * * Examples: * * > -- spawn a ship 5-6AU from the system centre * > local ship = Ship.Spawn("eagle_lrf", 5, 6) * * > -- spawn a ship in the ~11AU hyperspace area and make it appear that it * > -- came from Sol and will arrive in ten minutes * > local ship = Ship.Spawn( * > "flowerfairy", 9, 11, * > { SystemPath:New(0,0,0), Game.time + 600 } * > ) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); float min_dist = luaL_checknumber(l, 2); float max_dist = luaL_checknumber(l, 3); SystemPath *path = NULL; double due = -1; _unpack_hyperspace_args(l, 4, path, due); Ship *ship = new Ship(type); assert(ship); Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body thing->SetFrame(Pi::game->GetSpace()->GetRootFrame()); if (path == NULL) thing->SetPosition(MathUtil::RandomPointOnSphere(min_dist, max_dist)*AU); else // XXX broken. this is ignoring min_dist & max_dist. otoh, what's the // correct behaviour given there's now a fixed hyperspace exit point? thing->SetPosition(Pi::game->GetSpace()->GetHyperspaceExitPoint(*path)); thing->SetVelocity(vector3d(0,0,0)); Pi::game->GetSpace()->AddBody(thing); LuaShip::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
/* * Function: SpawnShipNear * * Create a ship and place it in space near the given <Body>. * * > ship = Space.SpawnShip(type, body, min, max, hyperspace) * * Parameters: * * type - the name of the ship * * body - the <Body> near which the ship should be spawned * * min - minimum distance from the body to place the ship, in Km * * max - maximum distance to place the ship * * hyperspace - optional table containing hyperspace entry information. If * this is provided the ship will not spawn directly. Instead, * a hyperspace cloud will be created that the ship will exit * from. The table contains two elements, a <SystemPath> for * the system the ship is travelling from, and the due * date/time that the ship should emerge from the cloud. * * Return: * * ship - a <Ship> object for the new ship * * Example: * * > -- spawn a ship 10km from the player * > local ship = Ship.SpawnNear("viper_police_craft", Game.player, 10, 10) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship_near(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Body *nearbody = LuaObject<Body>::CheckFromLua(2); float min_dist = luaL_checknumber(l, 3); float max_dist = luaL_checknumber(l, 4); SystemPath *path = 0; double due = -1; _unpack_hyperspace_args(l, 5, path, due); Ship *ship = new Ship(type); assert(ship); Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body Frame * newframe = nearbody->GetFrame(); const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist)* 1000.0) + nearbody->GetPosition(); // If the frame is rotating and the chosen position is too far, use non-rotating parent. // Otherwise the ship will be given a massive initial velocity when it's bumped out of the // rotating frame in the next update if (newframe->IsRotFrame() && newframe->GetRadius() < newPosition.Length()) { assert(newframe->GetParent()); newframe = newframe->GetParent(); } thing->SetFrame(newframe);; thing->SetPosition(newPosition); thing->SetVelocity(vector3d(0,0,0)); Pi::game->GetSpace()->AddBody(thing); LuaObject<Ship>::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
Body *Body::Unserialize(Serializer::Reader &_rd, Space *space) { Serializer::Reader rd = _rd.RdSection("Body"); Body *b = 0; Object::Type type = Object::Type(rd.Int32()); switch (type) { case Object::STAR: b = new Star(); break; case Object::PLANET: b = new Planet(); break; case Object::SPACESTATION: b = new SpaceStation(); break; case Object::SHIP: b = new Ship(); break; case Object::PLAYER: b = new Player(); break; case Object::MISSILE: b = new Missile(); break; case Object::PROJECTILE: b = new Projectile(); break; case Object::CARGOBODY: b = new CargoBody(); break; case Object::HYPERSPACECLOUD: b = new HyperspaceCloud(); break; default: assert(0); } b->Load(rd, space); // must SetFrame() correctly so ModelBodies can add geom to space Frame *f = b->m_frame; b->m_frame = 0; b->SetFrame(f); // b->SetPosition(rd.Vector3d()); matrix4x4d m; for (int i=0; i<16; i++) m[i] = rd.Double(); b->SetRotMatrix(m); return b; }