From 5d84d0e61bc5857567956da1b36ee1be0e76d9d0 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Tue, 11 Feb 2020 19:40:31 -0500 Subject: [PATCH] increase kcal spent walking with carry weight --- src/character.cpp | 16 ++++- src/character.h | 2 + src/game_constants.h | 8 +-- tests/hiking_test.cpp | 134 +++++++++++++++++++++++++++++++++++++++ tests/player_helpers.cpp | 1 + 5 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 tests/hiking_test.cpp diff --git a/src/character.cpp b/src/character.cpp index a829eef142034..454e015e5a261 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -6208,6 +6208,15 @@ int Character::height() const return height; } +float Character::weight_bmr_modifier() const +{ + units::mass carried_weight = get_weight() - bodyweight(); + const float weight_ratio = units::to_gram( carried_weight ) + / units::to_gram( bodyweight() ); + const float percentage = 0.008f * units::to_kilogram( get_weight() ) * pow( weight_ratio, 2 ); + return 1.0f + std::max( 0.0f, percentage ); +} + int Character::get_bmr() const { /** @@ -6215,9 +6224,10 @@ int Character::get_bmr() const */ const int age = 25; const int equation_constant = 5; - return ceil( metabolic_rate_base() * activity_level * ( units::to_gram - ( bodyweight() / 100.0 ) + - ( 6.25 * height() ) - ( 5 * age ) + equation_constant ) ); + const double base_bmr = metabolic_rate_base() * activity_level * ( units::to_gram + ( bodyweight() / 100.0 ) + + ( 6.25 * height() ) - ( 5 * age ) + equation_constant ); + return ceil( base_bmr * weight_bmr_modifier() ); } void Character::increase_activity_level( float new_level ) diff --git a/src/character.h b/src/character.h index be0bd5bc7f1c7..0f36b85afd7fa 100644 --- a/src/character.h +++ b/src/character.h @@ -1527,6 +1527,8 @@ class Character : public Creature, public visitable float get_bmi() const; // returns amount of calories burned in a day given various metabolic factors int get_bmr() const; + // redurns a modifier for bmr based on weight carried and weight of player + float weight_bmr_modifier() const; // returns the height of the player character in cm int height() const; // returns bodyweight of the Character diff --git a/src/game_constants.h b/src/game_constants.h index 10b0f54f41178..6a40ca709d4df 100644 --- a/src/game_constants.h +++ b/src/game_constants.h @@ -168,10 +168,10 @@ constexpr int SIMPLEX_NOISE_RANDOM_SEED_LIMIT = 32768; * did this activity for a longer period of time. */ constexpr float NO_EXERCISE = 1.2f; -constexpr float LIGHT_EXERCISE = 1.375f; -constexpr float MODERATE_EXERCISE = 1.55f; -constexpr float ACTIVE_EXERCISE = 1.725f; -constexpr float EXTRA_EXERCISE = 1.9f; +constexpr float LIGHT_EXERCISE = 1.375f * 2.5f; +constexpr float MODERATE_EXERCISE = 1.55f * 6; +constexpr float ACTIVE_EXERCISE = 1.725f * 9; +constexpr float EXTRA_EXERCISE = 1.9f * 14; // these are the lower bounds of each of the weight classes. namespace character_weight_category diff --git a/tests/hiking_test.cpp b/tests/hiking_test.cpp new file mode 100644 index 0000000000000..82097ac5bc0a3 --- /dev/null +++ b/tests/hiking_test.cpp @@ -0,0 +1,134 @@ +#include "catch/catch.hpp" + +#include "avatar.h" +#include "avatar_action.h" +#include "calendar.h" +#include "character.h" +#include "game.h" +#include "map.h" +#include "map_helpers.h" +#include "player_helpers.h" +#include "point.h" +#include "units.h" + +static void remain_centered( const tripoint ¢er, avatar &dummy ) +{ + if( dummy.pos().x < SEEX * int( MAPSIZE / 2 ) || + dummy.pos().y < SEEY * int( MAPSIZE / 2 ) || + dummy.pos().x >= SEEX * ( 1 + int( MAPSIZE / 2 ) ) || + dummy.pos().y >= SEEY * ( 1 + int( MAPSIZE / 2 ) ) ) { + dummy.setpos( center ); + // Verify that only the player is present. + REQUIRE( g->num_creatures() == 1 ); + } +} + +static int distance_test( avatar &dummy, const time_duration &time_spent ) +{ + clear_map(); + dummy.set_stored_kcal( dummy.get_healthy_kcal() ); + dummy.stomach.empty(); + dummy.guts.empty(); + dummy.moves = dummy.get_speed(); + const tripoint center{ 65, 65, 0 }; + const time_point start = calendar::turn; + int calories_spent = 0; + int tiles_moved = 0; + while( start + time_spent > calendar::turn ) { + const int calories_before = dummy.get_stored_kcal(); + avatar_action::move( dummy, g->m, dummy.pos() + tripoint_east ); + ++tiles_moved; + remain_centered( center, dummy ); + + dummy.update_body(); + dummy.process_turn(); + calendar::turn += 1_turns; + calories_spent += calories_before - dummy.get_stored_kcal(); + } + printf( "player weight: %.2f kg, bmr: %d\n", units::to_kilogram( dummy.get_weight() ), + dummy.get_bmr() ); + return calories_spent; +} + +static bool between( const int num, const int lower, const int high ) +{ + return num < high && num > lower; +} + +static void test_carry( units::mass carry_weight, int min_cal, int max_cal, + character_movemode mode = character_movemode::CMM_WALK ) +{ + item bag( "bigback" ); + REQUIRE( carry_weight >= bag.weight() ); + carry_weight -= bag.weight(); + clear_avatar(); + avatar &dummy = g->u; + dummy.reset_move_mode(); + if( mode == character_movemode::CMM_RUN ) { + dummy.toggle_run_mode(); + } + dummy.i_add( bag ); + dummy.wear( bag, false ); + dummy.i_add( item( "thread", calendar::turn, units::to_gram( carry_weight ) ) ); + const int cal_spent = distance_test( dummy, 1_hours ); + CAPTURE( cal_spent ); + CHECK( between( cal_spent, min_cal, max_cal ) ); +} + +TEST_CASE( "naked_walk", "[hike]" ) +{ + clear_avatar(); + avatar &dummy = g->u; + const int cal_spent = distance_test( dummy, 1_hours ); + CAPTURE( cal_spent ); + CHECK( between( cal_spent, 204, 234 ) ); +} + +TEST_CASE( "naked_run", "[hike]" ) +{ + clear_avatar(); + avatar &dummy = g->u; + dummy.toggle_run_mode(); + const int cal_spent = distance_test( dummy, 1_hours ); + CAPTURE( cal_spent ); + CHECK( between( cal_spent, 1032, 1200 ) ); +} + +TEST_CASE( "walk_carry", "[hike]" ) +{ + SECTION( "10 kg" ) { + test_carry( 10000_gram, 230, 260 ); + } + SECTION( "20 kg" ) { + test_carry( 20000_gram, 242, 272 ); + } + SECTION( "30 kg" ) { + test_carry( 30000_gram, 270, 300 ); + } + SECTION( "40 kg" ) { + test_carry( 40000_gram, 306, 336 ); + } + SECTION( "60 kg" ) { + test_carry( 60000_gram, 412, 442 ); + } +} + +TEST_CASE( "run_carry", "[hike]" ) +{ + const character_movemode run = character_movemode::CMM_RUN; + SECTION( "10 kg" ) { + test_carry( 10000_gram, 1120, 1140, run ); + } + SECTION( "20 kg" ) { + test_carry( 20000_gram, 1180, 1200, run ); + } + SECTION( "30 kg" ) { + test_carry( 30000_gram, 1260, 1280, run ); + } + SECTION( "40 kg" ) { + test_carry( 40000_gram, 1400, 1420, run ); + } + SECTION( "60 kg" ) { + test_carry( 60000_gram, 1880, 1900, run ); + } +} diff --git a/tests/player_helpers.cpp b/tests/player_helpers.cpp index ebc1a5f46d023..c0d17add52fbf 100644 --- a/tests/player_helpers.cpp +++ b/tests/player_helpers.cpp @@ -71,6 +71,7 @@ void clear_character( player &dummy ) const tripoint spot( 60, 60, 0 ); g->place_player( spot ); + dummy.reset_activity_level(); } void clear_avatar()