diff --git a/data/json/player_activities.json b/data/json/player_activities.json index 7e76f85a4685f..fdf68c78ceda4 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -531,14 +531,6 @@ "can_resume": false, "auto_needs": true }, - { - "id": "ACT_ADV_INVENTORY", - "type": "activity_type", - "activity_level": "MODERATE_EXERCISE", - "verb": "interacting with inventory", - "based_on": "neither", - "can_resume": false - }, { "id": "ACT_ARMOR_LAYERS", "type": "activity_type", @@ -944,15 +936,6 @@ "ignored_distractions": [ "hunger", "thirst" ], "can_resume": false }, - { - "id": "ACT_VIEW_RECIPE", - "type": "activity_type", - "activity_level": "NO_EXERCISE", - "verb": "viewing recipe", - "rooted": true, - "based_on": "neither", - "can_resume": false - }, { "id": "ACT_SPELLCASTING", "type": "activity_type", diff --git a/doc/OBSOLETION_AND_MIGRATION.md b/doc/OBSOLETION_AND_MIGRATION.md index 4b32262a23beb..37f44b937d980 100644 --- a/doc/OBSOLETION_AND_MIGRATION.md +++ b/doc/OBSOLETION_AND_MIGRATION.md @@ -244,6 +244,11 @@ For EOC/dialogue variables you can use `var_migration`. This currently only migr } ``` +# Activity Migration +See if it is mentioned in `src/savegame_legacy.cpp`. + +In `src/savegame_json.cpp` in `player_activity::deserialize( const JsonObject &data )` add to `std::set obs_activities` the activity ID with comment to remove it after the next version (after 0.B when in 0.A experimental). There should always be at least one example left. + # Ammo types Ammo types don't need an infrastructure to be obsoleted, but it is required to remove all items that use this ammo type diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index a2eddff3a7c37..d42948d764d9e 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -108,7 +108,6 @@ enum class creature_size : int; #define dbg(x) DebugLog((x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " -static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" ); static const activity_id ACT_ATM( "ACT_ATM" ); static const activity_id ACT_BLEED( "ACT_BLEED" ); @@ -168,7 +167,6 @@ static const activity_id ACT_VEHICLE( "ACT_VEHICLE" ); static const activity_id ACT_VEHICLE_DECONSTRUCTION( "ACT_VEHICLE_DECONSTRUCTION" ); static const activity_id ACT_VEHICLE_REPAIR( "ACT_VEHICLE_REPAIR" ); static const activity_id ACT_VIBE( "ACT_VIBE" ); -static const activity_id ACT_VIEW_RECIPE( "ACT_VIEW_RECIPE" ); static const activity_id ACT_WAIT( "ACT_WAIT" ); static const activity_id ACT_WAIT_NPC( "ACT_WAIT_NPC" ); static const activity_id ACT_WAIT_WEATHER( "ACT_WAIT_WEATHER" ); @@ -277,9 +275,7 @@ activity_handlers::do_turn_functions = { { ACT_CONSUME_FOOD_MENU, consume_food_menu_do_turn }, { ACT_CONSUME_DRINK_MENU, consume_drink_menu_do_turn }, { ACT_CONSUME_MEDS_MENU, consume_meds_menu_do_turn }, - { ACT_VIEW_RECIPE, view_recipe_do_turn }, { ACT_MOVE_LOOT, move_loot_do_turn }, - { ACT_ADV_INVENTORY, adv_inventory_do_turn }, { ACT_ARMOR_LAYERS, armor_layers_do_turn }, { ACT_ATM, atm_do_turn }, { ACT_FISH, fish_do_turn }, @@ -343,7 +339,6 @@ activity_handlers::finish_functions = { { ACT_CONSUME_FOOD_MENU, eat_menu_finish }, { ACT_CONSUME_DRINK_MENU, eat_menu_finish }, { ACT_CONSUME_MEDS_MENU, eat_menu_finish }, - { ACT_VIEW_RECIPE, view_recipe_finish }, { ACT_JACKHAMMER, jackhammer_finish }, { ACT_ROBOT_CONTROL, robot_control_finish }, { ACT_PULL_CREATURE, pull_creature_finish }, @@ -2832,64 +2827,11 @@ void activity_handlers::consume_meds_menu_do_turn( player_activity *, Character avatar_action::eat_or_use( player_character, game_menus::inv::consume_meds( player_character ) ); } -void activity_handlers::view_recipe_do_turn( player_activity *act, Character *you ) -{ - if( !you->is_avatar() ) { - return; - } - - recipe_id id( act->name ); - std::string itname; - if( act->index != 0 ) { - // act->name is recipe_id - itname = id->result_name(); - if( !you->get_group_available_recipes().contains( &id.obj() ) ) { - add_msg( m_info, _( "You don't know how to craft the %s!" ), itname ); - return; - } - you->craft( std::nullopt, id ); - return; - } - // act->name is itype_id - itype_id item( act->name ); - itname = item->nname( 1U ); - - bool is_byproduct = false; // product or byproduct - bool can_craft = false; - // Does a recipe for the item exist? - for( const auto& [_, r] : recipe_dict ) { - if( !r.obsolete && ( item == r.result() || r.in_byproducts( item ) ) ) { - is_byproduct = true; - // If a recipe exists, does my group know it? - if( you->get_group_available_recipes().contains( &r ) ) { - can_craft = true; - break; - } - } - } - if( !is_byproduct ) { - add_msg( m_info, _( "You wonder if it's even possible to craft the %s…" ), itname ); - return; - } else if( !can_craft ) { - add_msg( m_info, _( "You don't know how to craft the %s!" ), itname ); - return; - } - - std::string filterstring = string_format( "r:%s", itname ); - you->craft( std::nullopt, recipe_id(), filterstring ); -} - void activity_handlers::move_loot_do_turn( player_activity *act, Character *you ) { activity_on_turn_move_loot( *act, *you ); } -void activity_handlers::adv_inventory_do_turn( player_activity *, Character *you ) -{ - you->cancel_activity(); - create_advanced_inv(); -} - void activity_handlers::travel_do_turn( player_activity *act, Character *you ) { if( !you->omt_path.empty() ) { @@ -3503,11 +3445,6 @@ void activity_handlers::eat_menu_finish( player_activity *, Character * ) // Only exists to keep the eat activity alive between turns } -void activity_handlers::view_recipe_finish( player_activity *act, Character * ) -{ - act->set_to_null(); -} - void activity_handlers::jackhammer_do_turn( player_activity *act, Character * ) { map &here = get_map(); diff --git a/src/activity_handlers.h b/src/activity_handlers.h index 7507dd1b4e109..54c4a8ae9f4a3 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -241,7 +241,6 @@ void tree_communion_do_turn( player_activity *act, Character *you ); void vehicle_deconstruction_do_turn( player_activity *act, Character *you ); void vehicle_repair_do_turn( player_activity *act, Character *you ); void vibe_do_turn( player_activity *act, Character *you ); -void view_recipe_do_turn( player_activity *act, Character *you ); // defined in activity_handlers.cpp extern const std::map< activity_id, std::function > @@ -273,7 +272,6 @@ void toolmod_add_finish( player_activity *act, Character *you ); void train_finish( player_activity *act, Character *you ); void vehicle_finish( player_activity *act, Character *you ); void vibe_finish( player_activity *act, Character *you ); -void view_recipe_finish( player_activity *act, Character *you ); void wait_finish( player_activity *act, Character *you ); void wait_npc_finish( player_activity *act, Character *you ); void wait_weather_finish( player_activity *act, Character *you ); diff --git a/src/advanced_inv.cpp b/src/advanced_inv.cpp index 40a1d2e020eee..44fa35ae8a87d 100644 --- a/src/advanced_inv.cpp +++ b/src/advanced_inv.cpp @@ -71,8 +71,6 @@ # include #endif -static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); - static const flag_id json_flag_NO_RELOAD( "NO_RELOAD" ); static const flag_id json_flag_NO_UNLOAD( "NO_UNLOAD" ); @@ -1760,24 +1758,20 @@ void advanced_inventory::action_examine( advanced_inv_listitem *sitem, if( spane.get_area() == AIM_INVENTORY || spane.get_area() == AIM_WORN || ( spane.container && spane.container.carrier() == player_character.as_character() ) ) { const item_location &loc = sitem->items.front(); - // Setup a "return to AIM" activity. If examining the item creates a new activity - // (e.g. reading, reloading, activating), the new activity will be put on top of - // "return to AIM". Once the new activity is finished, "return to AIM" comes back - // (automatically, see player activity handling) and it re-opens the AIM. - // If examining the item did not create a new activity, we have to remove - // "return to AIM". - do_return_entry(); - cata_assert( player_character.has_activity( ACT_ADV_INVENTORY ) ); + // Setup for a "return to AIM" in case examining the item creates a new activity + // (e.g. reading, reloading, activating). + activity_id last_activity = player_character.activity.id(); // `inventory_item_menu` may call functions that move items, so we should // always recalculate during this period to ensure all item references are valid always_recalc = true; ret = g->inventory_item_menu( loc, info_startx, info_width, src == advanced_inventory::side::left ? game::LEFT_OF_INFO : game::RIGHT_OF_INFO ); always_recalc = false; - if( !player_character.has_activity( ACT_ADV_INVENTORY ) || !ui ) { + // If examining the item did create a new activity, we have to add "return to AIM". + if( last_activity != player_character.activity.id() || !ui ) { exit = true; + do_return_entry(); } else { - player_character.cancel_activity(); uistate.transfer_save.exit_code = aim_exit::none; } // Might have changed a stack (activated an item, repaired an item, etc.) @@ -2388,11 +2382,9 @@ void advanced_inventory::swap_panes() void advanced_inventory::do_return_entry() { - Character &player_character = get_player_character(); // only save pane settings save_settings( true ); - player_character.assign_activity( ACT_ADV_INVENTORY ); - player_character.activity.auto_resume = true; + uistate.open_menu = create_advanced_inv; save_state->exit_code = aim_exit::re_entry; } diff --git a/src/character.cpp b/src/character.cpp index 0ac06bf4203c0..707d1f6f3ba51 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -130,7 +130,6 @@ class activity_actor; struct dealt_projectile_attack; -static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); static const activity_id ACT_AUTODRIVE( "ACT_AUTODRIVE" ); static const activity_id ACT_CONSUME_DRINK_MENU( "ACT_CONSUME_DRINK_MENU" ); static const activity_id ACT_CONSUME_FOOD_MENU( "ACT_CONSUME_FOOD_MENU" ); @@ -152,7 +151,6 @@ static const activity_id ACT_TRAVELLING( "ACT_TRAVELLING" ); static const activity_id ACT_TREE_COMMUNION( "ACT_TREE_COMMUNION" ); static const activity_id ACT_TRY_SLEEP( "ACT_TRY_SLEEP" ); static const activity_id ACT_VIBE( "ACT_VIBE" ); -static const activity_id ACT_VIEW_RECIPE( "ACT_VIEW_RECIPE" ); static const activity_id ACT_WAIT( "ACT_WAIT" ); static const activity_id ACT_WAIT_NPC( "ACT_WAIT_NPC" ); static const activity_id ACT_WAIT_STAMINA( "ACT_WAIT_STAMINA" ); @@ -8857,13 +8855,8 @@ void Character::cancel_activity() stop_hauling(); } // Clear any backlog items that aren't auto-resume. - // but keep only one instance of ACT_ADV_INVENTORY - // FIXME: this is required by the legacy code in advanced_inventory::move_all_items() - bool has_adv_inv = has_activity( ACT_ADV_INVENTORY ); for( auto backlog_item = backlog.begin(); backlog_item != backlog.end(); ) { - if( backlog_item->auto_resume && - ( !has_adv_inv || backlog_item->id() != ACT_ADV_INVENTORY ) ) { - has_adv_inv |= backlog_item->id() == ACT_ADV_INVENTORY; + if( backlog_item->auto_resume ) { backlog_item++; } else { backlog_item = backlog.erase( backlog_item ); @@ -9082,7 +9075,6 @@ bool Character::can_use_floor_warmth() const has_activity( ACT_CONSUME_FOOD_MENU ) || has_activity( ACT_CONSUME_DRINK_MENU ) || has_activity( ACT_CONSUME_MEDS_MENU ) || - has_activity( ACT_VIEW_RECIPE ) || has_activity( ACT_STUDY_SPELL ); } diff --git a/src/game.cpp b/src/game.cpp index c2299faa13791..800309758775e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -235,7 +235,6 @@ static const activity_id ACT_SKIN( "ACT_SKIN" ); static const activity_id ACT_TRAIN( "ACT_TRAIN" ); static const activity_id ACT_TRAIN_TEACHER( "ACT_TRAIN_TEACHER" ); static const activity_id ACT_TRAVELLING( "ACT_TRAVELLING" ); -static const activity_id ACT_VIEW_RECIPE( "ACT_VIEW_RECIPE" ); static const ascii_art_id ascii_art_ascii_tombstone( "ascii_tombstone" ); @@ -1893,6 +1892,47 @@ static hint_rating rate_action_view_recipe( avatar &you, const item &it ) return hint_rating::iffy; } +static void view_recipe_crafting_menu( const item &it ) +{ + avatar &you = get_avatar(); + std::string itname; + if( it.is_craft() ) { + recipe_id id = it.get_making().ident(); + if( !you.get_group_available_recipes().contains( &id.obj() ) ) { + add_msg( m_info, _( "You don't know how to craft the %s!" ), id->result_name() ); + return; + } + you.craft( std::nullopt, id ); + return; + } + itype_id item = it.typeId(); + itname = item->nname( 1U ); + + bool is_byproduct = false; // product or byproduct + bool can_craft = false; + // Does a recipe for the item exist? + for( const auto& [_, r] : recipe_dict ) { + if( !r.obsolete && ( item == r.result() || r.in_byproducts( item ) ) ) { + is_byproduct = true; + // If a recipe exists, does my group know it? + if( you.get_group_available_recipes().contains( &r ) ) { + can_craft = true; + break; + } + } + } + if( !is_byproduct ) { + add_msg( m_info, _( "You wonder if it's even possible to craft the %s…" ), itname ); + return; + } else if( !can_craft ) { + add_msg( m_info, _( "You don't know how to craft the %s!" ), itname ); + return; + } + + std::string filterstring = string_format( "r:%s", itname ); + you.craft( std::nullopt, recipe_id(), filterstring ); +} + static hint_rating rate_action_eat( const avatar &you, const item &it ) { if( it.is_container() ) { @@ -2310,14 +2350,7 @@ int game::inventory_item_menu( item_location locThisItem, } break; case 'V': { - int is_recipe = 0; - std::string this_itype = oThisItem.typeId().str(); - if( oThisItem.is_craft() ) { - this_itype = oThisItem.get_making().ident().str(); - is_recipe = 1; - } - player_activity recipe_act = player_activity( ACT_VIEW_RECIPE, 0, is_recipe, 0, this_itype ); - u.assign_activity( recipe_act ); + view_recipe_crafting_menu( oThisItem ); break; } case 'i': diff --git a/src/player_activity.cpp b/src/player_activity.cpp index e890843dc2454..2d425d4f1903a 100644 --- a/src/player_activity.cpp +++ b/src/player_activity.cpp @@ -29,7 +29,6 @@ #include "units.h" #include "value_ptr.h" -static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); static const activity_id ACT_AIM( "ACT_AIM" ); static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" ); static const activity_id ACT_ATM( "ACT_ATM" ); @@ -54,7 +53,6 @@ static const activity_id ACT_READ( "ACT_READ" ); static const activity_id ACT_SPELLCASTING( "ACT_SPELLCASTING" ); static const activity_id ACT_TRAVELLING( "ACT_TRAVELLING" ); static const activity_id ACT_VEHICLE( "ACT_VEHICLE" ); -static const activity_id ACT_VIEW_RECIPE( "ACT_VIEW_RECIPE" ); static const activity_id ACT_WORKOUT_ACTIVE( "ACT_WORKOUT_ACTIVE" ); static const activity_id ACT_WORKOUT_HARD( "ACT_WORKOUT_HARD" ); static const activity_id ACT_WORKOUT_LIGHT( "ACT_WORKOUT_LIGHT" ); @@ -142,8 +140,7 @@ std::optional player_activity::get_progress_message( const avatar & return std::optional(); } - if( type == ACT_ADV_INVENTORY || - type == ACT_AIM || + if( type == ACT_AIM || type == ACT_ARMOR_LAYERS || type == ACT_ATM || type == ACT_CONSUME_DRINK_MENU || @@ -151,8 +148,8 @@ std::optional player_activity::get_progress_message( const avatar & type == ACT_CONSUME_MEDS_MENU || type == ACT_EAT_MENU || type == ACT_INVOKE_ITEM || - type == ACT_PICKUP_MENU || - type == ACT_VIEW_RECIPE ) { + type == ACT_PICKUP_MENU + ) { return std::nullopt; } diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index e34ccd009d7f1..7eba9dd986e0d 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -369,7 +369,8 @@ void player_activity::deserialize( const JsonObject &data ) bool is_obsolete = false; std::set obs_activities { - "ACT_MAKE_ZLAVE" // Remove after 0.F + "ACT_VIEW_RECIPE", // Remove after 0.I + "ACT_ADV_INVENTORY" // Remove after 0.I }; if( !data.read( "type", tmptype ) ) { // Then it's a legacy save. diff --git a/src/savegame_legacy.cpp b/src/savegame_legacy.cpp index 5489b940d82ea..671d3fb6fed70 100644 --- a/src/savegame_legacy.cpp +++ b/src/savegame_legacy.cpp @@ -9,7 +9,6 @@ #include "npc.h" #include "player_activity.h" -static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); static const activity_id ACT_AIM( "ACT_AIM" ); static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" ); static const activity_id ACT_ATM( "ACT_ATM" ); @@ -233,7 +232,7 @@ void player_activity::deserialize_legacy_type( int legacy_type, activity_id &des activity_id::NULL_ID(), // ACT_STASH is an actor now ACT_PICKUP, ACT_MOVE_ITEMS, - ACT_ADV_INVENTORY, + activity_id::NULL_ID(), // ACT_ADV_INVENTORY is uistate.open_menu now ACT_ARMOR_LAYERS, ACT_START_FIRE, ACT_OPEN_GATE, diff --git a/src/uistate.h b/src/uistate.h index 3eab31eab9a22..f74308c0caaa5 100644 --- a/src/uistate.h +++ b/src/uistate.h @@ -215,12 +215,12 @@ class uistatedata return input_history[id]; } /** - * A function pointer to be run before the player's next action. + * A function pointer to be run before the player's next action (but after activities conclude). * * Useful for opening a menu with passed arguments. + * As it is not serialized it should not be used for any game state logic! Like moving a character. */ - // NOLINTNEXTLINE(cata-serialize) - std::optional> open_menu; + std::optional> open_menu; // NOLINT(cata-serialize) // nice little convenience function for serializing an array, regardless of amount. :^) template