From b6d2c9463f852d29f2e9e75c934fa6f91ab6c535 Mon Sep 17 00:00:00 2001 From: GuardianDll Date: Mon, 2 Sep 2024 22:03:46 +0200 Subject: [PATCH] add butchering profs --- data/json/proficiencies/butchering.json | 47 +++++++++++ .../proficiencies/proficiency_categories.json | 6 ++ src/activity_handlers.cpp | 79 ++++++++++++++++++- 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 data/json/proficiencies/butchering.json diff --git a/data/json/proficiencies/butchering.json b/data/json/proficiencies/butchering.json new file mode 100644 index 0000000000000..c13239b116b6e --- /dev/null +++ b/data/json/proficiencies/butchering.json @@ -0,0 +1,47 @@ +[ + { + "type": "proficiency", + "id": "prof_butchering_basic", + "category": "prof_butchering", + "name": { "str": "Principles of Butchering" }, + "description": "You know how to pick up most of the meat from the animal body.", + "can_learn": true, + "time_to_learn": "3 h" + }, + { + "type": "proficiency", + "id": "prof_butchering_adv", + "category": "prof_butchering", + "name": { "str": "Butchering Expert" }, + "description": "There is very little meat left after your skillful knife movements.", + "can_learn": true, + "time_to_learn": "15 h" + }, + { + "type": "proficiency", + "id": "prof_skinning_basic", + "category": "prof_butchering", + "name": { "str": "Principles of Skinning" }, + "description": "You stopped making holes in the skin of animals you butcher.", + "can_learn": true, + "time_to_learn": "3 h" + }, + { + "type": "proficiency", + "id": "prof_skinning_adv", + "category": "prof_butchering", + "name": { "str": "Skinning Expert" }, + "description": "You really know how to skin the animal.", + "can_learn": true, + "time_to_learn": "15 h" + }, + { + "type": "proficiency", + "id": "prof_butchery_offal", + "category": "prof_butchering", + "name": { "str": "Evisceration" }, + "description": "You know how to properly remove offals from the body.", + "can_learn": true, + "time_to_learn": "3 h" + } +] diff --git a/data/json/proficiencies/proficiency_categories.json b/data/json/proficiencies/proficiency_categories.json index 5d95e0d26a2ce..3eabe88e57fc2 100644 --- a/data/json/proficiencies/proficiency_categories.json +++ b/data/json/proficiencies/proficiency_categories.json @@ -23,6 +23,12 @@ "name": "Food Handling", "description": "Proficiencies for cooking and food preparation, as well as experience with food handling tools." }, + { + "type": "proficiency_category", + "id": "prof_butchering", + "name": "Butchering", + "description": "Proficiencies for carving and proper dressing of meat and skin of animals." + }, { "type": "proficiency_category", "id": "prof_electronic", diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 989825905925d..11d1ce79e7fe8 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -231,7 +231,12 @@ static const morale_type morale_feeling_good( "morale_feeling_good" ); static const morale_type morale_game( "morale_game" ); static const morale_type morale_tree_communion( "morale_tree_communion" ); +static const proficiency_id proficiency_prof_butchering_adv( "prof_butchering_adv" ); +static const proficiency_id proficiency_prof_butchering_basic( "prof_butchering_basic" ); +static const proficiency_id proficiency_prof_butchery_offal( "prof_butchery_offal" ); static const proficiency_id proficiency_prof_dissect_humans( "prof_dissect_humans" ); +static const proficiency_id proficiency_prof_skinning_adv( "prof_skinning_adv" ); +static const proficiency_id proficiency_prof_skinning_basic( "prof_skinning_basic" ); static const quality_id qual_BUTCHER( "BUTCHER" ); static const quality_id qual_CUT_FINE( "CUT_FINE" ); @@ -811,6 +816,28 @@ int butcher_time_to_cut( Character &you, const item &corpse_item, const butcher_ if( corpse_item.has_flag( flag_QUARTERED ) ) { time_to_cut /= 4; } + + if( corpse.harvest->has_entry_type( harvest_drop_flesh ) && ( action == butcher_type::FULL || + action == butcher_type::QUICK ) ) { + time_to_cut *= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_butchering_adv ) ); + } + + if( corpse.harvest->has_entry_type( harvest_drop_flesh ) && ( action == butcher_type::FULL || + action == butcher_type::QUICK ) ) { + time_to_cut *= 1.75 - ( 0.75 * you.get_proficiency_practice( proficiency_prof_butchering_basic ) ); + } + + if( corpse.harvest->has_entry_type( harvest_drop_offal ) && ( action == butcher_type::FULL || + action == butcher_type::QUICK || action == butcher_type::FIELD_DRESS ) ) { + time_to_cut *= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_butchery_offal ) ); + } + + // Skinning decrease the cutting speed only a little, and decreases the output mostly + if( corpse.harvest->has_entry_type( harvest_drop_skin ) && ( action == butcher_type::FULL || + action == butcher_type::QUICK || action == butcher_type::SKIN ) ) { + time_to_cut *= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_skinning_adv ) ); + } + time_to_cut *= ( 1.0f - ( get_player_character().get_num_crafting_helpers( 3 ) / 10.0f ) ); return time_to_cut; } @@ -950,7 +977,7 @@ static std::vector create_charge_items( const itype *drop, int count, // Returns false if the calling function should abort static bool butchery_drops_harvest( item *corpse_item, const mtype &mt, Character &you, - butcher_type action ) + butcher_type action, int moves_total ) { const int tool_quality = you.max_quality( action == butcher_type::DISSECT ? qual_CUT_FINE : qual_BUTCHER, PICKUP_RANGE ); @@ -1057,6 +1084,26 @@ static bool butchery_drops_harvest( item *corpse_item, const mtype &mt, Characte roll = 0; } + if( entry.type == harvest_drop_flesh ) { + roll /= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_butchering_adv ) ); + } + + if( entry.type == harvest_drop_flesh ) { + roll /= 3.2 - ( 2.2 * you.get_proficiency_practice( proficiency_prof_butchering_basic ) ); + } + + if( entry.type == harvest_drop_offal ) { + roll /= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_butchery_offal ) ); + } + + if( entry.type == harvest_drop_skin ) { + roll /= 1.25 - ( 0.25 * you.get_proficiency_practice( proficiency_prof_skinning_adv ) ); + } + + if( entry.type == harvest_drop_skin ) { + roll /= 3.2 - ( 2.2 * you.get_proficiency_practice( proficiency_prof_skinning_basic ) ); + } + // QUICK BUTCHERY if( action == butcher_type::QUICK ) { if( entry.type == harvest_drop_flesh ) { @@ -1267,6 +1314,34 @@ static bool butchery_drops_harvest( item *corpse_item, const mtype &mt, Characte 0 ) + 4 ); } + // handle our prof training + + if( mt.harvest->has_entry_type( harvest_drop_flesh ) ) { + if( you.has_proficiency( proficiency_prof_butchering_basic ) ) { + you.practice_proficiency( proficiency_prof_butchering_adv, + time_duration::from_seconds( moves_total ) ); + } else { + you.practice_proficiency( proficiency_prof_butchering_basic, + time_duration::from_seconds( moves_total ) ); + } + } + + if( mt.harvest->has_entry_type( harvest_drop_offal ) ) { + you.practice_proficiency( proficiency_prof_butchery_offal, + time_duration::from_seconds( moves_total ) ); + } + + if( mt.harvest->has_entry_type( harvest_drop_skin ) ) { + if( you.has_proficiency( proficiency_prof_skinning_basic ) ) { + you.practice_proficiency( proficiency_prof_skinning_adv, + time_duration::from_seconds( moves_total ) ); + } else { + you.practice_proficiency( proficiency_prof_skinning_basic, + time_duration::from_seconds( moves_total ) ); + } + } + + // after this point, if there was a liquid handling from the harvest, // and the liquid handling was interrupted, then the activity was canceled, // therefore operations on this activity's targets and values may be invalidated. @@ -1353,7 +1428,7 @@ void activity_handlers::butcher_finish( player_activity *act, Character *you ) } // all action types - yields - if( !butchery_drops_harvest( &corpse_item, *corpse, *you, action ) ) { + if( !butchery_drops_harvest( &corpse_item, *corpse, *you, action, act->moves_total ) ) { // FATAL FAILURE add_msg( m_warning, SNIPPET.random_from_category( "harvest_drop_default_dissect_failed" ).value_or( translation() ).translated() );