diff --git a/data/lang/core/en.json b/data/lang/core/en.json index 808d32395be..da1ecb577ea 100644 --- a/data/lang/core/en.json +++ b/data/lang/core/en.json @@ -411,6 +411,10 @@ "description": "", "message": "Equatorial to polar radius ratio" }, + "ESCAPE_VELOCITY": { + "description": "", + "message": "Escape velocity" + }, "EXACT_MATCH_X": { "description": "", "message": "Exact match: %system" @@ -783,6 +787,10 @@ "description": "", "message": "Mass: %{mass}t" }, + "MEAN_DENSITY": { + "description": "", + "message": "Mean density" + }, "MEDICINES": { "description": "", "message": "Medicines" diff --git a/data/lang/module-advice/en.json b/data/lang/module-advice/en.json index e7f6ce82f4c..402d7852b02 100644 --- a/data/lang/module-advice/en.json +++ b/data/lang/module-advice/en.json @@ -7,6 +7,14 @@ "description": "", "message": "Know when to leave town" }, + "ADVICE_11_BODYTEXT": { + "description": "", + "message": "Make sure you know the surface gravity of a planet before you even think of landing on it." + }, + "ADVICE_11_HEADLINE": { + "description": "A reference to the song 'The Harder They Come', by Jimmy Cliff", + "message": "The harder the g, the harder the fall" + }, "ADVICE_1_BODYTEXT": { "description": "Point made is: the real illegal goods traders are fixed to each station, but police's fake illegal goods traders will be random every time.", "message": "As you return to a station, be wary of those alternative market places you do not recognize, and you will stay out of trouble with the law." diff --git a/data/lang/module-searchrescue/en.json b/data/lang/module-searchrescue/en.json index 817615f82e1..af78886099c 100644 --- a/data/lang/module-searchrescue/en.json +++ b/data/lang/module-searchrescue/en.json @@ -305,7 +305,7 @@ }, "FLAVOUR_4_TYPEOFHELPTEXT": { "description": "", - "message": "The pilot is asking for {unit} tons of {cargo}." + "message": "The pilot is asking for {unit} tons of {cargo}. {high_gravity}" }, "FLAVOUR_5_ADTEXT": { "description": "", @@ -427,6 +427,22 @@ "description": "", "message": "All cabins full. No more space for more passengers." }, + "HIGHGRAVITY_0": { + "description": "", + "message": "The surface gravity on {planet} is {gravity} g. Please take this into consideration." + }, + "HIGHGRAVITY_1": { + "description": "", + "message": "You should know that {planet} is {gravity} g." + }, + "HIGHGRAVITY_2": { + "description": "", + "message": "You will land and take off in {gravity} g." + }, + "HIGHGRAVITY_3": { + "description": "", + "message": "{planet} is {gravity} g." + }, "HOW_FAR": { "description": "", "message": "How far away is the target?" diff --git a/data/modules/Advice/Advice.lua b/data/modules/Advice/Advice.lua index a29f331f109..467110c3d8f 100644 --- a/data/modules/Advice/Advice.lua +++ b/data/modules/Advice/Advice.lua @@ -32,6 +32,7 @@ local travellers_advice_indices = {481, -- tame black market 23, -- double trouble 52, -- service ship 248, -- change faction + 171, -- the harder the g } -- Hold all different types of advice/rumours available: diff --git a/data/modules/SearchRescue/SearchRescue.lua b/data/modules/SearchRescue/SearchRescue.lua index 66bb436d6d6..bf4a7e57da5 100644 --- a/data/modules/SearchRescue/SearchRescue.lua +++ b/data/modules/SearchRescue/SearchRescue.lua @@ -862,7 +862,8 @@ local onChat = function (form, ref, option) pass = ad.pickup_pass, deliver_crew = ad.deliver_crew, unit = unit, - cargo = cargo + cargo = cargo, + high_gravity = ad.high_gravity, }) form:SetMessage(typeofhelptext) @@ -1203,7 +1204,7 @@ end local makeAdvert = function (station, manualFlavour, closestplanets) -- Make a single advertisement for the bulletin board of the supplied station. - local due, dist, client, entity, problem, location + local due, dist, client, entity, problem, location, high_gravity local lat = 0 local long = 0 @@ -1270,6 +1271,15 @@ local makeAdvert = function (station, manualFlavour, closestplanets) due = (5 * dist + 4) * Engine.rand:Integer(20,24) * 60 * 60 -- TODO: adjust due date based on urgency end + -- Create message string for the cases where the target landed on a planet that is higher gravity (> 1.2 g) + high_gravity = "" + if planet_target:GetSystemBody().gravity / 9.8066 > 1.2 and flavour.id == 4 then -- flavour id 4 is landed on a planet + high_gravity = string.interp(l["HIGHGRAVITY_" .. Engine.rand:Integer(0, getNumberOfFlavours("HIGHGRAVITY"))], { + planet = planet_target:GetSystemBody().name, + gravity = string.format("%.2f", planet_target:GetSystemBody().gravity / 9.8066), + }) + end + --double the time if return to original station is required if flavour.reward_immediate == false then due = 2 * due end due = Game.time + due @@ -1358,6 +1368,7 @@ local makeAdvert = function (station, manualFlavour, closestplanets) system_local = system_local, station_target = station_target, planet_target = planet_target, + high_gravity = high_gravity, system_target = system_target, flavour = flavour, client = client, diff --git a/data/pigui/modules/system-view-ui.lua b/data/pigui/modules/system-view-ui.lua index 2a2568b8f70..f86b850aa51 100644 --- a/data/pigui/modules/system-view-ui.lua +++ b/data/pigui/modules/system-view-ui.lua @@ -808,6 +808,10 @@ function Windows.objectInfo:Show() value = (not starport) and ui.Format.Distance(body.radius) or nil }, { name = lc.SURFACE_GRAVITY, icon = icons.body_radius, value = (not starport) and ui.Format.Speed(body.gravity, true).." ("..ui.Format.Gravity(body.gravity / 9.8066)..")" or nil }, + { name = lc.ESCAPE_VELOCITY, icon = icons.body_radius, + value = (not starport) and ui.Format.Speed(body.escapeVelocity , true) or nil }, + { name = lc.MEAN_DENSITY, icon = icons.body_radius, + value = (not starport) and ui.Format.Mass(body.meanDensity).."/m3" or nil }, { name = lc.ORBITAL_PERIOD, icon = icons.body_orbit_period, value = op and op > 0 and ui.Format.Duration(op, 2) or nil }, { name = lc.DAY_LENGTH, icon = icons.body_day_length, diff --git a/src/LangStrings.inc.h b/src/LangStrings.inc.h index 8c91e7a4a4d..b524a49a97c 100644 --- a/src/LangStrings.inc.h +++ b/src/LangStrings.inc.h @@ -304,6 +304,8 @@ DECLARE_STRING(N_EARTH_RADII) DECLARE_STRING(N_SOLAR_RADII) DECLARE_STRING(SURFACE_TEMPERATURE) DECLARE_STRING(SURFACE_GRAVITY) +DECLARE_STRING(ESCAPE_VELOCITY) +DECLARE_STRING(MEAN_DENSITY) DECLARE_STRING(N_CELSIUS) DECLARE_STRING(N_YEARS) DECLARE_STRING(N_DAYS) diff --git a/src/galaxy/StarSystemGenerator.cpp b/src/galaxy/StarSystemGenerator.cpp index cf749a39333..37379a40cc6 100644 --- a/src/galaxy/StarSystemGenerator.cpp +++ b/src/galaxy/StarSystemGenerator.cpp @@ -29,6 +29,9 @@ static const fixed AU_EARTH_RADIUS = fixed(3, 65536); // XXX Duplication from St static const fixed FIXED_PI = fixed(103993, 33102); // XXX Duplication from StarSystem.cpp static const double CELSIUS = 273.15; +// max surface gravity for a permanent human settlement +static const double MAX_SETTLEMENT_SURFACE_GRAVITY = 50; // m/s2 .. roughly 5 g + static const Uint32 POLIT_SEED = 0x1234abcd; static const Uint32 POLIT_SALT = 0x8732abdf; @@ -655,7 +658,7 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) // We get some more fractional bits for small bodies otherwise we can easily end up with 0 radius which breaks stuff elsewhere // // AndyC - Updated to use the empirically gathered data from this site: - // http://phl.upr.edu/library/notes/standardmass-radiusrelationforexoplanets + // https://phl.upr.edu/library/labnotes/standard-mass-radius-relation-for-exoplanets // but we still limit at the lowest end if (sbody->GetMassAsFixed() <= fixed(1, 1)) { sbody->m_radius = fixed(fixedf<48>::CubeRootOf(fixedf<48>(sbody->GetMassAsFixed()))); @@ -669,6 +672,9 @@ void StarSystemRandomGenerator::PickPlanetType(SystemBody *sbody, Random &rand) // Anything bigger than 200 EU masses is a Gas Giant or bigger but the density changes to decrease from here on up... sbody->m_radius = fixed::FromDouble(22.6 * (1.0 / pow(sbody->GetMassAsFixed().ToDouble(), double(0.0886)))); } + // randomize radius or the surface gravity will be consistently 1.0 g for planets in the 1 - 200 EU range. + sbody->m_radius = fixed::FromDouble(sbody->GetRadiusAsFixed().ToDouble() * ( 1.2 - (0.4 * rand.Double()))); // +/-20% radius + // enforce minimum size of 10km sbody->m_radius = std::max(sbody->GetRadiusAsFixed(), fixed(1, 630)); @@ -1447,7 +1453,7 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody *sbody, StarSystem:: sbody->m_population = fixed(); /* Bad type of planet for settlement */ - if ((sbody->GetAverageTemp() > CELSIUS + 100) || (sbody->GetAverageTemp() < 100) || + if ((sbody->GetAverageTemp() > CELSIUS + 100) || (sbody->GetAverageTemp() < 100) || (sbody->CalcSurfaceGravity() > MAX_SETTLEMENT_SURFACE_GRAVITY) || (sbody->GetType() != SystemBody::TYPE_PLANET_TERRESTRIAL && sbody->GetType() != SystemBody::TYPE_PLANET_ASTEROID)) { Random starportPopRand; starportPopRand.seed(_init, 6); @@ -1458,9 +1464,14 @@ void PopulateStarSystemGenerator::PopulateStage1(SystemBody *sbody, StarSystem:: sbody->m_population = fixed(1, 100000) + fixed(starportPopRand.Int32(-1000, 20000), 1000000000); outTotalPop += sbody->m_population; } else if (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE) { - // give surface spaceports a population between 80000 and 250000 - sbody->m_population = fixed(1, 10000) + fixed(starportPopRand.Int32(-2000, 15000), 100000000); - outTotalPop += sbody->m_population; + // No permanent population on gravities larger than defined in MAX_SETTLEMENT_SURFACE_GRAVITY + if (sbody->CalcSurfaceGravity() > MAX_SETTLEMENT_SURFACE_GRAVITY) { + outTotalPop = fixed(); + } else { + // give surface spaceports a population between 80000 and 250000 + sbody->m_population = fixed(1, 10000) + fixed(starportPopRand.Int32(-2000, 15000), 100000000); + outTotalPop += sbody->m_population; + } } return; @@ -1623,6 +1634,9 @@ void PopulateStarSystemGenerator::PopulateAddStations(SystemBody *sbody, StarSys ++NumToMake; pop -= rand.Fixed(); } + if ((NumToMake == 0) and (sbody->CalcSurfaceGravity() > 10.5)) { // 10.5 m/s2 = 1,07 g + NumToMake = 1; + } // Any to position? if (NumToMake > 0) { diff --git a/src/galaxy/SystemBody.cpp b/src/galaxy/SystemBody.cpp index a930b7f8cfd..3b74a27596c 100644 --- a/src/galaxy/SystemBody.cpp +++ b/src/galaxy/SystemBody.cpp @@ -805,6 +805,26 @@ double SystemBody::CalcSurfaceGravity() const } } +double SystemBody::CalcEscapeVelocity() const +{ + double r = GetRadius(); + if (r > 0.0) { + return pow((2 * CalcSurfaceGravity() * r) , 0.5); + } else { + return 0.0; + } +} + +double SystemBody::CalcMeanDensity() const +{ + double r = GetRadius(); + if (r > 0.0) { + return GetMass() / (4.0 / 3.0 * M_PI * pow(r, 3)); // Density = Mass / Volume + } else { + return 0.0; + } +} + void SystemBody::Dump(FILE *file, const char *indent) const { fprintf(file, "%sSystemBody(%d,%d,%d,%u,%u) : %s/%s %s{\n", indent, m_path.sectorX, m_path.sectorY, m_path.sectorZ, m_path.systemIndex, diff --git a/src/galaxy/SystemBody.h b/src/galaxy/SystemBody.h index f599328b809..70f5b3b372c 100644 --- a/src/galaxy/SystemBody.h +++ b/src/galaxy/SystemBody.h @@ -253,6 +253,8 @@ class SystemBody : public RefCounted, public SystemBodyType, protected SystemBod double GetPopulation() const { return m_population.ToDouble(); } double CalcSurfaceGravity() const; + double CalcEscapeVelocity() const; + double CalcMeanDensity() const; double GetMaxChildOrbitalDistance() const; diff --git a/src/lua/LuaSystemBody.cpp b/src/lua/LuaSystemBody.cpp index c78d7a8ba0f..da2ff60cbbd 100644 --- a/src/lua/LuaSystemBody.cpp +++ b/src/lua/LuaSystemBody.cpp @@ -260,6 +260,47 @@ static int l_sbody_attr_gravity(lua_State *l) return 1; } +/* + * Attribute: escapeVelocity + * + * The speed an object need to break free from the gravitational influence + * of a body and leave it behind with no further acceleration. + * + * Availability: + * + * July 2023 + * + * Status: + * + * experimental + */ +static int l_sbody_attr_escape_velocity(lua_State *l) +{ + SystemBody *sbody = LuaObject::CheckFromLua(1); + lua_pushnumber(l, sbody->CalcEscapeVelocity()); + return 1; +} + +/* + * Attribute: meanDensity + * + * The mean density of a body (kg/m3). + * + * Availability: + * + * July 2023 + * + * Status: + * + * experimental + */ +static int l_sbody_attr_mean_density(lua_State *l) +{ + SystemBody *sbody = LuaObject::CheckFromLua(1); + lua_pushnumber(l, sbody->CalcMeanDensity()); + return 1; +} + /* * Attribute: periapsis * @@ -758,6 +799,8 @@ void LuaObject::RegisterClass() { "radius", l_sbody_attr_radius }, { "mass", l_sbody_attr_mass }, { "gravity", l_sbody_attr_gravity }, + { "escapeVelocity", l_sbody_attr_escape_velocity }, + { "meanDensity", l_sbody_attr_mean_density }, { "periapsis", l_sbody_attr_periapsis }, { "apoapsis", l_sbody_attr_apoapsis }, { "orbitPeriod", l_sbody_attr_orbital_period },