Exemplo n.º 1
0
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);
    }
}
Exemplo n.º 2
0
/*
 * 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;
}
Exemplo n.º 3
0
/*
 * 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;
}
Exemplo n.º 4
0
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;
}