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

Finish making consume take time #40177

Merged
merged 12 commits into from
May 11, 2020
11 changes: 10 additions & 1 deletion data/json/mutations/mutations.json
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@
"id": "TABLEMANNERS",
"name": { "str": "Rigid Table Manners" },
"points": -1,
"description": "You've been taught proper table manners from your early childhood on. Now you can't even think about eating without a table. Eating without it frustrates you, but eating like a civilized person gives you a bigger morale bonus.",
"consume_time_modifier": 1.5,
"description": "You've been taught proper table manners from your early childhood on. Now you can't even think about eating without a table or not taking your time. Eating without it frustrates you, but eating like a civilized person gives you a bigger morale bonus.",
"starting_trait": true,
"valid": false
},
Expand Down Expand Up @@ -393,6 +394,7 @@
"id": "GOURMAND",
"name": { "str": "Gourmand" },
"points": 2,
"consume_time_modifier": 1.25,
"description": "You eat faster, and can eat and drink more, than anyone else! You also enjoy food more; delicious food is better for your morale, and you don't mind unsavory meals as much. Activate to skip prompt for overeating.",
"starting_trait": true,
"category": [ "MOUSE", "LUPINE" ],
Expand Down Expand Up @@ -2993,6 +2995,7 @@
"id": "BURROW",
"name": { "str": "Burrowing" },
"points": 10,
"consume_time_modifier": 2.0,
"valid": false,
"purifiable": false,
"description": "Between your claws and teeth, you can tunnel through just about anything.",
Expand Down Expand Up @@ -3632,6 +3635,7 @@
"points": 1,
"visibility": 8,
"ugliness": 5,
"consume_time_modifier": 0.5,
"description": "A set of tentacles surrounds your mouth. They allow you to eat twice as fast. Slightly decreases wet penalties.",
"prereqs": [ "MOUTH_FLAPS" ],
"cancels": [ "MANDIBLES" ],
Expand All @@ -3646,6 +3650,7 @@
"visibility": 8,
"ugliness": 6,
"butchering_quality": 4,
"consume_time_modifier": 0.5,
"mixed_effect": true,
"description": "A set of insect-like mandibles have grown around your mouth. They allow you to eat faster and provide a slicing unarmed attack, but prevent wearing mouthwear. Slightly reduces wet effects.",
"types": [ "TEETH", "MUZZLE" ],
Expand Down Expand Up @@ -3679,6 +3684,7 @@
"prereqs2": [ "POISONOUS", "POISONOUS2" ],
"threshreq": [ "THRESH_SPIDER" ],
"category": [ "SPIDER" ],
"consume_time_modifier": 2.0,
"wet_protection": [ { "part": "MOUTH", "ignored": 1 } ],
"attacks": {
"attack_text_u": "You bite %s with your fangs",
Expand Down Expand Up @@ -4989,6 +4995,7 @@
"points": -2,
"visibility": 10,
"ugliness": 5,
"consume_time_modifier": 1.8,
"description": "Though your beak's not suitable for pecking, those flowers out there are a good source of energy. Examine them to feed.",
"valid": false,
"purifiable": false,
Expand Down Expand Up @@ -5109,6 +5116,7 @@
"points": -2,
"visibility": 10,
"ugliness": 10,
"consume_time_modifier": 1.1,
"description": "Your flesh is a pleasing gel-like consistency. Your bodily functions seem to be moving around, and your leg-equivalents flow comfortably - if a little slower than your old meat-legs.",
"purifiable": false,
"leads_to": [ "INT_SLIME", "PER_SLIME" ],
Expand Down Expand Up @@ -6080,6 +6088,7 @@
"points": 3,
"visibility": 10,
"ugliness": 8,
"consume_time_modifier": 0.3,
"description": "Your teeth have grown incredibly sharp and are formed of very dense calcium material. In addition to making you eat much faster, you can use them as a lethal natural weapon, as long as your anatomy favors it. They also grow very fast, and you harmlessly shed them more or less at random.",
"prereqs": [ "FANGS" ],
"types": [ "TEETH" ],
Expand Down
1 change: 1 addition & 0 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,7 @@ completed when you wake up for the first time after 24 hours into the game.
"scent_intensity": 800,// int affecting the target scent toward which you current smell gravitates. (default: 500)
"scent_mask": -200,// int added to your target scent value. (default: 0)
"scent_type": "sc_flower",// scent_typeid, defined in scent_types.json, The type scent you emit. (default: empty)
"consume_time_modifier": 1.0f,//time to eat or drink is multiplied by this
"bleed_resist": 1000, // Int quantifiying your resistance to bleed effect, if its > to the intensity of the effect you don't get any bleeding. (default: 0)
"fat_to_max_hp": 1.0, // Amount of hp_max gained for each unit of bmi above character_weight_category::normal. (default: 0.0)
"healthy_rate": 0.0, // How fast your health can change. If set to 0 it never changes. (default: 1.0)
Expand Down
29 changes: 5 additions & 24 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,37 +585,18 @@ std::unique_ptr<activity_actor> open_gate_activity_actor::deserialize( JsonIn &j
return actor.clone();
}

void consume_activity_actor::start( player_activity &act, Character & )
{
const int charges = std::max( loc->charges, 1 );
int volume = units::to_milliliter( loc->volume() ) / charges;
time_duration time = 0_seconds;
const bool eat_verb = loc->has_flag( flag_USE_EAT_VERB );
if( eat_verb || loc->get_comestible()->comesttype == "FOOD" ) {
time = time_duration::from_seconds( volume / 5 ); //Eat 5 mL (1 teaspoon) per second
} else if( !eat_verb && loc->get_comestible()->comesttype == "DRINK" ) {
time = time_duration::from_seconds( volume / 15 ); //Drink 15 mL (1 tablespoon) per second
} else if( loc->is_medication() ) {
time = time_duration::from_seconds(
30 ); //Medicine/drugs takes 30 seconds this is pretty arbitrary and should probable be broken up more but seems ok for a start
} else {
debugmsg( "Consumed something that was not food, drink or medicine/drugs" );
}
void consume_activity_actor::start( player_activity &act, Character &guy )
{
int moves = to_moves<int>( guy.get_consume_time( *loc ) );

act.moves_total = to_moves<int>( time );
act.moves_left = to_moves<int>( time );
act.moves_total = moves;
act.moves_left = moves;
}

void consume_activity_actor::finish( player_activity &act, Character & )
{
if( !loc ) {
debugmsg( "Consume actor lost item_location target" );
act.set_to_null();
return;
}
if( loc.where() == item_location::type::character ) {
g->u.consume( loc );

} else if( g->u.consume_item( *loc ) ) {
loc.remove_item();
}
Expand Down
11 changes: 9 additions & 2 deletions src/activity_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,13 @@ class consume_activity_actor : public activity_actor
private:
item_location loc;

/**
* @pre @p other is a consume_activity_actor
*/
bool can_resume_with_internal( const activity_actor &other, const Character & ) const override {
const consume_activity_actor &c_actor = static_cast<const consume_activity_actor &>( other );
return loc == c_actor.loc;
}
public:
consume_activity_actor( const item_location &loc ) :
loc( loc ) {}
Expand All @@ -371,9 +378,9 @@ class consume_activity_actor : public activity_actor
return activity_id( "ACT_CONSUME" );
}

void start( player_activity &act, Character & ) override;
void start( player_activity &act, Character &guy ) override;
void do_turn( player_activity &, Character & ) override {};
void finish( player_activity &act, Character &who ) override;
void finish( player_activity &act, Character & ) override;

std::unique_ptr<activity_actor> clone() const override {
return std::make_unique<consume_activity_actor>( *this );
Expand Down
3 changes: 2 additions & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6821,7 +6821,8 @@ mutation_value_map = {
{ "overmap_multiplier", calc_mutation_value_multiplicative<&mutation_branch::overmap_multiplier> },
{ "map_memory_capacity_multiplier", calc_mutation_value_multiplicative<&mutation_branch::map_memory_capacity_multiplier> },
{ "reading_speed_multiplier", calc_mutation_value_multiplicative<&mutation_branch::reading_speed_multiplier> },
{ "skill_rust_multiplier", calc_mutation_value_multiplicative<&mutation_branch::skill_rust_multiplier> }
{ "skill_rust_multiplier", calc_mutation_value_multiplicative<&mutation_branch::skill_rust_multiplier> },
{ "consume_time_modifier", calc_mutation_value_multiplicative<&mutation_branch::consume_time_modifier> }
};

float Character::mutation_value( const std::string &val ) const
Expand Down
1 change: 1 addition & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -2147,6 +2147,7 @@ class Character : public Creature, public visitable<Character>
std::vector<tripoint> &get_auto_move_route();
action_id get_next_auto_move_direction();
bool defer_move( const tripoint &next );
time_duration get_consume_time( const item &it );

protected:
Character();
Expand Down
78 changes: 47 additions & 31 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "game.h"
#include "item_contents.h"
#include "itype.h"
#include "iuse_actor.h"
#include "map.h"
#include "material.h"
#include "messages.h"
Expand Down Expand Up @@ -887,37 +888,6 @@ bool player::eat( item &food, bool force )
food.mod_charges( -1 );

const bool amorphous = has_trait( trait_AMORPHOUS );
int mealtime = 250;
if( drinkable || chew ) {
// Those bonuses/penalties only apply to food
// Not to smoking weed or applying bandages!
if( has_trait( trait_MOUTH_TENTACLES ) || has_trait( trait_MANDIBLES ) ||
has_trait( trait_FANGS_SPIDER ) ) {
mealtime /= 2;
} else if( has_trait( trait_SHARKTEETH ) ) {
// SHARKBAIT! HOO HA HA!
mealtime /= 3;
} else if( has_trait( trait_GOURMAND ) ) {
// Don't stack those two - that would be 25 moves per item
mealtime -= 100;
}

if( has_trait( trait_BEAK_HUM ) && !drinkable ) {
// Much better than PROBOSCIS but still optimized for fluids
mealtime += 200;
} else if( has_trait( trait_SABER_TEETH ) ) {
// They get In The Way
mealtime += 250;
}

if( amorphous ) {
mealtime *= 1.1;
// Minor speed penalty for having to flow around it
// rather than just grab & munch
}
}

moves -= mealtime;

// If it's poisonous... poison us.
// TODO: Move this to a flag
Expand Down Expand Up @@ -1647,3 +1617,49 @@ item &Character::get_consumable_from( item &it ) const
null_comestible = item();
return null_comestible;
}

time_duration Character::get_consume_time( const item &it )
{
const int charges = std::max( it.charges, 1 );
int volume = units::to_milliliter( it.volume() ) / charges;
time_duration time = 0_seconds;
float consume_time_modifier = 1;//only for food and drinks
const bool eat_verb = it.has_flag( flag_USE_EAT_VERB );
if( eat_verb || it.get_comestible()->comesttype == "FOOD" ) {
time = time_duration::from_seconds( volume / 5 ); //Eat 5 mL (1 teaspoon) per second
consume_time_modifier = mutation_value( "consume_time_modifier" );
} else if( !eat_verb && it.get_comestible()->comesttype == "DRINK" ) {
time = time_duration::from_seconds( volume / 15 ); //Drink 15 mL (1 tablespoon) per second
consume_time_modifier = mutation_value( "consume_time_modifier" );
} else if( it.is_medication() ) {
const use_function *consume_drug = it.type->get_use( "consume_drug" );
const use_function *smoking = it.type->get_use( "SMOKING" );
const use_function *adrenaline_injector = it.type->get_use( "ADRENALINE_INJECTOR" );
const use_function *heal = it.type->get_use( "heal" );
if( consume_drug != nullptr ) { //its a drug
const auto consume_drug_use = dynamic_cast<const consume_drug_iuse *>
( consume_drug->get_actor_ptr() );
if( consume_drug_use->tools_needed.find( "syringe" ) != consume_drug_use->tools_needed.end() ) {
time = time_duration::from_minutes( 5 );//sterile injections take 5 minutes
} else if( consume_drug_use->tools_needed.find( "apparatus" ) !=
consume_drug_use->tools_needed.end() ||
consume_drug_use->tools_needed.find( "dab_pen_on" ) != consume_drug_use->tools_needed.end() ) {
time = time_duration::from_seconds( 30 );//smoke a bowl
} else {
time = time_duration::from_seconds( 5 );//popping a pill is quick
}
} else if( smoking != nullptr ) {
time = time_duration::from_minutes( 1 );//about five minutes for a cig or joint so 1 minute a charge
} else if( adrenaline_injector != nullptr ) {
time = time_duration::from_seconds( 15 );//epi-pens are fairly quick
} else if( heal != nullptr ) {
time = time_duration::from_seconds( 15 );//bandages and disinfectant are fairly quick
} else {
time = time_duration::from_seconds( 5 ); //probably pills so quick
}
} else {
debugmsg( "Consumed something that was not food, drink or medicine/drugs" );
}

return time * consume_time_modifier;
}
5 changes: 5 additions & 0 deletions src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@ class comestible_inventory_preset : public inventory_selector_preset
return string_format( _( "%.2f%s" ), converted_volume, volume_units_abbr() );
}, _( "VOLUME" ) );

append_cell( []( const item_location & loc ) {
time_duration time = g->u.get_consume_time( *loc );
return string_format( _( "%s" ), to_string( time ) );
}, _( "CONSUME TIME" ) );

append_cell( [this]( const item_location & loc ) {
if( g->u.can_estimate_rot() ) {
if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) {
Expand Down
3 changes: 3 additions & 0 deletions src/mutation.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ struct mutation_branch {
// Multiplier for skill rust, defaulting to 1.
float skill_rust_multiplier = 1.0f;

// Multiplier for consume time, defaulting to 1.
float consume_time_modifier = 1.0f;

// Bonus or penalty to social checks (additive). 50 adds 50% to success, -25 subtracts 25%
social_modifiers social_mods;

Expand Down
1 change: 1 addition & 0 deletions src/mutation_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ void mutation_branch::load( const JsonObject &jo, const std::string & )
optional( jo, was_loaded, "map_memory_capacity_multiplier", map_memory_capacity_multiplier, 1.0f );
optional( jo, was_loaded, "reading_speed_multiplier", reading_speed_multiplier, 1.0f );
optional( jo, was_loaded, "skill_rust_multiplier", skill_rust_multiplier, 1.0f );
optional( jo, was_loaded, "consume_time_modifier", consume_time_modifier, 1.0f );
optional( jo, was_loaded, "scent_modifier", scent_modifier, 1.0f );
optional( jo, was_loaded, "scent_intensity", scent_intensity, cata::nullopt );
optional( jo, was_loaded, "scent_mask", scent_mask, cata::nullopt );
Expand Down
2 changes: 1 addition & 1 deletion tests/crafting_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ static void prep_craft( const recipe_id &rid, const std::vector<item> &tools,
// and just in case "used" skill difficulty is higher, set that too
g->u.set_skill_level( r.skill_used, std::max( r.difficulty,
g->u.get_skill_level( r.skill_used ) ) );

g->u.moves--;
const inventory &crafting_inv = g->u.crafting_inventory();
bool can_craft = r.deduped_requirements().can_make_with_inventory(
crafting_inv, r.get_component_filter() );
Expand Down