From 93a8f76af2915f931f5a54dad154d786ce95cd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Thu, 6 Jun 2024 01:25:21 +0200 Subject: [PATCH 1/8] Provide body volume calculation based on body density --- src/character.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index a372590232e03..6177ace1b4c75 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3103,14 +3103,13 @@ units::volume Character::get_total_volume() const units::volume Character::get_base_volume() const { const int your_height = height(); // avg 175cm - // Arbitrary number picked relative to aisle (100L), not necessarily accurate - const units::volume avg_human_volume = 70_liter; - - // Very scientific video game size to metric human volume calculation. Avg height == avg_human_volume; - units::volume your_base_volume = units::from_liter( static_cast( your_height ) / 2.5 ); - double volume_proport = units::to_liter( your_base_volume ) / units::to_liter( avg_human_volume ); - - return std::pow( volume_proport, 3.0 ) * avg_human_volume; + const double your_weight = units::to_gram( bodyweight() ) * 1000; + const double your_density = 1.097 - 0.00046971 * your_weight + + 0.00000056 * std::pow( your_weight, 2 ) + - 0.00012828 * your_height; + units::volume your_base_volume = units::from_liter( static_cast + ( your_weight ) / your_density ); + return your_base_volume; } units::mass Character::weight_carried() const From 5afd5b5177703b8f898d6d5d0079b28d4355944d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Thu, 6 Jun 2024 12:02:08 +0200 Subject: [PATCH 2/8] Simplify calculations --- src/character.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 6177ace1b4c75..0327f59d0df4f 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3102,13 +3102,22 @@ units::volume Character::get_total_volume() const units::volume Character::get_base_volume() const { - const int your_height = height(); // avg 175cm - const double your_weight = units::to_gram( bodyweight() ) * 1000; + // The formula used here to calculate base volume for a human body is + // BV = W / BD + // Where: + // * BV is the body volume in liters + // * W is the weight in kilograms + // * BD is the body density (kg/L), estimated using the Brozek formula: + // BD = 1.097 – 0.00046971 * W + 0.00000056 * W^2 – 0.00012828 * H + // See + // https://en.wikipedia.org/wiki/Body_fat_percentage + // https://calculator.academy/body-volume-calculator/ + const int your_height = height(); + const double your_weight = units::to_kilogram( bodyweight() ); const double your_density = 1.097 - 0.00046971 * your_weight + 0.00000056 * std::pow( your_weight, 2 ) - 0.00012828 * your_height; - units::volume your_base_volume = units::from_liter( static_cast - ( your_weight ) / your_density ); + units::volume your_base_volume = units::from_liter( your_weight / your_density ); return your_base_volume; } From 64cf7a67df9938eb90775ed3456817da76bd01c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Thu, 6 Jun 2024 15:05:17 +0200 Subject: [PATCH 3/8] Adjust test cases to the volume calculation --- tests/char_volume_test.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index 3c90e01a0c214..4c07ed0640999 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -44,10 +44,9 @@ TEST_CASE( "character_baseline_volumes", "[volume]" ) Character &you = get_player_character(); REQUIRE( you.get_mutations().empty() ); REQUIRE( you.height() == 175 ); - CHECK( you.get_base_volume() == 70_liter ); REQUIRE( your_height_with_trait( trait_SMALL2 ) == 70 ); - CHECK( your_volume_with_trait( trait_SMALL2 ) == 4480_ml ); + CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); REQUIRE( your_height_with_trait( trait_SMALL ) == 122 ); CHECK( your_volume_with_trait( trait_SMALL ) == 23717_ml ); @@ -56,7 +55,7 @@ TEST_CASE( "character_baseline_volumes", "[volume]" ) CHECK( your_volume_with_trait( trait_LARGE ) == 152778_ml ); REQUIRE( your_height_with_trait( trait_HUGE ) == 280 ); - CHECK( your_volume_with_trait( trait_HUGE ) == 286720_ml ); + CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); } TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) @@ -66,8 +65,6 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) map &here = get_map(); Character &you = get_player_character(); REQUIRE( you.get_mutations().empty() ); - REQUIRE( you.get_base_volume() == 70_liter ); - REQUIRE( you.get_total_volume() == 70_liter ); tripoint test_pos = tripoint{10, 10, 0 }; @@ -107,7 +104,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) cramped = false; // Try the cramped aisle with a rock again, but now we are tiny, so it is easy. - CHECK( your_volume_with_trait( trait_SMALL2 ) == 4480_ml ); + CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( you.can_move_to_vehicle_tile( dest_loc, cramped ) ); @@ -115,7 +112,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) dest_loc = you.get_location(); //reset // Same aisle, but now we have HUGE GUTS. We will never fit. - CHECK( your_volume_with_trait( trait_HUGE ) == 286720_ml ); + CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( !you.can_move_to_vehicle_tile( dest_loc ) ); From 8850226ead66ff221d1d6cec11a565c01eed7ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Thu, 6 Jun 2024 15:30:58 +0200 Subject: [PATCH 4/8] Adjust volumes for baseline tests too --- tests/char_volume_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index 4c07ed0640999..45392af67f090 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -49,10 +49,10 @@ TEST_CASE( "character_baseline_volumes", "[volume]" ) CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); REQUIRE( your_height_with_trait( trait_SMALL ) == 122 ); - CHECK( your_volume_with_trait( trait_SMALL ) == 23717_ml ); + CHECK( your_volume_with_trait( trait_SMALL ) == 42476_ml ); REQUIRE( your_height_with_trait( trait_LARGE ) == 227 ); - CHECK( your_volume_with_trait( trait_LARGE ) == 152778_ml ); + CHECK( your_volume_with_trait( trait_LARGE ) == 116034_ml ); REQUIRE( your_height_with_trait( trait_HUGE ) == 280 ); CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); From e1a257bcef7c6295e6e3251e837b0a5816d1a42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Tue, 11 Jun 2024 12:46:26 +0200 Subject: [PATCH 5/8] Make checks for volume pass within reasaonable ranges Relying on volumes down to the ml allows us to make changes to volume calculations, and keep the tests withing reasaonable boundaries. references #74263 --- tests/char_volume_test.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index 45392af67f090..b6e267bfac4fd 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -44,18 +44,23 @@ TEST_CASE( "character_baseline_volumes", "[volume]" ) Character &you = get_player_character(); REQUIRE( you.get_mutations().empty() ); REQUIRE( you.height() == 175 ); + CHECK( ( you.get_base_volume() > 55_liter && you.get_base_volume() < 80_liter ) ); REQUIRE( your_height_with_trait( trait_SMALL2 ) == 70 ); - CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); + CHECK( ( your_volume_with_trait( trait_SMALL2 ) > 20_liter && + your_volume_with_trait( trait_SMALL2 ) < 30_liter ) ); REQUIRE( your_height_with_trait( trait_SMALL ) == 122 ); - CHECK( your_volume_with_trait( trait_SMALL ) == 42476_ml ); + CHECK( ( your_volume_with_trait( trait_SMALL ) > 40_liter && + your_volume_with_trait( trait_SMALL ) < 50_liter ) ); REQUIRE( your_height_with_trait( trait_LARGE ) == 227 ); - CHECK( your_volume_with_trait( trait_LARGE ) == 116034_ml ); + CHECK( ( your_volume_with_trait( trait_LARGE ) > 100_liter && + your_volume_with_trait( trait_LARGE ) < 120_liter ) ); REQUIRE( your_height_with_trait( trait_HUGE ) == 280 ); - CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); + CHECK( ( your_volume_with_trait( trait_HUGE ) > 150_liter && + your_volume_with_trait( trait_HUGE ) < 200_liter ) ); } TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) From 5e8eb72a684ea305f971cf935c65753eac9da789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Tue, 11 Jun 2024 13:13:24 +0200 Subject: [PATCH 6/8] Make checks for volume less dependent on exact volumes Make tests more flexible --- tests/char_volume_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index b6e267bfac4fd..20e3c2b380fd0 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -109,7 +109,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) cramped = false; // Try the cramped aisle with a rock again, but now we are tiny, so it is easy. - CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); + CHECK( your_volume_with_trait( trait_SMALL2 ) < 30_liter ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( you.can_move_to_vehicle_tile( dest_loc, cramped ) ); @@ -117,7 +117,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) dest_loc = you.get_location(); //reset // Same aisle, but now we have HUGE GUTS. We will never fit. - CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); + CHECK( your_volume_with_trait( trait_HUGE ) > 150_liter ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( !you.can_move_to_vehicle_tile( dest_loc ) ); From 9fcc074ca5cd5e7c09d0b86d6c2a0de0a6605cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Tue, 11 Jun 2024 22:33:24 +0200 Subject: [PATCH 7/8] Make tests exact, set character to exact calorie count This strategy makes the test repeatable --- tests/char_volume_test.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index 20e3c2b380fd0..8c5d50b861e75 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -9,6 +9,7 @@ #include "map_helpers.h" #include "mutation.h" #include "player_helpers.h" +#include "units.h" #include "vehicle.h" #include "veh_type.h" @@ -42,25 +43,23 @@ TEST_CASE( "character_baseline_volumes", "[volume]" ) { clear_avatar(); Character &you = get_player_character(); + you.set_stored_kcal( you.get_healthy_kcal() ); REQUIRE( you.get_mutations().empty() ); REQUIRE( you.height() == 175 ); - CHECK( ( you.get_base_volume() > 55_liter && you.get_base_volume() < 80_liter ) ); + REQUIRE( you.bodyweight() == 76562390_milligram ); + CHECK( you.get_base_volume() == 73485_ml ); REQUIRE( your_height_with_trait( trait_SMALL2 ) == 70 ); - CHECK( ( your_volume_with_trait( trait_SMALL2 ) > 20_liter && - your_volume_with_trait( trait_SMALL2 ) < 30_liter ) ); + CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); REQUIRE( your_height_with_trait( trait_SMALL ) == 122 ); - CHECK( ( your_volume_with_trait( trait_SMALL ) > 40_liter && - your_volume_with_trait( trait_SMALL ) < 50_liter ) ); + CHECK( your_volume_with_trait( trait_SMALL ) == 42476_ml ); REQUIRE( your_height_with_trait( trait_LARGE ) == 227 ); - CHECK( ( your_volume_with_trait( trait_LARGE ) > 100_liter && - your_volume_with_trait( trait_LARGE ) < 120_liter ) ); + CHECK( your_volume_with_trait( trait_LARGE ) == 116034_ml ); REQUIRE( your_height_with_trait( trait_HUGE ) == 280 ); - CHECK( ( your_volume_with_trait( trait_HUGE ) > 150_liter && - your_volume_with_trait( trait_HUGE ) < 200_liter ) ); + CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); } TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) @@ -109,7 +108,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) cramped = false; // Try the cramped aisle with a rock again, but now we are tiny, so it is easy. - CHECK( your_volume_with_trait( trait_SMALL2 ) < 30_liter ); + CHECK( your_volume_with_trait( trait_SMALL2 ) == 23326_ml ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( you.can_move_to_vehicle_tile( dest_loc, cramped ) ); @@ -117,7 +116,7 @@ TEST_CASE( "character_at_volume_can_or_cannot_enter_vehicle", "[volume]" ) dest_loc = you.get_location(); //reset // Same aisle, but now we have HUGE GUTS. We will never fit. - CHECK( your_volume_with_trait( trait_HUGE ) > 150_liter ); + CHECK( your_volume_with_trait( trait_HUGE ) == 156228_ml ); you.setpos( test_pos ); // set our position again, clear_avatar() moved us dest_loc = dest_loc + tripoint_north; CHECK( !you.can_move_to_vehicle_tile( dest_loc ) ); From d86a466d3461e2bcce6009525279bdfe750021ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Tue, 11 Jun 2024 22:51:40 +0200 Subject: [PATCH 8/8] Remove unused header units.h --- tests/char_volume_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/char_volume_test.cpp b/tests/char_volume_test.cpp index 8c5d50b861e75..82cca754a9494 100644 --- a/tests/char_volume_test.cpp +++ b/tests/char_volume_test.cpp @@ -9,7 +9,6 @@ #include "map_helpers.h" #include "mutation.h" #include "player_helpers.h" -#include "units.h" #include "vehicle.h" #include "veh_type.h"