// Returns how much fuel did it provide // But contains only fuels actually used by engines std::map<itype_id, long> set_vehicle_fuel( vehicle &v, const float veh_fuel_mult ) { // First we need to find the fuels to set // That is, fuels actually used by some engine std::set<itype_id> actually_used; for( const vpart_reference vp : v.get_all_parts() ) { vehicle_part &pt = vp.part(); if( pt.is_engine() ) { actually_used.insert( pt.info().fuel_type ); pt.enabled = true; } else { // Disable all parts that use up power or electric cars become non-deterministic pt.enabled = false; } } // We ignore battery when setting fuel because it uses designated "tanks" actually_used.erase( "battery" ); // Currently only one liquid fuel supported REQUIRE( actually_used.size() <= 1 ); itype_id liquid_fuel = "null"; for( const auto &ft : actually_used ) { if( item::find_type( ft )->phase == LIQUID ) { liquid_fuel = ft; break; } } // Set fuel to a given percentage // Batteries are special cased because they aren't liquid fuel std::map<itype_id, long> ret; for( const vpart_reference vp : v.get_all_parts() ) { vehicle_part &pt = vp.part(); if( pt.is_battery() ) { pt.ammo_set( "battery", pt.ammo_capacity() * veh_fuel_mult ); ret[ "battery" ] += pt.ammo_capacity() * veh_fuel_mult; } else if( pt.is_tank() && liquid_fuel != "null" ) { float qty = pt.ammo_capacity() * veh_fuel_mult; qty *= std::max( item::find_type( liquid_fuel )->stack_size, 1 ); qty /= to_milliliter( units::legacy_volume_factor ); pt.ammo_set( liquid_fuel, qty ); ret[ liquid_fuel ] += qty; } else { pt.ammo_unset(); } } // We re-add battery because we want it accounted for, just not in the section above actually_used.insert( "battery" ); for( auto iter = ret.begin(); iter != ret.end(); ) { if( iter->second <= 0 || actually_used.count( iter->first ) == 0 ) { iter = ret.erase( iter ); } else { ++iter; } } return ret; }
// Returns the lowest percentage of fuel left // ie. 1 means no fuel was used, 0 means at least one dry tank float fuel_percentage_left( vehicle &v, const std::map<itype_id, long> &started_with ) { std::map<itype_id, long> fuel_amount; std::set<itype_id> consumed_fuels; for( const vpart_reference vp : v.get_all_parts() ) { vehicle_part &pt = vp.part(); if( ( pt.is_battery() || pt.is_reactor() || pt.is_tank() ) && pt.ammo_current() != "null" ) { fuel_amount[ pt.ammo_current() ] += pt.ammo_remaining(); } if( pt.is_engine() && pt.info().fuel_type != "null" ) { consumed_fuels.insert( pt.info().fuel_type ); } } float left = 1.0f; for( const auto &type : consumed_fuels ) { const auto iter = started_with.find( type ); // Weird - we started without this fuel float fuel_amt_at_start = iter != started_with.end() ? iter->second : 0.0f; REQUIRE( fuel_amt_at_start != 0.0f ); left = std::min( left, static_cast<float>( fuel_amount[type] ) / fuel_amt_at_start ); } return left; }