diff --git a/data/json/item_actions.json b/data/json/item_actions.json index b3d0bfdc1b84b..0fb4f209e188c 100644 --- a/data/json/item_actions.json +++ b/data/json/item_actions.json @@ -374,21 +374,11 @@ "id": "EHANDCUFFS", "name": { "str": "Take off" } }, - { - "type": "item_action", - "id": "EINKTABLETPC", - "name": { "str": "Use SD-Card apps" } - }, { "type": "item_action", "id": "EBOOKSAVE", "name": { "str": "Store books" } }, - { - "type": "item_action", - "id": "EBOOKREAD", - "name": { "str": "Read stored books" } - }, { "type": "item_action", "id": "EMF_PASSIVE_ON", @@ -699,11 +689,6 @@ "id": "PROZAC", "name": { "str": "Take" } }, - { - "type": "item_action", - "id": "ELECTRICSTORAGE", - "name": { "str": "Manage external storage" } - }, { "type": "item_action", "id": "E_FILE_DEVICE", diff --git a/data/json/item_category.json b/data/json/item_category.json index c6d73a4fdf409..e6fe318e2eb40 100644 --- a/data/json/item_category.json +++ b/data/json/item_category.json @@ -1,4 +1,20 @@ [ + { + "id": "e_files", + "type": "ITEM_CATEGORY", + "name_header": { "str": "Files" }, + "name_noun": { "ctxt": "item_category", "str": "file" }, + "zone": "LOOT_OTHER", + "sort_rank": -25 + }, + { + "id": "software", + "type": "ITEM_CATEGORY", + "name_header": { "str": "Software" }, + "name_noun": { "ctxt": "item_category", "str_sp": "software" }, + "zone": "LOOT_OTHER", + "sort_rank": -24 + }, { "id": "guns", "type": "ITEM_CATEGORY", diff --git a/data/json/itemgroups/efiles.json b/data/json/itemgroups/efiles.json index c17900c00ff6a..79f8ff7f62add 100644 --- a/data/json/itemgroups/efiles.json +++ b/data/json/itemgroups/efiles.json @@ -1,14 +1,4 @@ [ - { - "id": "laptop_files_work", - "type": "item_group", - "subtype": "collection", - "entries": [ - { "item": "book_nonf_hard_homemk_anythingcan", "prob": 100, "count": 1 }, - { "item": "book_nonf_hard_homemk_grtrms", "prob": 100, "count": 1 }, - { "item": "book_nonf_hard_homemk_handshome", "prob": 100, "count": 1 } - ] - }, { "id": "edevice_work", "type": "item_group", diff --git a/data/json/items/fake.json b/data/json/items/fake.json index 2d9bdbb0df0d6..161fd2dc69200 100644 --- a/data/json/items/fake.json +++ b/data/json/items/fake.json @@ -119,7 +119,7 @@ "name": { "str": "Integrated AR System" }, "description": "Extremely thin lenses provides user with augmented reality overlay allowing the user to zoom, and it displays handy information about local topology.", "charges_per_use": 1, - "use_action": [ "CAMERA", "PORTABLE_GAME", "EINKTABLETPC", "ELECTRICSTORAGE", "EBOOKSAVE", "EBOOKREAD" ], + "use_action": [ "CAMERA", "PORTABLE_GAME", "EBOOKSAVE", "E_FILE_DEVICE" ], "pocket_data": [ { "pocket_type": "EBOOK", diff --git a/data/json/items/software.json b/data/json/items/software.json index f937c1978124e..b22920f708fa3 100644 --- a/data/json/items/software.json +++ b/data/json/items/software.json @@ -1,16 +1,16 @@ [ { - "id": "software", + "id": "abstract_software", + "copy-from": "abstract_efile", "type": "GENERIC", - "name": { "str_sp": "software" }, - "symbol": "#", - "container": "usb_drive", - "description": { "str": "IF YOU ARE SEEING THIS IT IS A BUG.", "//~": "NO_I18N" }, - "flags": [ "IRREMOVABLE", "NO_DROP" ] + "category": "software", + "name": { "str_sp": "abstract software" }, + "description": "Copy from this for any software", + "ememory_size": "1 KB" }, { "id": "software_useless", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "misc software" }, "description": "A miscellaneous piece of hobby software. Probably useless.", @@ -20,7 +20,7 @@ }, { "id": "software_hacking", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "hackPRO" }, "description": "A piece of hacking software.", @@ -30,7 +30,7 @@ }, { "id": "software_medical", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "MediSoft" }, "description": "A piece of medical software.", @@ -40,7 +40,7 @@ }, { "id": "software_math", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "MatheMAX" }, "description": "A piece of mathematical software.", @@ -50,7 +50,7 @@ }, { "id": "software_blood_data", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "infection data" }, "description": "Medical data on zombie blood.", @@ -60,7 +60,7 @@ }, { "id": "software_lab_data", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "lab data" }, "description": "Research archives from a government laboratory.", @@ -70,7 +70,7 @@ }, { "id": "software_encryption_codes", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "encryption codes" }, "description": "There are numerous security keys with dates for potential future access to encrypted archived data.", @@ -80,7 +80,7 @@ }, { "id": "software_archived_data", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str_sp": "archive data" }, "description": "Extremely compressed research data, observation and experiment statistics. The only pattern you manage to recognize is an increase in the amount of report closer to the Cataclysm, but also a reduction in the number of facilities still submitting reports.", @@ -90,7 +90,7 @@ }, { "id": "software_electronics_reference", - "copy-from": "abstract_efile", + "copy-from": "abstract_software", "type": "GENERIC", "name": { "str": "integrated circuit datasheet archives", "str_pl": "misc software" }, "description": "Huge archives of numerous IC circuit datasheets from several major manufacturers. Probably valuable to the right person, as it would be hard to salvage and reuse these components without them.", @@ -101,6 +101,7 @@ { "abstract": "abstract_efile", "type": "GENERIC", + "category": "e_files", "symbol": "o", "name": "abstract electronic file", "description": "abstract electronic file, copy-from for any item that should solely be on an electronic storage medium", @@ -110,13 +111,13 @@ }, { "abstract": "abstract_efile_copiable", + "copy-from": "abstract_efile", "type": "GENERIC", "symbol": "o", "name": "abstract copiable electronic file", "description": "abstract copiable electronic file", "ememory_size": "1 KB", - "flags": [ "E_STORABLE", "ZERO_WEIGHT", "NO_DROP", "IRREMOVABLE", "E_COPIABLE" ], - "variables": { "browsed": "false" } + "extend": { "flags": [ "E_COPIABLE" ] } }, { "abstract": "abstract_efile_read", diff --git a/data/json/items/tool/electronics.json b/data/json/items/tool/electronics.json index 08fbe9d083ff2..6e1fac32476d3 100644 --- a/data/json/items/tool/electronics.json +++ b/data/json/items/tool/electronics.json @@ -252,6 +252,7 @@ "revert_to": "eink_tablet_pc", "use_action": [ "E_FILE_DEVICE", + "EBOOKSAVE", { "ammo_scale": 0, "type": "transform", diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index 3d181b42d4734..9bb1710a592f2 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -1124,7 +1124,7 @@ "color": "light_gray", "ammo": "battery", "charges_per_use": 1, - "use_action": [ "CAMERA", "PORTABLE_GAME", "EINKTABLETPC", "ELECTRICSTORAGE", "EBOOKSAVE", "EBOOKREAD" ], + "use_action": [ "CAMERA", "PORTABLE_GAME", "EBOOKSAVE", "E_FILE_DEVICE" ], "tick_action": [ "EPIC_MUSIC" ], "pocket_data": [ { @@ -1134,7 +1134,7 @@ "default_magazine": "light_battery_cell" }, { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", diff --git a/data/mods/Aftershock/items/armor.json b/data/mods/Aftershock/items/armor.json index 8758c53361b4d..c1d178faa7c02 100644 --- a/data/mods/Aftershock/items/armor.json +++ b/data/mods/Aftershock/items/armor.json @@ -110,13 +110,7 @@ "flags": [ "WATCH", "BELTED", "STURDY", "WATER_FRIENDLY" ], "ammo": [ "battery" ], "charges_per_use": 1, - "use_action": [ - "EINKTABLETPC", - "EBOOKREAD", - "ELECTRICSTORAGE", - "PORTABLE_GAME", - { "type": "link_up", "cable_length": 5, "charge_rate": "140 W" } - ], + "use_action": [ "E_FILE_DEVICE", "PORTABLE_GAME", { "type": "link_up", "cable_length": 5, "charge_rate": "140 W" } ], "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -125,7 +119,7 @@ "default_magazine": "medium_battery_cell" }, { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", diff --git a/data/mods/Aftershock/items/tools.json b/data/mods/Aftershock/items/tools.json index c2bc34d3eeacc..c1e0767ce84e7 100644 --- a/data/mods/Aftershock/items/tools.json +++ b/data/mods/Aftershock/items/tools.json @@ -23,15 +23,13 @@ "MP3", "CALORIES_INTAKE_TRACKER", "PORTABLE_GAME", - "EINKTABLETPC", - "ELECTRICSTORAGE", - "EBOOKSAVE", - "EBOOKREAD" + "E_FILE_DEVICE", + "EBOOKSAVE" ], "flags": [ "WATCH", "ALARMCLOCK", "NO_UNLOAD", "NO_RELOAD", "CALORIES_INTAKE" ], "pocket_data": [ { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", @@ -160,7 +158,7 @@ "name": { "str": "atomic smartphone - music", "str_pl": "atomic smartphones - music" }, "description": "This phone is playing music, steadily raising your morale. You can't hear anything else while you're listening.", "revert_to": "afs_atomic_smartphone", - "use_action": [ "PORTABLE_GAME", "EINKTABLETPC", "EBOOKSAVE", "EBOOKREAD", "MP3_DEACTIVATE" ], + "use_action": [ "PORTABLE_GAME", "E_FILE_DEVICE", "EBOOKSAVE", "MP3_DEACTIVATE" ], "tick_action": [ "MP3_ON" ], "extend": { "flags": [ "TRADER_AVOID" ] } }, @@ -172,9 +170,8 @@ "revert_to": "afs_atomic_smartphone", "use_action": [ "PORTABLE_GAME", - "EINKTABLETPC", + "E_FILE_DEVICE", "EBOOKSAVE", - "EBOOKREAD", { "target": "afs_atomic_smartphone", "msg": "You deactivate the flashlight app.", @@ -205,14 +202,12 @@ "ROBOTCONTROL", "CALORIES_INTAKE_TRACKER", "PORTABLE_GAME", - "EINKTABLETPC", - "ELECTRICSTORAGE", - "EBOOKSAVE", - "EBOOKREAD" + "E_FILE_DEVICE", + "EBOOKSAVE" ], "pocket_data": [ { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", @@ -227,7 +222,7 @@ "name": { "str": "Wraitheon executive's smartphone - music", "str_pl": "Wraitheon executive's smartphones - music" }, "description": "This phone is playing music, steadily raising your morale. You can't hear anything else while you're listening.", "revert_to": "afs_atomic_smartphone", - "use_action": [ "PORTABLE_GAME", "EINKTABLETPC", "EBOOKSAVE", "EBOOKREAD", "MP3_DEACTIVATE" ], + "use_action": [ "PORTABLE_GAME", "E_FILE_DEVICE", "EBOOKSAVE", "MP3_DEACTIVATE" ], "extend": { "flags": [ "TRADER_AVOID" ] }, "tick_action": [ "MP3_ON" ] }, @@ -239,9 +234,8 @@ "revert_to": "afs_atomic_smartphone", "use_action": [ "PORTABLE_GAME", - "EINKTABLETPC", + "E_FILE_DEVICE", "EBOOKSAVE", - "EBOOKREAD", { "target": "afs_wraitheon_smartphone", "msg": "You deactivate the flashlight app.", @@ -462,7 +456,7 @@ "charges_per_use": 2, "use_action": [ "ROBOTCONTROL", - "EINKTABLETPC", + "E_FILE_DEVICE", "PORTABLE_GAME", { "target": "control_laptop_screen_lit", @@ -514,7 +508,7 @@ "ammo": [ "battery" ], "charges_per_use": 2, "use_action": [ - "EINKTABLETPC", + "E_FILE_DEVICE", "PORTABLE_GAME", { "target": "vr_laptop_holosuite", diff --git a/data/mods/BombasticPerks/perkdata/flawless_memory.json b/data/mods/BombasticPerks/perkdata/flawless_memory.json index dbc264219f4cb..65786470d7b93 100644 --- a/data/mods/BombasticPerks/perkdata/flawless_memory.json +++ b/data/mods/BombasticPerks/perkdata/flawless_memory.json @@ -6,11 +6,11 @@ "name": { "str_sp": "Flawless memory" }, "description": "You can remember with perfect detail everything you've ever lived, even allowing you to read books and play games by remembering them.", "charges_per_use": 0, - "use_action": [ "CAMERA", "PORTABLE_GAME", "EBOOKSAVE", "EBOOKREAD" ], + "use_action": [ "CAMERA", "PORTABLE_GAME", "EBOOKSAVE", "E_FILE_DEVICE" ], "tick_action": [ "EPIC_MUSIC" ], "pocket_data": [ { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index bab4eeb9b4b6b..053563c54e9af 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -954,18 +954,7 @@ "id": "test_ebook_reader", "name": { "str": "eBook reader" }, "description": "Test book reader.", - "weight": "250 g", - "volume": "250 ml", - "longest_side": "25 cm", - "price": "200 USD", - "price_postapoc": "1 USD", - "to_hit": -1, - "material": [ "plastic" ], - "symbol": ";", - "color": "green", - "ammo": [ "battery" ], - "charges_per_use": 1, - "use_action": [ "EBOOKSAVE", "EBOOKREAD" ], + "copy-from": "eink_tablet_pc", "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -976,7 +965,7 @@ "item_restriction": [ "test_battery_disposable" ] }, { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", diff --git a/data/mods/TEST_DATA/legacy_to_hit.json b/data/mods/TEST_DATA/legacy_to_hit.json index 5e0013bf0a2ac..cbf59a4c16a47 100644 --- a/data/mods/TEST_DATA/legacy_to_hit.json +++ b/data/mods/TEST_DATA/legacy_to_hit.json @@ -254,7 +254,6 @@ "test_balanced_sword", "test_clumsy_sword", "test_compbow", - "test_ebook_reader", "test_fire_ax", "test_fire_ax_mostly_steel", "test_fire_ax_mostly_wood", diff --git a/data/mods/Xedra_Evolved/items/inventor/armor.json b/data/mods/Xedra_Evolved/items/inventor/armor.json index 4cfd8cd20fbf8..20834ef1fd89c 100644 --- a/data/mods/Xedra_Evolved/items/inventor/armor.json +++ b/data/mods/Xedra_Evolved/items/inventor/armor.json @@ -366,10 +366,8 @@ "CAMERA", "CALORIES_INTAKE_TRACKER", "PORTABLE_GAME", - "EINKTABLETPC", - "ELECTRICSTORAGE", + "E_FILE_DEVICE", "EBOOKSAVE", - "EBOOKREAD", { "target": "vision_halo_on", "msg": "Turn on.", @@ -405,7 +403,7 @@ "default_magazine": "light_minus_disposable_cell" }, { - "pocket_type": "EBOOK", + "pocket_type": "E_FILE_STORAGE", "rigid": true, "max_contains_volume": "1 ml", "max_contains_weight": "1 g", @@ -451,10 +449,8 @@ "revert_to": "vision_halo", "use_action": [ "CAMERA", - "EINKTABLETPC", - "ELECTRICSTORAGE", + "E_FILE_DEVICE", "EBOOKSAVE", - "EBOOKREAD", { "target": "vision_halo", "msg": "Turn off.", diff --git a/data/mods/Xedra_Evolved/items/inventor/misc.json b/data/mods/Xedra_Evolved/items/inventor/misc.json index 2f222c701ba18..b79bf122a9cba 100644 --- a/data/mods/Xedra_Evolved/items/inventor/misc.json +++ b/data/mods/Xedra_Evolved/items/inventor/misc.json @@ -111,10 +111,10 @@ }, { "id": "software_AI", - "copy-from": "software", + "copy-from": "abstract_software", "type": "TOOL", "name": { "str_sp": "IA software" }, - "description": "A USB thumb drive with a simple intelligent agent to provide support in parsing big layers of information.", + "description": "A simple intelligent agent to provide support in parsing big layers of information.", "extend": { "flags": [ "INVENTOR_CRAFTED" ] }, "qualities": [ [ "AI_TOOL", 1 ] ] }, diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index b35d2a53def2c..4c63a93688792 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -125,7 +125,6 @@ static const activity_id ACT_CONSUME( "ACT_CONSUME" ); static const activity_id ACT_CONSUME_MEDS_MENU( "ACT_CONSUME_MEDS_MENU" ); static const activity_id ACT_CRACKING( "ACT_CRACKING" ); static const activity_id ACT_CRAFT( "ACT_CRAFT" ); -static const activity_id ACT_DATA_HANDLING( "ACT_DATA_HANDLING" ); static const activity_id ACT_DISABLE( "ACT_DISABLE" ); static const activity_id ACT_DISASSEMBLE( "ACT_DISASSEMBLE" ); static const activity_id ACT_DROP( "ACT_DROP" ); @@ -1038,231 +1037,6 @@ std::unique_ptr bookbinder_copy_activity_actor::deserialize( Jso return actor.clone(); } -data_handling_activity_actor::data_handling_activity_actor( - const item_location &recorder, const std::vector &targets ) - : recorder( recorder ), targets( targets ) {} - -static int get_quality_from_string( const std::string_view s ) -{ - const ret_val try_quality = try_parse_integer( s, false ); - if( try_quality.success() ) { - return try_quality.value(); - } else { - debugmsg( "Error parsing photo quality: %s", try_quality.str() ); - return 0; - } -} - -void data_handling_activity_actor::start( player_activity &act, Character & ) -{ - act.moves_left = act.moves_total = targets.size() * to_moves( time_per_card ); -} - -void data_handling_activity_actor::do_turn( player_activity &act, Character &p ) -{ - if( !recorder || !recorder->ammo_sufficient( &p ) ) { - p.cancel_activity(); - p.add_msg_if_player( m_warning, _( "%s appears to have no energy." ), recorder->display_name() ); - return; - } - if( calendar::once_every( 5_minutes ) ) { - recorder->ammo_consume( recorder->type->charges_to_use(), p.pos_bub(), &p ); - } - time_until_next_card -= 1_seconds; - if( time_until_next_card > 0_seconds ) { - return; // not yet - } - item &eink = *recorder; - item &mc = *targets.back(); - targets.pop_back(); - if( targets.empty() ) { - act.moves_left = 0; - } - time_until_next_card = time_per_card; - handled_cards++; - - if( mc.has_var( "MC_EXTENDED_PHOTOS" ) ) { - std::vector extended_photos; - try { - mc.read_extended_photos( extended_photos, "MC_EXTENDED_PHOTOS", false ); - eink.read_extended_photos( extended_photos, "EIPC_EXTENDED_PHOTOS", true ); - eink.write_extended_photos( extended_photos, "EIPC_EXTENDED_PHOTOS" ); - downloaded_extended_photos++; - } catch( const JsonError &e ) { - debugmsg( "Error card reading photos (loaded photos = %i) : %s", extended_photos.size(), - e.c_str() ); - } - } - - const std::string monster_photos = mc.get_var( "MC_MONSTER_PHOTOS" ); - if( !monster_photos.empty() ) { - downloaded_monster_photos++; - std::string photos = eink.get_var( "EINK_MONSTER_PHOTOS" ); - if( photos.empty() ) { - eink.set_var( "EINK_MONSTER_PHOTOS", monster_photos ); - } else { - std::istringstream f( monster_photos ); - std::string s; - while( getline( f, s, ',' ) ) { - if( s.empty() ) { - continue; - } - const std::string mtype = s; - getline( f, s, ',' ); - const int quality = get_quality_from_string( s ); - - const size_t eink_strpos = photos.find( "," + mtype + "," ); - - if( eink_strpos == std::string::npos ) { - photos += mtype + "," + string_format( "%d", quality ) + ","; - } else { - const size_t strqpos = eink_strpos + mtype.size() + 2; - const size_t next_comma = photos.find( ',', strqpos ); - const int old_quality = - get_quality_from_string( photos.substr( strqpos, next_comma ) ); - - if( quality > old_quality ) { - const std::string quality_s = string_format( "%d", quality ); - cata_assert( quality_s.size() == 1 ); - photos[strqpos] = quality_s.front(); - } - } - - } - eink.set_var( "EINK_MONSTER_PHOTOS", photos ); - } - } - const memory_card_info *mmd = mc.type->memory_card_data ? &*mc.type->memory_card_data : nullptr; - const bool failed_encrypted = mmd && mmd->data_chance < rng_float( 0.0, 1.0 ); - if( mmd && mmd->on_read_convert_to.is_valid() ) { - mc.clear_vars(); - mc.unset_flags(); - mc.convert( mmd->on_read_convert_to ); - } // mc is invalid past this point - if( !mmd || failed_encrypted ) { - encrypted_cards += failed_encrypted ? 1 : 0; - return; - } - if( mmd->photos_chance >= rng_float( 0.0, 1.0 ) ) { - const int new_photos = rng( 1, mmd->photos_amount ); - eink.set_var( "EIPC_PHOTOS", eink.get_var( "EIPC_PHOTOS", 0 ) + new_photos ); - downloaded_photos += new_photos; - } - if( mmd->songs_chance >= rng_float( 0.0, 1.0 ) ) { - const int new_songs = rng( 1, mmd->songs_amount ); - eink.set_var( "EIPC_MUSIC", eink.get_var( "EIPC_MUSIC", 0 ) + new_songs ); - downloaded_songs += new_songs; - } - if( mmd->recipes_chance >= rng_float( 0.0, 1.0 ) ) { - std::set saved_recipes = eink.get_saved_recipes(); - std::set candidates; - for( const auto& [rid, r] : recipe_dict ) { - if( r.never_learn || r.obsolete || mmd->recipes_categories.count( r.category ) == 0 || - saved_recipes.count( rid ) || - r.difficulty > mmd->recipes_level_max || r.difficulty < mmd->recipes_level_min || - ( r.has_flag( "SECRET" ) && !mmd->secret_recipes ) ) { - continue; - } - candidates.emplace( rid ); - } - - const int recipe_num = rng( 1, mmd->recipes_amount ); - for( int i = 0; i < recipe_num && !candidates.empty(); i++ ) { - const recipe_id rid = random_entry_removed( candidates ); - if( saved_recipes.emplace( rid ).second ) { - downloaded_recipes.emplace_back( rid ); - } else { - debugmsg( "failed saving '%s' to '%s'", rid.str(), eink.display_name() ); - } - } - eink.set_saved_recipes( saved_recipes ); - } -} - -static void print_data_handling_tally( Character &who, int encrypted_cards, int photos, int songs, - const std::vector &recipes, int extended_photos, int monster_photos ) -{ - if( !recipes.empty() ) { - who.add_msg_if_player( m_good, _( "Downloaded %d %s: %s." ), recipes.size(), - n_gettext( "recipe", "recipes", recipes.size() ), - enumerate_as_string( recipes, []( const recipe_id & rid ) { - return rid->result_name(); - } ) ); - } - if( monster_photos > 0 ) { - who.add_msg_if_player( m_good, _( "You have updated your monster collection." ) ); - } - if( extended_photos > 0 ) { - who.add_msg_if_player( m_good, _( "You have downloaded your photos." ) ); - } - if( encrypted_cards > 0 ) { - who.add_msg_if_player( m_bad, _( "%d %s appeared to be encrypted or corrupted." ), - encrypted_cards, n_gettext( "card", "cards", encrypted_cards ) ); - } - if( photos > 0 && who.is_avatar() ) { - who.add_msg_if_player( m_good, _( "Downloaded %d new %s." ), - photos, n_gettext( "photo", "photos", photos ) ); - } - if( songs > 0 && who.is_avatar() ) { - who.add_msg_if_player( m_good, _( "Downloaded %d new %s." ), - songs, n_gettext( "song", "songs", songs ) ); - } - if( !( photos || songs || monster_photos || extended_photos || !recipes.empty() ) ) { - who.add_msg_if_player( m_warning, _( "No new data has been discovered." ) ); - } -} - -void data_handling_activity_actor::canceled( player_activity &act, Character &p ) -{ - print_data_handling_tally( p, encrypted_cards, downloaded_photos, downloaded_songs, - downloaded_recipes, downloaded_extended_photos, downloaded_monster_photos ); - p.add_msg_if_player( m_info, _( "You stop downloading data after %d %s." ), - handled_cards, n_gettext( "card", "cards", handled_cards ) ); - act.set_to_null(); -} - -void data_handling_activity_actor::finish( player_activity &act, Character &p ) -{ - print_data_handling_tally( p, encrypted_cards, downloaded_photos, downloaded_songs, - downloaded_recipes, downloaded_extended_photos, downloaded_monster_photos ); - p.add_msg_if_player( m_info, _( "You finish downloading data from %d %s." ), - handled_cards, n_gettext( "card", "cards", handled_cards ) ); - act.set_to_null(); -} - -void data_handling_activity_actor::serialize( JsonOut &jsout ) const -{ - jsout.start_object(); - jsout.member( "recorder", recorder ); - jsout.member( "targets", targets ); - jsout.member( "time_until_next_action", time_until_next_card ); - jsout.member( "handled_cards", handled_cards ); - jsout.member( "encrypted_cards", encrypted_cards ); - jsout.member( "downloaded_photos", downloaded_photos ); - jsout.member( "downloaded_songs", downloaded_songs ); - jsout.member( "downloaded_recipes", downloaded_recipes ); - jsout.member( "downloaded_extended_photos", downloaded_extended_photos ); - jsout.member( "downloaded_monster_photos", downloaded_monster_photos ); - jsout.end_object(); -} - -std::unique_ptr data_handling_activity_actor::deserialize( JsonValue &jsin ) -{ - data_handling_activity_actor actor; - JsonObject jsobj = jsin.get_object(); - jsobj.read( "recorder", actor.recorder ); - jsobj.read( "targets", actor.targets ); - jsobj.read( "time_until_next_action", actor.time_until_next_card ); - jsobj.read( "handled_cards", actor.handled_cards ); - jsobj.read( "encrypted_cards", actor.encrypted_cards ); - jsobj.read( "downloaded_photos", actor.downloaded_photos ); - jsobj.read( "downloaded_songs", actor.downloaded_songs ); - jsobj.read( "downloaded_recipes", actor.downloaded_recipes ); - jsobj.read( "downloaded_extended_photos", actor.downloaded_extended_photos ); - jsobj.read( "downloaded_monster_photos", actor.downloaded_monster_photos ); - return actor.clone(); -} - void hotwire_car_activity_actor::start( player_activity &act, Character & ) { act.moves_total = moves_total; @@ -8838,7 +8612,6 @@ deserialize_functions = { { ACT_CONSUME, &consume_activity_actor::deserialize }, { ACT_CRACKING, &safecracking_activity_actor::deserialize }, { ACT_CRAFT, &craft_activity_actor::deserialize }, - { ACT_DATA_HANDLING, &data_handling_activity_actor::deserialize }, { ACT_DISABLE, &disable_activity_actor::deserialize }, { ACT_DISASSEMBLE, &disassemble_activity_actor::deserialize }, { ACT_DROP, &drop_activity_actor::deserialize }, diff --git a/src/activity_actor_definitions.h b/src/activity_actor_definitions.h index d23ef1de708b1..9bf14638e8cc7 100644 --- a/src/activity_actor_definitions.h +++ b/src/activity_actor_definitions.h @@ -309,46 +309,6 @@ class bookbinder_copy_activity_actor: public activity_actor static std::unique_ptr deserialize( JsonValue &jsin ); }; -class data_handling_activity_actor: public activity_actor -{ - public: - explicit data_handling_activity_actor() = default; - explicit data_handling_activity_actor( const item_location &, const std::vector & ); - - const activity_id &get_type() const override { - static const activity_id ACT_DATA_HANDLING( "ACT_DATA_HANDLING" ); - return ACT_DATA_HANDLING; - } - - bool can_resume_with_internal( const activity_actor &, const Character & ) const override { - return false; - } - - void start( player_activity &, Character & ) override; - void do_turn( player_activity &, Character & ) override; - void finish( player_activity &, Character & ) override; - void canceled( player_activity &, Character & ) override; - - std::unique_ptr clone() const override { - return std::make_unique( *this ); - } - - void serialize( JsonOut & ) const override; - static std::unique_ptr deserialize( JsonValue & ); - private: - static constexpr time_duration time_per_card = 1_minutes; - item_location recorder; - std::vector targets; - time_duration time_until_next_card = 0_seconds; - int handled_cards = 0; - int encrypted_cards = 0; - int downloaded_photos = 0; - int downloaded_songs = 0; - std::vector downloaded_recipes; - int downloaded_extended_photos = 0; - int downloaded_monster_photos = 0; -}; - class hotwire_car_activity_actor : public activity_actor { private: diff --git a/src/character_crafting.cpp b/src/character_crafting.cpp index 34ea4e01e38f5..7889a45f759d7 100644 --- a/src/character_crafting.cpp +++ b/src/character_crafting.cpp @@ -142,7 +142,7 @@ recipe_subset Character::get_recipes_from_ebooks( const inventory &crafting_inv for( const std::list *&stack : crafting_inv.const_slice() ) { const item &ereader = stack->front(); - if( !ereader.is_ebook_storage() || !ereader.ammo_sufficient( this ) || + if( !ereader.is_estorage() || !ereader.ammo_sufficient( this ) || ereader.is_broken_on_active() ) { continue; } diff --git a/src/character_inventory.cpp b/src/character_inventory.cpp index 00b7513ed97c2..9c8442a87b509 100644 --- a/src/character_inventory.cpp +++ b/src/character_inventory.cpp @@ -161,7 +161,7 @@ int Character::count_softwares( const itype_id &id ) { int count = 0; for( const item_location &it_loc : all_items_loc() ) { - if( it_loc->is_software_storage() ) { + if( it_loc->is_estorage() ) { for( const item *soft : it_loc->softwares() ) { if( soft->typeId() == id ) { count++; diff --git a/src/computer_session.cpp b/src/computer_session.cpp index f38639ffaa537..44242c56a68c0 100644 --- a/src/computer_session.cpp +++ b/src/computer_session.cpp @@ -298,14 +298,14 @@ bool computer_session::hack_attempt( Character &you, int Security ) const return successful_attempt; } -static item *pick_usb() +static item *pick_estorage( units::ememory can_hold_ememory ) { - auto filter = []( const item & it ) { - return it.typeId() == itype_usb_drive; + auto filter = [&can_hold_ememory]( const item & it ) { + return it.is_estorage() && it.remaining_ememory() >= can_hold_ememory; }; item_location loc = game_menus::inv::titled_filter_menu( filter, get_avatar(), - _( "Choose drive:" ) ); + _( "Choose device:" ) ); if( loc ) { return &*loc; } @@ -1025,20 +1025,22 @@ void computer_session::action_repeater_mod() void computer_session::action_download_software() { - if( item *const usb = pick_usb() ) { - mission *miss = mission::find( comp.mission_id ); - if( miss == nullptr ) { - debugmsg( _( "Computer couldn't find its mission!" ) ); - return; - } + mission *miss = mission::find( comp.mission_id ); + if( miss == nullptr ) { + debugmsg( _( "Computer couldn't find its mission!" ) ); + return; + } + item software( miss->get_item_id(), calendar::turn_zero ); + units::ememory downloaded_size = software.ememory_size(); + + if( item *const estorage = pick_estorage( downloaded_size ) ) { get_player_character().mod_moves( -to_moves( 1_seconds ) * 0.3 ); - item software( miss->get_item_id(), calendar::turn_zero ); software.mission_id = comp.mission_id; - usb->clear_items(); - usb->put_in( software, pocket_type::SOFTWARE ); - print_line( _( "Software downloaded." ) ); + estorage->put_in( software, pocket_type::E_FILE_STORAGE ); + print_line( string_format( _( "%s downloaded." ), software.tname() ) ); } else { - print_error( _( "USB drive required!" ) ); + print_error( string_format( _( "Electronic storage device with %s free required!" ), + units::display( downloaded_size ) ) ); } query_any(); } @@ -1074,14 +1076,16 @@ void computer_session::action_blood_anal() print_line( _( "Result: Unknown blood type. Unknown pathogen found." ) ); } print_line( _( "Pathogen bonded to erythrocytes and leukocytes." ) ); + item software( itype_software_blood_data, calendar::turn_zero ); + units::ememory downloaded_size = software.ememory_size(); if( query_bool( _( "Download data?" ) ) ) { - if( item *const usb = pick_usb() ) { + if( item *const estorage = pick_estorage( downloaded_size ) ) { item software( itype_software_blood_data, calendar::turn_zero ); - usb->clear_items(); - usb->put_in( software, pocket_type::SOFTWARE ); - print_line( _( "Software downloaded." ) ); + estorage->put_in( software, pocket_type::E_FILE_STORAGE ); + print_line( string_format( _( "%s downloaded." ), software.tname() ) ); } else { - print_error( _( "USB drive required!" ) ); + print_error( string_format( _( "Electronic storage device with %s free required!" ), + units::display( downloaded_size ) ) ); } } } else { diff --git a/src/crafting.cpp b/src/crafting.cpp index 69eb9b4193241..d327b5c733ba3 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -2178,7 +2178,7 @@ bool Character::consume_software_container( const itype_id &software_id ) if( !it.get_item() ) { continue; } - if( it.get_item()->is_software_storage() ) { + if( it.get_item()->is_estorage() ) { for( const item *soft : it.get_item()->softwares() ) { if( soft->typeId() == software_id ) { it.remove_item(); diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 3b975263a37c3..a3c2b2bdde2d9 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -1355,7 +1355,7 @@ class ereader_inventory_preset : public pickup_inventory_preset } bool is_shown( const item_location &loc ) const override { - return loc->is_ebook_storage(); + return loc->is_estorage(); } std::string get_denial( const item_location &loc ) const override { @@ -1463,7 +1463,7 @@ class read_inventory_preset: public pickup_inventory_preset const item_location p_loc = loc.parent_item(); return ( loc->is_book() || loc->type->can_use( "learn_spell" ) ) && - ( p_loc.where() == item_location::type::invalid || !p_loc->is_ebook_storage() || + ( p_loc.where() == item_location::type::invalid || !p_loc->is_estorage() || !p_loc->uses_energy() || p_loc->energy_remaining( p_loc.carrier(), false ) >= 1_kJ ); } @@ -1678,7 +1678,8 @@ drop_locations game_menus::inv::edevice_select( Character &who, item_location &u bool has_use_check = !unusable_only || !efile_activity_actor::edevice_has_use( loc.get_item() ); bool browsed_equal_check = browse_equals == loc->is_browsed(); bool fast_transfer = compat == efile_activity_actor::edevice_compatible::ECOMPAT_FAST; - bool compatible_check = browse_equals || //if browsing, no compatibility check + bool compatible_check = ( action == EF_BROWSE && browse_equals ) || + //if browsing, no compatibility check ( action == EF_READ && fast_transfer ) || //if reading, only fast-compatible edevices compat != efile_activity_actor::edevice_compatible::ECOMPAT_NONE; //otherwise, any compatible edevice bool preset_bool = is_tool_has_charge && diff --git a/src/inventory_ui.cpp b/src/inventory_ui.cpp index 7d478f22d79d2..23ea3432f0715 100644 --- a/src/inventory_ui.cpp +++ b/src/inventory_ui.cpp @@ -2073,7 +2073,7 @@ void inventory_selector::add_contained_gunmods( Character &you, item &gun ) void inventory_selector::add_contained_ebooks( item_location &container ) { - if( !container->is_ebook_storage() ) { + if( !container->is_estorage() ) { return; } diff --git a/src/item.cpp b/src/item.cpp index aa499b320587c..565c75307d774 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -162,6 +162,7 @@ static const item_category_id item_category_container( "container" ); static const item_category_id item_category_drugs( "drugs" ); static const item_category_id item_category_food( "food" ); static const item_category_id item_category_maps( "maps" ); +static const item_category_id item_category_software( "software" ); static const item_category_id item_category_spare_parts( "spare_parts" ); static const item_category_id item_category_tools( "tools" ); static const item_category_id item_category_weapons( "weapons" ); @@ -1290,10 +1291,6 @@ item item::in_container( const itype_id &cont, int qty, bool sealed, } container.add_automatic_whitelist(); return container; - } else if( is_software() && container.is_software_storage() ) { - container.put_in( *this, pocket_type::SOFTWARE ); - container.invlet = invlet; - return container; } return *this; } @@ -4995,7 +4992,7 @@ void item::tool_info( std::vector &info, const iteminfo_query *parts, } // Display e-ink tablet ebook recipes - if( is_ebook_storage() && !is_broken_on_active() ) { + if( is_estorage() && !is_broken_on_active() ) { std::vector known_recipe_list; std::vector learnable_recipe_list; std::vector unlearnable_recipe_list; @@ -8828,24 +8825,6 @@ bool item::is_cash_card() const return typeId() == itype_cash_card; } -bool item::is_software() const -{ - if( const std::optional &cont = type->default_container ) { - return item( *cont ).is_software_storage(); - } - return false; -} - -bool item::is_software_storage() const -{ - return contents.has_pocket_type( pocket_type::SOFTWARE ); -} - -bool item::is_ebook_storage() const -{ - return contents.has_pocket_type( pocket_type::EBOOK ); -} - bool item::is_estorage() const { return contents.has_pocket_type( pocket_type::E_FILE_STORAGE ); @@ -8872,7 +8851,7 @@ void item::set_browsed( bool browsed ) bool item::is_ecopiable() const { - return has_flag( flag_E_COPIABLE ) || ( type->book && type->book->chapters == 0 ); + return has_flag( flag_E_COPIABLE ) || ( is_book() && get_chapters() == 0 ); } bool item::efiles_all_browsed() const @@ -8990,6 +8969,11 @@ int item::total_photos() const return extended_photos.size(); } +bool item::is_software() const +{ + return type->category_force == item_category_software; +} + bool item::is_maybe_melee_weapon() const { item_category_id my_cat_id = get_category_shallow().id; @@ -10743,7 +10727,7 @@ book_proficiency_bonuses item::get_book_proficiency_bonuses() const { book_proficiency_bonuses ret; - if( is_ebook_storage() ) { + if( is_estorage() ) { for( const item *book : ebooks() ) { ret += book->get_book_proficiency_bonuses(); } @@ -15719,8 +15703,7 @@ item const *item::this_or_single_content() const bool item::contents_only_one_type() const { std::list const items = contents.all_items_top( []( item_pocket const & pkt ) { - return pkt.is_type( pocket_type::CONTAINER ) || - pkt.is_type( pocket_type::SOFTWARE ); + return pkt.is_type( pocket_type::CONTAINER ); } ); return items.size() == 1 || ( items.size() > 1 && @@ -15766,8 +15749,7 @@ item::aggregate_t item::aggregated_contents( int depth, int maxdepth ) const aggregate_t *running_max{}; aggregate_t *max_type{}; auto const cont_and_soft = []( item_pocket const & pkt ) { - return pkt.is_type( pocket_type::CONTAINER ) || pkt.is_type( pocket_type::SOFTWARE ) || - pkt.is_type( pocket_type::E_FILE_STORAGE ); + return pkt.is_type( pocket_type::CONTAINER ) || pkt.is_type( pocket_type::E_FILE_STORAGE ); }; diff --git a/src/item.h b/src/item.h index a523d82068fe2..60db8900668e8 100644 --- a/src/item.h +++ b/src/item.h @@ -358,10 +358,7 @@ class item : public visitable public: bool is_cash_card() const; - bool is_software() const; - bool is_software_storage() const; - bool is_ebook_storage() const; bool is_estorage() const; bool is_estorable() const; bool is_browsed() const; @@ -388,6 +385,8 @@ class item : public visitable const item *get_photo_gallery() const; /** @return total number of photos this item holds */ int total_photos() const; + /** @return does this item have category `software`?*/ + bool is_software() const; /** * Checks whether the item's components (and sub-components if deep_search) are food items diff --git a/src/item_contents.cpp b/src/item_contents.cpp index 8daf0d853f59f..e2509c7381a3b 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -689,8 +689,6 @@ void item_contents::combine( const item_contents &read_input, const bool convert pocket.is_type( pocket_type::CORPSE ) || pocket.is_type( pocket_type::MAGAZINE ) || pocket.is_type( pocket_type::MAGAZINE_WELL ) || - pocket.is_type( pocket_type::SOFTWARE ) || - pocket.is_type( pocket_type::EBOOK ) || pocket.is_type( pocket_type::E_FILE_STORAGE ) ) { ++pocket_index; for( const item *it : pocket.all_items_top() ) { @@ -1623,8 +1621,7 @@ item &item_contents::only_item() const item &item_contents::first_item() const { for( const item_pocket &pocket : contents ) { - if( pocket.empty() || !( pocket.is_type( pocket_type::CONTAINER ) || - pocket.is_type( pocket_type::SOFTWARE ) ) ) { + if( pocket.empty() || !pocket.is_type( pocket_type::CONTAINER ) ) { continue; } // the first item we come to is the only one. @@ -1863,9 +1860,11 @@ std::vector item_contents::softwares() const { std::vector softwares; for( const item_pocket &pocket : contents ) { - if( pocket.is_type( pocket_type::SOFTWARE ) ) { + if( pocket.is_type( pocket_type::E_FILE_STORAGE ) ) { for( const item *it : pocket.all_items_top() ) { - softwares.insert( softwares.end(), it ); + if( it->is_software() ) { + softwares.insert( softwares.end(), it ); + } } } } @@ -1876,9 +1875,11 @@ std::vector item_contents::ebooks() { std::vector ebooks; for( item_pocket &pocket : contents ) { - if( pocket.is_type( pocket_type::EBOOK ) ) { + if( pocket.is_type( pocket_type::E_FILE_STORAGE ) ) { for( item *it : pocket.all_items_top() ) { - ebooks.emplace_back( it ); + if( it->is_book() ) { + ebooks.emplace_back( it ); + } } } } @@ -1889,9 +1890,11 @@ std::vector item_contents::ebooks() const { std::vector ebooks; for( const item_pocket &pocket : contents ) { - if( pocket.is_type( pocket_type::EBOOK ) ) { + if( pocket.is_type( pocket_type::E_FILE_STORAGE ) ) { for( const item *it : pocket.all_items_top() ) { - ebooks.emplace_back( it ); + if( it->is_book() ) { + ebooks.emplace_back( it ); + } } } } diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 696c77ba72677..ecc7d985c7534 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1759,10 +1759,7 @@ void Item_factory::init() add_iuse( "EHANDCUFFS", &iuse::ehandcuffs ); add_iuse( "EHANDCUFFS_TICK", &iuse::ehandcuffs_tick ); add_iuse( "EPIC_MUSIC", &iuse::epic_music ); - add_iuse( "EINKTABLETPC", &iuse::einktabletpc ); - add_iuse( "ELECTRICSTORAGE", &iuse::electricstorage ); add_iuse( "EBOOKSAVE", &iuse::ebooksave ); - add_iuse( "EBOOKREAD", &iuse::ebookread ); add_iuse( "EMF_PASSIVE_ON", &iuse::emf_passive_on ); add_iuse( "EXTINGUISHER", &iuse::extinguisher ); add_iuse( "EYEDROPS", &iuse::eyedrops ); diff --git a/src/item_group.cpp b/src/item_group.cpp index 9d2dbfdbf0f67..af79b5593ece5 100644 --- a/src/item_group.cpp +++ b/src/item_group.cpp @@ -97,9 +97,6 @@ static pocket_type guess_pocket_for( const item &container, const item &payload payload.is_toolmod() ) ) { return pocket_type::MOD; } - if( container.is_software_storage() && payload.is_software() ) { - return pocket_type::SOFTWARE; - } if( ( container.is_gun() || container.is_tool() ) && payload.is_magazine() ) { return pocket_type::MAGAZINE_WELL; } else if( container.is_magazine() && payload.is_ammo() ) { diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 72e9940873478..e2ff9e18deb2a 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -637,7 +637,7 @@ units::mass item_pocket::item_weight_modifier() const units::length item_pocket::item_length_modifier() const { - if( is_type( pocket_type::EBOOK ) || is_type( pocket_type::E_FILE_STORAGE ) ) { + if( is_type( pocket_type::E_FILE_STORAGE ) ) { return 0_mm; } units::length total_length = 0_mm; @@ -1329,16 +1329,6 @@ ret_val item_pocket::is_compatible( const item &it ) // we simply don't want them to "spill" return ret_val::make_success(); } - - if( data->type == pocket_type::SOFTWARE ) { - if( it.has_flag( flag_NO_DROP ) && it.has_flag( flag_IRREMOVABLE ) ) { - return ret_val::make_success(); - } else { - return ret_val::make_failure( - contain_code::ERR_MOD, _( "only immaterial items can go into software pocket" ) ); - } - } - if( data->type == pocket_type::E_FILE_STORAGE ) { if( it.is_estorable() ) { return ret_val::make_success(); @@ -1348,15 +1338,6 @@ ret_val item_pocket::is_compatible( const item &it ) } } - if( data->type == pocket_type::EBOOK ) { - if( it.is_book() ) { - return ret_val::make_success(); - } else { - return ret_val::make_failure( - contain_code::ERR_MOD, _( "only books can go into ebook pocket" ) ); - } - } - if( data->type == pocket_type::CABLE ) { if( it.has_flag( flag_CABLE_SPOOL ) ) { return ret_val::make_success(); @@ -1795,7 +1776,7 @@ static void move_to_parent_pocket_recursive( const tripoint_bub_ms &pos, item &i void item_pocket::overflow( const tripoint_bub_ms &pos, const item_location &loc ) { if( is_type( pocket_type::MOD ) || is_type( pocket_type::CORPSE ) || - is_type( pocket_type::EBOOK ) || is_type( pocket_type::CABLE ) || + is_type( pocket_type::CABLE ) || is_type( pocket_type::E_FILE_STORAGE ) ) { return; } @@ -1919,7 +1900,7 @@ void item_pocket::on_contents_changed() bool item_pocket::spill_contents( const tripoint_bub_ms &pos ) { - if( is_type( pocket_type::EBOOK ) || is_type( pocket_type::E_FILE_STORAGE ) || + if( is_type( pocket_type::E_FILE_STORAGE ) || is_type( pocket_type::CORPSE ) || is_type( pocket_type::CABLE ) ) { return false; } diff --git a/src/iuse.cpp b/src/iuse.cpp index 7c0230dcb8b69..43555c0979d4b 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -326,7 +326,6 @@ static const morale_type morale_game( "morale_game" ); static const morale_type morale_game_found_kitten( "morale_game_found_kitten" ); static const morale_type morale_marloss( "morale_marloss" ); static const morale_type morale_music( "morale_music" ); -static const morale_type morale_photos( "morale_photos" ); static const morale_type morale_pyromania_nofire( "morale_pyromania_nofire" ); static const morale_type morale_pyromania_startfire( "morale_pyromania_startfire" ); static const morale_type morale_wet( "morale_wet" ); @@ -393,7 +392,6 @@ static const trait_id trait_MARLOSS_AVOID( "MARLOSS_AVOID" ); static const trait_id trait_MARLOSS_BLUE( "MARLOSS_BLUE" ); static const trait_id trait_MARLOSS_YELLOW( "MARLOSS_YELLOW" ); static const trait_id trait_M_DEPENDENT( "M_DEPENDENT" ); -static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" ); static const trait_id trait_PYROMANIA( "PYROMANIA" ); static const trait_id trait_SPIRITUAL( "SPIRITUAL" ); static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" ); @@ -5621,225 +5619,6 @@ std::optional iuse::epic_music( Character *p, item *it, const tripoint_bub_ return std::nullopt; } -std::optional iuse::einktabletpc( Character *p, item *it, const tripoint_bub_ms & ) -{ - - if( p->cant_do_mounted() ) { - return std::nullopt; - } else if( !p->is_npc() ) { - - enum { - ei_invalid, ei_photo, ei_music, ei_recipe, ei_uploaded_photos, ei_monsters, ei_download, - }; - - if( p->cant_do_underwater() ) { - return std::nullopt; - } - if( p->has_trait( trait_ILLITERATE ) ) { - p->add_msg_if_player( m_info, _( "You can't read a computer screen." ) ); - return std::nullopt; - } - if( p->has_flag( json_flag_HYPEROPIC ) && !p->worn_with_flag( flag_FIX_FARSIGHT ) && - !p->has_effect( effect_contacts ) && !p->has_effect( effect_transition_contacts ) && - !p->has_flag( json_flag_ENHANCED_VISION ) ) { - p->add_msg_if_player( m_info, - _( "You'll need to put on reading glasses before you can see the screen." ) ); - return std::nullopt; - } - - if( !it->active ) { - it->erase_var( "EIPC_MUSIC_ON" ); - } - uilist amenu; - - amenu.text = _( "Choose menu option:" ); - - const int photos = it->get_var( "EIPC_PHOTOS", 0 ); - if( photos > 0 ) { - amenu.addentry( ei_photo, true, 'p', _( "Unsorted photos [%d]" ), photos ); - } else { - amenu.addentry( ei_photo, false, 'p', _( "No photos on device" ) ); - } - - const int songs = it->get_var( "EIPC_MUSIC", 0 ); - if( songs > 0 ) { - if( it->has_var( "EIPC_MUSIC_ON" ) ) { - amenu.addentry( ei_music, true, 'm', _( "Turn music off" ) ); - } else { - amenu.addentry( ei_music, true, 'm', _( "Turn music on [%d]" ), songs ); - } - } else { - amenu.addentry( ei_music, false, 'm', _( "No music on device" ) ); - } - - if( !it->get_saved_recipes().empty() ) { - amenu.addentry( ei_recipe, true, 'r', _( "List stored recipes" ) ); - } - - if( !it->get_var( "EIPC_EXTENDED_PHOTOS" ).empty() ) { - amenu.addentry( ei_uploaded_photos, true, 'l', _( "Your photos" ) ); - } - - if( !it->get_var( "EINK_MONSTER_PHOTOS" ).empty() ) { - amenu.addentry( ei_monsters, true, 'y', _( "Your collection of monsters" ) ); - } else { - amenu.addentry( ei_monsters, false, 'y', _( "Collection of monsters is empty" ) ); - } - - amenu.addentry( ei_download, true, 'w', _( "Download data from memory cards" ) ); - amenu.query(); - - const int choice = amenu.ret; - - if( ei_photo == choice ) { - - const int photos = it->get_var( "EIPC_PHOTOS", 0 ); - const int viewed = std::min( photos, static_cast( rng( 10, 30 ) ) ); - const int count = photos - viewed; - if( count == 0 ) { - it->erase_var( "EIPC_PHOTOS" ); - } else { - it->set_var( "EIPC_PHOTOS", count ); - } - - p->mod_moves( -to_moves( rng( 3_seconds, 7_seconds ) ) ); - - if( p->has_trait( trait_PSYCHOPATH ) ) { - p->add_msg_if_player( m_info, _( "Wasted time. These pictures do not provoke your senses." ) ); - } else { - p->add_morale( morale_photos, rng( 15, 30 ), 100 ); - p->add_msg_if_player( m_good, "%s", - SNIPPET.random_from_category( "examine_photo_msg" ).value_or( translation() ) ); - } - - return 1; - } - - if( ei_music == choice ) { - - p->mod_moves( -to_moves( 1_seconds ) * 0.3 ); - // Turn on the screen before playing musics - if( !it->active ) { - if( it->is_transformable() ) { - const use_function *readinglight = it->type->get_use( "transform" ); - if( readinglight ) { - readinglight->call( p, *it, p->pos_bub() ); - } - } - it->activate(); - } - // If transformable we use transform action to turn off the device - else if( !it->is_transformable() ) { - it->deactivate(); - } - - if( it->has_var( "EIPC_MUSIC_ON" ) ) { - it->erase_var( "EIPC_MUSIC_ON" ); - - p->add_msg_if_player( m_info, _( "You turned off the music on your %s." ), it->tname() ); - } else { - it->set_var( "EIPC_MUSIC_ON", "1" ); - p->add_msg_if_player( m_info, _( "You turned on the music on your %s." ), it->tname() ); - } - - return 1; - } - - if( ei_recipe == choice ) { - p->mod_moves( -to_moves( 1_seconds ) * 0.5 ); - - uilist rmenu; - for( const recipe_id &rid : it->get_saved_recipes() ) { - rmenu.addentry( 0, true, 0, rid->result_name( /* decorated = */ true ) ); - } - - rmenu.text = _( "List recipes:" ); - rmenu.query(); - - return 1; - } - - if( ei_uploaded_photos == choice ) { - show_photo_selection( *p, *it, "EIPC_EXTENDED_PHOTOS" ); - return 1; - } - - if( ei_monsters == choice ) { - - uilist pmenu; - - pmenu.text = _( "Your collection of monsters:" ); - - std::vector monster_photos; - - std::istringstream f( it->get_var( "EINK_MONSTER_PHOTOS" ) ); - std::string s; - int k = 0; - while( getline( f, s, ',' ) ) { - if( s.empty() ) { - continue; - } - monster_photos.emplace_back( s ); - std::string menu_str; - const monster dummy( monster_photos.back() ); - menu_str = dummy.name(); - getline( f, s, ',' ); - const int quality = get_quality_from_string( s ); - menu_str += " [" + photo_quality_name( quality ) + "]"; - pmenu.addentry( k++, true, -1, menu_str.c_str() ); - } - - int choice; - do { - pmenu.query(); - choice = pmenu.ret; - - if( choice < 0 ) { - break; - } - - const monster dummy( monster_photos[choice] ); - popup( dummy.type->get_description() ); - } while( true ); - return 1; - } - - if( ei_download == choice ) { - if( !p->has_item( *it ) ) { - p->add_msg_if_player( m_info, _( "You don't have that item!" ) ); - return std::nullopt; // need posession of reader item for item_location to work right - } - if( !p->is_avatar() ) { - return std::nullopt; // npc triggered iuse? - } - inventory_filter_preset preset( []( const item_location & it ) { - return it->has_flag( flag_MC_HAS_DATA ) || it->type->memory_card_data; - } ); - inventory_multiselector inv_s( *p, preset ); - - inv_s.set_title( _( "Choose memory cards to download data from:" ) ); - inv_s.set_display_stats( true ); - inv_s.add_character_items( *p ); - inv_s.add_nearby_items( 1 ); - - const std::list> locs = inv_s.execute(); - if( locs.empty() ) { - p->add_msg_if_player( m_info, _( "Nevermind." ) ); - return std::nullopt; - } - std::vector targets; - targets.reserve( locs.size() ); - for( const auto& [item_loc, count] : locs ) { - targets.emplace_back( item_loc ); - } - const item_location reader( *p, it ); - const data_handling_activity_actor actor( reader, targets ); - p->assign_activity( player_activity( actor ) ); - } - } - return std::nullopt; -} - std::optional iuse::efiledevice( Character *p, item *it, const tripoint_bub_ms & ) { //restrictions @@ -9166,134 +8945,6 @@ std::optional iuse::change_outfit( Character *p, item *it, const tripoint_b return std::nullopt; } -std::optional iuse::electricstorage( Character *p, item *it, const tripoint_bub_ms & ) -{ - // From item processing - if( !p ) { - debugmsg( "%s called action electricstorage that requires character but no character is present", - it->typeId().str() ); - return std::nullopt; - } - - if( p->is_npc() ) { - return std::nullopt; - } - - if( p->is_underwater() ) { - p->add_msg_if_player( m_info, _( "Unfortunately your device is not waterproof." ) ); - return std::nullopt; - } - - if( !it->is_ebook_storage() ) { - debugmsg( "ELECTRICSTORAGE iuse called on item without ebook type pocket" ); - return std::nullopt; - } - - if( p->has_flag( json_flag_HYPEROPIC ) && !p->worn_with_flag( flag_FIX_FARSIGHT ) && - !p->has_effect( effect_contacts ) && !p->has_effect( effect_transition_contacts ) && - !p->has_flag( json_flag_ENHANCED_VISION ) ) { - p->add_msg_if_player( m_info, - _( "You'll need to put on reading glasses before you can see the screen." ) ); - return std::nullopt; - } - - auto filter = [it]( const item & itm ) { - return !itm.is_broken() && - &itm != it && - itm.has_pocket_type( pocket_type::EBOOK ); - }; - - item_location storage_card = game_menus::inv::titled_filter_menu( - filter, *p->as_avatar(), _( "Use what storage device?" ), - -1, _( "You don't have any empty book storage devices." ) ); - - if( !storage_card ) { - return std::nullopt; - } - - // list of books of from_it that are not in to_it - auto book_difference = []( const item & from_it, const item & to_it ) -> std::vector { - std::set existing_ebooks; - for( const item *ebook : to_it.ebooks() ) - { - if( !ebook->is_book() ) { - debugmsg( "ebook type pocket contains non-book item %s", ebook->typeId().str() ); - continue; - } - - existing_ebooks.insert( ebook->typeId() ); - } - - std::vector ebooks; - for( const item *ebook : from_it.ebooks() ) - { - if( !ebook->is_book() ) { - debugmsg( "ebook type pocket contains non-book item %s", ebook->typeId().str() ); - continue; - } - - if( existing_ebooks.count( ebook->typeId() ) ) { - continue; - } - - ebooks.emplace_back( ebook ); - } - return ebooks; - }; - - std::vector to_storage = book_difference( *it, *storage_card ); - std::vector to_device = book_difference( *storage_card, *it ); - - uilist smenu; - smenu.text = _( "What to do with your storage devices:" ); - - smenu.addentry( 1, !to_device.empty(), 't', _( "Copy to device from the card" ) ); - smenu.addentry( 2, !to_storage.empty(), 'f', _( "Copy from device to the card" ) ); - smenu.addentry( 3, !storage_card->ebooks().empty(), 'v', _( "View books in the card" ) ); - smenu.query(); - - // were any books moved to or from the device - int books_moved = 0; - - auto move_books = [&books_moved]( const std::vector &fromset, item & toit ) -> void { - books_moved = fromset.size(); - for( const item *ebook : fromset ) - { - toit.put_in( *ebook, pocket_type::EBOOK ); - } - }; - - if( smenu.ret == 1 ) { - // to device - move_books( to_device, *it ); - } else if( smenu.ret == 2 ) { - // from device - move_books( to_storage, *storage_card ); - } else if( smenu.ret == 3 ) { - game_menus::inv::ebookread( *p, storage_card ); - return std::nullopt; - } else { - return std::nullopt; - } - - if( books_moved > 0 ) { - p->mod_moves( -to_moves( 2_seconds ) ); - if( smenu.ret == 1 ) { - p->add_msg_if_player( m_info, - n_gettext( "Copied one book to the device.", - "Copied %1$s books to the device.", books_moved ), - books_moved ); - } else if( smenu.ret == 2 ) { - p->add_msg_if_player( m_info, - n_gettext( "Copied one book to the %2$s.", - "Copied %1$s books to the %2$s.", books_moved ), - books_moved, storage_card->tname() ); - } - } - - return std::nullopt; -} - std::optional iuse::ebooksave( Character *p, item *it, const tripoint_bub_ms & ) { if( !p ) { @@ -9342,55 +8993,6 @@ std::optional iuse::ebooksave( Character *p, item *it, const tripoint_bub_m return std::nullopt; } -std::optional iuse::ebookread( Character *p, item *it, const tripoint_bub_ms & ) -{ - if( !p ) { - debugmsg( "%s called action ebookread that requires character but no character is present", - it->typeId().str() ); - return std::nullopt; - } - if( !it->is_ebook_storage() ) { - debugmsg( "EBOOKREAD iuse called on item without ebook type pocket" ); - return std::nullopt; - } - - if( p->is_npc() ) { - return std::nullopt; - } - - if( p->is_underwater() ) { - p->add_msg_if_player( m_info, _( "Unfortunately your device is not waterproof." ) ); - return std::nullopt; - } - - if( p->has_flag( json_flag_HYPEROPIC ) && !p->worn_with_flag( flag_FIX_FARSIGHT ) && - !p->has_effect( effect_contacts ) && !p->has_effect( effect_transition_contacts ) && - !p->has_flag( json_flag_ENHANCED_VISION ) ) { - p->add_msg_if_player( m_info, - _( "You'll need to put on reading glasses before you can see the screen." ) ); - return std::nullopt; - } - - // Only turn on the eBook light, if it's too dark to read - if( p->fine_detail_vision_mod() > 4 && !it->active && it->is_transformable() ) { - const use_function *readinglight = it->type->get_use( "transform" ); - if( readinglight ) { - readinglight->call( p, *it, p->pos_bub() ); - } - } - - item_location ereader = item_location( *p, it ); - item_location book = game_menus::inv::ebookread( *p, ereader ); - - if( !book ) { - return std::nullopt; - } - - p->as_avatar()->read( book, ereader ); - - return std::nullopt; -} - std::optional iuse::binder_add_recipe( Character *p, item *binder, const tripoint_bub_ms & ) { if( p->cant_do_mounted() ) { diff --git a/src/iuse.h b/src/iuse.h index b021b9815633f..357e2ff86c700 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -104,7 +104,6 @@ std::optional dog_whistle( Character *, item *, const tripoint_bub_ms & ); std::optional ehandcuffs( Character *, item *, const tripoint_bub_ms & ); std::optional ehandcuffs_tick( Character *, item *, const tripoint_bub_ms & ); std::optional epic_music( Character *, item *, const tripoint_bub_ms & ); -std::optional einktabletpc( Character *, item *, const tripoint_bub_ms & ); std::optional emf_passive_on( Character *, item *, const tripoint_bub_ms & ); std::optional extinguisher( Character *, item *, const tripoint_bub_ms & ); std::optional fill_pit( Character *, item *, const tripoint_bub_ms & ); @@ -139,9 +138,7 @@ std::optional ma_manual( Character *, item *, const tripoint_bub_ms & ); std::optional magic_8_ball( Character *, item *, const tripoint_bub_ms & ); std::optional measure_resonance( Character *, item *, const tripoint_bub_ms & ); std::optional change_outfit( Character *, item *, const tripoint_bub_ms & ); -std::optional electricstorage( Character *, item *, const tripoint_bub_ms & ); std::optional ebooksave( Character *, item *, const tripoint_bub_ms & ); -std::optional ebookread( Character *, item *, const tripoint_bub_ms & ); std::optional makemound( Character *, item *, const tripoint_bub_ms & ); std::optional mace( Character *, item *, const tripoint_bub_ms & ); std::optional manage_exosuit( Character *, item *, const tripoint_bub_ms & ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 4b9168f3ce8a1..9c2055923afdb 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -3110,7 +3110,7 @@ void item::migrate_content_item( const item &contained ) put_in( contained, pocket_type::MOD ); } else if( typeId() == itype_usb_drive ) { // as of this migration, only usb_drive has any software in it. - put_in( contained, pocket_type::SOFTWARE ); + put_in( contained, pocket_type::E_FILE_STORAGE ); } else if( contents.insert_item( contained, pocket_type::MAGAZINE ).success() || contents.insert_item( contained, pocket_type::MAGAZINE_WELL ).success() ) { // left intentionally blank diff --git a/tests/item_pocket_test.cpp b/tests/item_pocket_test.cpp index d7ab5401a4888..b24e65edd346d 100644 --- a/tests/item_pocket_test.cpp +++ b/tests/item_pocket_test.cpp @@ -1789,7 +1789,7 @@ TEST_CASE( "usb_drives_and_software", "[pocket][software]" ) item software( itype_software_math ); // USB drives aren't containers, and cannot "contain" software, but software can be inserted CHECK_FALSE( usb.can_contain( software ).success() ); - CHECK( usb.put_in( software, pocket_type::SOFTWARE ).success() ); + CHECK( usb.put_in( software, pocket_type::E_FILE_STORAGE ).success() ); } static void test_pickup_autoinsert_results( Character &u, bool wear, const item_location &nested, diff --git a/tests/item_test.cpp b/tests/item_test.cpp index 93a94c57ec39a..6263e2f0e8993 100644 --- a/tests/item_test.cpp +++ b/tests/item_test.cpp @@ -332,7 +332,7 @@ static void check_spawning_in_container( const itype_id &item_type ) return it.typeId() == test_item.typeId(); } ) ); } else if( test_item.is_software() ) { - REQUIRE( container_item.is_software_storage() ); + REQUIRE( container_item.is_estorage() ); const std::vector softwares = container_item.softwares(); CHECK( !softwares.empty() ); for( const item *itm : softwares ) { @@ -1034,7 +1034,7 @@ TEST_CASE( "item_single_type_contents", "[item]" ) item usb_drive( itype_usb_drive ); item software_hacking( itype_software_hacking ); REQUIRE( usb_drive.get_category_of_contents().id == item_category_tools ); - REQUIRE( usb_drive.put_in( software_hacking, pocket_type::SOFTWARE ).success() ); + REQUIRE( usb_drive.put_in( software_hacking, pocket_type::E_FILE_STORAGE ).success() ); CHECK( usb_drive.get_category_of_contents().id == item_category_tools ); } } diff --git a/tests/reading_test.cpp b/tests/reading_test.cpp index efa3d0a34ca56..16b5ec2d40cc3 100644 --- a/tests/reading_test.cpp +++ b/tests/reading_test.cpp @@ -503,7 +503,7 @@ TEST_CASE( "reading_a_book_with_an_ebook_reader", "[reading][book][ereader]" ) item_location ereader = dummy.i_add( item( itype_test_ebook_reader ) ); item book( itype_test_textbook_fabrication ); - ereader->put_in( book, pocket_type::EBOOK ); + ereader->put_in( book, pocket_type::E_FILE_STORAGE ); item battery( itype_test_battery_disposable ); battery.ammo_set( battery.ammo_default(), 100 );