diff --git a/data/json/item_actions.json b/data/json/item_actions.json index e3f2318625781..9bac8b7dda6f8 100644 --- a/data/json/item_actions.json +++ b/data/json/item_actions.json @@ -854,6 +854,11 @@ "id": "SHAVEKIT", "name": { "str": "Shave" } }, + { + "type": "item_action", + "id": "WASHKIT", + "name": { "str": "Wash yourself" } + }, { "type": "item_action", "id": "SHOCKTONFA_OFF", diff --git a/data/json/itemgroups/Clothing_Gear/gear_civilian.json b/data/json/itemgroups/Clothing_Gear/gear_civilian.json index 995e72c563eca..70720d0c8b54f 100644 --- a/data/json/itemgroups/Clothing_Gear/gear_civilian.json +++ b/data/json/itemgroups/Clothing_Gear/gear_civilian.json @@ -217,6 +217,7 @@ [ "motorbike_pants", 10 ], [ "motorbike_boots", 10 ], [ "shavingkit", 30 ], + [ "washingkit", 30 ], [ "elec_hairtrimmer", 15 ], [ "razor_blade", 5 ], [ "razor_shaving", 5 ], diff --git a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json index 038e054ecb350..496f42cabffad 100644 --- a/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json +++ b/data/json/itemgroups/Drugs_Tobacco_Alcohol/drugs.json @@ -120,6 +120,7 @@ [ "smoxygen_tank", 5 ], [ "eyedrops", 35 ], [ "shavingkit", 5 ], + [ "washingkit", 5 ], [ "elec_hairtrimmer", 2 ], [ "nic_gum", 25 ], [ "weak_antibiotic", 30 ] diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index 3379cf2e87a4a..862964268a318 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -235,6 +235,7 @@ [ "fancy_sunglasses", 5 ], [ "glasses_reading", 30 ], [ "shavingkit", 20 ], + [ "washingkit", 20 ], [ "elec_hairtrimmer", 10 ], [ "glasses_bifocal", 30 ], [ "tailor_portfolio", 3 ], diff --git a/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json b/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json index a096774419bba..b25341cc21d44 100644 --- a/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json +++ b/data/json/itemgroups/Locations_MapExtras/mall_item_groups.json @@ -282,6 +282,7 @@ [ "soap", 45 ], [ "tailors_kit", 25 ], [ "shavingkit", 20 ], + [ "washingkit", 20 ], [ "elec_hairtrimmer", 20 ], [ "razor_shaving", 20 ], [ "curler_hair", 30 ], diff --git a/data/json/itemgroups/SUS/domestic.json b/data/json/itemgroups/SUS/domestic.json index 09d2688803a11..7eda034696f55 100644 --- a/data/json/itemgroups/SUS/domestic.json +++ b/data/json/itemgroups/SUS/domestic.json @@ -689,7 +689,11 @@ "entries": [ { "item": "soap", "count": [ 1, 4 ], "prob": 70 }, { - "distribution": [ { "item": "razor_shaving", "count": [ 1, 2 ], "prob": 50 }, { "item": "shavingkit", "prob": 50 } ], + "distribution": [ + { "item": "razor_shaving", "count": [ 1, 2 ], "prob": 50 }, + { "item": "shavingkit", "prob": 50 }, + { "item": "washingkit", "prob": 50 } + ], "prob": 75 }, { diff --git a/data/json/items/tool/toileteries.json b/data/json/items/tool/toileteries.json index 3c67c3d1a4c5d..fa63199562d81 100644 --- a/data/json/items/tool/toileteries.json +++ b/data/json/items/tool/toileteries.json @@ -116,6 +116,26 @@ "charges_per_use": 1, "use_action": "SHAVEKIT" }, + { + "id": "washingkit", + "type": "TOOL", + "name": { "str": "toiletry bag" }, + "looks_like": "shavingkit", + "description": "This is a compact and lightweight washing kit made for travelers. You can use it to freshen up if it's supplied with soap. It requires 1 unit of soap per use.", + "weight": "200 g", + "volume": "250 ml", + "price": 1000, + "price_postapoc": 250, + "to_hit": -1, + "material": "plastic", + "symbol": ";", + "color": "white", + "ammo": "soap", + "initial_charges": 5, + "max_charges": 10, + "charges_per_use": 1, + "use_action": "WASHKIT" + }, { "id": "sponge", "type": "TOOL", @@ -166,6 +186,26 @@ "charges_per_use": 1, "use_action": "SHAVEKIT" }, + { + "id": "survivor_washkit", + "type": "TOOL", + "name": { "str": "makeshift toiletry bag" }, + "looks_like": "survivor_shavingkit", + "description": "This is a makeshift washing kit. You can use it to freshen up if it's supplied with soap. It requires 1 unit of soap per use.", + "weight": "540 g", + "volume": "750 ml", + "price": 1000, + "price_postapoc": 100, + "to_hit": -1, + "bashing": 1, + "material": [ "leather", "glass" ], + "symbol": ";", + "color": "brown", + "ammo": "soap", + "max_charges": 10, + "charges_per_use": 1, + "use_action": "WASHKIT" + }, { "id": "washboard", "type": "TOOL", diff --git a/data/json/morale_types.json b/data/json/morale_types.json index ced01a7c072f5..33eab1d19bed9 100644 --- a/data/json/morale_types.json +++ b/data/json/morale_types.json @@ -309,6 +309,11 @@ "type": "morale_type", "text": "Freshly Shaven" }, + { + "id": "morale_washself", + "type": "morale_type", + "text": "Freshly Washed" + }, { "id": "morale_vomited", "type": "morale_type", diff --git a/data/json/npcs/items_generic.json b/data/json/npcs/items_generic.json index 720702f73c4dc..18217f58f0417 100644 --- a/data/json/npcs/items_generic.json +++ b/data/json/npcs/items_generic.json @@ -1047,6 +1047,7 @@ [ "sword_bayonet", 1 ], [ "syringe", 3 ], [ "shavingkit", 3 ], + [ "washingkit", 3 ], [ "survivor_shavingkit", 5 ], [ "elec_hairtrimmer", 2 ], [ "survivor_hairtrimmer", 3 ], diff --git a/data/json/player_activities.json b/data/json/player_activities.json index 02c1913c54a40..7a67c933e277e 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -711,6 +711,14 @@ "rooted": true, "based_on": "speed" }, + { + "id": "ACT_WASHSELF", + "type": "activity_type", + "activity_level": "NO_EXERCISE", + "verb": "washing yourself", + "rooted": true, + "based_on": "speed" + }, { "id": "ACT_HAIRCUT", "type": "activity_type", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index b40bcdff159c6..192a4832f7869 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -4092,6 +4092,25 @@ [ [ "plastic_chunk", 1 ], [ "skewer_bone", 4 ], [ "splinter", 4 ] ] ] }, + { + "type": "recipe", + "result": "survivor_washkit", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_TOOLS", + "skill_used": "fabrication", + "difficulty": 1, + "time": "1 m", + "reversible": true, + "autolearn": true, + "using": [ [ "cordage_short", 2 ] ], + "components": [ + [ [ "leather", 2 ], [ "fur", 2 ] ], + [ [ "rag", 2 ] ], + [ [ "toothbrush_plain", 1 ] ], + [ [ "mirror", 1 ] ], + [ [ "plastic_chunk", 1 ], [ "skewer_bone", 4 ], [ "splinter", 4 ] ] + ] + }, { "type": "recipe", "result": "survivor_hairtrimmer", diff --git a/data/mods/more_classes_scenarios/cs_classes.json b/data/mods/more_classes_scenarios/cs_classes.json index e288adc5f55ed..42d6c12dbeae4 100644 --- a/data/mods/more_classes_scenarios/cs_classes.json +++ b/data/mods/more_classes_scenarios/cs_classes.json @@ -93,6 +93,7 @@ "roadmap", "restaurantmap", "shavingkit", + "washingkit", "aluminum_foil", "can_chowder", "apple_cider", diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 6d1568b63ba71..c036254a957f6 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -199,6 +199,7 @@ static const activity_id ACT_WAIT_NPC( "ACT_WAIT_NPC" ); static const activity_id ACT_WAIT_STAMINA( "ACT_WAIT_STAMINA" ); static const activity_id ACT_WAIT_WEATHER( "ACT_WAIT_WEATHER" ); static const activity_id ACT_WASH( "ACT_WASH" ); +static const activity_id ACT_WASHSELF( "ACT_WASHSELF" ); static const activity_id ACT_WEAR( "ACT_WEAR" ); static const efftype_id effect_blind( "blind" ); @@ -407,6 +408,7 @@ activity_handlers::finish_functions = { { ACT_FILL_PIT, fill_pit_finish }, { ACT_PLAY_WITH_PET, play_with_pet_finish }, { ACT_SHAVE, shaving_finish }, + { ACT_WASHSELF, washingself_finish }, { ACT_HAIRCUT, haircut_finish }, { ACT_UNLOAD_MAG, unload_mag_finish }, { ACT_ROBOT_CONTROL, robot_control_finish }, @@ -4260,6 +4262,13 @@ void activity_handlers::haircut_finish( player_activity *act, player *p ) act->set_to_null(); } +void activity_handlers::washingself_finish( player_activity *act, player *p ) +{ + p->add_msg_if_player( _("You wash yourself and give your teeth a scrub." ) ); + p->add_morale( MORALE_WASHSELF, 4, 4, 360_minutes, 5_minutes ); + act->set_to_null(); +} + void activity_handlers::unload_mag_finish( player_activity *act, player *p ) { int qty = 0; diff --git a/src/activity_handlers.h b/src/activity_handlers.h index 24c533b712a6a..cd477a9d9b316 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -230,7 +230,8 @@ void hand_crank_finish( player_activity *act, player *p ); void atm_finish( player_activity *act, player *p ); void aim_finish( player_activity *act, player *p ); void eat_menu_finish( player_activity *act, player *p ); -void washing_finish( player_activity *act, player *p ); +void washingself_finish( player_activity *act, player *p ); +void washing_finish(player_activity *act, player* p); void hacksaw_finish( player_activity *act, player *p ); void pry_nails_finish( player_activity *act, player *p ); void chop_tree_finish( player_activity *act, player *p ); diff --git a/src/item_factory.cpp b/src/item_factory.cpp index f615c9ce1ab59..bf31f76d7d4d6 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -878,6 +878,7 @@ void Item_factory::init() add_iuse( "SEED", &iuse::seed ); add_iuse( "SEWAGE", &iuse::sewage ); add_iuse( "SHAVEKIT", &iuse::shavekit ); + add_iuse( "WASHKIT", &iuse::washkit ); add_iuse( "SHOCKTONFA_OFF", &iuse::shocktonfa_off ); add_iuse( "SHOCKTONFA_ON", &iuse::shocktonfa_on ); add_iuse( "SIPHON", &iuse::siphon ); diff --git a/src/iuse.cpp b/src/iuse.cpp index d2e1459b00765..da3fca22e6340 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -134,6 +134,7 @@ static const activity_id ACT_ROBOT_CONTROL( "ACT_ROBOT_CONTROL" ); static const activity_id ACT_SHAVE( "ACT_SHAVE" ); static const activity_id ACT_VIBE( "ACT_VIBE" ); static const activity_id ACT_WASH( "ACT_WASH" ); +static const activity_id ACT_WASHSELF( "ACT_WASHSELF" ); static const efftype_id effect_adrenaline( "adrenaline" ); static const efftype_id effect_antibiotic( "antibiotic" ); @@ -9276,6 +9277,17 @@ int iuse::hairkit( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } +int iuse::washkit( player *p, item *it, bool, const tripoint & ) +{ + if( p->is_mounted() ) { + p->add_msg_if_player( m_info, _( "You cannot do that while mounted." ) ); + return 0; + } + const int moves = to_moves( 5_minutes ); + p->assign_activity( ACT_WASHSELF, moves ); + return it->type->charges_to_use(); +} + int iuse::weather_tool( player *p, item *it, bool, const tripoint & ) { const w_point weatherPoint = *g->weather.weather_precise; diff --git a/src/iuse.h b/src/iuse.h index f051087df6353..e49301031a64b 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -191,6 +191,7 @@ class iuse int tow_attach( player *, item *, bool, const tripoint & ); int cable_attach( player *, item *, bool, const tripoint & ); int shavekit( player *, item *, bool, const tripoint & ); + int washkit( player *, item *, bool, const tripoint & ); int hairkit( player *, item *, bool, const tripoint & ); int weather_tool( player *, item *, bool, const tripoint & ); int ladder( player *, item *, bool, const tripoint & ); diff --git a/src/morale_types.cpp b/src/morale_types.cpp index 4a768de9785d8..f1cabfd98a9d6 100644 --- a/src/morale_types.cpp +++ b/src/morale_types.cpp @@ -174,6 +174,7 @@ const morale_type MORALE_PERM_NOMAD( "morale_perm_nomad" ); const morale_type MORALE_GAME_FOUND_KITTEN( "morale_game_found_kitten" ); const morale_type MORALE_HAIRCUT( "morale_haircut" ); const morale_type MORALE_SHAVE( "morale_shave" ); +const morale_type MORALE_WASHSELF( "morale_washself" ); const morale_type MORALE_CHAT( "morale_chat" ); const morale_type MORALE_VOMITED( "morale_vomited" ); const morale_type MORALE_PLAY_WITH_PET( "morale_play_with_pet" ); diff --git a/src/morale_types.h b/src/morale_types.h index ba1073a926320..b79cd6625b53b 100644 --- a/src/morale_types.h +++ b/src/morale_types.h @@ -97,6 +97,7 @@ extern const morale_type MORALE_PERM_CONSTRAINED; extern const morale_type MORALE_PERM_NOMAD; extern const morale_type MORALE_GAME_FOUND_KITTEN; extern const morale_type MORALE_HAIRCUT; +extern const morale_type MORALE_WASHSELF; extern const morale_type MORALE_SHAVE; extern const morale_type MORALE_CHAT; extern const morale_type MORALE_VOMITED;