Handle fuel energy and vehicle energy_consumption as units::energy (#60607)

* energy_consumption as energy

* units::energy fuel

* units::energy material

* item fuel adjustments

* bionuc reload window

* bionic reload window

* typo

* bionic power from pedaling

* adjust electric vehicle tests

* mods

* mods

* rename some variables

* cleanup

* temp fix bionic

* temp fix treshold

* fuel tests

* adjust mod

* adjust mod

* adjust mod

* rename variable

* migration

* migration

* consumption_per_hour

* fuel does not need to count by charge

* actually is sort of has to
This commit is contained in:
Hirmuolio 2022-09-08 14:53:47 +03:00 committed by GitHub
parent 577380a82b
commit 6adf2881a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 250 additions and 195 deletions

View File

@ -12,7 +12,7 @@
"flags": [ "TRADER_AVOID", "ZERO_WEIGHT" ],
"material": [ "battery" ],
"effects": [ "COOKOFF" ],
"volume": "250 ml",
"volume": "100 ml",
"//": "Setting battery volume to 0 causes weirdness in vehicle tests. Please don't do that.",
"ammo_type": "battery",
"count": 100,

View File

@ -9,7 +9,7 @@
"description": "seeing this is a bug",
"stackable": true,
"price": 0,
"volume": "0 ml",
"volume": "1 L",
"material": [ "animal" ],
"flags": [ "PSEUDO", "PERPETUAL" ]
},
@ -35,7 +35,7 @@
"description": "seeing this is a bug",
"stackable": true,
"price": 0,
"volume": "0 ml",
"volume": "1 L",
"material": [ "muscle" ],
"flags": [ "PSEUDO", "PERPETUAL" ]
},
@ -49,7 +49,7 @@
"description": "seeing this is a bug",
"stackable": true,
"price": 0,
"volume": "0 ml",
"volume": "1 L",
"material": [ "wind" ],
"flags": [ "PSEUDO", "PERPETUAL" ]
},
@ -63,7 +63,7 @@
"description": "seeing this is a bug",
"stackable": true,
"price": 0,
"volume": "0 ml",
"volume": "1 L",
"material": [ "sunlight" ],
"flags": [ "PSEUDO", "PERPETUAL" ]
},
@ -77,7 +77,7 @@
"description": "seeing this is a bug",
"stackable": true,
"price": 0,
"volume": "0 ml",
"volume": "1 L",
"material": [ "metabolism" ],
"flags": [ "PSEUDO", "PERPETUAL" ]
},

View File

@ -60,47 +60,49 @@
"dmg_adj": [ "scratched", "cut", "cracked", "shattered" ],
"bash_dmg_verb": "dented",
"cut_dmg_verb": "gouged",
"fuel_data": { "energy": 1 }
"fuel_data": { "energy": "1000 kJ" }
},
{
"type": "material",
"id": "battery",
"name": "Battery",
"copy-from": "pseudo_fuel"
"copy-from": "pseudo_fuel",
"//": "This gives battery item 1 kJ/unit",
"fuel_data": { "energy": "1000 kJ" }
},
{
"type": "material",
"id": "wind",
"name": "Wind",
"fuel_data": { "energy": 1, "perpetual": true },
"fuel_data": { "energy": "1 kJ", "perpetual": true },
"copy-from": "pseudo_fuel"
},
{
"type": "material",
"id": "sunlight",
"name": "Sunlight",
"fuel_data": { "energy": 1, "perpetual": true },
"fuel_data": { "energy": "1 kJ", "perpetual": true },
"copy-from": "pseudo_fuel"
},
{
"type": "material",
"id": "animal",
"name": "Animal",
"fuel_data": { "energy": 1, "perpetual": true },
"fuel_data": { "energy": "1 kJ", "perpetual": true },
"copy-from": "pseudo_fuel"
},
{
"type": "material",
"id": "muscle",
"name": "Muscle",
"fuel_data": { "energy": 1, "perpetual": true },
"fuel_data": { "energy": "1 kJ", "perpetual": true },
"copy-from": "pseudo_fuel"
},
{
"type": "material",
"id": "metabolism",
"name": "Metabolism",
"fuel_data": { "energy": 1, "perpetual": true },
"fuel_data": { "energy": "1 kJ", "perpetual": true },
"copy-from": "pseudo_fuel"
},
{
@ -123,7 +125,7 @@
"bash_dmg_verb": "damaged",
"cut_dmg_verb": "damaged",
"fuel_data": {
"energy": 15.6,
"energy": "15600 kJ",
"explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
},
"burn_data": [
@ -1014,7 +1016,7 @@
"density": 0.85,
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 35.8,
"energy": "35800 kJ",
"pump_terrain": "t_diesel_pump",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
}
@ -1026,7 +1028,7 @@
"density": 0.84,
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 34.7,
"energy": "34700 kJ",
"pump_terrain": "t_jp8_pump",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
}
@ -1038,7 +1040,7 @@
"name": "Avgas Fuel",
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 45.8,
"energy": "45800 kJ",
"pump_terrain": "t_avgas_pump",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
}
@ -1050,7 +1052,7 @@
"density": 0.875,
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 29.6,
"energy": "29600 kJ",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
}
},
@ -1061,7 +1063,7 @@
"density": 0.75,
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 34.2,
"energy": "34200 kJ",
"pump_terrain": "t_gas_pump",
"explosion_data": { "chance_hot": 2, "chance_cold": 5, "factor": 1, "fiery": true, "size_factor": 0.1 }
}
@ -1074,7 +1076,7 @@
"copy-from": "hydrocarbons",
"fuel_data": {
"//": "Roughly equivalent to LPG",
"energy": 26,
"energy": "26000 kJ",
"explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
}
},
@ -1085,7 +1087,7 @@
"name": "Crude lamp oil",
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 24,
"energy": "24000 kJ",
"explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
}
},
@ -1097,7 +1099,7 @@
"copy-from": "hydrocarbons",
"fuel_data": {
"//": "Roughly equivalent to LPG",
"energy": 26,
"energy": "26000 kJ",
"explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
}
},
@ -1675,7 +1677,7 @@
"dmg_adj": [ "lightly damaged", "damaged", "very damaged", "thoroughly damaged" ],
"bash_dmg_verb": "damaged",
"cut_dmg_verb": "damaged",
"fuel_data": { "energy": 5.2 }
"fuel_data": { "energy": "5200 kJ" }
},
{
"type": "material",
@ -2068,7 +2070,7 @@
"bash_dmg_verb": "dented",
"cut_dmg_verb": "scratched",
"burn_products": [ [ "scrap", 1 ] ],
"fuel_data": { "energy": 10 }
"fuel_data": { "energy": "10000 kJ" }
},
{
"type": "material",
@ -2092,7 +2094,7 @@
"burn_products": [ [ "scrap", 1 ] ],
"fuel_data": {
"//": "Compressed gaseous hydrogen has 9.2 MJ/L. This stuff has a very high energy density but is also bulky and explosive.",
"energy": 4000,
"energy": "4000000 kJ",
"explosion_data": { "chance_hot": 2, "chance_cold": 2, "factor": 1, "fiery": true, "size_factor": 0.15 }
}
},
@ -2502,21 +2504,21 @@
{ "fuel": 3, "smoke": 1, "burn": 0.03 }
],
"burn_products": [ [ "ash", 0.018 ] ],
"fuel_data": { "energy": 1 }
"fuel_data": { "energy": "1000 kJ" }
},
{
"type": "material",
"id": "charcoal",
"name": "Charcoal",
"copy-from": "wood",
"fuel_data": { "energy": 1.6 }
"fuel_data": { "energy": "1600 kJ" }
},
{
"type": "material",
"id": "coal",
"name": "Coal",
"copy-from": "wood",
"fuel_data": { "energy": 30 }
"fuel_data": { "energy": "30000 kJ" }
},
{
"type": "material",
@ -2747,7 +2749,7 @@
"name": "Propane",
"copy-from": "hydrocarbons",
"fuel_data": {
"energy": 25,
"energy": "25000 kJ",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
}
},
@ -2810,7 +2812,7 @@
"bash_dmg_verb": "damaged",
"cut_dmg_verb": "damaged",
"freezing_point": -77.73,
"fuel_data": { "energy": 11.5 }
"fuel_data": { "energy": "11500 kJ" }
},
{
"type": "material",
@ -2833,7 +2835,7 @@
"cut_dmg_verb": "damaged",
"freezing_point": -55,
"fuel_data": {
"energy": 34.8,
"energy": "34800 kJ",
"explosion_data": { "chance_hot": 5, "chance_cold": 1000, "factor": 0.2, "fiery": false, "size_factor": 0.1 }
},
"burn_data": [

View File

@ -65,7 +65,7 @@
"durability": 400,
"epower": -350,
"power": 223800,
"energy_consumption": 559500,
"energy_consumption": "559500 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 40 ] },
{ "item": "steel_chunk", "count": [ 30, 40 ] },
@ -91,7 +91,7 @@
"durability": 400,
"epower": -250,
"power": 149200,
"energy_consumption": 373000,
"energy_consumption": "373000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 40 ] },
{ "item": "steel_chunk", "count": [ 30, 40 ] },
@ -117,7 +117,7 @@
"durability": 400,
"epower": -350,
"power": 242450,
"energy_consumption": 606250,
"energy_consumption": "606250 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 40 ] },
{ "item": "steel_chunk", "count": [ 30, 40 ] },
@ -144,7 +144,7 @@
"durability": 150,
"epower": 0,
"power": 7370,
"energy_consumption": 18425,
"energy_consumption": "18425 J",
"folded_volume": "60 L",
"breaks_into": [
{ "item": "steel_lump", "count": [ 5, 10 ] },
@ -173,7 +173,7 @@
"durability": 150,
"epower": 0,
"power": 41000,
"energy_consumption": 124500,
"energy_consumption": "124500 J",
"folded_volume": "90 L",
"breaks_into": [
{ "item": "steel_lump", "count": [ 6, 12 ] },
@ -203,7 +203,7 @@
"durability": 120,
"epower": 0,
"power": 3728,
"energy_consumption": 9320,
"energy_consumption": "9320 J",
"folded_volume": "629 ml",
"breaks_into": [
{ "item": "steel_lump", "count": [ 2, 4 ] },
@ -230,7 +230,7 @@
"durability": 300,
"epower": -200,
"power": 111900,
"energy_consumption": 373000,
"energy_consumption": "373000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 40 ] },
{ "item": "steel_chunk", "count": [ 30, 40 ] },
@ -256,7 +256,7 @@
"durability": 300,
"epower": -150,
"power": 93250,
"energy_consumption": 311000,
"energy_consumption": "311000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 20, 30 ] },
{ "item": "steel_chunk", "count": [ 20, 30 ] },
@ -282,7 +282,7 @@
"durability": 600,
"epower": -350,
"power": 447600,
"energy_consumption": 1492000,
"energy_consumption": "1492000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 45, 58 ] },
{ "item": "steel_chunk", "count": [ 45, 58 ] },
@ -308,7 +308,7 @@
"durability": 600,
"epower": -400,
"power": 447600,
"energy_consumption": 1119000,
"energy_consumption": "1119000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 45, 58 ] },
{ "item": "steel_chunk", "count": [ 45, 58 ] },
@ -334,7 +334,7 @@
"durability": 400,
"epower": -200,
"power": 149200,
"energy_consumption": 497500,
"energy_consumption": "497500 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 40 ] },
{ "item": "steel_chunk", "count": [ 30, 40 ] },
@ -360,7 +360,7 @@
"durability": 400,
"epower": -250,
"power": 242450,
"energy_consumption": 808200,
"energy_consumption": "808200 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 40, 50 ] },
{ "item": "steel_chunk", "count": [ 40, 50 ] },
@ -386,7 +386,7 @@
"durability": 200,
"epower": -50,
"power": 37300,
"energy_consumption": 124500,
"energy_consumption": "124500 J",
"folded_volume": "109 L",
"breaks_into": [
{ "item": "steel_lump", "count": [ 10, 20 ] },
@ -429,7 +429,7 @@
"durability": 200,
"epower": 0,
"power": 55950,
"energy_consumption": 112000,
"energy_consumption": "112000 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 60 ] },
{ "item": "steel_chunk", "count": [ 30, 60 ] },
@ -455,7 +455,7 @@
"durability": 200,
"epower": 0,
"power": 93250,
"energy_consumption": 186500,
"energy_consumption": "186500 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 60 ] },
{ "item": "steel_chunk", "count": [ 30, 60 ] },
@ -481,7 +481,7 @@
"durability": 200,
"epower": -20,
"power": 149200,
"energy_consumption": 298500,
"energy_consumption": "298500 J",
"breaks_into": [
{ "item": "steel_lump", "count": [ 30, 60 ] },
{ "item": "steel_chunk", "count": [ 30, 60 ] },
@ -508,7 +508,7 @@
"durability": 400,
"epower": -10,
"power": 1006695,
"energy_consumption": 4026780,
"energy_consumption": "4026780 J",
"breaks_into": [
{ "item": "alloy_plate", "count": [ 1, 2 ] },
{ "item": "steel_lump", "count": [ 45, 58 ] },
@ -535,7 +535,7 @@
"durability": 400,
"epower": -10,
"power": 1416830,
"energy_consumption": 5667320,
"energy_consumption": "5667320 J",
"breaks_into": [
{ "item": "alloy_plate", "count": [ 2, 4 ] },
{ "item": "steel_lump", "count": [ 50, 65 ] },
@ -562,7 +562,7 @@
"durability": 400,
"epower": -10,
"power": 4474199,
"energy_consumption": 17896796,
"energy_consumption": "17896796 J",
"breaks_into": [
{ "item": "alloy_plate", "count": [ 4, 6 ] },
{ "item": "steel_lump", "count": [ 100, 120 ] },

View File

@ -25,7 +25,7 @@
"looks_like": "motor_small",
"durability": 80,
"power": 800,
"energy_consumption": 1000,
"energy_consumption": "1 kJ",
"damage_modifier": 80,
"folded_volume": "250 ml",
"requirements": {
@ -49,7 +49,7 @@
"item": "motor_small",
"durability": 120,
"power": 7040,
"energy_consumption": 8000,
"energy_consumption": "8 kJ",
"damage_modifier": 80,
"folded_volume": "250 ml",
"requirements": {
@ -78,7 +78,7 @@
"item": "motor",
"durability": 200,
"power": 36000,
"energy_consumption": 40000,
"energy_consumption": "40 kJ",
"damage_modifier": 80,
"folded_volume": "1500 ml",
"requirements": {
@ -115,7 +115,7 @@
"item": "motor_large",
"durability": 400,
"power": 150000,
"energy_consumption": 163000,
"energy_consumption": "163 kJ",
"damage_modifier": 80,
"requirements": {
"install": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },
@ -151,7 +151,7 @@
"item": "motor_enhanced",
"durability": 200,
"power": 282000,
"energy_consumption": 300000,
"energy_consumption": "300 kJ",
"damage_modifier": 80,
"requirements": {
"install": { "skills": [ [ "mechanics", 4 ] ], "time": "60 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },
@ -187,7 +187,7 @@
"item": "motor_super",
"durability": 400,
"power": 475000,
"energy_consumption": 500000,
"energy_consumption": "500 kJ",
"damage_modifier": 80,
"requirements": {
"install": { "skills": [ [ "mechanics", 5 ] ], "time": "60 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },
@ -223,7 +223,7 @@
"item": "motor_train1300",
"durability": 500,
"power": 1000000,
"energy_consumption": 1050000,
"energy_consumption": "1050 kJ",
"damage_modifier": 80,
"requirements": {
"install": { "skills": [ [ "mechanics", 8 ] ], "time": "60 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },

View File

@ -219,7 +219,7 @@
{ "fuel": 900, "smoke": 6, "burn": 3 }
],
"fuel_data": {
"energy": 50,
"energy": "50000000 kJ",
"explosion_data": { "chance_hot": 20, "chance_cold": 1000, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
}
},
@ -247,35 +247,35 @@
{ "fuel": -50, "smoke": 2, "burn": 1 },
{ "fuel": -10, "smoke": 2, "burn": 2 }
],
"fuel_data": { "energy": 1 }
"fuel_data": { "energy": "1000 kJ" }
},
{
"type": "material",
"id": "tainted_blood",
"name": "Tainted blood",
"copy-from": "blood",
"fuel_data": { "energy": 5 }
"fuel_data": { "energy": "5000 kJ" }
},
{
"type": "material",
"id": "alumentum",
"name": "Alumentum",
"copy-from": "charcoal",
"fuel_data": { "energy": 150 }
"fuel_data": { "energy": "150000 kJ" }
},
{
"type": "material",
"id": "crystallized_mana",
"name": "Crystallized mana",
"copy-from": "stone",
"fuel_data": { "energy": 1 }
"fuel_data": { "energy": "1000 kJ" }
},
{
"type": "material",
"id": "mana",
"name": "Mana",
"copy-from": "pseudo_fuel",
"fuel_data": { "energy": 500, "perpetual": true }
"fuel_data": { "energy": "500000 kJ", "perpetual": true }
},
{
"type": "material",

View File

@ -37,7 +37,7 @@
{ "fuel": -50, "smoke": 2, "burn": 1 },
{ "fuel": -10, "smoke": 2, "burn": 2 }
],
"fuel_data": { "energy": 10 },
"fuel_data": { "energy": "10000 kJ" },
"vitamins": [ [ "calcium", 0.1 ], [ "iron", 1.3 ], [ "underhill_essence", 5 ] ]
},
{

View File

@ -1306,11 +1306,8 @@ If a fuel has the PERPETUAL flag, engines powered by it never use any fuel. Thi
```C++
"fuel_data" : {
energy": 34.2, // battery charges per mL of fuel. batteries have energy 1
// is also MJ/L from https://en.wikipedia.org/wiki/Energy_density
// assumes stacksize 250 per volume 1 (250mL). Multiply
// by 250 / stacksize * volume for other stack sizes and
// volumes
"energy": "34200_kJ", // Energy per litre of fuel.
// https://en.wikipedia.org/wiki/Energy_density
"perpetual": true, // this material is a perpetual fuel like `wind`, `sunlight`, `muscle`, `animal` and `metabolism`.
"pump_terrain": "t_gas_pump", // optional. terrain id for the fuel's pump, if any.
"explosion_data": { // optional for fuels that can cause explosions

View File

@ -207,7 +207,7 @@ struct Character::auto_toggle_bionic_result {
other
};
fuel_type_t fuel_type = fuel_type_t::other;
int fuel_energy = 0;
units::energy fuel_energy = 0_J;
float effective_efficiency = 0.0f;
int current_fuel_stock = 0;
};
@ -1357,7 +1357,8 @@ Character::auto_toggle_bionic_result Character::auto_toggle_bionic( bionic &bio,
std::string msg_player;
std::string msg_npc;
for( const material_id &fuel : fuel_available ) {
const int fuel_energy = fuel->get_fuel_data().energy;
const units::energy fuel_energy = fuel->get_fuel_data().energy /
1000; // TODO: Rewrite to use item volume
const bool is_metabolism_powered = fuel == fuel_type_metabolism;
const bool is_perpetual_fuel = fuel->get_fuel_data().is_perpetual_fuel;
const bool is_remote_fuel = is_remote_fueled && fuel == remote_fuel;
@ -1392,7 +1393,7 @@ Character::auto_toggle_bionic_result Character::auto_toggle_bionic( bionic &bio,
}
if( bio.get_safe_fuel_thresh() > 0
&& get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency >
&& get_power_level() + fuel_energy * effective_efficiency >
get_max_power_level() * std::min( 1.0f, bio.get_safe_fuel_thresh() ) ) {
if( bio.powered || start ) {
if( !start ) {
@ -1493,12 +1494,13 @@ void Character::burn_fuel( bionic &bio, const auto_toggle_bionic_result &result
map &here = get_map();
weather_manager &weather = get_weather();
// TODO: Rewrite fuels to use item volume.
// The energy is in energy/L but we just divide by 1000 and treat it as energy/unit
switch( result.fuel_type ) {
case auto_toggle_bionic_result::fuel_type_t::metabolism: {
const int kcal_consumed = result.fuel_energy;
// 1kcal = 4184 J
const units::energy power_gain = kcal_consumed * 4184_J * result.effective_efficiency;
mod_stored_kcal( -kcal_consumed, true );
const units::energy power_gain = result.fuel_energy * 4184 * result.effective_efficiency / 1000;
mod_stored_kcal( -units::to_kilojoule( result.fuel_energy ), true );
mod_power_level( power_gain );
break;
}
@ -1506,8 +1508,8 @@ void Character::burn_fuel( bionic &bio, const auto_toggle_bionic_result &result
if( result.burnable_fuel_id == fuel_type_sun_light && g->is_in_sunlight( pos() ) ) {
const weather_type_id &wtype = current_weather( pos() );
const float intensity = incident_sun_irradiance( wtype, calendar::turn ) / max_sun_irradiance();
mod_power_level( units::from_kilojoule( result.fuel_energy ) * intensity *
result.effective_efficiency );
mod_power_level( result.fuel_energy * intensity *
result.effective_efficiency / 1000 );
} else if( result.burnable_fuel_id == fuel_type_wind ) {
int vehwindspeed = 0;
const optional_vpart_position vp = here.veh_at( pos() );
@ -1518,8 +1520,8 @@ void Character::burn_fuel( bionic &bio, const auto_toggle_bionic_result &result
const int windpower = get_local_windpower( weather.windspeed + vehwindspeed,
overmap_buffer.ter( global_omt_location() ), pos(), weather.winddirection,
g->is_sheltered( pos() ) );
mod_power_level( units::from_kilojoule( result.fuel_energy ) * windpower *
result.effective_efficiency );
mod_power_level( result.fuel_energy * windpower *
result.effective_efficiency / 1000 );
} else if( result.burnable_fuel_id == fuel_type_muscle ) {
// simply return
}
@ -1528,7 +1530,7 @@ void Character::burn_fuel( bionic &bio, const auto_toggle_bionic_result &result
const int unconsumed = consume_remote_fuel( 1 );
int current_fuel_stock = result.current_fuel_stock;
if( unconsumed == 0 ) {
mod_power_level( units::from_kilojoule( result.fuel_energy ) * result.effective_efficiency );
mod_power_level( result.fuel_energy * result.effective_efficiency / 1000 );
current_fuel_stock -= 1;
} else {
current_fuel_stock = 0;
@ -1539,7 +1541,7 @@ void Character::burn_fuel( bionic &bio, const auto_toggle_bionic_result &result
case auto_toggle_bionic_result::fuel_type_t::other:
set_value( result.burnable_fuel_id.str(), std::to_string( result.current_fuel_stock - 1 ) );
update_fuel_storage( result.burnable_fuel_id );
mod_power_level( units::from_kilojoule( result.fuel_energy ) * result.effective_efficiency );
mod_power_level( result.fuel_energy * result.effective_efficiency / 1000 );
break;
}
@ -1562,7 +1564,8 @@ void Character::passive_power_gen( const bionic &bio )
weather_manager &weather = get_weather();
for( const material_id &fuel : fuel_available ) {
const int fuel_energy = fuel->get_fuel_data().energy;
const units::energy fuel_energy = fuel->get_fuel_data().energy /
1000; // TODO: Rewrite to use item volume
if( !fuel->get_fuel_data().is_perpetual_fuel ) {
continue;
}
@ -1570,7 +1573,7 @@ void Character::passive_power_gen( const bionic &bio )
if( fuel == fuel_type_sun_light ) {
const float intensity = incident_sun_irradiance( current_weather( pos() ),
calendar::turn ) / max_sun_irradiance();
mod_power_level( units::from_kilojoule( fuel_energy ) * intensity * effective_passive_efficiency );
mod_power_level( fuel_energy * intensity * effective_passive_efficiency );
} else if( fuel == fuel_type_wind ) {
int vehwindspeed = 0;
const optional_vpart_position vp = here.veh_at( pos() );
@ -1581,9 +1584,9 @@ void Character::passive_power_gen( const bionic &bio )
const int windpower = get_local_windpower( weather.windspeed + vehwindspeed,
overmap_buffer.ter( global_omt_location() ), pos(), weather.winddirection,
g->is_sheltered( pos() ) );
mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_passive_efficiency );
mod_power_level( fuel_energy * windpower * effective_passive_efficiency );
} else {
mod_power_level( units::from_kilojoule( fuel_energy ) * effective_passive_efficiency );
mod_power_level( fuel_energy * effective_passive_efficiency );
}
heat_emission( bio, fuel_energy );
@ -1682,14 +1685,14 @@ void Character::reset_remote_fuel()
remove_value( "rem_battery" );
}
void Character::heat_emission( const bionic &bio, int fuel_energy )
void Character::heat_emission( const bionic &bio, units::energy fuel_energy )
{
if( !bio.info().exothermic_power_gen ) {
return;
}
const float efficiency = bio.info().fuel_efficiency;
const int heat_prod = fuel_energy * ( 1.0f - efficiency );
const int heat_prod = units::to_kilojoule( fuel_energy * ( 1.0f - efficiency ) );
const int heat_level = std::min( heat_prod / 10, 4 );
const emit_id hotness = emit_id( "emit_hot_air" + std::to_string( heat_level ) + "_cbm" );
map &here = get_map();

View File

@ -1620,7 +1620,7 @@ class Character : public Creature, public visitable
int consume_remote_fuel( int amount );
void reset_remote_fuel();
/**Handle heat from exothermic power generation*/
void heat_emission( const bionic &bio, int fuel_energy );
void heat_emission( const bionic &bio, units::energy fuel_energy );
/**Applies modifier to fuel_efficiency and returns the resulting efficiency*/
float get_effective_efficiency( const bionic &bio, float fuel_efficiency ) const;
@ -2898,7 +2898,9 @@ class Character : public Creature, public visitable
* Asks about them if @param interactive is true, refuses otherwise.
*/
ret_val<edible_rating> will_eat( const item &food, bool interactive = false ) const;
/** Determine character's capability of recharging their CBMs. */
/** Determine character's capability of recharging their CBMs.
* Returns energy in kJ
*/
int get_acquirable_energy( const item &it ) const;
/**

View File

@ -1633,19 +1633,16 @@ int Character::get_acquirable_energy( const item &it ) const
}
const bionic_id &bid = get_most_efficient_bionic( bids );
int to_consume;
int to_charge = 0;
units::energy energy_per_charge;
item fuel;
if( it.type->magazine ) {
item ammo = item( it.ammo_current() );
to_consume = std::min( it.ammo_remaining(), bid->fuel_capacity );
to_charge = ammo.fuel_energy() * to_consume * bid->fuel_efficiency;
} else if( it.flammable() ) {
to_consume = std::min( units::to_milliliter( it.volume() ), bid->fuel_capacity );
to_charge = it.get_base_material().id->get_fuel_data().energy * to_consume * bid->fuel_efficiency;
fuel = it.loaded_ammo();
} else {
to_consume = std::min( it.charges, bid->fuel_capacity );
to_charge = it.fuel_energy() * to_consume * bid->fuel_efficiency;
fuel = it;
}
return to_charge;
energy_per_charge = fuel.fuel_energy() / fuel.charges;
to_consume = std::min( fuel.charges, bid->fuel_capacity );
return units::to_kilojoule( energy_per_charge * to_consume * bid->fuel_efficiency );
}
bool Character::can_estimate_rot() const

View File

@ -10786,9 +10786,9 @@ void game::on_move_effects()
const item muscle( "muscle" );
for( const bionic_id &bid : u.get_bionic_fueled_with( muscle ) ) {
if( u.has_active_bionic( bid ) ) {// active power gen
u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency );
u.mod_power_level( muscle.fuel_energy() * bid->fuel_efficiency );
} else if( u.has_bionic( bid ) ) {// passive power gen
u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->passive_fuel_efficiency );
u.mod_power_level( muscle.fuel_energy() * bid->passive_fuel_efficiency );
}
}
if( u.has_active_bionic( bio_jointservo ) ) {

View File

@ -9943,7 +9943,7 @@ bool item::is_fuel() const
return false;
}
// and this material has to produce energy
if( get_base_material().get_fuel_data().energy <= 0.0 ) {
if( get_base_material().get_fuel_data().energy <= 0_J ) {
return false;
}
// and it needs to be have consumable charges
@ -10011,9 +10011,10 @@ int item::wheel_area() const
return is_wheel() ? type->wheel->diameter * type->wheel->width : 0;
}
float item::fuel_energy() const
units::energy item::fuel_energy() const
{
return get_base_material().get_fuel_data().energy;
// The odd units and division are to avoid integer rounding errors.
return get_base_material().get_fuel_data().energy * units::to_milliliter( volume() ) / 1000;
}
std::string item::fuel_pump_terrain() const

View File

@ -1526,8 +1526,8 @@ class item : public visitable
/** Returns the total area of this wheel or 0 if it isn't one. */
int wheel_area() const;
/** Returns energy of one charge of this item as fuel for an engine. */
float fuel_energy() const;
/** Returns energy of this item as fuel for an engine. */
units::energy fuel_energy() const;
/** Returns the string of the id of the terrain that pumps this fuel, if any. */
std::string fuel_pump_terrain() const;
bool has_explosion_data() const;

View File

@ -57,8 +57,8 @@ struct fuel_explosion_data {
struct fuel_data {
public:
/** Energy of the fuel (kilojoules per charge) */
float energy = 0.0f;
/** Energy of the fuel per litre */
units::energy energy = 0_J;
fuel_explosion_data explosion_data;
std::string pump_terrain = "t_null";
bool is_perpetual_fuel = false;

View File

@ -3455,10 +3455,22 @@ void vehicle::deserialize( const JsonObject &data )
}
data.read( "tags", tags );
data.read( "fuel_remainder", fuel_remainder );
data.read( "fuel_used_last_turn", fuel_used_last_turn );
data.read( "labels", labels );
if( data.has_string( "fuel_remainder" ) ) {
data.read( "fuel_remainder", fuel_remainder );
} else {
// Compatibility with 0.F
// It is a small and not important number so just ignore it.
}
if( data.has_string( "fuel_used_last_turn" ) ) {
data.read( "fuel_used_last_turn", fuel_used_last_turn );
} else {
// Compatibility with 0.F
// It is a small and not important number so just ignore it.
}
// TODO: Remove after enough time passes for save games to migrate.
// This migrates old "convertible" vehicles to new generic "folding" ones
if( has_tag( "convertible" ) ) {

View File

@ -3043,7 +3043,7 @@ void veh_interact::display_details( const vpart_info *part )
c_white, _( "Charge: <color_light_gray>%s</color>" ),
item::nname( part->fuel_type ) );
}
int part_consumption = part->energy_consumption;
int part_consumption = units::to_joule( part->energy_consumption );
if( part_consumption != 0 ) {
fold_and_print( w_details, point( col_2, line + 4 ), column_width, c_white,
_( "Drain: <color_light_gray>%+8d</color>" ), -part_consumption );

View File

@ -454,10 +454,10 @@ class vpart_info
int epower = 0;
/**
* Energy consumed by engines and motors (watts) when delivering max @ref power
* Energy consumed per second by engines and motors when delivering max @ref power
* Includes waste. Gets scaled based on powertrain demand.
*/
int energy_consumption = 0;
units::energy energy_consumption = 0_J;
/**
* For engines and motors this is maximum output (watts)

View File

@ -3438,16 +3438,17 @@ int vehicle::basic_consumption( const itype_id &ftype ) const
return fcon;
}
int vehicle::consumption_per_hour( const itype_id &ftype, int fuel_rate_w ) const
int vehicle::consumption_per_hour( const itype_id &ftype, units::energy fuel_per_s ) const
{
item fuel = item( ftype );
if( fuel_rate_w == 0 || fuel.has_flag( flag_PERPETUAL ) || !engine_on ) {
if( fuel_per_s == 0_J || fuel.has_flag( flag_PERPETUAL ) || !engine_on ) {
return 0;
}
// constant is 3600 sec/hr * 1/1000 J/kJ
// expression units are mL/hr
return -3.6 * fuel_rate_w / fuel.fuel_energy();
units::energy energy_per_h = fuel_per_s * 3600;
units::energy energy_per_liter = fuel.get_base_material().get_fuel_data().energy;
return -1000 * energy_per_h / energy_per_liter;
}
int vehicle::total_power_w( const bool fueled, const bool safe ) const
@ -4534,23 +4535,23 @@ float vehicle::handling_difficulty() const
return velocity * diff_mod / vehicles::vmiph_per_tile;
}
int vehicle::engine_fuel_usage( int e ) const
units::energy vehicle::engine_fuel_usage( int e ) const
{
if( !is_engine_on( e ) ) {
return 0;
return 0_J;
}
const itype_id &cur_fuel = parts[engines[e]].fuel_current();
if( cur_fuel == fuel_type_null ) {
return 0;
return 0_J;
}
if( is_perpetual_type( e ) ) {
return 0;
return 0_J;
}
const vpart_info &info = part_info( engines[ e ] );
int usage = info.energy_consumption;
units::energy usage = info.energy_consumption;
if( parts[ engines[ e ] ].has_fault_flag( "DOUBLE_FUEL_CONSUMPTION" ) ) {
usage *= 2;
}
@ -4558,41 +4559,31 @@ int vehicle::engine_fuel_usage( int e ) const
return usage;
}
std::map<itype_id, int> vehicle::fuel_usage() const
std::map<itype_id, units::energy> vehicle::fuel_usage() const
{
std::map<itype_id, int> ret;
std::map<itype_id, units::energy> ret;
for( size_t i = 0; i < engines.size(); i++ ) {
// Note: functions with "engine" in name do NOT take part indices
// TODO: Use part indices and not engine vector indices
if( !is_engine_on( i ) ) {
continue;
}
const size_t e = engines[ i ];
const itype_id &cur_fuel = parts[ e ].fuel_current();
if( cur_fuel == fuel_type_null ) {
continue;
}
if( !is_perpetual_type( i ) ) {
ret[cur_fuel] += engine_fuel_usage( i );
}
const size_t e = engines[i];
const itype_id &cur_fuel = parts[e].fuel_current();
ret[cur_fuel] += engine_fuel_usage( i );
}
return ret;
}
double vehicle::drain_energy( const itype_id &ftype, double energy_j )
units::energy vehicle::drain_energy( const itype_id &ftype, units::energy wanted_energy )
{
double drained = 0.0f;
units::energy drained = 0_J;
for( vehicle_part &p : parts ) {
if( energy_j <= 0.0f ) {
if( wanted_energy <= 0_J ) {
break;
}
double consumed = p.consume_energy( ftype, energy_j );
units::energy consumed = p.consume_energy( ftype, wanted_energy );
drained += consumed;
energy_j -= consumed;
wanted_energy -= consumed;
}
invalidate_mass();
@ -4608,17 +4599,17 @@ void vehicle::consume_fuel( int load, bool idling )
continue;
}
double amnt_precise_j = static_cast<double>( fuel_pr.second );
amnt_precise_j *= load / 1000.0 * ( 1.0 + st * st * 100.0 );
auto inserted = fuel_used_last_turn.insert( { ft, 0.0f } );
inserted.first->second += amnt_precise_j;
double remainder = fuel_remainder[ ft ];
amnt_precise_j -= remainder;
units::energy to_consume = fuel_pr.second;
to_consume *= load * ( 1 + st * st * 100 ) / 1000;
auto inserted = fuel_used_last_turn.insert( { ft, 0_J } );
inserted.first->second += to_consume;
units::energy remainder = fuel_remainder[ ft ];
to_consume -= remainder;
if( amnt_precise_j > 0.0f ) {
fuel_remainder[ ft ] = drain_energy( ft, amnt_precise_j ) - amnt_precise_j;
if( to_consume > 0_J ) {
fuel_remainder[ ft ] = drain_energy( ft, to_consume ) - to_consume;
} else {
fuel_remainder[ ft ] = -amnt_precise_j;
fuel_remainder[ ft ] = -to_consume;
}
}
// Only process muscle power things when moving.
@ -4651,14 +4642,14 @@ void vehicle::consume_fuel( int load, bool idling )
for( const bionic_id &bid : player_character.get_bionic_fueled_with( muscle ) ) {
if( player_character.has_active_bionic( bid ) ) { // active power gen
// more pedaling = more power
player_character.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) *
player_character.mod_power_level( muscle.fuel_energy() *
bid->fuel_efficiency *
( load / 1000 ) );
load / 1000 );
mod += eff_load / 5;
} else { // passive power gen
player_character.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) *
player_character.mod_power_level( muscle.fuel_energy() *
bid->passive_fuel_efficiency *
( load / 1000 ) );
load / 1000 );
mod += eff_load / 10;
}
}

View File

@ -113,7 +113,7 @@ struct smart_controller_cache {
bool gas_engine_shutdown_forbidden = false;
int velocity = 0;
int battery_percent = 0;
int battery_net_charge_rate = 0;
units::energy battery_net_charge_rate = 0_J;
float load = 0.0f;
};
@ -300,10 +300,10 @@ struct vehicle_part {
/**
* Consume fuel by energy content.
* @param ftype Type of fuel to consume
* @param energy_j Energy to consume, in J
* @return Energy actually consumed, in J
* @param wanted_energy Energy to consume
* @return Energy actually consumed
*/
double consume_energy( const itype_id &ftype, double energy_j );
units::energy consume_energy( const itype_id &ftype, units::energy wanted_energy );
/* @return true if part in current state be reloaded optionally with specific itype_id */
bool can_reload( const item &obj = item() ) const;
@ -755,7 +755,7 @@ class vehicle
// get vpart epowerinfo for part number.
int part_epower_w( int index ) const;
// convert watts over time to battery energy
// convert watts over time to battery energy (kJ)
int power_to_energy_bat( int power_w, const time_duration &d ) const;
// convert vhp to watts.
@ -770,7 +770,7 @@ class vehicle
bool verbose = false, bool desc = false );
void print_fuel_indicator( const catacurses::window &w, const point &p,
const itype_id &fuel_type,
std::map<itype_id, float> fuel_usages,
std::map<itype_id, units::energy> fuel_usages,
bool verbose = false, bool desc = false );
// Calculate how long it takes to attempt to start an engine
@ -1256,24 +1256,28 @@ class vehicle
/**
* Consumes enough fuel by energy content. Does not support cable draining.
* @param ftype Type of fuel
* @param energy_j Desired amount of energy of fuel to consume
* @param wanted_energy Desired amount of energy of fuel to consume
* @return Amount of energy actually consumed. May be more or less than energy.
*/
double drain_energy( const itype_id &ftype, double energy_j );
units::energy drain_energy( const itype_id &ftype, units::energy wanted_energy );
// fuel consumption of vehicle engines of given type
int basic_consumption( const itype_id &ftype ) const;
int consumption_per_hour( const itype_id &ftype, int fuel_rate ) const;
// Fuel consumption mL/hour
int consumption_per_hour( const itype_id &ftype, units::energy fuel_per_s ) const;
void consume_fuel( int load, bool idling );
/**
* Maps used fuel to its basic (unscaled by load/strain) consumption.
*/
std::map<itype_id, int> fuel_usage() const;
std::map<itype_id, units::energy> fuel_usage() const;
// current fuel usage for specific engine
int engine_fuel_usage( int e ) const;
/**
* Fuel usage for specific engine
* @param e is the index of the engine in the engines array
*/
units::energy engine_fuel_usage( int e ) const;
/**
* Get all vehicle lights (excluding any that are destroyed)
* @param active if true return only lights which are enabled
@ -2009,8 +2013,9 @@ class vehicle
std::set<label> labels; // stores labels
std::set<std::string> tags; // Properties of the vehicle
// After fuel consumption, this tracks the remainder of fuel < 1, and applies it the next time.
std::map<itype_id, float> fuel_remainder;
std::map<itype_id, float> fuel_used_last_turn;
// The value is negative.
std::map<itype_id, units::energy> fuel_remainder;
std::map<itype_id, units::energy> fuel_used_last_turn;
std::unordered_multimap<point, zone_data> loot_zones;
active_item_cache active_items; // NOLINT(cata-serialize)
// a magic vehicle, powered by magic.gif

View File

@ -413,13 +413,13 @@ void vehicle::print_fuel_indicators( const catacurses::window &win, const point
void vehicle::print_fuel_indicator( const catacurses::window &win, const point &p,
const itype_id &fuel_type, bool verbose, bool desc )
{
std::map<itype_id, float> fuel_usages;
std::map<itype_id, units::energy> fuel_usages;
print_fuel_indicator( win, p, fuel_type, fuel_usages, verbose, desc );
}
void vehicle::print_fuel_indicator( const catacurses::window &win, const point &p,
const itype_id &fuel_type,
std::map<itype_id, float> fuel_usages,
std::map<itype_id, units::energy> fuel_usages,
bool verbose, bool desc )
{
static constexpr std::array<char, 5> fsyms = { 'E', '\\', '|', '/', 'F' };

View File

@ -187,8 +187,13 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
// otherwise trying to charge battery to 90% within 30 minutes
bool discharge_forbidden_soft = battery_level_percent <= cfg.battery_hi;
bool discharge_forbidden_hard = battery_level_percent <= cfg.battery_lo;
int target_charging_rate = ( max_battery_level == 0 || !discharge_forbidden_soft ) ? 0 :
( max_battery_level * cfg.battery_hi / 100 - cur_battery_level ) * 10 / ( 6 * 3 );
units::energy target_charging_rate;
if( max_battery_level == 0 || !discharge_forbidden_soft ) {
target_charging_rate = 0_J;
} else {
target_charging_rate = units::from_joule( ( max_battery_level * cfg.battery_hi / 100 -
cur_battery_level ) * 10 / ( 6 * 3 ) );
}
// ( max_battery_level * battery_hi / 100 - cur_battery_level ) * (1000 / (60 * 30)) // originally
// ^ battery_hi% bat to W ^ ^ 30 minutes
@ -216,9 +221,9 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
int prev_mask = 0;
// opt_ prefix denotes values for currently found "optimal" engine configuration
int opt_net_echarge_rate = net_battery_charge_rate_w();
units::energy opt_net_echarge_rate = units::from_joule( net_battery_charge_rate_w() );
// total engine fuel energy usage (J)
int opt_fuel_usage = 0;
units::energy opt_fuel_usage = 0_J;
int opt_accel = is_stationary ? 1 : current_acceleration() * traction;
int opt_safe_vel = is_stationary ? 1 : safe_ground_velocity( true );
@ -230,8 +235,8 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
if( is_engine_on( c_engines[i] ) ) {
prev_mask |= 1 << i;
bool is_electric = is_engine_type( c_engines[i], fuel_type_battery );
int fu = engine_fuel_usage( c_engines[i] ) * ( cur_load_approx + ( is_electric ? 0 :
cur_load_alternator ) );
units::energy fu = engine_fuel_usage( c_engines[i] ) * ( cur_load_approx + ( is_electric ? 0 :
cur_load_alternator ) );
opt_fuel_usage += fu;
if( is_electric ) {
opt_net_echarge_rate -= fu;
@ -287,15 +292,16 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
int safe_vel = is_stationary ? 1 : safe_ground_velocity( true );
int accel = is_stationary ? 1 : current_acceleration() * traction;
int fuel_usage = 0;
int net_echarge_rate = net_battery_charge_rate_w();
units::energy fuel_usage = 0_J;
units::energy net_echarge_rate = units::from_joule( net_battery_charge_rate_w() );
float load_approx = static_cast<float>( std::min( accel_demand, accel ) ) / std::max( accel, 1 );
update_alternator_load();
float load_approx_alternator = std::min( 0.01f, static_cast<float>( alternator_load ) / 1000 );
for( int e : c_engines ) {
bool is_electric = is_engine_type( e, fuel_type_battery );
int fu = engine_fuel_usage( e ) * ( load_approx + ( is_electric ? 0 : load_approx_alternator ) );
units::energy fu = engine_fuel_usage( e ) * ( load_approx + ( is_electric ? 0 :
load_approx_alternator ) );
fuel_usage += fu;
if( is_electric ) {
net_echarge_rate -= fu;
@ -303,7 +309,7 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
}
if( std::forward_as_tuple(
!discharge_forbidden_hard || ( net_echarge_rate > 0 ),
!discharge_forbidden_hard || ( net_echarge_rate > 0_J ),
accel >= accel_demand,
opt_accel < accel_demand ? accel : 0, // opt_accel usage here is intentional
safe_vel >= velocity_demand,
@ -312,7 +318,7 @@ void vehicle::smart_controller_handle_turn( bool thrusting,
-fuel_usage,
net_echarge_rate
) >= std::forward_as_tuple(
!discharge_forbidden_hard || ( opt_net_echarge_rate > 0 ),
!discharge_forbidden_hard || ( opt_net_echarge_rate > 0_J ),
opt_accel >= accel_demand,
opt_accel < accel_demand ? opt_accel : 0,
opt_safe_vel >= velocity_demand,

View File

@ -337,22 +337,20 @@ int vehicle_part::ammo_consume( int qty, const tripoint &pos )
return base.ammo_consume( qty, pos, nullptr );
}
double vehicle_part::consume_energy( const itype_id &ftype, double energy_j )
units::energy vehicle_part::consume_energy( const itype_id &ftype, units::energy wanted_energy )
{
if( base.empty() || !is_fuel_store() ) {
return 0.0f;
return 0_J;
}
item &fuel = base.legacy_front();
if( fuel.typeId() == ftype ) {
cata_assert( fuel.is_fuel() );
// convert energy density in MJ/L to J/ml
const double energy_p_mL = fuel.fuel_energy() * 1000;
const int ml_to_use = static_cast<int>( std::floor( energy_j / energy_p_mL ) );
int charges_to_use = fuel.charges_per_volume( ml_to_use * 1_ml );
units::energy energy_per_charge = fuel.fuel_energy() / fuel.charges;
int charges_to_use = wanted_energy / energy_per_charge;
if( !charges_to_use ) {
return 0.0;
return 0_J;
}
if( charges_to_use >= fuel.charges ) {
charges_to_use = fuel.charges;
@ -360,10 +358,10 @@ double vehicle_part::consume_energy( const itype_id &ftype, double energy_j )
} else {
fuel.charges -= charges_to_use;
}
item fuel_consumed( ftype, calendar::turn, charges_to_use );
return energy_p_mL * units::to_milliliter<int>( fuel_consumed.volume( true ) );
return charges_to_use * energy_per_charge;
}
return 0.0;
return 0_J;
}
bool vehicle_part::can_reload( const item &obj ) const

39
tests/fuel_test.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "cata_catch.h"
#include "item.h"
TEST_CASE( "Fuel energy", "[energy]" )
{
item battery( "battery" );
item gasoline( "gasoline" );
const int64_t gasoline_per_charge = units::to_millijoule( 34200_J );
const int64_t battery_per_charge = units::to_millijoule( 1_kJ );
SECTION( "Energy of 1 unit" ) {
battery.charges = 1;
gasoline.charges = 1;
CHECK( units::to_millijoule( gasoline.fuel_energy() ) == gasoline_per_charge );
CHECK( units::to_millijoule( battery.fuel_energy() ) == battery_per_charge );
}
SECTION( "Energy of 200 units" ) {
battery.charges = 200;
gasoline.charges = 200;
CHECK( units::to_millijoule( gasoline.fuel_energy() ) == gasoline_per_charge * 200 ); // 6840 kJ
CHECK( units::to_millijoule( battery.fuel_energy() ) == battery_per_charge * 200 ); // 200 kJ
}
SECTION( "Energy of gasoline liter" ) {
gasoline.charges = 1000;
REQUIRE( units::to_milliliter( gasoline.volume() ) == 1000 );
// 34200 kJ
// Fuel data has energy per liter so it should match here.
CHECK( units::to_millijoule( gasoline.fuel_energy() )
== units::to_millijoule( gasoline.get_base_material().get_fuel_data().energy ) );
}
}

View File

@ -261,6 +261,8 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass,
const float fuel_percentage_used = fuel_level * ( starting_fuel_per - fuel_left );
int adjusted_tiles_travelled = tiles_travelled / fuel_percentage_used;
if( target_distance >= 0 ) {
INFO( "Target distance: " << target_distance )
INFO( "Travelled distance: " << adjusted_tiles_travelled )
CHECK( adjusted_tiles_travelled >= min_dist );
CHECK( adjusted_tiles_travelled <= max_dist );
}
@ -438,7 +440,7 @@ TEST_CASE( "vehicle_efficiency", "[vehicle] [engine]" )
test_vehicle( "beetle", 707777, 399680, 358994, 110952, 91402 );
test_vehicle( "car", 1011976, 555111, 399360, 60344, 30655 );
test_vehicle( "car_sports", 998322, 336539, 283905, 41326, 30440 );
test_vehicle( "electric_car", 698493, 533760, 473105, 43302, 37555 );
test_vehicle( "electric_car", 698493, 209563, 182602, 17265, 14957 );
test_vehicle( "suv", 1246644, 1050949, 630063, 90148, 34734 );
test_vehicle( "motorcycle", 173585, 109802, 87649, 57566, 44497 );
test_vehicle( "quad_bike", 275845, 107440, 107440, 44021, 44021 );
@ -452,7 +454,7 @@ TEST_CASE( "vehicle_efficiency", "[vehicle] [engine]" )
test_vehicle( "apc", 5919120, 1512911, 1042420, 123904, 79286 );
test_vehicle( "humvee", 5980330, 676881, 284910, 23790, 7337 );
test_vehicle( "road_roller", 9055909, 542552, 132476, 21598, 6925 );
test_vehicle( "golf_cart", 319630, 128762, 124548, 57882, 32461 );
test_vehicle( "golf_cart", 319630, 50080, 47850, 22925, 12889 );
// in reverse
test_vehicle( "beetle", 707777, 58800, 58800, 45900, 44560, 0, 0, true );
test_vehicle( "car", 1011976, 76390, 76260, 48330, 30270, 0, 0, true );