Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly warn if food will cause you to overeat #74318

Merged
merged 5 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6424,6 +6424,11 @@ float Character::get_bmi_fat() const
2 ) * get_cached_organic_size() );
}

bool Character::has_calorie_deficit() const
{
return get_bmi_fat() < character_weight_category::normal;
}

units::mass Character::bodyweight() const
{
return bodyweight_fat() + bodyweight_lean();
Expand Down
1 change: 1 addition & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -3013,6 +3013,7 @@ class Character : public Creature, public visitable
float get_bmi() const;
float get_bmi_fat() const;
float get_bmi_lean() const;
bool has_calorie_deficit() const;
// returns amount of calories burned in a day given various metabolic factors
int get_bmr() const;
// add spent calories to calorie diary (if avatar)
Expand Down
10 changes: 5 additions & 5 deletions src/character_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ void Character::update_stomach( const time_point &from, const time_point &to )
set_thirst( 0 );
}

const bool calorie_deficit = get_bmi_fat() < character_weight_category::normal;
const bool calorie_deficit = has_calorie_deficit();
const units::volume contains = stomach.contains();
const units::volume cap = stomach.capacity( *this );

Expand All @@ -1068,9 +1068,9 @@ void Character::update_stomach( const time_point &from, const time_point &to )
// > 3/4 cap full full full
// > 1/2 cap satisfied v. hungry famished/(near)starving
// <= 1/2 cap hungry v. hungry famished/(near)starving
if( contains >= cap ) {
if( stomach.would_be_engorged_with( *this, 0_ml, calorie_deficit ) ) {
hunger_effect = effect_hunger_engorged;
} else if( contains > cap * 3 / 4 ) {
} else if( stomach.would_be_full_with( *this, 0_ml, calorie_deficit ) ) {
hunger_effect = effect_hunger_full;
} else if( just_ate && contains > cap / 2 ) {
hunger_effect = effect_hunger_satisfied;
Expand All @@ -1093,9 +1093,9 @@ void Character::update_stomach( const time_point &from, const time_point &to )
// >= 3/8 cap satisfied satisfied blank
// > 0 blank blank blank
// 0 blank blank (v.) hungry
if( contains >= cap * 5 / 6 ) {
if( stomach.would_be_engorged_with( *this, 0_ml, calorie_deficit ) ) {
hunger_effect = effect_hunger_engorged;
} else if( contains > cap * 11 / 20 ) {
} else if( stomach.would_be_full_with( *this, 0_ml, calorie_deficit ) ) {
hunger_effect = effect_hunger_full;
} else if( recently_ate && contains >= cap * 3 / 8 ) {
hunger_effect = effect_hunger_satisfied;
Expand Down
4 changes: 3 additions & 1 deletion src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,10 @@ ret_val<edible_rating> Character::will_eat( const item &food, bool interactive )
add_consequence( _( "Your stomach won't be happy (not rotten enough)." ), ALLERGY_WEAK );
}

units::volume in_stomach_volume =
food.volume( false, false, 1 ) * compute_effective_food_volume_ratio( food );
if( food.is_food() &&
( food.charges_per_volume( stomach.stomach_remaining( *this ) ) < 1 ||
( stomach.would_be_engorged_with( *this, in_stomach_volume, has_calorie_deficit() ) ||
has_effect( effect_hunger_full ) || has_effect( effect_hunger_engorged ) ) ) {
if( edible ) {
add_consequence( _( "You're full already and will be forcing yourself to eat." ), TOO_FULL );
Expand Down
9 changes: 8 additions & 1 deletion src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,14 @@ void basecamp::choose_new_leader()

void basecamp::player_eats_meal()
{
int kcal_to_eat = 3000;
uilist smenu;
smenu.text = _( "Have a meal?" );
int i = 1;
smenu.addentry( i++, true, '1', _( "Snack" ) );
smenu.addentry( i++, true, '2', _( "Meal" ) );
smenu.addentry( i++, true, '3', _( "Just stuff your face. You're hungry!" ) );
smenu.query();
int kcal_to_eat = smenu.ret * 750 - 250; // 500, 1250, 2000 kcal
Character &you = get_player_character();
const int &food_available = fac()->food_supply.kcal();
if( food_available <= 0 ) {
Expand Down
14 changes: 14 additions & 0 deletions src/stomach.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,20 @@ units::volume stomach_contents::stomach_remaining( const Character &owner ) cons
return capacity( owner ) - contents - water;
}

bool stomach_contents::would_be_engorged_with( const Character &owner, units::volume intake,
bool calorie_deficit ) const
{
const double fullness_ratio = ( contains() + intake ) / capacity( owner );
return ( calorie_deficit && fullness_ratio >= 1.0 ) || ( fullness_ratio >= 5.0 / 6.0 );
}

bool stomach_contents::would_be_full_with( const Character &owner, units::volume intake,
bool calorie_deficit ) const
{
const double fullness_ratio = ( contains() + intake ) / capacity( owner );
return ( calorie_deficit && fullness_ratio >= 11.0 / 20.0 ) || ( fullness_ratio >= 3.0 / 4.0 );
}

units::volume stomach_contents::contains() const
{
return contents + water;
Expand Down
4 changes: 4 additions & 0 deletions src/stomach.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ class stomach_contents
* @return This stomach's capacity, in units::volume
*/
units::volume capacity( const Character &owner ) const;
// These functions need a ref to the stomach's owner because capacity() does
bool would_be_engorged_with( const Character &owner, units::volume intake,
bool calorie_deficit ) const;
bool would_be_full_with( const Character &owner, units::volume intake, bool calorie_deficit ) const;
// how much stomach capacity you have left before you puke from stuffing your gob
units::volume stomach_remaining( const Character &owner ) const;
// how much volume is in the stomach_contents
Expand Down
Loading