Skip to content

Commit

Permalink
Merge pull request #77106 from RenechCDDA/default_compute_effective_n…
Browse files Browse the repository at this point in the history
…utrients

Make comestible default nutrition mostly private
  • Loading branch information
Maleclypse authored Nov 10, 2024
2 parents 66098b4 + f129d53 commit a62dd27
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,8 @@ struct run_cost_effect {
float plus = 0;
};

nutrients default_character_compute_effective_nutrients( const item &comest );

class Character : public Creature, public visitable
{
public:
Expand Down
10 changes: 8 additions & 2 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,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_read_only().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 @@ -262,7 +262,7 @@ static std::map<vitamin_id, int> compute_default_effective_vitamins(
return {};
}

std::map<vitamin_id, int> res = it.get_comestible()->default_nutrition.vitamins();
std::map<vitamin_id, int> res = it.get_comestible()->default_nutrition_read_only().vitamins();

// for actual vitamins convert RDA to a internal value
for( std::pair<const vitamin_id, int> &vit : res ) {
Expand Down Expand Up @@ -312,6 +312,12 @@ static nutrients compute_default_effective_nutrients( const item &comest,
return ret;
}

extern nutrients default_character_compute_effective_nutrients( const item &comest )
{
static npc dummy;
return dummy.compute_effective_nutrients( comest );
}

// Calculate the nutrients that the given character would receive from consuming
// the given item, taking into account the item components and the character's
// traits.
Expand Down
10 changes: 2 additions & 8 deletions src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5760,16 +5760,10 @@ item basecamp::make_fake_food( const nutrients &to_use ) const
item food_item( food_id );
// Set the default nutritional of the item.
// This doesn't persist through save/load, but that's ok, we will be eating it immediately.
food_item.get_comestible()->default_nutrition = to_use;
food_item.get_comestible()->set_default_nutrition( to_use );
return food_item;
}

static const npc &getAverageJoe()
{
static npc averageJoe;
return averageJoe;
}

// mission support
bool basecamp::distribute_food( bool player_command )
{
Expand Down Expand Up @@ -5843,7 +5837,7 @@ bool basecamp::distribute_food( bool player_command )
if( it.rotten() ) {
return false;
}
nutrients from_it = getAverageJoe().compute_effective_nutrients( it ) * it.count();
nutrients from_it = default_character_compute_effective_nutrients( it ) * it.count();
// Do this multiplication separately to make sure we're using the *= operator with double argument..
from_it *= rot_multip( it, container );
// Can distribute COMESTIBLE type items with 0kcal, if they have vitamins and player selected option to do so
Expand Down
9 changes: 3 additions & 6 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7661,10 +7661,7 @@ bool item::has_vitamin( const vitamin_id &v ) const
if( !this->is_comestible() ) {
return false;
}
// We need this function to get all vitamins including from inheritance.
// But we don't care about calories, so we can just pass a dummy.
npc dummy;
const nutrients food_item = dummy.compute_effective_nutrients( *this );
const nutrients food_item = default_character_compute_effective_nutrients( *this );
for( auto const& [vit_id, amount] : food_item.vitamins() ) {
if( vit_id == v ) {
if( amount > 0 ) {
Expand Down Expand Up @@ -8675,8 +8672,8 @@ bool item::made_of_any_food_components( bool deep_search ) const
for( const std::pair<itype_id, std::vector<item>> pair : components ) {
for( const item &it : pair.second ) {
const auto &maybe_food = it.get_comestible();
bool must_be_food = maybe_food && ( maybe_food->default_nutrition.kcal() > 0 ||
!maybe_food->default_nutrition.vitamins().empty() );
bool must_be_food = maybe_food && ( maybe_food->default_nutrition_read_only().kcal() > 0 ||
!maybe_food->default_nutrition_read_only().vitamins().empty() );
bool has_food_component = false;
if( deep_search && !it.components.empty() ) {
// make true if any component has food values, even if some don't
Expand Down
21 changes: 17 additions & 4 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,6 @@ struct islot_comestible {
/** effect on character thirst (may be negative) */
int quench = 0;

/** Nutrition values to use for this type when they aren't calculated from
* components */
nutrients default_nutrition;

/** Time until becomes rotten at standard temperature, or zero if never spoils */
time_duration spoils = 0_turns;

Expand All @@ -155,6 +151,19 @@ struct islot_comestible {
/** Reference to item that will be received after smoking current item */
itype_id smoking_result;

/*
* For the few rare cases where default nutrition needs to be accessible. Prefer using
* default_character_compute_effective_nutrients unless absolutely necessary.
*/
nutrients default_nutrition_read_only() const {
return default_nutrition;
}

/** For the one case where default nutrition needs to be overridden. */
void set_default_nutrition( nutrients new_nutrition ) {
default_nutrition = std::move( new_nutrition );
};

/** TODO: add documentation */
int healthy = 0;

Expand Down Expand Up @@ -204,6 +213,10 @@ struct islot_comestible {
std::pair<int, int> rot_spawn_monster_amount = {1, 1};

private:
/** Nutrition values to use for this type when they aren't calculated from
* components */
nutrients default_nutrition;

/** effect on morale when consuming */
int fun = 0;

Expand Down
4 changes: 2 additions & 2 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ std::optional<int> iuse::purify_smart( Character *p, item *it, const tripoint &

item syringe( "syringe", it->birthday() );
p->i_add( syringe );
p->vitamins_mod( it->get_comestible()->default_nutrition.vitamins() );
p->vitamins_mod( default_character_compute_effective_nutrients( *it ).vitamins() );
get_event_bus().send<event_type::administers_mutagen>( p->getID(),
mutagen_technique::injected_smart_purifier );
return 1;
Expand Down Expand Up @@ -1615,7 +1615,7 @@ std::optional<int> iuse::petfood( Character *p, item *it, const tripoint & )

p->add_msg_if_player( _( "You feed your %1$s to the %2$s." ), it->tname(), mon->get_name() );
if( !mon->has_fully_eaten() && mon->has_flag( mon_flag_EATS ) ) {
int kcal = it->get_comestible()->default_nutrition.kcal();
int kcal = default_character_compute_effective_nutrients( *it ).kcal();
mon->mod_amount_eaten( kcal );
if( mon->has_fully_eaten() ) {
p->add_msg_if_player( _( "The %1$s seems full now." ), mon->get_name() );
Expand Down
3 changes: 1 addition & 2 deletions src/math_parser_diag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1593,8 +1593,7 @@ std::function<double( dialogue & )> calories_eval( char scope,
}
item_location const *it = static_cast<talker const *>( d.actor( beta ) )->get_item();
if( it && *it ) {
npc dummy;
return dummy.compute_effective_nutrients( *it->get_item() ).kcal();
return default_character_compute_effective_nutrients( *it->get_item() ).kcal();
}
}
debugmsg( "For calories(), talker is not character nor item" );
Expand Down
8 changes: 4 additions & 4 deletions src/monattack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,12 @@ bool mattack::eat_crop( monster *z )
//been given a stomach size yet.
int consumed = 1;
if( item.count_by_charges() ) {
int kcal = item.get_comestible()->default_nutrition.kcal();
int kcal = default_character_compute_effective_nutrients( item ).kcal();
z->mod_amount_eaten( kcal );
add_msg_if_player_sees( *z, _( "The %1s eats the %2s." ), z->name(), item.display_name() );
here.use_charges( p, 1, item.type->get_id(), consumed );
} else {
int kcal = item.get_comestible()->default_nutrition.kcal();
int kcal = default_character_compute_effective_nutrients( item ).kcal();
z->mod_amount_eaten( kcal );
add_msg_if_player_sees( *z, _( "The %1s gobbles up the %2s." ), z->name(), item.display_name() );
here.use_amount( p, 1, item.type->get_id(), consumed );
Expand Down Expand Up @@ -495,12 +495,12 @@ bool mattack::eat_food( monster *z )
if( z->type->baby_type.baby_egg != item.type->get_id() && ( !z->has_fully_eaten() ) ) {
int consumed = 1;
if( item.count_by_charges() ) {
int kcal = item.get_comestible()->default_nutrition.kcal();
int kcal = default_character_compute_effective_nutrients( item ).kcal();
z->mod_amount_eaten( kcal );
add_msg_if_player_sees( *z, _( "The %1s eats the %2s." ), z->name(), item.display_name() );
here.use_charges( p, 1, item.type->get_id(), consumed );
} else {
int kcal = item.get_comestible()->default_nutrition.kcal();
int kcal = default_character_compute_effective_nutrients( item ).kcal();
z->mod_amount_eaten( kcal );
add_msg_if_player_sees( *z, _( "The %1s gobbles up the %2s." ), z->name(), item.display_name() );
here.use_amount( p, 1, item.type->get_id(), consumed );
Expand Down
10 changes: 5 additions & 5 deletions tests/comestible_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ static int comp_calories( const std::vector<item_comp> &components )
for( const item_comp &it : components ) {
const cata::value_ptr<islot_comestible> &temp = item::find_type( it.type )->comestible;
if( temp && temp->cooks_like.is_empty() ) {
calories += temp->default_nutrition.kcal() * it.count;
calories += temp->default_nutrition_read_only().kcal() * it.count;
} else if( temp ) {
const itype *cooks_like = item::find_type( temp->cooks_like );
calories += cooks_like->comestible->default_nutrition.kcal() * it.count;
calories += cooks_like->comestible->default_nutrition_read_only().kcal() * it.count;
}
}
return calories;
Expand Down Expand Up @@ -136,15 +136,15 @@ static int byproduct_calories( const recipe &recipe_obj )
int kcal = 0;
for( const item &it : byproducts ) {
if( it.is_comestible() ) {
kcal += it.type->comestible->default_nutrition.kcal() * it.count();
kcal += it.type->comestible->default_nutrition_read_only().kcal() * it.count();
}
}
return kcal;
}

static bool has_mutagen_vit( const islot_comestible &comest )
{
const std::map<vitamin_id, int> &vits = comest.default_nutrition.vitamins();
const std::map<vitamin_id, int> &vits = comest.default_nutrition_read_only().vitamins();
for( const vitamin_id &vit : mutagen_vit_list ) {
if( vits.find( vit ) != vits.end() && vits.at( vit ) > 0 ) {
return true;
Expand Down Expand Up @@ -179,7 +179,7 @@ TEST_CASE( "comestible_health_bounds", "[comestible]" )

static int get_default_calories_recursive( item &it )
{
int calories = it.type->comestible ? it.type->comestible->default_nutrition.kcal() : 0;
int calories = it.type->comestible ? it.type->comestible->default_nutrition_read_only().kcal() : 0;

if( it.count_by_charges() ) {
calories *= it.charges;
Expand Down

0 comments on commit a62dd27

Please sign in to comment.