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); } }
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"); }
/* * 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; }
/* * 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; }
/* * 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; }