Merge pull request #4005 from fluffyfreak/under-pressure

Simple atmospheric crush pressure
master
Andrew Copland 2017-05-13 13:21:27 +01:00 committed by GitHub
commit 41575a7618
9 changed files with 109 additions and 10 deletions

View File

@ -91,6 +91,24 @@ void Player::InitCockpit()
m_cockpit.reset(new ShipCockpit(cockpitModelName));
}
bool Player::DoCrushDamage(float kgDamage)
{
bool r = Ship::DoCrushDamage(kgDamage);
// Don't fire audio on EVERY iteration (aka every 16ms, or 60fps), only when exceeds a value randomly
const float dam = kgDamage*0.01f;
if (Pi::rng.Double() < dam)
{
if (!IsDead() && (GetPercentHull() < 25.0f)) {
Sound::BodyMakeNoise(this, "warning", .5f);
}
if (dam < (0.01 * float(GetShipType()->hullMass)))
Sound::BodyMakeNoise(this, "Hull_hit_Small", 1.0f);
else
Sound::BodyMakeNoise(this, "Hull_Hit_Medium", 1.0f);
}
return r;
}
//XXX perhaps remove this, the sound is very annoying
bool Player::OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData)
{

View File

@ -20,6 +20,7 @@ public:
Player(const ShipType::Id &shipId);
Player() {}; //default constructor used before Load
virtual void SetDockedWith(SpaceStation *, int port) override;
virtual bool DoCrushDamage(float kgDamage) override final; // overloaded to add "crush" audio
virtual bool OnDamage(Object *attacker, float kgDamage, const CollisionContact& contactData) override;
virtual bool SetWheelState(bool down) override; // returns success of state change, NOT state itself
virtual Missile * SpawnMissile(ShipType::Id missile_type, int power=-1) override;
@ -48,7 +49,7 @@ public:
sigc::signal<void> onChangeEquipment;
virtual vector3d GetManeuverVelocity() const;
virtual int GetManeuverTime() const;
protected:
virtual void SaveToJson(Json::Value &jsonObj, Space *space) override;
virtual void LoadFromJson(const Json::Value &jsonObj, Space *space) override;

View File

@ -485,6 +485,49 @@ void Ship::Explode()
ClearThrusterState();
}
bool Ship::DoCrushDamage(float kgDamage)
{
if (m_invulnerable) {
return true;
}
if (!IsDead()) {
float dam = kgDamage*0.01f;
if (m_stats.shield_mass_left > 0.0f) {
if (m_stats.shield_mass_left > dam) {
m_stats.shield_mass_left -= dam;
dam = 0;
} else {
dam -= m_stats.shield_mass_left;
m_stats.shield_mass_left = 0;
}
Properties().Set("shieldMassLeft", m_stats.shield_mass_left);
}
m_shieldCooldown = DEFAULT_SHIELD_COOLDOWN_TIME;
// create a collision location in the models local space and add it as a hit.
Random rnd; rnd.seed(time(0));
const vector3d randPos(
rnd.Double() * 2.0 - 1.0,
rnd.Double() * 2.0 - 1.0,
rnd.Double() * 2.0 - 1.0);
GetShields()->AddHit(randPos * (GetPhysRadius() * 0.75));
m_stats.hull_mass_left -= dam;
Properties().Set("hullMassLeft", m_stats.hull_mass_left);
Properties().Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass)));
if (m_stats.hull_mass_left < 0) {
Explode();
} else {
if (Pi::rng.Double() < dam)
SfxManager::Add(this, TYPE_DAMAGE);
}
}
//Output("Ouch! %s took %.1f kilos of damage from %s! (%.1f t hull left)\n", GetLabel().c_str(), kgDamage, attacker->GetLabel().c_str(), m_stats.hull_mass_left);
return true;
}
void Ship::UpdateEquipStats()
{
PropertyMap &p = Properties();
@ -1010,6 +1053,22 @@ void Ship::StaticUpdate(const float timeStep)
if (GetHullTemperature() > 1.0)
Explode();
if (m_flightState == FLYING) {
Body *astro = GetFrame()->GetBody();
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet*>(astro);
double dist = GetPosition().Length();
double pressure, density;
p->GetAtmosphericState(dist, &pressure, &density);
if (pressure > m_type->atmosphericPressureLimit) {
float damage = float(pressure - m_type->atmosphericPressureLimit);
DoCrushDamage(damage);
}
}
}
UpdateAlertState();
/* FUEL SCOOPING!!!!!!!!! */
@ -1020,16 +1079,16 @@ void Ship::StaticUpdate(const float timeStep)
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet*>(astro);
if (p->GetSystemBody()->IsScoopable()) {
double dist = GetPosition().Length();
const 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);
const double speed = GetVelocity().Length();
const vector3d vdir = GetVelocity().Normalized();
const vector3d pdir = -GetOrient().VectorZ();
const double dot = vdir.Dot(pdir);
if ((m_stats.free_capacity) && (dot > 0.90) && (speed > 1000.0) && (density > 0.5)) {
const double rate = speed * density * 0.00000333 * double(capacity);
if (Pi::rng.Double() < rate) {
lua_State *l = Lua::manager->GetLuaState();
pi_lua_import(l, "Equipment");

View File

@ -86,6 +86,7 @@ public:
const shipstats_t &GetStats() const { return m_stats; }
void Explode();
virtual bool DoCrushDamage(float kgDamage); // can be overloaded in Player to add "crush" audio
void SetGunState(int idx, int state);
void UpdateMass();
virtual bool SetWheelState(bool down); // returns success of state change, NOT state itself

View File

@ -286,6 +286,11 @@ void ShipCpanel::SetOverlayToolTip(OverlayTextPos pos, const std::string &text)
m_overlay[pos]->SetToolTip(text);
}
void ShipCpanel::SetOverlayTextColour(OverlayTextPos pos, const Color &colour)
{
m_overlay[pos]->Color(colour);
}
void ShipCpanel::ClearOverlay()
{
for (int i = 0; i < OVERLAY_MAX; i++) {

View File

@ -41,6 +41,7 @@ public:
};
void SetOverlayText(OverlayTextPos pos, const std::string &text);
void SetOverlayToolTip(OverlayTextPos pos, const std::string &text);
void SetOverlayTextColour(OverlayTextPos pos, const Color &colour);
void ClearOverlay();
void SetRadarVisible(bool visible) { if(visible) m_radar->Show(); else m_radar->Hide(); }

View File

@ -197,6 +197,8 @@ ShipType::ShipType(const Id &_id, const std::string &path)
thrusterUpgrades[index] = data["thrust_upgrades"].get(slotname, 0).asDouble();
}
atmosphericPressureLimit = data.get("atmospheric_pressure_limit", 10.0).asDouble(); // 10 atmosphere is about 90 metres underwater (on Earth)
{
const auto it = slots.find("engine");
if (it != slots.end())

View File

@ -46,6 +46,7 @@ struct ShipType {
Color directionThrusterColor[THRUSTER_MAX];
bool isDirectionColorDefined[THRUSTER_MAX];
double thrusterUpgrades[4];
double atmosphericPressureLimit;
int capacity; // tonnes
int hullMass;
float effectiveExhaustVelocity; // velocity at which the propellant escapes the engines

View File

@ -536,10 +536,21 @@ void WorldView::RefreshButtonStateAndVisibility()
double pressure, density;
static_cast<Planet*>(astro)->GetAtmosphericState(center_dist, &pressure, &density);
if (pressure > 0.001)
if (pressure > 0.001) {
m_game->GetCpan()->SetOverlayText(ShipCpanel::OVERLAY_BOTTOM_LEFT, stringf(Lang::PRESSURE_N_ATMOSPHERES, formatarg("pressure", pressure)));
else
const double apl = Pi::player->GetShipType()->atmosphericPressureLimit;
if (pressure > (apl * 0.9)) {
m_game->GetCpan()->SetOverlayTextColour(ShipCpanel::OVERLAY_BOTTOM_LEFT, Color::RED);
} else if (pressure > (apl * 0.75)) {
m_game->GetCpan()->SetOverlayTextColour(ShipCpanel::OVERLAY_BOTTOM_LEFT, Color::YELLOW);
} else {
m_game->GetCpan()->SetOverlayTextColour(ShipCpanel::OVERLAY_BOTTOM_LEFT, s_hudTextColor);
}
} else {
m_game->GetCpan()->SetOverlayText(ShipCpanel::OVERLAY_BOTTOM_LEFT, "");
m_game->GetCpan()->SetOverlayTextColour(ShipCpanel::OVERLAY_BOTTOM_LEFT, s_hudTextColor);
}
if (Pi::player->GetHullTemperature() > 0.01) {
m_hudHullTemp->SetValue(float(Pi::player->GetHullTemperature()));
m_hudHullTemp->Show();