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

Remove randomness from metabolism #46906

Merged
merged 4 commits into from
Jan 24, 2021
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
2 changes: 1 addition & 1 deletion src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2905,7 +2905,7 @@ int get_auto_consume_moves( player &p, const bool food )
if( !p.can_consume( comest ) ) {
continue;
}
if( food && p.compute_effective_nutrients( comest ).kcal < 50 ) {
if( food && p.compute_effective_nutrients( comest ).kcal() < 50 ) {
// not filling enough
continue;
}
Expand Down
33 changes: 23 additions & 10 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ Character::Character() :
update_type_of_scent( true );
pkill = 0;
// 45 days to starve to death
healthy_calories = 55000;
// 55 Mcal or 55k kcal
healthy_calories = 55'000'000;
anothersimulacrum marked this conversation as resolved.
Show resolved Hide resolved
stored_calories = healthy_calories;
initialize_stomach_contents();

Expand Down Expand Up @@ -5019,7 +5020,7 @@ void Character::mod_healthy_mod( int nhealthy_mod, int cap )

int Character::get_stored_kcal() const
{
return stored_calories;
return stored_calories / 1000;
}

static std::string exert_lvl_to_str( float level )
Expand Down Expand Up @@ -5054,8 +5055,8 @@ std::string Character::debug_weary_info() const
float bmi = get_bmi();

return string_format( "Weariness: %s Max Full Exert: %s Mult: %g\nBMR: %d Intake: %d Tracker: %d Thresh: %d At: %d\nCal: %d/%d Fatigue: %d Morale: %d Wgt: %d (BMI %.1f)",
amt, max_act, move_mult, bmr, intake, input, thresh, current, stored_calories,
healthy_calories, fatigue, morale, weight, bmi );
amt, max_act, move_mult, bmr, intake, input, thresh, current, get_stored_kcal(),
get_healthy_kcal(), fatigue, morale, weight, bmi );
}

void weariness_tracker::clear()
Expand All @@ -5068,6 +5069,12 @@ void weariness_tracker::clear()

void Character::mod_stored_kcal( int nkcal )
{
mod_stored_calories( nkcal * 1000 );
}

void Character::mod_stored_calories( int ncal )
{
int nkcal = ncal / 1000;
if( nkcal > 0 ) {
add_gained_calories( nkcal );
weary.intake += nkcal;
Expand All @@ -5076,7 +5083,7 @@ void Character::mod_stored_kcal( int nkcal )
// nkcal is negative, we need positive
weary.tracker -= nkcal;
}
set_stored_kcal( stored_calories + nkcal );
set_stored_calories( stored_calories + ncal );
}

void Character::mod_stored_nutr( int nnutr )
Expand All @@ -5087,8 +5094,13 @@ void Character::mod_stored_nutr( int nnutr )

void Character::set_stored_kcal( int kcal )
{
if( stored_calories != kcal ) {
stored_calories = kcal;
set_stored_calories( kcal * 1000 );
}

void Character::set_stored_calories( int cal )
{
if( stored_calories != cal ) {
stored_calories = cal;

//some mutant change their max_hp according to their bmi
recalc_hp();
Expand All @@ -5097,7 +5109,7 @@ void Character::set_stored_kcal( int kcal )

int Character::get_healthy_kcal() const
{
return healthy_calories;
return healthy_calories / 1000;
}

float Character::get_kcal_percent() const
Expand Down Expand Up @@ -5702,14 +5714,15 @@ void Character::update_stomach( const time_point &from, const time_point &to )
guts.ingest( digested_to_guts );
// Apply nutrients, unless this is an NPC and NO_NPC_FOOD is enabled.
if( !npc_no_food ) {
mod_stored_kcal( digested_to_body.nutr.kcal );
mod_stored_kcal( digested_to_body.nutr.kcal() );
log_activity_level( activity_level() );
vitamins_mod( digested_to_body.nutr.vitamins, false );
}
if( !foodless && rates.hunger > 0.0f ) {
mod_hunger( roll_remainder( rates.hunger * five_mins ) );
// instead of hunger keeping track of how you're living, burn calories instead
mod_stored_kcal( -roll_remainder( five_mins * kcal_per_time ) );
// Explicitly floor it here, the int cast will do so anyways
mod_stored_calories( -std::floor( five_mins * kcal_per_time * 1000 ) );
}
}
// if npc_no_food no need to calc hunger, and set hunger_effect
Expand Down
9 changes: 9 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,14 @@ class Character : public Creature, public visitable
virtual void set_fatigue( fatigue_levels nfatigue );
virtual void set_sleep_deprivation( int nsleep_deprivation );

protected:

// These accept values in calories, 1/1000s of kcals (or Calories)
virtual void mod_stored_calories( int ncal );
virtual void set_stored_calories( int cal );

public:

void mod_stat( const std::string &stat, float modifier ) override;

int get_standard_stamina_cost( item *thrown_item = nullptr );
Expand Down Expand Up @@ -2911,6 +2919,7 @@ class Character : public Creature, public visitable
int old_weary_level = 0;

/// @brief Needs (hunger, starvation, thirst, fatigue, etc.)
// Stored calories is a value in 'calories' - 1/1000s of kcals (or Calories)
int stored_calories;
int healthy_calories;

Expand Down
16 changes: 9 additions & 7 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static int compute_default_effective_kcal( const item &comest, const Character &
}

// As float to avoid rounding too many times
float kcal = comest.get_comestible()->default_nutrition.kcal;
float kcal = comest.get_comestible()->default_nutrition.kcal();

// Many raw foods give less calories, as your body has expends more energy digesting them.
bool cooked = comest.has_flag( flag_COOKED ) || extra_flags.count( flag_COOKED );
Expand Down Expand Up @@ -231,7 +231,8 @@ static std::map<vitamin_id, int> compute_default_effective_vitamins(
static nutrients compute_default_effective_nutrients( const item &comest,
const Character &you, const cata::flat_set<flag_id> &extra_flags = {} )
{
return { compute_default_effective_kcal( comest, you, extra_flags ),
// Multiply by 1000 to get it in calories
return { compute_default_effective_kcal( comest, you, extra_flags ) * 1000,
compute_default_effective_vitamins( comest, you ) };
}

Expand Down Expand Up @@ -373,7 +374,7 @@ std::pair<nutrients, nutrients> Character::compute_nutrient_range(

int Character::nutrition_for( const item &comest ) const
{
return compute_effective_nutrients( comest ).kcal / islot_comestible::kcal_per_nutr;
return compute_effective_nutrients( comest ).kcal() / islot_comestible::kcal_per_nutr;
}

std::pair<int, int> Character::fun_for( const item &comest ) const
Expand Down Expand Up @@ -1228,7 +1229,8 @@ double Character::compute_effective_food_volume_ratio( const item &food ) const
units::mass food_weight = ( food.weight() / food.count() );
double ratio = 1.0f;
if( units::to_gram( food_weight ) != 0 ) {
ratio = std::max( static_cast<double>( food_nutrients.kcal ) / units::to_gram( food_weight ), 1.0 );
ratio = std::max( static_cast<double>( food_nutrients.kcal() ) / units::to_gram( food_weight ),
1.0 );
if( ratio > 3.0f ) {
ratio = std::sqrt( 3 * ratio );
}
Expand Down Expand Up @@ -1264,9 +1266,9 @@ int Character::compute_calories_per_effective_volume( const item &food,
int kcalories;
if( nutrient ) {
// if given the optional nutrient argument, we will compute kcal based on that. ( Crafting menu ).
kcalories = nutrient->kcal;
kcalories = nutrient->kcal();
} else {
kcalories = compute_effective_nutrients( food ).kcal;
kcalories = compute_effective_nutrients( food ).kcal();
}
units::volume food_vol = masticated_volume( food ) * food.count();
// Divide by 1000 to convert to L. Final quantity is essentially dimensionless, so unit of measurement does not matter.
Expand Down Expand Up @@ -1394,7 +1396,7 @@ bool Character::consume_effects( item &food )
add_msg_debug(
"Effective volume: %d (solid) %d (liquid)\n multiplier: %g calories: %d, weight: %d",
units::to_milliliter( ingested.solids ), units::to_milliliter( ingested.water ), ratio,
food_nutrients.kcal, units::to_gram( food_weight ) );
food_nutrients.kcal(), units::to_gram( food_weight ) );
// Maybe move tapeworm to digestion
if( has_effect( effect_tapeworm ) ) {
ingested.nutr /= 2;
Expand Down
2 changes: 1 addition & 1 deletion src/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ bool game::dump_stats( const std::string &what, dump_mode mode,
r.push_back( to_string( obj.volume() / units::legacy_volume_factor ) );
r.push_back( to_string( to_gram( obj.weight() ) ) );
r.push_back( to_string( obj.type->stack_size ) );
r.push_back( to_string( obj.get_comestible()->default_nutrition.kcal ) );
r.push_back( to_string( obj.get_comestible()->default_nutrition.kcal() ) );
r.push_back( to_string( obj.get_comestible()->quench ) );
r.push_back( to_string( obj.get_comestible()->healthy ) );
auto vits = obj.get_comestible()->default_nutrition.vitamins;
Expand Down
2 changes: 1 addition & 1 deletion src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3821,7 +3821,7 @@ bool basecamp::distribute_food()
if( it.rotten() ) {
return false;
}
const int kcal = it.get_comestible()->default_nutrition.kcal * it.count() * rot_multip( it,
const int kcal = it.get_comestible()->default_nutrition.kcal() * it.count() * rot_multip( it,
container );
if( kcal <= 0 ) {
// can happen if calories is low and rot is high.
Expand Down
2 changes: 1 addition & 1 deletion src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ class comestible_inventory_preset : public inventory_selector_preset

append_cell( [&p]( const item_location & loc ) {
const nutrients nutr = p.compute_effective_nutrients( *loc );
return good_bad_none( nutr.kcal );
return good_bad_none( nutr.kcal() );
}, _( "CALORIES" ) );

append_cell( []( const item_location & loc ) {
Expand Down
10 changes: 5 additions & 5 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1845,13 +1845,13 @@ void item::food_info( const item *food_item, std::vector<iteminfo> &info,
}
}

if( max_nutr.kcal != 0 || food_item->get_comestible()->quench != 0 ) {
if( max_nutr.kcal() != 0 || food_item->get_comestible()->quench != 0 ) {
if( parts->test( iteminfo_parts::FOOD_NUTRITION ) ) {
info.push_back( iteminfo( "FOOD", _( "<bold>Calories (kcal)</bold>: " ),
"", iteminfo::no_newline, min_nutr.kcal ) );
if( max_nutr.kcal != min_nutr.kcal ) {
"", iteminfo::no_newline, min_nutr.kcal() ) );
if( max_nutr.kcal() != min_nutr.kcal() ) {
info.push_back( iteminfo( "FOOD", _( "-" ),
"", iteminfo::no_newline, max_nutr.kcal ) );
"", iteminfo::no_newline, max_nutr.kcal() ) );
}
}
if( parts->test( iteminfo_parts::FOOD_QUENCH ) ) {
Expand All @@ -1861,7 +1861,7 @@ void item::food_info( const item *food_item, std::vector<iteminfo> &info,
}
if( parts->test( iteminfo_parts::FOOD_SATIATION ) ) {

if( max_nutr.kcal == min_nutr.kcal ) {
if( max_nutr.kcal() == min_nutr.kcal() ) {
info.push_back( iteminfo( "FOOD", _( "<bold>Satiety: </bold>" ),
satiety_bar( player_character.compute_calories_per_effective_volume( *food_item ) ) ) );
} else {
Expand Down
13 changes: 9 additions & 4 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2263,19 +2263,24 @@ void Item_factory::load( islot_comestible &slot, const JsonObject &jo, const std
bool got_calories = false;

if( jo.has_member( "calories" ) ) {
slot.default_nutrition.kcal = jo.get_int( "calories" );
// The value here is in kcal, but is stored as simply calories
slot.default_nutrition.calories = 1000 * jo.get_int( "calories" );
got_calories = true;

} else if( relative.has_member( "calories" ) ) {
slot.default_nutrition.kcal += relative.get_int( "calories" );
// The value here is in kcal, but is stored as simply calories
slot.default_nutrition.calories += 1000 * relative.get_int( "calories" );
got_calories = true;

} else if( proportional.has_member( "calories" ) ) {
slot.default_nutrition.kcal *= proportional.get_float( "calories" );
// The value here is in kcal, but is stored as simply calories
slot.default_nutrition.calories *= proportional.get_float( "calories" );
got_calories = true;

} else if( jo.has_member( "nutrition" ) ) {
slot.default_nutrition.kcal = jo.get_int( "nutrition" ) * islot_comestible::kcal_per_nutr;
// The value here is in kcal, but is stored as simply calories
slot.default_nutrition.calories = jo.get_int( "nutrition" ) * islot_comestible::kcal_per_nutr *
1000;
}

if( jo.has_member( "nutrition" ) && got_calories ) {
Expand Down
4 changes: 2 additions & 2 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ struct islot_comestible {
static constexpr float kcal_per_nutr = 2500.0f / ( 12 * 24 );

bool has_calories() const {
return default_nutrition.kcal > 0;
return default_nutrition.calories > 0;
}

int get_default_nutr() const {
return default_nutrition.kcal / kcal_per_nutr;
return default_nutrition.kcal() / kcal_per_nutr;
}

/** The monster group that is drawn from when the item rots away */
Expand Down
2 changes: 1 addition & 1 deletion src/savegame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern std::map<std::string, std::list<input_event>> quick_shortcuts_map;
* Changes that break backwards compatibility should bump this number, so the game can
* load a legacy format loader.
*/
const int savegame_version = 31;
const int savegame_version = 32;

/*
* This is a global set by detected version header in .sav, maps.txt, or overmap.
Expand Down
4 changes: 4 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@ void Character::load( const JsonObject &data )
data.read( "weary", weary );
data.read( "sleep_deprivation", sleep_deprivation );
data.read( "stored_calories", stored_calories );
// stored_calories was changed from being in kcal to being in just cal
if( savegame_loading_version <= 31 ) {
stored_calories *= 1000;
}
data.read( "radiation", radiation );
data.read( "oxygen", oxygen );
data.read( "pkill", pkill );
Expand Down
Loading