Skip to content

Commit

Permalink
Finish making consume take time (#40177)
Browse files Browse the repository at this point in the history
* Add activity for consume

* Added new json mutation flag and updated existing traits using existing values

* Add time to consume menu

* Remove debug line

* Break up drug/medicine use times

* Make rigid table manners slow down eating

* Sync variables names

* Fixed merge error

* Fixes auto eat, drink by making it simply insta consume.

* fix crafting tests

* Undo unneeded fix

* Add in support for resuming consume
  • Loading branch information
Ramza13 authored May 11, 2020
1 parent 961ec1b commit 6913049
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 60 deletions.
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 @@ -6823,7 +6823,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

0 comments on commit 6913049

Please sign in to comment.