本文整理汇总了C++中Planet::GetSystemBody方法的典型用法代码示例。如果您正苦于以下问题:C++ Planet::GetSystemBody方法的具体用法?C++ Planet::GetSystemBody怎么用?C++ Planet::GetSystemBody使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Planet
的用法示例。
在下文中一共展示了Planet::GetSystemBody方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: l_space_spawn_ship_landed
/*
* Function: SpawnShipLanded
*
* Create a ship and place it landed on the given <Body>.
*
* > ship = Space.SpawnShipLanded(type, body, lat, long)
*
* Parameters:
*
* type - the name of the ship
*
* body - the <Body> near which the ship should be spawned
*
* lat - latitude in radians (like in custom body defintions)
*
* long - longitude in radians (like in custom body definitions)
*
* Return:
*
* ship - a <Ship> object for the new ship
*
* Example:
*
* > -- spawn 16km from L.A. when in Sol system
* > local earth = Space.GetBody(3)
* > local ship = Space.SpawnShipLanded("viper_police", earth, math.deg2rad(34.06473923), math.deg2rad(-118.1591568))
*
* Availability:
*
* July 2013
*
* Status:
*
* experimental
*/
static int l_space_spawn_ship_landed(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);
Planet *planet = LuaObject<Planet>::CheckFromLua(2);
if (planet->GetSystemBody()->GetSuperType() != SystemBody::SUPERTYPE_ROCKY_PLANET)
luaL_error(l, "Body is not a rocky planet");
float latitude = luaL_checknumber(l, 3);
float longitude = luaL_checknumber(l, 4);
Ship *ship = new Ship(type);
assert(ship);
Pi::game->GetSpace()->AddBody(ship);
ship->SetLandedOn(planet, latitude, longitude);
LuaObject<Ship>::PushToLua(ship);
LUA_DEBUG_END(l, 1);
return 1;
}
示例2: CalcLighting
// Calculates the ambiently and directly lit portions of the lighting model taking into account the atmosphere and sun positions at a given location
// 1. Calculates the amount of direct illumination available taking into account
// * multiple suns
// * sun positions relative to up direction i.e. light is dimmed as suns set
// * Thickness of the atmosphere overhead i.e. as atmospheres get thicker light starts dimming earlier as sun sets, without atmosphere the light switches off at point of sunset
// 2. Calculates the split between ambient and directly lit portions taking into account
// * Atmosphere density (optical thickness) of the sky dome overhead
// as optical thickness increases the fraction of ambient light increases
// this takes altitude into account automatically
// * As suns set the split is biased towards ambient
void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *camera)
{
const double minAmbient = 0.05;
ambient = minAmbient;
direct = 1.0;
Body *astro = GetFrame()->GetBody();
if ( ! (astro && astro->IsType(Object::PLANET)) )
return;
Planet *planet = static_cast<Planet*>(astro);
// position relative to the rotating frame of the planet
vector3d upDir = GetInterpPositionRelTo(planet->GetFrame());
const double planetRadius = planet->GetSystemBody()->GetRadius();
const double dist = std::max(planetRadius, upDir.Length());
upDir = upDir.Normalized();
double pressure, density;
planet->GetAtmosphericState(dist, &pressure, &density);
double surfaceDensity;
Color cl;
planet->GetSystemBody()->GetAtmosphereFlavor(&cl, &surfaceDensity);
// approximate optical thickness fraction as fraction of density remaining relative to earths
double opticalThicknessFraction = density/EARTH_ATMOSPHERE_SURFACE_DENSITY;
// tweak optical thickness curve - lower exponent ==> higher altitude before ambient level drops
// Commenting this out, since it leads to a sharp transition at
// atmosphereRadius, where density is suddenly 0
//opticalThicknessFraction = pow(std::max(0.00001,opticalThicknessFraction),0.15); //max needed to avoid 0^power
if (opticalThicknessFraction < 0.0001)
return;
//step through all the lights and calculate contributions taking into account sun position
double light = 0.0;
double light_clamped = 0.0;
const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources();
for(std::vector<Camera::LightSource>::const_iterator l = lightSources.begin();
l != lightSources.end(); ++l) {
double sunAngle;
// calculate the extent the sun is towards zenith
if (l->GetBody()){
// relative to the rotating frame of the planet
const vector3d lightDir = (l->GetBody()->GetInterpPositionRelTo(planet->GetFrame()).Normalized());
sunAngle = lightDir.Dot(upDir);
} else {
// light is the default light for systems without lights
sunAngle = 1.0;
}
const double critAngle = -sqrt(dist*dist-planetRadius*planetRadius)/dist;
//0 to 1 as sunangle goes from critAngle to 1.0
double sunAngle2 = (Clamp(sunAngle, critAngle, 1.0)-critAngle)/(1.0-critAngle);
// angle at which light begins to fade on Earth
const double surfaceStartAngle = 0.3;
// angle at which sun set completes, which should be after sun has dipped below the horizon on Earth
const double surfaceEndAngle = -0.18;
const double start = std::min((surfaceStartAngle*opticalThicknessFraction),1.0);
const double end = std::max((surfaceEndAngle*opticalThicknessFraction),-0.2);
sunAngle = (Clamp(sunAngle-critAngle, end, start)-end)/(start-end);
light += sunAngle;
light_clamped += sunAngle2;
}
light_clamped /= lightSources.size();
light /= lightSources.size();
// brightness depends on optical depth and intensity of light from all the stars
direct = 1.0 - Clamp((1.0 - light),0.0,1.0) * Clamp(opticalThicknessFraction,0.0,1.0);
// ambient light fraction
// alter ratio between directly and ambiently lit portions towards ambiently lit as sun sets
const double fraction = ( 0.2 + 0.8 * (1.0-light_clamped) ) * Clamp(opticalThicknessFraction,0.0,1.0);
// fraction of light left over to be lit directly
direct = (1.0-fraction)*direct;
// scale ambient by amount of light
ambient = fraction*(Clamp((light),0.0,1.0))*0.25;
ambient = std::max(minAmbient, ambient);
}
示例3: StaticUpdate
void Ship::StaticUpdate(const float timeStep)
{
// do player sounds before dead check, so they also turn off
if (IsType(Object::PLAYER)) DoThrusterSounds();
if (IsDead()) return;
if (m_controller) m_controller->StaticUpdate(timeStep);
if (GetHullTemperature() > 1.0)
Explode();
UpdateAlertState();
/* FUEL SCOOPING!!!!!!!!! */
int capacity = 0;
Properties().Get("fuel_scoop_cap", capacity);
if (m_flightState == FLYING && capacity > 0) {
Body *astro = GetFrame()->GetBody();
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet*>(astro);
if (p->GetSystemBody()->IsScoopable()) {
double dist = GetPosition().Length();
double pressure, density;
p->GetAtmosphericState(dist, &pressure, &density);
double speed = GetVelocity().Length();
vector3d vdir = GetVelocity().Normalized();
vector3d pdir = -GetOrient().VectorZ();
double dot = vdir.Dot(pdir);
if ((m_stats.free_capacity) && (dot > 0.95) && (speed > 2000.0) && (density > 1.0)) {
double rate = speed*density*0.00000333f*double(capacity);
if (Pi::rng.Double() < rate) {
lua_State *l = Lua::manager->GetLuaState();
pi_lua_import(l, "Equipment");
LuaTable hydrogen = LuaTable(l, -1).Sub("cargo").Sub("hydrogen");
LuaObject<Ship>::CallMethod(this, "AddEquip", hydrogen);
UpdateEquipStats();
if (this->IsType(Object::PLAYER)) {
Pi::game->log->Add(stringf(Lang::FUEL_SCOOP_ACTIVE_N_TONNES_H_COLLECTED,
formatarg("quantity", LuaObject<Ship>::CallMethod<int>(this, "CountEquip", hydrogen))));
}
lua_pop(l, 3);
}
}
}
}
}
// Cargo bay life support
capacity = 0;
Properties().Get("cargo_life_support_cap", capacity);
if (!capacity) {
// Hull is pressure-sealed, it just doesn't provide
// temperature regulation and breathable atmosphere
// kill stuff roughly every 5 seconds
if ((!m_dockedWith) && (5.0*Pi::rng.Double() < timeStep)) {
std::string t(Pi::rng.Int32(2) ? "live_animals" : "slaves");
lua_State *l = Lua::manager->GetLuaState();
pi_lua_import(l, "Equipment");
LuaTable cargo = LuaTable(l, -1).Sub("cargo");
if (LuaObject<Ship>::CallMethod<int>(this, "RemoveEquip", cargo.Sub(t))) {
LuaObject<Ship>::CallMethod<int>(this, "AddEquip", cargo.Sub("fertilizer"));
if (this->IsType(Object::PLAYER)) {
Pi::game->log->Add(Lang::CARGO_BAY_LIFE_SUPPORT_LOST);
}
lua_pop(l, 4);
}
else
lua_pop(l, 3);
}
}
if (m_flightState == FLYING)
m_launchLockTimeout -= timeStep;
if (m_launchLockTimeout < 0) m_launchLockTimeout = 0;
if (m_flightState == JUMPING || m_flightState == HYPERSPACE)
m_launchLockTimeout = 0;
// lasers
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
m_gun[i].recharge -= timeStep;
float rateCooling = 0.01f;
float cooler = 1.0f;
Properties().Get("laser_cooler_cap", cooler);
rateCooling *= cooler;
m_gun[i].temperature -= rateCooling*timeStep;
if (m_gun[i].temperature < 0.0f) m_gun[i].temperature = 0;
if (m_gun[i].recharge < 0.0f) m_gun[i].recharge = 0;
if (!m_gun[i].state) continue;
if (m_gun[i].recharge > 0.0f) continue;
if (m_gun[i].temperature > 1.0) continue;
FireWeapon(i);
}
if (m_ecmRecharge > 0.0f) {
//.........这里部分代码省略.........
示例4: l_space_spawn_ship_landed_near
/*
* 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;
}
示例5: StaticUpdate
void Ship::StaticUpdate(const float timeStep)
{
// do player sounds before dead check, so they also turn off
if (IsType(Object::PLAYER)) DoThrusterSounds();
if (IsDead()) return;
if (m_controller) m_controller->StaticUpdate(timeStep);
if (GetHullTemperature() > 1.0)
Explode();
UpdateAlertState();
/* FUEL SCOOPING!!!!!!!!! */
if ((m_flightState == FLYING) && (m_equipment.Get(Equip::SLOT_FUELSCOOP) != Equip::NONE)) {
Body *astro = GetFrame()->GetBody();
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet*>(astro);
if (p->GetSystemBody()->IsScoopable()) {
double dist = GetPosition().Length();
double pressure, density;
p->GetAtmosphericState(dist, &pressure, &density);
double speed = GetVelocity().Length();
vector3d vdir = GetVelocity().Normalized();
vector3d pdir = -GetOrient().VectorZ();
double dot = vdir.Dot(pdir);
if ((m_stats.free_capacity) && (dot > 0.95) && (speed > 2000.0) && (density > 1.0)) {
double rate = speed*density*0.00001f;
if (Pi::rng.Double() < rate) {
m_equipment.Add(Equip::HYDROGEN);
UpdateEquipStats();
if (this->IsType(Object::PLAYER)) {
Pi::Message(stringf(Lang::FUEL_SCOOP_ACTIVE_N_TONNES_H_COLLECTED,
formatarg("quantity", m_equipment.Count(Equip::SLOT_CARGO, Equip::HYDROGEN))));
}
}
}
}
}
}
// Cargo bay life support
if (m_equipment.Get(Equip::SLOT_CARGOLIFESUPPORT) != Equip::CARGO_LIFE_SUPPORT) {
// Hull is pressure-sealed, it just doesn't provide
// temperature regulation and breathable atmosphere
// kill stuff roughly every 5 seconds
if ((!m_dockedWith) && (5.0*Pi::rng.Double() < timeStep)) {
Equip::Type t = (Pi::rng.Int32(2) ? Equip::LIVE_ANIMALS : Equip::SLAVES);
if (m_equipment.Remove(t, 1)) {
m_equipment.Add(Equip::FERTILIZER);
if (this->IsType(Object::PLAYER)) {
Pi::Message(Lang::CARGO_BAY_LIFE_SUPPORT_LOST);
}
}
}
}
if (m_flightState == FLYING)
m_launchLockTimeout -= timeStep;
if (m_launchLockTimeout < 0) m_launchLockTimeout = 0;
// lasers
for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) {
m_gunRecharge[i] -= timeStep;
float rateCooling = 0.01f;
if (m_equipment.Get(Equip::SLOT_LASERCOOLER) != Equip::NONE) {
rateCooling *= float(Equip::types[ m_equipment.Get(Equip::SLOT_LASERCOOLER) ].pval);
}
m_gunTemperature[i] -= rateCooling*timeStep;
if (m_gunTemperature[i] < 0.0f) m_gunTemperature[i] = 0;
if (m_gunRecharge[i] < 0.0f) m_gunRecharge[i] = 0;
if (!m_gunState[i]) continue;
if (m_gunRecharge[i] > 0.0f) continue;
if (m_gunTemperature[i] > 1.0) continue;
FireWeapon(i);
}
if (m_ecmRecharge > 0.0f) {
m_ecmRecharge = std::max(0.0f, m_ecmRecharge - timeStep);
}
if (m_stats.shield_mass_left < m_stats.shield_mass) {
// 250 second recharge
float recharge_rate = 0.004f;
if (m_equipment.Get(Equip::SLOT_ENERGYBOOSTER) != Equip::NONE) {
recharge_rate *= float(Equip::types[ m_equipment.Get(Equip::SLOT_ENERGYBOOSTER) ].pval);
}
m_stats.shield_mass_left += m_stats.shield_mass * recharge_rate * timeStep;
}
m_stats.shield_mass_left = Clamp(m_stats.shield_mass_left, 0.0f, m_stats.shield_mass);
if (m_wheelTransition) {
m_wheelState += m_wheelTransition*0.3f*timeStep;
m_wheelState = Clamp(m_wheelState, 0.0f, 1.0f);
//.........这里部分代码省略.........
示例6: if
static Frame *MakeFrameFor(SystemBody *sbody, Body *b, Frame *f)
{
Frame *orbFrame, *rotFrame;
double frameRadius;
if (!sbody->parent) {
if (b) b->SetFrame(f);
f->m_sbody = sbody;
f->m_astroBody = b;
return f;
}
if (sbody->type == SystemBody::TYPE_GRAVPOINT) {
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->m_astroBody = b;
orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
return orbFrame;
}
SystemBody::BodySuperType supertype = sbody->GetSuperType();
if ((supertype == SystemBody::SUPERTYPE_GAS_GIANT) ||
(supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) {
// for planets we want an non-rotating frame for a few radii
// and a rotating frame in the same position but with maybe 1.05*radius,
// which actually contains the object.
frameRadius = std::max(4.0*sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance()*1.05);
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->SetRadius(frameRadius);
//printf("\t\t\t%s has frame size %.0fkm, body radius %.0fkm\n", sbody->name.c_str(),
// (frameRadius ? frameRadius : 10*sbody->GetRadius())*0.001f,
// sbody->GetRadius()*0.001f);
assert(sbody->rotationPeriod != 0);
rotFrame = new Frame(orbFrame, sbody->name.c_str());
// rotating frame has size of GeoSphere terrain bounding sphere
rotFrame->SetRadius(b->GetBoundingRadius());
rotFrame->SetAngVelocity(vector3d(0,2*M_PI/sbody->GetRotationPeriod(),0));
rotFrame->m_astroBody = b;
SetFrameOrientationFromSystemBodyAxialTilt(rotFrame, sbody);
b->SetFrame(rotFrame);
return orbFrame;
}
else if (supertype == SystemBody::SUPERTYPE_STAR) {
// stars want a single small non-rotating frame
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->m_astroBody = b;
orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
b->SetFrame(orbFrame);
return orbFrame;
}
else if (sbody->type == SystemBody::TYPE_STARPORT_ORBITAL) {
// space stations want non-rotating frame to some distance
// and a much closer rotating frame
frameRadius = 1000000.0; // XXX NFI!
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
// orbFrame->SetRadius(10*sbody->GetRadius());
orbFrame->SetRadius(frameRadius);
assert(sbody->rotationPeriod != 0);
rotFrame = new Frame(orbFrame, sbody->name.c_str());
rotFrame->SetRadius(1000.0);
// rotFrame->SetRadius(1.1*sbody->GetRadius()); // enough for collisions?
rotFrame->SetAngVelocity(vector3d(0.0,double(static_cast<SpaceStation*>(b)->GetDesiredAngVel()),0.0));
rotFrame->m_astroBody = b; // hope this doesn't break anything
b->SetFrame(rotFrame);
return orbFrame;
} else if (sbody->type == SystemBody::TYPE_STARPORT_SURFACE) {
// just put body into rotating frame of planet, not in its own frame
// (because collisions only happen between objects in same frame,
// and we want collisions on starport and on planet itself)
Frame *frame = *f->m_children.begin();
b->SetFrame(frame);
assert(frame->m_astroBody->IsType(Object::PLANET));
Planet *planet = static_cast<Planet*>(frame->m_astroBody);
/* position on planet surface */
double height;
int tries;
matrix4x4d rot;
vector3d pos;
// first try suggested position
rot = sbody->orbit.rotMatrix;
pos = rot * vector3d(0,1,0);
if (planet->GetTerrainHeight(pos) - planet->GetSystemBody()->GetRadius() <= 0.0) {
MTRand r(sbody->seed);
// position is under water. try some random ones
for (tries=0; tries<100; tries++) {
// used for orientation on planet surface
double r2 = r.Double(); // function parameter evaluation order is implementation-dependent
double r1 = r.Double(); // can't put two rands in the same expression
rot = matrix4x4d::RotateZMatrix(2*M_PI*r1)
* matrix4x4d::RotateYMatrix(2*M_PI*r2);
pos = rot * vector3d(0,1,0);
height = planet->GetTerrainHeight(pos) - planet->GetSystemBody()->GetRadius();
// don't want to be under water
//.........这里部分代码省略.........