From 454940036fe96c8c67289dfa9c90f284b77471a6 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 17:05:58 +0100 Subject: [PATCH 01/11] Jsonize solar panel --- data/json/items/generic.json | 15 +++++++++++++++ data/mods/Aftershock/player/afs_bionics.json | 5 ++++- src/bionics.cpp | 11 ++++++++++- src/player.cpp | 6 ------ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/data/json/items/generic.json b/data/json/items/generic.json index 8ac168f0eb8d4..b44fef2d75389 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -57,6 +57,21 @@ "flags": [ "PSEUDO", "PERPETUAL" ], "fuel": { "energy": 1 } }, + { + "type": "GENERIC", + "//": "pseudo item, used as fuel type for CBMs that are sun-powered", + "id": "sunlight", + "symbol": "?", + "color": "white", + "name": "sun light", + "name_plural": "none", + "description": "seeing this is a bug", + "stackable": true, + "price": 0, + "volume": 0, + "flags": [ "PSEUDO", "PERPETUAL" ], + "fuel": { "energy": 1 } + }, { "type": "GENERIC", "//": "pseudo item, used as fuel type for CBMs that are metabolism-powered", diff --git a/data/mods/Aftershock/player/afs_bionics.json b/data/mods/Aftershock/player/afs_bionics.json index 1d9e4eb1b0882..528fd89c8095b 100644 --- a/data/mods/Aftershock/player/afs_bionics.json +++ b/data/mods/Aftershock/player/afs_bionics.json @@ -6,7 +6,10 @@ "name": "Solar Panels", "description": "Installed on your back is a set of retractable, reinforced solar panels resembling angular butterfly wings. When in direct sunlight, they will automatically deploy and slowly recharge your power level.", "occupied_bodyparts": [ [ "TORSO", 10 ] ], - "flags": [ "BIONIC_POWER_SOURCE" ] + "fuel_options": [ "sunlight" ], + "fuel_efficiency": 1.0, + "time": 1, + "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_TOGGLED" ] }, { "id": "afs_bio_precision_solderers", diff --git a/src/bionics.cpp b/src/bionics.cpp index f273797c0bac9..3086fbd8357cd 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -859,12 +859,15 @@ bool Character::burn_fuel( int b, bool start ) //in the menu if( !start ) { for( const itype_id &fuel : fuel_available ) { - const int fuel_energy = item( fuel ).fuel_energy(); + const item &tmp_fuel = item( fuel ); + const int fuel_energy = tmp_fuel.fuel_energy(); int current_fuel_stock; if( is_metabolism_powered ) { current_fuel_stock = std::max( 0.0f, get_stored_kcal() - 0.8f * get_healthy_kcal() ); + } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { + current_fuel_stock = 1; } else { current_fuel_stock = std::stoi( get_value( fuel ) ); } @@ -887,6 +890,12 @@ bool Character::burn_fuel( int b, bool start ) const units::energy power_gain = kcal_consumed * 4184_J * fuel_efficiency; mod_stored_kcal( -kcal_consumed ); mod_power_level( power_gain ); + } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { + if( fuel == itype_id( "sunlight" ) ) { + const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + add_msg( std::to_string( fuel_energy * modifier * fuel_efficiency ) ); + mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); + } } else { current_fuel_stock -= 1; set_value( fuel, std::to_string( current_fuel_stock ) ); diff --git a/src/player.cpp b/src/player.cpp index bbd9d08718982..3e89b22a2894e 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2871,12 +2871,6 @@ void player::update_needs( int rate_multiplier ) mod_painkiller( -std::min( get_painkiller(), rate_multiplier ) ); } - if( g->is_in_sunlight( pos() ) ) { - if( has_bionic( bn_bio_solar ) ) { - mod_power_level( units::from_kilojoule( rate_multiplier * 25 ) ); - } - } - // Huge folks take penalties for cramming themselves in vehicles if( in_vehicle && ( has_trait( trait_HUGE ) || has_trait( trait_HUGE_OK ) ) ) { vehicle *veh = veh_pointer_or_null( g->m.veh_at( pos() ) ); From 559dab153c2e78d1ab8f8f8621d92b9f747f6698 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 17:22:03 +0100 Subject: [PATCH 02/11] passive power generation --- src/bionics.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/character.h | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 3086fbd8357cd..43e80c0540a2b 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -893,7 +893,6 @@ bool Character::burn_fuel( int b, bool start ) } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); - add_msg( std::to_string( fuel_energy * modifier * fuel_efficiency ) ); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); } } else { @@ -939,6 +938,43 @@ bool Character::burn_fuel( int b, bool start ) return true; } +void Character::passive_power_gen( int b ) +{ + bionic &bio = ( *my_bionics )[b]; + const float &passive_fuel_efficiency = bio.info().passive_fuel_efficiency; + if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( "muscle" ) || + passive_fuel_efficiency == 0.0 ) { + } + const std::vector &fuel_available = get_fuel_available( bio.id ); + + for( const itype_id &fuel : fuel_available ) { + const item &tmp_fuel = item( fuel ); + const int fuel_energy = tmp_fuel.fuel_energy(); + if( !tmp_fuel.has_flag( "PERPETUAL" ) ) { + continue; + } + + if( fuel == itype_id( "sunlight" ) ) { + const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * passive_fuel_efficiency ); + } else { + mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); + } + + if( bio.info().exothermic_power_gen ) { + const int heat_prod = fuel_energy * ( 1 - passive_fuel_efficiency ); + const int heat_level = std::min( heat_prod / 10, 4 ); + const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); + const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); + g->m.emit_field( pos(), hotness, heat_spread ); + for( const auto bp : bio.info().occupied_bodyparts ) { + add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); + } + } + g->m.emit_field( pos(), bio.info().power_gen_emission ); + } +} + /** * @param p the player * @param bio the bionic that is meant to be recharged. @@ -983,6 +1019,7 @@ void Character::process_bionic( int b ) bionic &bio = ( *my_bionics )[b]; // Only powered bionics should be processed if( !bio.powered ) { + passive_power_gen( b ); return; } diff --git a/src/character.h b/src/character.h index 413c76773f8aa..8b50c6aa5c8d0 100644 --- a/src/character.h +++ b/src/character.h @@ -787,6 +787,7 @@ class Character : public Creature, public visitable virtual bool deactivate_bionic( int b, bool eff_only = false ); /**Convert fuel to bionic power*/ bool burn_fuel( int b, bool start = false ); + void passive_power_gen( int b ); units::energy get_power_level() const; units::energy get_max_power_level() const; From e09403831a697dbfb395495fc690863459ae8117 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 17:49:54 +0100 Subject: [PATCH 03/11] const and & stuff --- src/bionics.cpp | 58 ++++++++++++++++++++++++------------------------- src/character.h | 1 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 43e80c0540a2b..007e0e819de73 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -845,8 +845,8 @@ bool Character::burn_fuel( int b, bool start ) return true; } const bool is_metabolism_powered = bio.is_this_fuel_powered( "metabolism" ); - const std::vector fuel_available = get_fuel_available( bio.id ); - const float fuel_efficiency = bio.info().fuel_efficiency; + const std::vector &fuel_available = get_fuel_available( bio.id ); + const float &fuel_efficiency = bio.info().fuel_efficiency; if( start && fuel_available.empty() ) { add_msg_player_or_npc( m_bad, _( "Your %s does not have enought fuel to start." ), @@ -860,7 +860,7 @@ bool Character::burn_fuel( int b, bool start ) if( !start ) { for( const itype_id &fuel : fuel_available ) { const item &tmp_fuel = item( fuel ); - const int fuel_energy = tmp_fuel.fuel_energy(); + const int &fuel_energy = tmp_fuel.fuel_energy(); int current_fuel_stock; if( is_metabolism_powered ) { @@ -885,14 +885,14 @@ bool Character::burn_fuel( int b, bool start ) if( current_fuel_stock > 0 ) { if( is_metabolism_powered ) { - const int kcal_consumed = fuel_energy; + const int &kcal_consumed = fuel_energy; // 1kcal = 4187 J - const units::energy power_gain = kcal_consumed * 4184_J * fuel_efficiency; + const units::energy &power_gain = kcal_consumed * 4184_J * fuel_efficiency; mod_stored_kcal( -kcal_consumed ); mod_power_level( power_gain ); } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { if( fuel == itype_id( "sunlight" ) ) { - const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + const double &modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); } } else { @@ -902,16 +902,7 @@ bool Character::burn_fuel( int b, bool start ) mod_power_level( units::from_kilojoule( fuel_energy ) * fuel_efficiency ); } - if( bio.info().exothermic_power_gen ) { - const int heat_prod = fuel_energy * ( 1 - fuel_efficiency ); - const int heat_level = std::min( heat_prod / 10, 4 ); - const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); - const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); - g->m.emit_field( pos(), hotness, heat_spread ); - for( const auto bp : bio.info().occupied_bodyparts ) { - add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); - } - } + heat_emission( b, fuel_energy, fuel_efficiency ); g->m.emit_field( pos(), bio.info().power_gen_emission ); } else { @@ -940,7 +931,7 @@ bool Character::burn_fuel( int b, bool start ) void Character::passive_power_gen( int b ) { - bionic &bio = ( *my_bionics )[b]; + const bionic &bio = ( *my_bionics )[b]; const float &passive_fuel_efficiency = bio.info().passive_fuel_efficiency; if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( "muscle" ) || passive_fuel_efficiency == 0.0 ) { @@ -949,29 +940,38 @@ void Character::passive_power_gen( int b ) for( const itype_id &fuel : fuel_available ) { const item &tmp_fuel = item( fuel ); - const int fuel_energy = tmp_fuel.fuel_energy(); + const int &fuel_energy = tmp_fuel.fuel_energy(); if( !tmp_fuel.has_flag( "PERPETUAL" ) ) { continue; } if( fuel == itype_id( "sunlight" ) ) { - const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + const double &modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * passive_fuel_efficiency ); } else { mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); } - if( bio.info().exothermic_power_gen ) { - const int heat_prod = fuel_energy * ( 1 - passive_fuel_efficiency ); - const int heat_level = std::min( heat_prod / 10, 4 ); - const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); - const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); - g->m.emit_field( pos(), hotness, heat_spread ); - for( const auto bp : bio.info().occupied_bodyparts ) { - add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); - } - } + heat_emission( b, fuel_energy, passive_fuel_efficiency ); g->m.emit_field( pos(), bio.info().power_gen_emission ); + + } +} + +void Character::heat_emission( int b, int fuel_energy, float efficiency ) +{ + const bionic &bio = ( *my_bionics )[b]; + if( !bio.info().exothermic_power_gen ) { + return; + } + + const int &heat_prod = fuel_energy * ( 1 - efficiency ); + const int &heat_level = std::min( heat_prod / 10, 4 ); + const int &heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); + const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); + g->m.emit_field( pos(), hotness, heat_spread ); + for( const auto bp : bio.info().occupied_bodyparts ) { + add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); } } diff --git a/src/character.h b/src/character.h index 8b50c6aa5c8d0..7fd3690490834 100644 --- a/src/character.h +++ b/src/character.h @@ -788,6 +788,7 @@ class Character : public Creature, public visitable /**Convert fuel to bionic power*/ bool burn_fuel( int b, bool start = false ); void passive_power_gen( int b ); + void heat_emission( int b, int fuel_energy, float efficiency ); units::energy get_power_level() const; units::energy get_max_power_level() const; From a7e79546a7f64aa62ffe03b6b456d39260ec080f Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 17:57:53 +0100 Subject: [PATCH 04/11] Revert "const and & stuff" This reverts commit e09403831a697dbfb395495fc690863459ae8117. --- src/bionics.cpp | 58 ++++++++++++++++++++++++------------------------- src/character.h | 1 - 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 007e0e819de73..43e80c0540a2b 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -845,8 +845,8 @@ bool Character::burn_fuel( int b, bool start ) return true; } const bool is_metabolism_powered = bio.is_this_fuel_powered( "metabolism" ); - const std::vector &fuel_available = get_fuel_available( bio.id ); - const float &fuel_efficiency = bio.info().fuel_efficiency; + const std::vector fuel_available = get_fuel_available( bio.id ); + const float fuel_efficiency = bio.info().fuel_efficiency; if( start && fuel_available.empty() ) { add_msg_player_or_npc( m_bad, _( "Your %s does not have enought fuel to start." ), @@ -860,7 +860,7 @@ bool Character::burn_fuel( int b, bool start ) if( !start ) { for( const itype_id &fuel : fuel_available ) { const item &tmp_fuel = item( fuel ); - const int &fuel_energy = tmp_fuel.fuel_energy(); + const int fuel_energy = tmp_fuel.fuel_energy(); int current_fuel_stock; if( is_metabolism_powered ) { @@ -885,14 +885,14 @@ bool Character::burn_fuel( int b, bool start ) if( current_fuel_stock > 0 ) { if( is_metabolism_powered ) { - const int &kcal_consumed = fuel_energy; + const int kcal_consumed = fuel_energy; // 1kcal = 4187 J - const units::energy &power_gain = kcal_consumed * 4184_J * fuel_efficiency; + const units::energy power_gain = kcal_consumed * 4184_J * fuel_efficiency; mod_stored_kcal( -kcal_consumed ); mod_power_level( power_gain ); } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { if( fuel == itype_id( "sunlight" ) ) { - const double &modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); } } else { @@ -902,7 +902,16 @@ bool Character::burn_fuel( int b, bool start ) mod_power_level( units::from_kilojoule( fuel_energy ) * fuel_efficiency ); } - heat_emission( b, fuel_energy, fuel_efficiency ); + if( bio.info().exothermic_power_gen ) { + const int heat_prod = fuel_energy * ( 1 - fuel_efficiency ); + const int heat_level = std::min( heat_prod / 10, 4 ); + const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); + const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); + g->m.emit_field( pos(), hotness, heat_spread ); + for( const auto bp : bio.info().occupied_bodyparts ) { + add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); + } + } g->m.emit_field( pos(), bio.info().power_gen_emission ); } else { @@ -931,7 +940,7 @@ bool Character::burn_fuel( int b, bool start ) void Character::passive_power_gen( int b ) { - const bionic &bio = ( *my_bionics )[b]; + bionic &bio = ( *my_bionics )[b]; const float &passive_fuel_efficiency = bio.info().passive_fuel_efficiency; if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( "muscle" ) || passive_fuel_efficiency == 0.0 ) { @@ -940,38 +949,29 @@ void Character::passive_power_gen( int b ) for( const itype_id &fuel : fuel_available ) { const item &tmp_fuel = item( fuel ); - const int &fuel_energy = tmp_fuel.fuel_energy(); + const int fuel_energy = tmp_fuel.fuel_energy(); if( !tmp_fuel.has_flag( "PERPETUAL" ) ) { continue; } if( fuel == itype_id( "sunlight" ) ) { - const double &modifier = g->natural_light_level( pos().z ) / default_daylight_level(); + const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * passive_fuel_efficiency ); } else { mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); } - heat_emission( b, fuel_energy, passive_fuel_efficiency ); + if( bio.info().exothermic_power_gen ) { + const int heat_prod = fuel_energy * ( 1 - passive_fuel_efficiency ); + const int heat_level = std::min( heat_prod / 10, 4 ); + const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); + const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); + g->m.emit_field( pos(), hotness, heat_spread ); + for( const auto bp : bio.info().occupied_bodyparts ) { + add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); + } + } g->m.emit_field( pos(), bio.info().power_gen_emission ); - - } -} - -void Character::heat_emission( int b, int fuel_energy, float efficiency ) -{ - const bionic &bio = ( *my_bionics )[b]; - if( !bio.info().exothermic_power_gen ) { - return; - } - - const int &heat_prod = fuel_energy * ( 1 - efficiency ); - const int &heat_level = std::min( heat_prod / 10, 4 ); - const int &heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); - const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); - g->m.emit_field( pos(), hotness, heat_spread ); - for( const auto bp : bio.info().occupied_bodyparts ) { - add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); } } diff --git a/src/character.h b/src/character.h index 7fd3690490834..8b50c6aa5c8d0 100644 --- a/src/character.h +++ b/src/character.h @@ -788,7 +788,6 @@ class Character : public Creature, public visitable /**Convert fuel to bionic power*/ bool burn_fuel( int b, bool start = false ); void passive_power_gen( int b ); - void heat_emission( int b, int fuel_energy, float efficiency ); units::energy get_power_level() const; units::energy get_max_power_level() const; From f147e24950f051f768ddf5e6509cdf8099ff4ab4 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 18:01:49 +0100 Subject: [PATCH 05/11] encapsulate heat emission from power gen --- src/bionics.cpp | 46 +++++++++++++++++++++++----------------------- src/character.h | 1 + 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 43e80c0540a2b..302fb7c0864e1 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -845,7 +845,7 @@ bool Character::burn_fuel( int b, bool start ) return true; } const bool is_metabolism_powered = bio.is_this_fuel_powered( "metabolism" ); - const std::vector fuel_available = get_fuel_available( bio.id ); + const std::vector &fuel_available = get_fuel_available( bio.id ); const float fuel_efficiency = bio.info().fuel_efficiency; if( start && fuel_available.empty() ) { @@ -902,16 +902,7 @@ bool Character::burn_fuel( int b, bool start ) mod_power_level( units::from_kilojoule( fuel_energy ) * fuel_efficiency ); } - if( bio.info().exothermic_power_gen ) { - const int heat_prod = fuel_energy * ( 1 - fuel_efficiency ); - const int heat_level = std::min( heat_prod / 10, 4 ); - const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); - const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); - g->m.emit_field( pos(), hotness, heat_spread ); - for( const auto bp : bio.info().occupied_bodyparts ) { - add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); - } - } + heat_emission( b, fuel_energy, fuel_efficiency ); g->m.emit_field( pos(), bio.info().power_gen_emission ); } else { @@ -940,8 +931,8 @@ bool Character::burn_fuel( int b, bool start ) void Character::passive_power_gen( int b ) { - bionic &bio = ( *my_bionics )[b]; - const float &passive_fuel_efficiency = bio.info().passive_fuel_efficiency; + const bionic &bio = ( *my_bionics )[b]; + const float passive_fuel_efficiency = bio.info().passive_fuel_efficiency; if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( "muscle" ) || passive_fuel_efficiency == 0.0 ) { } @@ -961,17 +952,26 @@ void Character::passive_power_gen( int b ) mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); } - if( bio.info().exothermic_power_gen ) { - const int heat_prod = fuel_energy * ( 1 - passive_fuel_efficiency ); - const int heat_level = std::min( heat_prod / 10, 4 ); - const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); - const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); - g->m.emit_field( pos(), hotness, heat_spread ); - for( const auto bp : bio.info().occupied_bodyparts ) { - add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); - } - } + heat_emission( b, fuel_energy, passive_fuel_efficiency ); g->m.emit_field( pos(), bio.info().power_gen_emission ); + + } +} + +void Character::heat_emission( int b, int fuel_energy, float efficiency ) +{ + const bionic &bio = ( *my_bionics )[b]; + if( !bio.info().exothermic_power_gen ) { + return; + } + + const int &heat_prod = fuel_energy * ( 1 - efficiency ); + const int &heat_level = std::min( heat_prod / 10, 4 ); + const int &heat_spread = std::max( heat_prod / 10 - heat_level, 1 ); + const emit_id hotness = emit_id( "emit_hot_air" + to_string( heat_level ) + "_cbm" ); + g->m.emit_field( pos(), hotness, heat_spread ); + for( const auto bp : bio.info().occupied_bodyparts ) { + add_effect( efftype_id( "heating_bionic" ), 2_seconds, bp.first, false, heat_prod ); } } diff --git a/src/character.h b/src/character.h index 8b50c6aa5c8d0..7fd3690490834 100644 --- a/src/character.h +++ b/src/character.h @@ -788,6 +788,7 @@ class Character : public Creature, public visitable /**Convert fuel to bionic power*/ bool burn_fuel( int b, bool start = false ); void passive_power_gen( int b ); + void heat_emission( int b, int fuel_energy, float efficiency ); units::energy get_power_level() const; units::energy get_max_power_level() const; From 57705da1a95aba2b6483bf0025e4ca4aed1fd125 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 19:45:43 +0100 Subject: [PATCH 06/11] Wind Turbine CBM --- data/mods/Aftershock/items/afs_cbms.json | 9 +++++++++ .../mods/Aftershock/maps/afs_item_groups.json | 11 +++++++++- data/mods/Aftershock/player/afs_bionics.json | 11 ++++++++++ src/bionics.cpp | 20 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/data/mods/Aftershock/items/afs_cbms.json b/data/mods/Aftershock/items/afs_cbms.json index c88da7db978d1..e15ab4e50818a 100644 --- a/data/mods/Aftershock/items/afs_cbms.json +++ b/data/mods/Aftershock/items/afs_cbms.json @@ -8,6 +8,15 @@ "price": 350000, "difficulty": 4 }, + { + "id": "afs_bio_wind_turbine", + "copy-from": "bionic_general", + "type": "BIONIC_ITEM", + "name": "Wind Turbine CBM", + "description": "Installed on your body is a set of small retractable wind turbines. When activated, they will deploy and slowly harvest wind power to recharge your power level.", + "price": 350000, + "difficulty": 4 + }, { "id": "afs_bio_precision_solderers", "copy-from": "bionic_general", diff --git a/data/mods/Aftershock/maps/afs_item_groups.json b/data/mods/Aftershock/maps/afs_item_groups.json index 72ecabacffbc9..3caff3d06f308 100644 --- a/data/mods/Aftershock/maps/afs_item_groups.json +++ b/data/mods/Aftershock/maps/afs_item_groups.json @@ -29,6 +29,7 @@ "items": [ [ "bio_furnace", 10 ], [ "bn_bio_solar", 10 ], + [ "afs_bio_wind_turbine", 5 ], [ "afs_bio_precision_solderers", 10 ], [ "afs_bio_missiles", 10 ], [ "afs_bio_linguistic_coprocessor", 10 ], @@ -42,6 +43,7 @@ "items": [ [ "bio_furnace", 10 ], [ "bn_bio_solar", 10 ], + [ "afs_bio_wind_turbine", 5 ], [ "afs_bio_precision_solderers", 5 ], [ "afs_bio_linguistic_coprocessor", 8 ] ] @@ -57,6 +59,7 @@ "items": [ [ "bio_furnace", 5 ], [ "bn_bio_solar", 5 ], + [ "afs_bio_wind_turbine", 2 ], [ "afs_bio_precision_solderers", 7 ], [ "afs_bio_linguistic_coprocessor", 5 ] ] @@ -64,7 +67,13 @@ { "id": "bionics_op", "type": "item_group", - "items": [ [ "bio_furnace", 15 ], [ "bn_bio_solar", 15 ], [ "afs_bio_missiles", 10 ], [ "afs_bio_dopamine_stimulators", 10 ] ] + "items": [ + [ "bio_furnace", 15 ], + [ "bn_bio_solar", 15 ], + [ "afs_bio_wind_turbine", 10 ], + [ "afs_bio_missiles", 10 ], + [ "afs_bio_dopamine_stimulators", 10 ] + ] }, { "id": "bionics_subs", diff --git a/data/mods/Aftershock/player/afs_bionics.json b/data/mods/Aftershock/player/afs_bionics.json index 528fd89c8095b..b941904904af9 100644 --- a/data/mods/Aftershock/player/afs_bionics.json +++ b/data/mods/Aftershock/player/afs_bionics.json @@ -11,6 +11,17 @@ "time": 1, "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_TOGGLED" ] }, + { + "id": "afs_bio_wind_turbine", + "type": "bionic", + "name": "Wind Turbines", + "description": "Installed on your body is a set of small retractable wind turbines. When activated, they will deploy and slowly harvest wind power to recharge your power level.", + "occupied_bodyparts": [ [ "TORSO", 10 ] ], + "fuel_options": [ "wind" ], + "fuel_efficiency": 0.25, + "time": 1, + "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_TOGGLED" ] + }, { "id": "afs_bio_precision_solderers", "type": "bionic", diff --git a/src/bionics.cpp b/src/bionics.cpp index 302fb7c0864e1..e5509cb484f5a 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -894,6 +894,16 @@ bool Character::burn_fuel( int b, bool start ) if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); + } else if( fuel == itype_id( "wind" ) ) { + int vehwindspeed = 0; + const optional_vpart_position vp = g->m.veh_at( pos() ); + if( vp ) { + vehwindspeed = abs( vp->vehicle().velocity / 100 ); // vehicle velocity in mph + } + const double windpower = get_local_windpower( g->weather.windspeed + vehwindspeed, + overmap_buffer.ter( global_omt_location() ), pos(), g->weather.winddirection, + g->is_sheltered( pos() ) ); + mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * fuel_efficiency ); } } else { current_fuel_stock -= 1; @@ -948,6 +958,16 @@ void Character::passive_power_gen( int b ) if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * passive_fuel_efficiency ); + } else if( fuel == itype_id( "wind" ) ) { + int vehwindspeed = 0; + const optional_vpart_position vp = g->m.veh_at( pos() ); + if( vp ) { + vehwindspeed = abs( vp->vehicle().velocity / 100 ); // vehicle velocity in mph + } + const double windpower = get_local_windpower( g->weather.windspeed + vehwindspeed, + overmap_buffer.ter( global_omt_location() ), pos(), g->weather.winddirection, + g->is_sheltered( pos() ) ); + mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * passive_fuel_efficiency ); } else { mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); } From 9b1c1d20059ad12346fac22fa76e7dff4a4bebf4 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 19:50:03 +0100 Subject: [PATCH 07/11] turn off message --- src/bionics.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index e5509cb484f5a..eee8e5e77c490 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -861,12 +861,13 @@ bool Character::burn_fuel( int b, bool start ) for( const itype_id &fuel : fuel_available ) { const item &tmp_fuel = item( fuel ); const int fuel_energy = tmp_fuel.fuel_energy(); + const bool is_perpetual_fuel = tmp_fuel.has_flag( "PERPETUAL" ); int current_fuel_stock; if( is_metabolism_powered ) { current_fuel_stock = std::max( 0.0f, get_stored_kcal() - 0.8f * get_healthy_kcal() ); - } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { + } else if( is_perpetual_fuel ) { current_fuel_stock = 1; } else { current_fuel_stock = std::stoi( get_value( fuel ) ); @@ -875,9 +876,19 @@ bool Character::burn_fuel( int b, bool start ) if( !bio.has_flag( "SAFE_FUEL_OFF" ) && get_power_level() + units::from_kilojoule( fuel_energy ) * fuel_efficiency > get_max_power_level() ) { - add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ), - _( "'s %s turns off to not waste fuel." ), - bio.info().name ); + if( is_metabolism_powered ) { + add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste calories." ), + _( "'s %s turns off to not waste calories." ), + bio.info().name ); + } else if( is_perpetual_fuel ) { + add_msg_player_or_npc( m_info, _( "Your %s turns off after filling your power banks." ), + _( "'s %s turns off after filling their power banks." ), + bio.info().name ); + } else { + add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ), + _( "'s %s turns off to not waste fuel." ), + bio.info().name ); + } bio.powered = false; deactivate_bionic( b, true ); return false; @@ -890,7 +901,7 @@ bool Character::burn_fuel( int b, bool start ) const units::energy power_gain = kcal_consumed * 4184_J * fuel_efficiency; mod_stored_kcal( -kcal_consumed ); mod_power_level( power_gain ); - } else if( tmp_fuel.has_flag( "PERPETUAL" ) ) { + } else if( is_perpetual_fuel ) { if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); From 75ef487f4a7af0a3e1217491bb5d63ccce4695c6 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 22:07:30 +0100 Subject: [PATCH 08/11] Penalty to power gen from bodypart coverage --- data/mods/Aftershock/player/afs_bionics.json | 1 - src/bionics.cpp | 51 +++++++++++++++----- src/bionics.h | 2 + src/character.h | 6 ++- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/data/mods/Aftershock/player/afs_bionics.json b/data/mods/Aftershock/player/afs_bionics.json index b941904904af9..17e0bc54e1fc7 100644 --- a/data/mods/Aftershock/player/afs_bionics.json +++ b/data/mods/Aftershock/player/afs_bionics.json @@ -1,7 +1,6 @@ [ { "id": "bn_bio_solar", - "//": "That's right, it's taken from Bright Nights. Sue me!", "type": "bionic", "name": "Solar Panels", "description": "Installed on your back is a set of retractable, reinforced solar panels resembling angular butterfly wings. When in direct sunlight, they will automatically deploy and slowly recharge your power level.", diff --git a/src/bionics.cpp b/src/bionics.cpp index eee8e5e77c490..c6c4ba0a7b612 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -846,7 +846,7 @@ bool Character::burn_fuel( int b, bool start ) } const bool is_metabolism_powered = bio.is_this_fuel_powered( "metabolism" ); const std::vector &fuel_available = get_fuel_available( bio.id ); - const float fuel_efficiency = bio.info().fuel_efficiency; + const float effective_efficiency = get_effective_efficiency( b, bio.info().fuel_efficiency ); if( start && fuel_available.empty() ) { add_msg_player_or_npc( m_bad, _( "Your %s does not have enought fuel to start." ), @@ -874,7 +874,7 @@ bool Character::burn_fuel( int b, bool start ) } if( !bio.has_flag( "SAFE_FUEL_OFF" ) && - get_power_level() + units::from_kilojoule( fuel_energy ) * fuel_efficiency + get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency > get_max_power_level() ) { if( is_metabolism_powered ) { add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste calories." ), @@ -898,13 +898,13 @@ bool Character::burn_fuel( int b, bool start ) if( is_metabolism_powered ) { const int kcal_consumed = fuel_energy; // 1kcal = 4187 J - const units::energy power_gain = kcal_consumed * 4184_J * fuel_efficiency; + const units::energy power_gain = kcal_consumed * 4184_J * effective_efficiency; mod_stored_kcal( -kcal_consumed ); mod_power_level( power_gain ); } else if( is_perpetual_fuel ) { if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); - mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * effective_efficiency ); } else if( fuel == itype_id( "wind" ) ) { int vehwindspeed = 0; const optional_vpart_position vp = g->m.veh_at( pos() ); @@ -914,16 +914,16 @@ bool Character::burn_fuel( int b, bool start ) const double windpower = get_local_windpower( g->weather.windspeed + vehwindspeed, overmap_buffer.ter( global_omt_location() ), pos(), g->weather.winddirection, g->is_sheltered( pos() ) ); - mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_efficiency ); } } else { current_fuel_stock -= 1; set_value( fuel, std::to_string( current_fuel_stock ) ); update_fuel_storage( fuel ); - mod_power_level( units::from_kilojoule( fuel_energy ) * fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency ); } - heat_emission( b, fuel_energy, fuel_efficiency ); + heat_emission( b, fuel_energy ); g->m.emit_field( pos(), bio.info().power_gen_emission ); } else { @@ -956,7 +956,9 @@ void Character::passive_power_gen( int b ) const float passive_fuel_efficiency = bio.info().passive_fuel_efficiency; if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( "muscle" ) || passive_fuel_efficiency == 0.0 ) { + return; } + const float effective_passive_efficiency = get_effective_efficiency( b, passive_fuel_efficiency ); const std::vector &fuel_available = get_fuel_available( bio.id ); for( const itype_id &fuel : fuel_available ) { @@ -968,7 +970,7 @@ void Character::passive_power_gen( int b ) if( fuel == itype_id( "sunlight" ) ) { const double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); - mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * passive_fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * effective_passive_efficiency ); } else if( fuel == itype_id( "wind" ) ) { int vehwindspeed = 0; const optional_vpart_position vp = g->m.veh_at( pos() ); @@ -978,23 +980,24 @@ void Character::passive_power_gen( int b ) const double windpower = get_local_windpower( g->weather.windspeed + vehwindspeed, overmap_buffer.ter( global_omt_location() ), pos(), g->weather.winddirection, g->is_sheltered( pos() ) ); - mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * passive_fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_passive_efficiency ); } else { - mod_power_level( units::from_kilojoule( fuel_energy ) * passive_fuel_efficiency ); + mod_power_level( units::from_kilojoule( fuel_energy ) * effective_passive_efficiency ); } - heat_emission( b, fuel_energy, passive_fuel_efficiency ); + heat_emission( b, fuel_energy ); g->m.emit_field( pos(), bio.info().power_gen_emission ); } } -void Character::heat_emission( int b, int fuel_energy, float efficiency ) +void Character::heat_emission( int b, int fuel_energy ) { const bionic &bio = ( *my_bionics )[b]; if( !bio.info().exothermic_power_gen ) { return; } + const float efficiency = bio.info().fuel_efficiency; const int &heat_prod = fuel_energy * ( 1 - efficiency ); const int &heat_level = std::min( heat_prod / 10, 4 ); @@ -1006,6 +1009,29 @@ void Character::heat_emission( int b, int fuel_energy, float efficiency ) } } +float Character::get_effective_efficiency( int b, float fuel_efficiency ) +{ + const bionic &bio = ( *my_bionics )[b]; + const cata::optional &coverage_penalty = bio.info().coverage_power_gen_penalty; + float effective_efficiency = fuel_efficiency; + if( coverage_penalty ) { + int coverage = 0; + const std::map< body_part, size_t > &occupied_bodyparts = bio.info().occupied_bodyparts; + for( const std::pair< body_part, size_t > &elem : occupied_bodyparts ) { + for( const item &i : worn ) { + if( i.covers( elem.first ) && !i.has_flag( "ALLOWS_NATURAL_ATTACKS" ) && + !i.has_flag( "SEMITANGIBLE" ) && + !i.has_flag( "PERSONAL" ) && !i.has_flag( "AURA" ) ) { + coverage += i.get_coverage(); + } + } + } + effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100 * occupied_bodyparts.size() ) ) + * coverage_penalty.value() ); + } + return effective_efficiency; +} + /** * @param p the player * @param bio the bionic that is meant to be recharged. @@ -2264,6 +2290,7 @@ void load_bionic( JsonObject &jsobj ) assign( jsobj, "weight_capacity_bonus", new_bionic.weight_capacity_bonus, false, 0_gram ); assign( jsobj, "exothermic_power_gen", new_bionic.exothermic_power_gen ); assign( jsobj, "power_gen_emission", new_bionic.power_gen_emission ); + assign( jsobj, "coverage_power_gen_penalty", new_bionic.coverage_power_gen_penalty ); jsobj.read( "canceled_mutations", new_bionic.canceled_mutations ); jsobj.read( "included_bionics", new_bionic.included_bionics ); diff --git a/src/bionics.h b/src/bionics.h index 0a7b8297f06f0..db3ffa3b6cb93 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -91,6 +91,8 @@ struct bionic_data { float fuel_efficiency; /**Fraction of fuel energy passively converted to bionic power*/ float passive_fuel_efficiency; + /**Fraction of coverage diminishing fuel_efficiency*/ + cata::optional coverage_power_gen_penalty; /**If true this bionic emits heat when producing power*/ bool exothermic_power_gen = false; /**Type of field emitted by this bionic when it produces energy*/ diff --git a/src/character.h b/src/character.h index 7fd3690490834..a96c0917a668a 100644 --- a/src/character.h +++ b/src/character.h @@ -787,8 +787,12 @@ class Character : public Creature, public visitable virtual bool deactivate_bionic( int b, bool eff_only = false ); /**Convert fuel to bionic power*/ bool burn_fuel( int b, bool start = false ); + /**Passively produce power from PERPETUAL fuel*/ void passive_power_gen( int b ); - void heat_emission( int b, int fuel_energy, float efficiency ); + /**Handle heat from exothermic power generation*/ + void heat_emission( int b, int fuel_energy ); + /**Applies modifier to fuel_efficiency and returns the resulting efficiency*/ + float get_effective_efficiency( int b, float fuel_efficiency ); units::energy get_power_level() const; units::energy get_max_power_level() const; From 2e78620af49ef37bc4ea8fc6d32fa858a9424d85 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 22:31:24 +0100 Subject: [PATCH 09/11] doc --- doc/JSON_INFO.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 6a0115d3504b8..88b68ae35a741 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -377,8 +377,9 @@ This section describes each json file and their contents. Each json has their ow | fuel_options | (_optional_) A list of fuel that this bionic can use to produce bionic power. | fuel_capacity | (_optional_) Volume of fuel this bionic can store. | fuel_efficiency | (_optional_) Fraction of fuel energy converted into power. (default: `0`) -| passive_fuel_efficiency | (_optional_) Fraction of fuel energy passively converted into power. Only useful for muscle powered CBM (default: `0`) +| passive_fuel_efficiency | (_optional_) Fraction of fuel energy passively converted into power. Useful for CBM using PERPETUAL fuel like `muscle`, `wind` or `sun_light`. (default: `0`) | exothermic_power_gen | (_optional_) If true this bionic emits heat when producing power. (default: `false`) +| coverage_power_gen_penalty | (_optional_) Fraction of coverage diminishing fuel_efficiency. Float between 0.0 and 1.0. (default: `nullopt`) | power_gen_emission | (_optional_) `emit_id` of the field emitted by this bionic when it produces energy. Emit_ids are defined in `emit.json`. | stat_bonus | (_optional_) List of passive stat bonus. Stat are designated as follow: "DEX", "INT", "STR", "PER". From 41448c8f00a8d7bae74195d4e20fa09a64bd8cd9 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Thu, 21 Nov 2019 22:32:47 +0100 Subject: [PATCH 10/11] doc format --- doc/JSON_INFO.md | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 88b68ae35a741..5f8dc9b13df7a 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -353,35 +353,35 @@ This section describes each json file and their contents. Each json has their ow ### Bionics -| Identifier | Description -|--- |--- -| id | Unique ID. Must be one continuous word, use underscores if necessary. -| name | In-game name displayed. -| active | Whether the bionic is active or passive. (default: `passive`) -| power_source | Whether the bionic provides power. (default: `false`) -| faulty | Whether it is a faulty type. (default: `false`) -| act_cost | How many kJ it costs to activate the bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) -| deact_cost | How many kJ it costs to deactivate the bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) -| react_cost | How many kJ it costs over time to keep this bionic active, does nothing without a non-zero "time". Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) -| time | How long, when activated, between drawing cost. If 0, it draws power once. (default: `0`) -| description | In-game description. -| encumbrance | (_optional_) A list of body parts and how much this bionic encumber them. -| weight_capacity_bonus | (_optional_) Bonus to weight carrying capacity in grams, can be negative. Strings can be used - "5000 g" or "5 kg" (default: `0`) -| weight_capacity_modifier | (_optional_) Factor modifying base weight carrying capacity. (default: `1`) -| canceled_mutations | (_optional_) A list of mutations/traits that are removed when this bionic is installed (e.g. because it replaces the fault biological part). -| included_bionics | (_optional_) Additional bionics that are installed automatically when this bionic is installed. This can be used to install several bionics from one CBM item, which is useful as each of those can be activated independently. -| included | (_optional_) Whether this bionic is included with another. If true this bionic does not require a CBM item to be defined. (default: `false`) -| env_protec | (_optional_) How much environmental protection does this bionic provide on the specified body parts. -| occupied_bodyparts | (_optional_) A list of body parts occupied by this bionic, and the number of bionic slots it take on those parts. -| capacity | (_optional_) Amount of power storage added by this bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) -| fuel_options | (_optional_) A list of fuel that this bionic can use to produce bionic power. -| fuel_capacity | (_optional_) Volume of fuel this bionic can store. -| fuel_efficiency | (_optional_) Fraction of fuel energy converted into power. (default: `0`) -| passive_fuel_efficiency | (_optional_) Fraction of fuel energy passively converted into power. Useful for CBM using PERPETUAL fuel like `muscle`, `wind` or `sun_light`. (default: `0`) -| exothermic_power_gen | (_optional_) If true this bionic emits heat when producing power. (default: `false`) -| coverage_power_gen_penalty | (_optional_) Fraction of coverage diminishing fuel_efficiency. Float between 0.0 and 1.0. (default: `nullopt`) -| power_gen_emission | (_optional_) `emit_id` of the field emitted by this bionic when it produces energy. Emit_ids are defined in `emit.json`. -| stat_bonus | (_optional_) List of passive stat bonus. Stat are designated as follow: "DEX", "INT", "STR", "PER". +| Identifier | Description +|--- |--- +| id | Unique ID. Must be one continuous word, use underscores if necessary. +| name | In-game name displayed. +| active | Whether the bionic is active or passive. (default: `passive`) +| power_source | Whether the bionic provides power. (default: `false`) +| faulty | Whether it is a faulty type. (default: `false`) +| act_cost | How many kJ it costs to activate the bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) +| deact_cost | How many kJ it costs to deactivate the bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) +| react_cost | How many kJ it costs over time to keep this bionic active, does nothing without a non-zero "time". Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) +| time | How long, when activated, between drawing cost. If 0, it draws power once. (default: `0`) +| description | In-game description. +| encumbrance | (_optional_) A list of body parts and how much this bionic encumber them. +| weight_capacity_bonus | (_optional_) Bonus to weight carrying capacity in grams, can be negative. Strings can be used - "5000 g" or "5 kg" (default: `0`) +| weight_capacity_modifier | (_optional_) Factor modifying base weight carrying capacity. (default: `1`) +| canceled_mutations | (_optional_) A list of mutations/traits that are removed when this bionic is installed (e.g. because it replaces the fault biological part). +| included_bionics | (_optional_) Additional bionics that are installed automatically when this bionic is installed. This can be used to install several bionics from one CBM item, which is useful as each of those can be activated independently. +| included | (_optional_) Whether this bionic is included with another. If true this bionic does not require a CBM item to be defined. (default: `false`) +| env_protec | (_optional_) How much environmental protection does this bionic provide on the specified body parts. +| occupied_bodyparts | (_optional_) A list of body parts occupied by this bionic, and the number of bionic slots it take on those parts. +| capacity | (_optional_) Amount of power storage added by this bionic. Strings can be used "1 kJ"/"1000 J"/"1000000 mJ" (default: `0`) +| fuel_options | (_optional_) A list of fuel that this bionic can use to produce bionic power. +| fuel_capacity | (_optional_) Volume of fuel this bionic can store. +| fuel_efficiency | (_optional_) Fraction of fuel energy converted into power. (default: `0`) +| passive_fuel_efficiency | (_optional_) Fraction of fuel energy passively converted into power. Useful for CBM using PERPETUAL fuel like `muscle`, `wind` or `sun_light`. (default: `0`) +| exothermic_power_gen | (_optional_) If true this bionic emits heat when producing power. (default: `false`) +| coverage_power_gen_penalty | (_optional_) Fraction of coverage diminishing fuel_efficiency. Float between 0.0 and 1.0. (default: `nullopt`) +| power_gen_emission | (_optional_) `emit_id` of the field emitted by this bionic when it produces energy. Emit_ids are defined in `emit.json`. +| stat_bonus | (_optional_) List of passive stat bonus. Stat are designated as follow: "DEX", "INT", "STR", "PER". ```C++ { From b3dd6554cbb310d48f8ff97227ff9d58fb67d225 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Fri, 22 Nov 2019 16:07:36 +0100 Subject: [PATCH 11/11] float --- src/bionics.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index c6c4ba0a7b612..839567001798c 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -1026,7 +1026,8 @@ float Character::get_effective_efficiency( int b, float fuel_efficiency ) } } } - effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100 * occupied_bodyparts.size() ) ) + effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100.0 * + occupied_bodyparts.size() ) ) * coverage_penalty.value() ); } return effective_efficiency;