Пример #1
0
static int l_sbody_attr_children(lua_State *l)
{
  SystemBody * sbody = LuaObject<SystemBody>::CheckFromLua(1);
  LuaTable children(l);
  int i = 1;
  for (auto child : sbody->GetChildren()) {
	LuaPush(l, i++);
	LuaObject<SystemBody>::PushToLua(child);
	lua_settable(l, -3);
  }
  return 1;
}
Пример #2
0
/*
 * Attribute: parent
 *
 * The parent of the body, as a <SystemBody>. A body orbits its parent.
 *
 * Availability:
 *
 *   alpha 14
 *
 * Status:
 *
 *   stable
 */
static int l_sbody_attr_parent(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);

	// sbody->parent is 0 as it was cleared by the acquirer. we need to go
	// back to the starsystem proper to get what we need.
	RefCountedPtr<StarSystem> s = Pi::game->GetGalaxy()->GetStarSystem(sbody->GetPath());
	SystemBody *live_sbody = s->GetBodyByPath(sbody->GetPath());

	if (!live_sbody->GetParent())
		return 0;

	LuaObject<SystemBody>::PushToLua(live_sbody->GetParent());
	return 1;
}
Пример #3
0
static int l_sbody_attr_body(lua_State *l)
{
  SystemBody * sbody = LuaObject<SystemBody>::CheckFromLua(1);
  if(Pi::game) {
	Space *space = Pi::game->GetSpace();
	if(space) {
	  const SystemPath &path = sbody->GetPath();
	  Body *body = space->FindBodyForPath(&path);
	  if(body) {
		LuaObject<Body>::PushToLua(body);
	  } else {
		lua_pushnil(l);
	  }
	}
  } else {
	lua_pushnil(l);
  }
  return 1;
}
Пример #4
0
vector3d Space::GetHyperspaceExitPoint(const SystemPath &source, const SystemPath &dest) const
{
	assert(m_starSystem);
	assert(source.IsSystemPath());

	assert(dest.IsSameSystem(m_starSystem->GetPath()));

	RefCountedPtr<const Sector> source_sec = m_sectorCache->GetCached(source);
	RefCountedPtr<const Sector> dest_sec = m_sectorCache->GetCached(dest);

	Sector::System source_sys = source_sec->m_systems[source.systemIndex];
	Sector::System dest_sys = dest_sec->m_systems[dest.systemIndex];

	const vector3d sourcePos = vector3d(source_sys.GetPosition()) + vector3d(source.sectorX, source.sectorY, source.sectorZ);
	const vector3d destPos = vector3d(dest_sys.GetPosition()) + vector3d(dest.sectorX, dest.sectorY, dest.sectorZ);

	Body *primary = 0;
	if (dest.IsBodyPath()) {
		assert(dest.bodyIndex < m_starSystem->GetNumBodies());
		primary = FindBodyForPath(&dest);
		while (primary && primary->GetSystemBody()->GetSuperType() != SystemBody::SUPERTYPE_STAR) {
			SystemBody* parent = primary->GetSystemBody()->GetParent();
			primary = parent ? FindBodyForPath(&parent->GetPath()) : 0;
		}
	}
	if (!primary) {
		// find the first non-gravpoint. should be the primary star
		for (Body* b : GetBodies())
			if (b->GetSystemBody()->GetType() != SystemBody::TYPE_GRAVPOINT) {
				primary = b;
				break;
			}
	}
	assert(primary);

	// point along the line between source and dest, a reasonable distance
	// away based on the radius (don't want to end up inside black holes, and
	// then mix it up so that ships don't end up on top of each other
	vector3d pos = (sourcePos - destPos).Normalized() * (primary->GetSystemBody()->GetRadius()/AU+1.0)*11.0*AU*Pi::rng.Double(0.95,1.2) + MathUtil::RandomPointOnSphere(5.0,20.0)*1000.0;
	assert(pos.Length() > primary->GetSystemBody()->GetRadius());
	return pos + primary->GetPositionRelTo(GetRootFrame());
}
Пример #5
0
static void position_system_lights(Frame *camFrame, Frame *frame, std::vector<Camera::LightSource> &lights)
{
	if (lights.size() > 3) return;

	SystemBody *body = frame->GetSystemBody();
	// IsRotFrame check prevents double counting
	if (body && !frame->IsRotFrame() && (body->GetSuperType() == SystemBody::SUPERTYPE_STAR)) {
		vector3d lpos = frame->GetPositionRelTo(camFrame);
		const double dist = lpos.Length() / AU;
		lpos *= 1.0/dist; // normalize

		const float *col = StarSystem::starRealColors[body->type];

		const Color lightCol(col[0], col[1], col[2], 0.f);
		vector3f lightpos(lpos.x, lpos.y, lpos.z);
		lights.push_back(Camera::LightSource(frame->GetBody(), Graphics::Light(Graphics::Light::LIGHT_DIRECTIONAL, lightpos, lightCol, lightCol)));
	}

	for (Frame::ChildIterator it = frame->BeginChildren(); it != frame->EndChildren(); ++it) {
		position_system_lights(camFrame, *it, lights);
	}
}
Пример #6
0
static int l_set_hyperspace_target(lua_State *l)
{
	LuaObject<Player>::CheckFromLua(1);
	if (Pi::game->IsNormalSpace()) {
		const SystemPath path = *LuaObject<SystemPath>::CheckFromLua(2);
		if (!path.IsSystemPath()) {
			if (!path.IsBodyPath()) {
				return luaL_error(l, "Player:SetHyperspaceTarget() -- second parameter is not a system path or the path of a star");
			}
			RefCountedPtr<StarSystem> sys = Pi::game->GetGalaxy()->GetStarSystem(path);
			// Lua should never be able to get an invalid SystemPath
			// (note: this may change if it becomes possible to remove systems during the game)
			assert(path.bodyIndex < sys->GetNumBodies());
			SystemBody *sbody = sys->GetBodyByPath(path);
			if (!sbody->GetSuperType() == SystemBody::SUPERTYPE_STAR)
				return luaL_error(l, "Player:SetHyperspaceTarget() -- second parameter is not a system path or the path of a star");
		}
		Pi::game->GetSectorView()->SetHyperspaceTarget(path);
		return 0;
	} else
		return luaL_error(l, "Player:SetHyperspaceTarget() cannot be used while in hyperspace");
}
Пример #7
0
/*
 * Function: SpawnShipLandedNear
 *
 * Create a ship and place it on the surface near the given <Body>.
 *
 * > ship = Space.SpawnShipLandedNear(type, body, min, max)
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   body - the <Body> near which the ship should be spawned. It must be on the ground or close to it,
 *          i.e. it must be in the rotating frame of the planetary body.
 *
 *   min - minimum distance from the surface point below the body to place the ship, in Km
 *
 *   max - maximum distance to place the ship
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship
 *
 * Example:
 *
 * > -- spawn a ship 10km from the player
 * > local ship = Ship.SpawnShipLandedNear("viper_police", Game.player, 10, 10)
 *
 * Availability:
 *
 *   July 2013
 *
 * Status:
 *
 *   experimental
 */
static int l_space_spawn_ship_landed_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);
    const float min_dist = luaL_checknumber(l, 3);
    const float max_dist = luaL_checknumber(l, 4);
    if (min_dist > max_dist)
        luaL_error(l, "min_dist must not be larger than max_dist");

    Ship *ship = new Ship(type);
    assert(ship);

    // XXX protect against spawning inside the body
    Frame * newframe = nearbody->GetFrame()->GetRotFrame();
    if (!newframe->IsRotFrame())
        luaL_error(l, "Body must be in rotating frame");
    SystemBody *sbody = newframe->GetSystemBody();
    if (sbody->GetSuperType() != SystemBody::SUPERTYPE_ROCKY_PLANET)
        luaL_error(l, "Body is not on a rocky planet");
    if (max_dist > sbody->GetRadius())
        luaL_error(l, "max_dist too large for planet radius");
    // We assume that max_dist is much smaller than the planet radius, i.e. that our area is reasonably flat
    // So, we
    const vector3d up = nearbody->GetPosition().Normalized();
    vector3d x;
    vector3d y;
    // Calculate a orthonormal basis for a horizontal plane. For numerical reasons we do that determining the smallest
    // coordinate and take the cross product with (1,0,0), (0,1,0) or (0,0,1) respectively to calculate the first vector.
    // The second vector is just the cross product of the up-vector and out first vector.
    if (up.x <= up.y && up.x <= up.z) {
        x = vector3d(0.0, up.z, -up.y).Normalized();
        y = vector3d(-up.y*up.y - up.z*up.z, up.x*up.y, up.x*up.z).Normalized();
    } else if (up.y <= up.x && up.y <= up.z) {
        x = vector3d(-up.z, 0.0, up.x).Normalized();
        y = vector3d(up.x*up.y, -up.x*up.x - up.z*up.z, up.y*up.z).Normalized();
    } else {
        x = vector3d(up.y, -up.x, 0.0).Normalized();
        y = vector3d(up.x*up.z, up.y*up.z, -up.x*up.x - up.y*up.y).Normalized();
    }
    Planet *planet = static_cast<Planet*>(newframe->GetBody());
    const double radius = planet->GetSystemBody()->GetRadius();
    const vector3d planar = MathUtil::RandomPointInCircle(min_dist * 1000.0, max_dist * 1000.0);
    vector3d pos = (radius * up + x * planar.x + y * planar.y).Normalized();
    float latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z));
    float longitude = atan2(pos.x, pos.z);

    Pi::game->GetSpace()->AddBody(ship);
    ship->SetLandedOn(planet, latitude, longitude);

    LuaObject<Ship>::PushToLua(ship);

    LUA_DEBUG_END(l, 1);

    return 1;
}
Пример #8
0
/*
 * Attribute: apoapsis
 *
 * The apoapsis of the body's orbit, in metres (m).
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_apoapsis(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetOrbMax()*AU);
	return 1;
}
Пример #9
0
/*
 * Attribute: superType
 *
 * The supertype of the body, as a <Constants.BodySuperType> constant
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  stable
 */
static int l_sbody_attr_super_type(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushstring(l, EnumStrings::GetString("BodySuperType", sbody->GetSuperType()));
	return 1;
}
Пример #10
0
static int l_sbody_attr_astro_description(lua_State *l)
{
	SystemBody * sbody = LuaObject<SystemBody>::CheckFromLua(1);
	LuaPush(l, sbody->GetAstroDescription());
	return 1;
}
Пример #11
0
/*
 * Attribute: orbitPeriod
 *
 * The orbit of the body, around its parent, in days, as a float
 *
 * Availability:
 *
 *   201708
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_orbital_period(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetOrbit().Period() / float(60*60*24));
	return 1;
}
Пример #12
0
/*
 * Attribute: eccentricity
 *
 * The orbital eccentricity of the body
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_eccentricty(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetEccentricity());
	return 1;
}
Пример #13
0
static int l_sbody_attr_path(lua_State *l)
{
	SystemBody * sbody = LuaObject<SystemBody>::CheckFromLua(1);
	LuaObject<SystemPath>::PushToLua(sbody->GetPath());
	return 1;
}
Пример #14
0
/*
 * Attribute: gravity
 *
 * The gravity on the surface of the body (m/s).
 *
 * Availability:
 *
 *   alpha 21
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_gravity(lua_State *l)
{
	SystemBody *sbody = LuaSystemBody::CheckFromLua(1);
	lua_pushnumber(l, sbody->CalcSurfaceGravity());
	return 1;
}
Пример #15
0
static int l_sbody_attr_is_scoopable(lua_State *l)
{
	SystemBody * sbody = LuaSystemBody::CheckFromLua(1);
	lua_pushboolean(l, sbody->IsScoopable());
	return 1;
}
Пример #16
0
/*
* Attribute: atmosOxidizing
*
* Returns the compositional value of any atmospheric gasses in the bodys atmosphere (if any)
* 0.0 = reducing (H2, NH3, etc), 1.0 = oxidising (CO2, O2, etc)
*
* Availability:
*
*   January 2018
*
* Status:
*
*   experimental
*/
static int l_sbody_attr_atmosOxidizing(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetAtmosOxidizing());
	return 1;
}
Пример #17
0
/*
 * Attribute: rotationPeriod
 *
 * The rotation period of the body, in days
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_rotation_period(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetRotationPeriodInDays());
	return 1;
}
Пример #18
0
/*
 * Attribute: averageTemp
 *
 * The average surface temperature of the body, in degrees kelvin
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_average_temp(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushinteger(l, sbody->GetAverageTemp());
	return 1;
}
Пример #19
0
/*
 * Attribute: axialTilt
 *
 * The axial tilt of the body, in radians
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_axial_tilt(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetAxialTilt());
	return 1;
}
Пример #20
0
/*
 * Attribute: index
 *
 * The body index of the body in its system
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  stable
 */
static int l_sbody_attr_index(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushinteger(l, sbody->GetPath().bodyIndex);
	return 1;
}
Пример #21
0
void Game::SwitchToNormalSpace()
{
	// remove the player from hyperspace
	m_space->RemoveBody(m_player.Get());

	// create a new space for the system
	const SystemPath &dest = m_player->GetHyperspaceDest();
	m_space.Reset(new Space(this, dest));

	// put the player in it
	m_player->SetFrame(m_space->GetRootFrame());
	m_space->AddBody(m_player.Get());

	// place it
	m_player->SetPosition(m_space->GetHyperspaceExitPoint(m_hyperspaceSource));
	m_player->SetVelocity(vector3d(0,0,-100.0));
	m_player->SetRotMatrix(matrix4x4d::Identity());

	// place the exit cloud
	HyperspaceCloud *cloud = new HyperspaceCloud(0, Pi::game->GetTime(), true);
	cloud->SetFrame(m_space->GetRootFrame());
	cloud->SetPosition(m_player->GetPosition());
	m_space->AddBody(cloud);

	for (std::list<HyperspaceCloud*>::iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) {
		cloud = *i;

		cloud->SetFrame(m_space->GetRootFrame());
		cloud->SetPosition(m_space->GetHyperspaceExitPoint(m_hyperspaceSource));

		m_space->AddBody(cloud);

		if (cloud->GetDueDate() < Pi::game->GetTime()) {
			// they emerged from hyperspace some time ago
			Ship *ship = cloud->EvictShip();

			ship->SetFrame(m_space->GetRootFrame());
			ship->SetVelocity(vector3d(0,0,-100.0));
			ship->SetRotMatrix(matrix4x4d::Identity());
			ship->Enable();
			ship->SetFlightState(Ship::FLYING);

			const SystemPath &sdest = ship->GetHyperspaceDest();
			if (sdest.IsSystemPath()) {
				// travelling to the system as a whole, so just dump them on
				// the cloud - we can't do any better in this case
				ship->SetPosition(cloud->GetPosition());
			}

			else {
				// on their way to a body. they're already in-system so we
				// want to simulate some travel to their destination. we
				// naively assume full accel for half the distance, flip and
				// full brake for the rest.
				Body *target_body = m_space->FindBodyForPath(&sdest);
				double dist_to_target = cloud->GetPositionRelTo(target_body).Length();
				double half_dist_to_target = dist_to_target / 2.0;
				double accel = -(ship->GetShipType().linThrust[ShipType::THRUSTER_FORWARD] / ship->GetMass());
				double travel_time = Pi::game->GetTime() - cloud->GetDueDate();

				// I can't help but feel some actual math would do better here
				double speed = 0;
				double dist = 0;
				while (travel_time > 0 && dist <= half_dist_to_target) {
					speed += accel;
					dist += speed;
					travel_time--;
				}
				while (travel_time > 0 && dist < dist_to_target) {
					speed -= accel;
					dist += speed;
					travel_time--;
				}

				if (travel_time <= 0) {
					vector3d pos =
						target_body->GetPositionRelTo(m_space->GetRootFrame()) +
						cloud->GetPositionRelTo(target_body).Normalized() * (dist_to_target - dist);
					ship->SetPosition(pos);
				}

				else {
					// ship made it with time to spare. just put it somewhere
					// near the body. the script should be issuing a dock or
					// flyto command in onEnterSystem so it should sort it
					// itself out long before the player can get near

					SystemBody *sbody = m_space->GetStarSystem()->GetBodyByPath(&sdest);
					if (sbody->type == SystemBody::TYPE_STARPORT_ORBITAL) {
						ship->SetFrame(target_body->GetFrame());
						ship->SetPosition(MathUtil::RandomPointOnSphere(1000.0)*1000.0); // somewhere 1000km out
					}

					else {
						if (sbody->type == SystemBody::TYPE_STARPORT_SURFACE) {
							sbody = sbody->parent;
							SystemPath path = m_space->GetStarSystem()->GetPathOf(sbody);
							target_body = m_space->FindBodyForPath(&path);
						}

						double sdist = sbody->GetRadius()*2.0;

						ship->SetFrame(target_body->GetFrame());
						ship->SetPosition(MathUtil::RandomPointOnSphere(sdist));
					}
				}
			}

			m_space->AddBody(ship);

			LuaEvent::Queue("onEnterSystem", ship);
		}
	}
	m_hyperspaceClouds.clear();

	m_state = STATE_NORMAL;
}
Пример #22
0
/*
 * Attribute: seed
 *
 * The random seed used to generate this <SystemBody>. This is guaranteed to
 * be the same for this body across runs of the same build of the game, and
 * should be used to seed a <Rand> object when you want to ensure the same
 * random numbers come out each time.
 *
 * This value is the same is the one available via <Body.seed> once you enter
 * this system.
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   stable
 */
static int l_sbody_attr_seed(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushinteger(l, sbody->GetSeed());
	return 1;
}
Пример #23
0
/*
* Attribute: volatileIces
*
* Returns the measure of volatile ices present on the body
* 0.0 = none, 1.0 = total ice cover (earth = 3%)
*
* Availability:
*
*   January 2018
*
* Status:
*
*   experimental
*/
static int l_sbody_attr_volatileIces(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetVolatileIces());
	return 1;
}
Пример #24
0
/*
 * Attribute: semiMajorAxis
 *
 * The semi-major axis of the orbit, in metres (m).
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_semi_major_axis(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetSemiMajorAxis()*AU);
	return 1;
}
Пример #25
0
/*
 * Attribute: mass
 *
 * The mass of the body, in kilograms (kg).
 *
 * Availability:
 *
 *   alpha 16
 *
 * Status:
 *
 *   experimental
 */
static int l_sbody_attr_mass(lua_State *l)
{
	SystemBody *sbody = LuaSystemBody::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetMass());
	return 1;
}
Пример #26
0
/*
* Attribute: life
*
* Returns the measure of life present on the body
* 0.0 = dead, 1.0 = teeming (~= pandora)
*
* Availability:
*
*   January 2018
*
* Status:
*
*   experimental
*/
static int l_sbody_attr_life(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushnumber(l, sbody->GetLife());
	return 1;
}
Пример #27
0
static int l_sbody_attr_has_atmosphere(lua_State *l)
{
	SystemBody * sbody = LuaSystemBody::CheckFromLua(1);
	lua_pushboolean(l, sbody->HasAtmosphere());
	return 1;
}
Пример #28
0
/*
 * Attribute: name
 *
 * The name of the body
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  stable
 */
static int l_sbody_attr_name(lua_State *l)
{
	SystemBody *sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushstring(l, sbody->GetName().c_str());
	return 1;
}
Пример #29
0
/*
 * Attribute: superType
 *
 * The supertype of the body, as a <Constants.BodySuperType> constant
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  stable
 */
static int l_sbody_attr_super_type(lua_State *l)
{
	SystemBody *sbody = LuaSystemBody::CheckFromLua(1);
	lua_pushstring(l, LuaConstants::GetConstantString(l, "BodySuperType", sbody->GetSuperType()));
	return 1;
}
Пример #30
0
static int l_sbody_attr_has_rings(lua_State *l)
{
	SystemBody * sbody = LuaObject<SystemBody>::CheckFromLua(1);
	lua_pushboolean(l, sbody->HasRings());
	return 1;
}