From c69d1119ba449a4671ecd157c7f8a57b3bf3b675 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 13:46:06 +0800 Subject: [PATCH 01/14] Fix translation update - skill names --- src/skill.cpp | 16 +++++++++------- src/skill.h | 17 +++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/skill.cpp b/src/skill.cpp index eb26133108005..fb08305aaa92a 100644 --- a/src/skill.cpp +++ b/src/skill.cpp @@ -46,15 +46,15 @@ bool string_id::is_valid() const return &obj() != &invalid_skill; } -Skill::Skill() : Skill( skill_id::NULL_ID(), "nothing", "The zen-most skill there is.", +Skill::Skill() : Skill( skill_id::NULL_ID(), translation( "nothing" ), + translation( "The zen-most skill there is." ), std::set {} ) { } -Skill::Skill( skill_id ident, std::string name, std::string description, - std::set tags ) - : _ident( std::move( ident ) ), _name( std::move( name ) ), - _description( std::move( description ) ), _tags( std::move( tags ) ) +Skill::Skill( const skill_id &ident, const translation &name, const translation &description, + const std::set &tags ) + : _ident( ident ), _name( name ), _description( description ), _tags( tags ) { } @@ -88,8 +88,10 @@ void Skill::load_skill( JsonObject &jsobj ) return s._ident == ident; } ), end( skills ) ); - const Skill sk( ident, _( jsobj.get_string( "name" ) ), _( jsobj.get_string( "description" ) ), - jsobj.get_tags( "tags" ) ); + translation name, desc; + jsobj.read( "name", name ); + jsobj.read( "description", desc ); + const Skill sk( ident, name, desc, jsobj.get_tags( "tags" ) ); if( sk.is_contextual_skill() ) { contextual_skills[sk.ident()] = sk; diff --git a/src/skill.h b/src/skill.h index 2dfc5daddcae1..991c53934a3da 100644 --- a/src/skill.h +++ b/src/skill.h @@ -10,6 +10,7 @@ #include "calendar.h" #include "string_id.h" +#include "translations.h" #include "type_id.h" class JsonObject; @@ -23,8 +24,8 @@ class Skill friend class string_id; skill_id _ident; - std::string _name; - std::string _description; + translation _name; + translation _description; std::set _tags; // these are not real skills, they depend on context static std::map contextual_skills; @@ -42,17 +43,17 @@ class Skill std::function pred ); Skill(); - Skill( skill_id ident, std::string name, std::string description, - std::set tags ); + Skill( const skill_id &ident, const translation &name, const translation &description, + const std::set &tags ); const skill_id &ident() const { return _ident; } - const std::string &name() const { - return _name; + std::string name() const { + return _name.translated(); } - const std::string &description() const { - return _description; + std::string description() const { + return _description.translated(); } bool operator==( const Skill &b ) const { From 77734c3aae680fe9709ad3e2871e8568a68ec165 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 15:49:07 +0800 Subject: [PATCH 02/14] Fix translation update - bionic names/descriptions --- src/activity_handlers.cpp | 20 +++++++++--------- src/bionics.cpp | 43 +++++++++++++++++++-------------------- src/bionics.h | 5 +++-- src/bionics_ui.cpp | 4 ++-- src/game_inventory.cpp | 2 +- src/handle_action.cpp | 2 +- src/player.h | 6 ++---- src/player_display.cpp | 8 ++++---- 8 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 373a316ff6108..7e7c3aa9f5663 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2881,9 +2881,9 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) - values[3]: pl_skill - values[4] and above: occupied body_parts - str_values[0]: install/uninstall - - str_values[1]: cbm name + - str_values[1]: deprecated - str_values[2]: bionic_id - - str_values[3]: upgraded cbm name + - str_values[3]: deprecated - str_values[4]: upgraded cbm bionic_id - str_values[5]: installer name - str_values[6]: bool autodoc @@ -2899,6 +2899,8 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) is_autodoc = 6, trait_first = 7 }; + const bionic_id bid( act->str_values[cbm_id] ); + const bionic_id upbid( act->str_values[upgraded_cbm_id] ); const bool autodoc = act->str_values[is_autodoc] == "true"; const bool u_see = p->is_player() ? true : g->u.sees( p->pos() ) && !g->u.has_effect( effect_narcosis ); @@ -2968,9 +2970,9 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) add_msg( m_info, _( "The Autodoc attempts to carefully extract the bionic." ) ); } - if( p->has_bionic( bionic_id( act->str_values[cbm_id] ) ) ) { - p->perform_uninstall( bionic_id( act->str_values[cbm_id] ), act->values[0], act->values[1], - act->values[2], act->values[3], act->str_values[cbm_name] ); + if( p->has_bionic( bid ) ) { + p->perform_uninstall( bid, act->values[0], act->values[1], + act->values[2], act->values[3] ); } else { debugmsg( _( "Tried to uninstall %s, but you don't have this bionic installed." ), act->str_values[cbm_id] ); @@ -2982,17 +2984,15 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) add_msg( m_info, _( "The Autodoc attempts to carefully insert the bionic." ) ); } - if( bionic_id( act->str_values[cbm_id] ).is_valid() ) { + if( bid.is_valid() ) { std::vector trait_to_rem; if( act->str_values.size() > trait_first + 1 ) { for( size_t i = trait_first; i < act->str_values.size(); i++ ) { trait_to_rem.emplace_back( trait_id( act->str_values[i] ) ); } } - p->perform_install( bionic_id( act->str_values[cbm_id] ), - bionic_id( act->str_values[upgraded_cbm_id] ), act->values[0], act->values[1], act->values[3], - act->str_values[cbm_name], act->str_values[upgraded_cbm_name], act->str_values[installer_name], - trait_to_rem, p->pos() ); + p->perform_install( bid, upbid, act->values[0], act->values[1], act->values[3], + act->str_values[installer_name], trait_to_rem, p->pos() ); } else { debugmsg( _( "%s is no a valid bionic_id" ), act->str_values[cbm_id] ); p->remove_effect( effect_under_op ); diff --git a/src/bionics.cpp b/src/bionics.cpp index 756978b73d05a..ccb2251f8e5b0 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -147,10 +147,9 @@ bool bionic_data::is_included( const bionic_id &id ) const return std::find( included_bionics.begin(), included_bionics.end(), id ) != included_bionics.end(); } -bionic_data::bionic_data() +bionic_data::bionic_data() : name( translation( "bad bionic" ) ), + description( translation( "This bionic was not set up correctly, this is a bug" ) ) { - name = "bad bionic"; - description = "This bionic was not set up correctly, this is a bug"; } static void force_comedown( effect &eff ) @@ -248,7 +247,7 @@ bool player::activate_bionic( int b, bool eff_only ) if( bio.incapacitated_time > 0_turns ) { add_msg( m_info, _( "Your %s is shorting out and can't be activated." ), - bionics[bio.id].name.c_str() ); + bionics[bio.id].name ); return false; } @@ -714,7 +713,7 @@ bool player::deactivate_bionic( int b, bool eff_only ) if( bio.incapacitated_time > 0_turns ) { add_msg( m_info, _( "Your %s is shorting out and can't be deactivated." ), - bionics[bio.id].name.c_str() ); + bionics[bio.id].name ); return false; } @@ -1368,8 +1367,8 @@ bool player::uninstall_bionic( const bionic_id &b_id, player &installer, bool au activity.values.push_back( bionics[b_id].capacity ); activity.values.push_back( pl_skill ); activity.str_values.push_back( "uninstall" ); - activity.str_values.push_back( bionics[b_id].name ); - activity.str_values.push_back( b_id.c_str() ); + activity.str_values.push_back( "" ); + activity.str_values.push_back( b_id.str() ); activity.str_values.push_back( "" ); activity.str_values.push_back( "" ); activity.str_values.push_back( "" ); @@ -1386,20 +1385,20 @@ bool player::uninstall_bionic( const bionic_id &b_id, player &installer, bool au } void player::perform_uninstall( bionic_id bid, int difficulty, int success, int power_lvl, - int pl_skill, std::string cbm_name ) + int pl_skill ) { if( success > 0 ) { if( is_player() ) { add_memorial_log( pgettext( "memorial_male", "Removed bionic: %s." ), pgettext( "memorial_female", "Removed bionic: %s." ), - cbm_name ); + bid.obj().name ); } // until bionics can be flagged as non-removable add_msg_player_or_npc( m_neutral, _( "Your parts are jiggled back into their familiar places." ), _( "'s parts are jiggled back into their familiar places." ) ); - add_msg( m_good, _( "Successfully removed %s." ), cbm_name ); + add_msg( m_good, _( "Successfully removed %s." ), bid.obj().name ); remove_bionic( bid ); // remove power bank provided by bionic @@ -1418,7 +1417,7 @@ void player::perform_uninstall( bionic_id bid, int difficulty, int success, int if( is_player() ) { add_memorial_log( pgettext( "memorial_male", "Failed to remove bionic: %s." ), pgettext( "memorial_female", "Failed to remove bionic: %s." ), - cbm_name ); + bid.obj().name ); } // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30 @@ -1620,11 +1619,11 @@ bool player::install_bionics( const itype &type, player &installer, bool autodoc activity.values.push_back( bionics[bioid].capacity ); activity.values.push_back( pl_skill ); activity.str_values.push_back( "install" ); - activity.str_values.push_back( bionics[bioid].name ); - activity.str_values.push_back( bioid.c_str() ); + activity.str_values.push_back( "" ); + activity.str_values.push_back( bioid.str() ); if( upbioid ) { - activity.str_values.push_back( bionics[upbioid].name ); - activity.str_values.push_back( upbioid.c_str() ); + activity.str_values.push_back( "" ); + activity.str_values.push_back( upbioid.str() ); } else { activity.str_values.push_back( "" ); activity.str_values.push_back( "" ); @@ -1652,7 +1651,7 @@ bool player::install_bionics( const itype &type, player &installer, bool autodoc } void player::perform_install( bionic_id bid, bionic_id upbid, int difficulty, int success, - int pl_skill, std::string cbm_name, std::string upcbm_name, std::string installer_name, + int pl_skill, std::string installer_name, std::vector trait_to_rem, tripoint patient_pos ) { if( success > 0 ) { @@ -1660,16 +1659,16 @@ void player::perform_install( bionic_id bid, bionic_id upbid, int difficulty, in if( is_player() ) { add_memorial_log( pgettext( "memorial_male", "Installed bionic: %s." ), pgettext( "memorial_female", "Installed bionic: %s." ), - cbm_name ); + bid.obj().name ); } if( upbid != bionic_id( "" ) ) { remove_bionic( upbid ); //~ %1$s - name of the bionic to be upgraded (inferior), %2$s - name of the upgraded bionic (superior). add_msg( m_good, _( "Successfully upgraded %1$s to %2$s." ), - upcbm_name, cbm_name ); + upbid.obj().name, bid.obj().name ); } else { //~ %s - name of the bionic. - add_msg( m_good, _( "Successfully installed %s." ), cbm_name ); + add_msg( m_good, _( "Successfully installed %s." ), bid.obj().name ); } add_bionic( bid ); @@ -1684,7 +1683,7 @@ void player::perform_install( bionic_id bid, bionic_id upbid, int difficulty, in if( is_player() ) { add_memorial_log( pgettext( "memorial_male", "Failed install of bionic: %s." ), pgettext( "memorial_female", "Failed install of bionic: %s." ), - cbm_name ); + bid.obj().name ); } // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30 @@ -2019,8 +2018,8 @@ void load_bionic( JsonObject &jsobj ) bionic_data new_bionic; const bionic_id id( jsobj.get_string( "id" ) ); - new_bionic.name = _( jsobj.get_string( "name" ) ); - new_bionic.description = _( jsobj.get_string( "description" ) ); + jsobj.read( "name", new_bionic.name ); + jsobj.read( "description", new_bionic.description ); new_bionic.power_activate = jsobj.get_int( "act_cost", 0 ); new_bionic.toggled = get_bool_or_flag( jsobj, "toggled", "BIONIC_TOGGLED", false ); diff --git a/src/bionics.h b/src/bionics.h index 9b2b9d951b2b0..9b4b310550e28 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -12,6 +12,7 @@ #include "bodypart.h" #include "calendar.h" #include "string_id.h" +#include "translations.h" #include "type_id.h" class player; @@ -23,8 +24,8 @@ using itype_id = std::string; struct bionic_data { bionic_data(); - std::string name; - std::string description; + translation name; + translation description; /** Power cost on activation */ int power_activate = 0; /** Power cost on deactivation */ diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index f4040f2c15007..0f1237e1a3c0c 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -148,12 +148,12 @@ static void draw_description( const catacurses::window &win, const bionic &bio ) werase( win ); const int width = getmaxx( win ); const std::string poweronly_string = build_bionic_poweronly_string( bio ); - int ypos = fold_and_print( win, point_zero, width, c_white, bio.id->name ); + int ypos = fold_and_print( win, point_zero, width, c_white, "%s", bio.id->name ); if( !poweronly_string.empty() ) { ypos += fold_and_print( win, point( 0, ypos ), width, c_light_gray, _( "Power usage: %s" ), poweronly_string ); } - ypos += 1 + fold_and_print( win, point( 0, ypos ), width, c_light_blue, bio.id->description ); + ypos += 1 + fold_and_print( win, point( 0, ypos ), width, c_light_blue, "%s", bio.id->description ); // TODO: Unhide when enforcing limits if( get_option < bool >( "CBM_SLOTS_ENABLED" ) ) { diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 81879d834ab5d..9ebc4977349d5 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -524,7 +524,7 @@ class comestible_inventory_preset : public inventory_selector_preset std::vector bids = p.get_bionic_fueled_with( get_consumable_item( loc ) ); if( !bids.empty() ) { bionic_id bid = p.get_most_efficient_bionic( bids ); - cbm_name = bid->name; + cbm_name = bid->name.translated(); } break; } diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 0c2a04550e15c..65f762f161b1a 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -919,7 +919,7 @@ static void sleep() const auto &info = bio.info(); if( info.power_over_time > 0 ) { - active.push_back( info.name ); + active.push_back( info.name.translated() ); } } for( auto &mut : u.get_mutations() ) { diff --git a/src/player.h b/src/player.h index 3b33116ed218c..81083b6ba3250 100644 --- a/src/player.h +++ b/src/player.h @@ -350,8 +350,7 @@ class player : public Character int skill_level = -1 ); /**Success or failure of installation happens here*/ void perform_install( bionic_id bid, bionic_id upbid, int difficulty, int success, - int pl_skill, - std::string cbm_name, std::string upcbm_name, std::string installer_name, + int pl_skill, std::string installer_name, std::vector trait_to_rem, tripoint patient_pos ); void bionics_install_failure( bionic_id bid, std::string installer, int difficulty, int success, float adjusted_skill, tripoint patient_pos ); @@ -362,8 +361,7 @@ class player : public Character bool uninstall_bionic( const bionic_id &b_id, player &installer, bool autodoc = false, int skill_level = -1 ); /**Succes or failure of removal happens here*/ - void perform_uninstall( bionic_id bid, int difficulty, int success, int power_lvl, int pl_skill, - std::string cbm_name ); + void perform_uninstall( bionic_id bid, int difficulty, int success, int power_lvl, int pl_skill ); /**Used by monster to perform surgery*/ bool uninstall_bionic( const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill, bool autodoc = false ); diff --git a/src/player_display.cpp b/src/player_display.cpp index c8e5100f7db34..6f5c7ff541059 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -536,11 +536,11 @@ static void draw_bionics_tab( const catacurses::window &w_bionics, const catacur for( size_t i = min; i < max; i++ ) { trim_and_print( w_bionics, point( 1, static_cast( 2 + i - min ) ), getmaxx( w_bionics ) - 1, - i == line ? hilite( c_white ) : c_white, bionicslist[i].info().name ); + i == line ? hilite( c_white ) : c_white, "%s", bionicslist[i].info().name ); } if( line < bionicslist.size() ) { // NOLINTNEXTLINE(cata-use-named-point-constants) - fold_and_print( w_info, point( 1, 0 ), FULL_SCREEN_WIDTH - 2, c_white, + fold_and_print( w_info, point( 1, 0 ), FULL_SCREEN_WIDTH - 2, c_white, "%s", bionicslist[line].info().description ); } wrefresh( w_bionics ); @@ -565,7 +565,7 @@ static void draw_bionics_tab( const catacurses::window &w_bionics, const catacur for( size_t i = 0; i < bionicslist.size() && i < bionics_win_size_y - 1; i++ ) { mvwprintz( w_bionics, point( 1, static_cast( i + 2 ) ), c_black, " " ); trim_and_print( w_bionics, point( 1, static_cast( i + 2 ) ), getmaxx( w_bionics ) - 1, - c_white, bionicslist[i].info().name ); + c_white, "%s", bionicslist[i].info().name ); } wrefresh( w_bionics ); line = 0; @@ -981,7 +981,7 @@ static void draw_initial_windows( const catacurses::window &w_stats, you.power_level, you.max_power_level ) ); for( size_t i = 0; i < bionicslist.size() && i < bionics_win_size_y - 1; i++ ) { trim_and_print( w_bionics, point( 1, static_cast( i ) + 2 ), getmaxx( w_bionics ) - 1, c_white, - bionicslist[i].info().name ); + "%s", bionicslist[i].info().name ); } wrefresh( w_bionics ); From e6edde5ce08ca28de5329c5bf088aa5891f4f28b Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 16:01:55 +0800 Subject: [PATCH 03/14] Remove some explicit `translated` calls --- src/effect.cpp | 4 ++-- src/magic.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/effect.cpp b/src/effect.cpp index 893f9a3a4ba91..0c30f9b9df9da 100644 --- a/src/effect.cpp +++ b/src/effect.cpp @@ -487,12 +487,12 @@ std::string effect::disp_name() const if( d_name.empty() ) { return std::string(); } - ret << d_name.translated(); + ret << d_name; } else { if( eff_type->name[0].empty() ) { return std::string(); } - ret << eff_type->name[0].translated(); + ret << eff_type->name[0]; if( intensity > 1 ) { if( eff_type->id == "bandaged" || eff_type->id == "disinfected" ) { ret << " [" << texitify_healing_power( intensity ) << "]"; diff --git a/src/magic.cpp b/src/magic.cpp index 3fa1638f11bcd..45786dae261a2 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -1584,7 +1584,7 @@ static void draw_spellbook_info( const spell_type &sp, uilist *menu ) print_colored_text( w, point( menu->pad_left - spell_class.length() - 1, line++ ), yellow, yellow, spell_class ); line++; - line += fold_and_print( w, point( start_x, line ), width, gray, sp.description.translated() ); + line += fold_and_print( w, point( start_x, line ), width, gray, "%s", sp.description ); line++; mvwprintz( w, point( start_x, line ), c_light_gray, string_format( "%s: %d", _( "Difficulty" ), From 4140b6d64f1a1b6cc136d69a9408e4ea9f933a91 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 16:21:47 +0800 Subject: [PATCH 04/14] Fix translation update - recipe category names --- src/crafting_gui.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/crafting_gui.cpp b/src/crafting_gui.cpp index 2927be82e6b8a..004ac3e9c829c 100644 --- a/src/crafting_gui.cpp +++ b/src/crafting_gui.cpp @@ -63,7 +63,7 @@ int related_menu_fill( uilist &rmenu, const std::vector> &related_recipes, const recipe_subset &available ); -static std::string get_cat_name( const std::string &prefixed_name ) +static std::string get_cat_unprefixed( const std::string &prefixed_name ) { return prefixed_name.substr( 3, prefixed_name.size() - 3 ); } @@ -80,7 +80,7 @@ void load_recipe_category( JsonObject &jsobj ) if( !is_hidden ) { craft_cat_list.push_back( category ); - const std::string cat_name = get_cat_name( category ); + const std::string cat_name = get_cat_unprefixed( category ); craft_subcat_list[category] = std::vector(); JsonArray subcats = jsobj.get_array( "recipe_subcategories" ); @@ -94,24 +94,25 @@ void load_recipe_category( JsonObject &jsobj ) } } -static std::string get_subcat_name( const std::string &cat, const std::string &prefixed_name ) +static std::string get_subcat_unprefixed( const std::string &cat, const std::string &prefixed_name ) { - std::string prefix = "CSC_" + get_cat_name( cat ) + "_"; + std::string prefix = "CSC_" + get_cat_unprefixed( cat ) + "_"; if( prefixed_name.find( prefix ) == 0 ) { return prefixed_name.substr( prefix.size(), prefixed_name.size() - prefix.size() ); } - return ( prefixed_name == "CSC_ALL" ? _( "ALL" ) : _( "NONCRAFT" ) ); + return prefixed_name == "CSC_ALL" ? translate_marker( "ALL" ) : translate_marker( "NONCRAFT" ); } static void translate_all() { + normalized_names.clear(); for( const auto &cat : craft_cat_list ) { - normalized_names[cat] = _( get_cat_name( cat ) ); + normalized_names[cat] = _( get_cat_unprefixed( cat ) ); for( const auto &subcat : craft_subcat_list[cat] ) { - normalized_names[subcat] = _( get_subcat_name( cat, subcat ) ) ; + normalized_names[subcat] = _( get_subcat_unprefixed( cat, subcat ) ) ; } } } @@ -151,9 +152,8 @@ static int print_items( const recipe &r, const catacurses::window &w, int ypos, const recipe *select_crafting_recipe( int &batch_size ) { - if( normalized_names.empty() ) { - translate_all(); - } + // always re-translate the category names in case the language has changed + translate_all(); const int headHeight = 3; const int subHeadHeight = 2; From a4b00838edf85fc26536fffbf0b0eeffdd3a563a Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 16:42:29 +0800 Subject: [PATCH 05/14] Fix translation update - terrain bash sound descriptions --- src/map.cpp | 2 +- src/mapdata.cpp | 6 ++++-- src/mapdata.h | 4 ++-- src/sounds.cpp | 6 ++++++ src/sounds.h | 4 ++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 7627be78407eb..1fc5e68082997 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3036,7 +3036,7 @@ static bool furn_is_supported( const map &m, const tripoint &p ) void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) { - std::string sound; + translation sound; int sound_volume = 0; std::string soundfxid; std::string soundfxvariant; diff --git a/src/mapdata.cpp b/src/mapdata.cpp index dad1c37838a6d..359c6e0a8c8a1 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -222,8 +222,10 @@ bool map_bash_info::load( JsonObject &jsobj, const std::string &member, bool is_ bash_below = j.get_bool( "bash_below", false ); - sound = _( j.get_string( "sound", "smash!" ) ); - sound_fail = _( j.get_string( "sound_fail", "thump!" ) ); + sound = translation( "smash!" ); + sound_fail = translation( "thump!" ); + j.read( "sound", sound ); + j.read( "sound_fail", sound_fail ); if( is_furniture ) { furn_set = furn_str_id( j.get_string( "furn_set", "f_null" ) ); diff --git a/src/mapdata.h b/src/mapdata.h index 70c4bec1cd7c0..215cfaef27861 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -42,8 +42,8 @@ struct map_bash_info { bool destroy_only; // Only used for destroying, not normally bashable bool bash_below; // This terrain is the roof of the tile below it, try to destroy that too std::string drop_group; // item group of items that are dropped when the object is bashed - std::string sound; // sound made on success ('You hear a "smash!"') - std::string sound_fail; // sound made on fail + translation sound; // sound made on success ('You hear a "smash!"') + translation sound_fail; // sound made on fail ter_str_id ter_set; // terrain to set (REQUIRED for terrain)) ter_str_id ter_set_bashed_from_above; // terrain to set if bashed from above (defaults to ter_set) furn_str_id furn_set; // furniture to set (only used by furniture, not terrain) diff --git a/src/sounds.cpp b/src/sounds.cpp index 802827926d03e..5d098db87c883 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -133,6 +133,12 @@ void sounds::sound( const tripoint &p, int vol, sound_t category, const std::str false, id, variant} ) ); } +void sounds::sound( const tripoint &p, int vol, sound_t category, const translation &description, + bool ambient, const std::string &id, const std::string &variant ) +{ + sounds::sound( p, vol, category, description.translated(), ambient, id, variant ); +} + void sounds::add_footstep( const tripoint &p, int volume, int, monster *, const std::string &footstep ) { diff --git a/src/sounds.h b/src/sounds.h index e8fa546cbfe6c..22cd49d04749a 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -11,6 +11,7 @@ class player; class Creature; class item; class JsonObject; +class translation; struct tripoint; namespace sounds @@ -48,6 +49,9 @@ enum class sound_t : int { void sound( const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient = false, const std::string &id = "", const std::string &variant = "default" ); +void sound( const tripoint &p, int vol, sound_t category, const translation &description, + bool ambient = false, const std::string &id = "", + const std::string &variant = "default" ); /** Functions identical to sound(..., true). */ void ambient_sound( const tripoint &p, int vol, sound_t category, const std::string &description ); /** Creates a list of coordinates at which to draw footsteps. */ From 22499cf00d1991e7e92e8997f26db6c0640f4384 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 17:05:26 +0800 Subject: [PATCH 06/14] Fix translation - trap-vehicle collision sound description --- lang/extract_json_strings.py | 7 ++++++- src/trap.cpp | 2 +- src/trap.h | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 36d917f1e78bf..4ce86c53dc1ea 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -156,7 +156,6 @@ def warning_supressed(filename): "TOOLMOD", "TOOL_ARMOR", "tool_quality", - "trap", "tutorial_messages", "VAR_VEH_PART", "vehicle", @@ -569,6 +568,11 @@ def extract_talk_topic(item): for r in item["responses"]: extract_talk_response(r, outfile) +def extract_trap(item): + outfile = get_outfile("trap") + writestr(outfile, item["name"]) + if "vehicle_data" in item and "sound" in item["vehicle_data"]: + writestr(outfile, item["vehicle_data"]["sound"], comment="Trap-vehicle collision message for trap '{}'".format(item["name"])) def extract_missiondef(item): outfile = get_outfile("mission_def") @@ -731,6 +735,7 @@ def extract_ter_furn_transform_messages(item): "recipe_group": extract_recipe_group, "scenario": extract_scenarios, "talk_topic": extract_talk_topic, + "trap": extract_trap, "gate": extract_gate, "vehicle_spawn": extract_vehspawn, "field_type": extract_field_type, diff --git a/src/trap.cpp b/src/trap.cpp index 3090ad3491820..5430f75be0b16 100644 --- a/src/trap.cpp +++ b/src/trap.cpp @@ -145,7 +145,7 @@ void trap::load( JsonObject &jo, const std::string & ) vehicle_data.damage = jv.get_int( "damage", 0 ); vehicle_data.shrapnel = jv.get_int( "shrapnel", 0 ); vehicle_data.sound_volume = jv.get_int( "sound_volume", 0 ); - vehicle_data.sound = jv.get_string( "sound", "" ); + jv.read( "sound", vehicle_data.sound ); vehicle_data.sound_type = jv.get_string( "sound_type", "" ); vehicle_data.sound_variant = jv.get_string( "sound_variant", "" ); } diff --git a/src/trap.h b/src/trap.h index 22383742cfec0..e2d55c15fc634 100644 --- a/src/trap.h +++ b/src/trap.h @@ -11,6 +11,7 @@ #include "color.h" #include "int_id.h" #include "string_id.h" +#include "translations.h" #include "type_id.h" #include "units.h" @@ -70,7 +71,7 @@ struct vehicle_handle_trap_data { int damage = 0; int shrapnel = 0; int sound_volume = 0; - std::string sound; + translation sound; std::string sound_type; std::string sound_variant; }; From 515b54afc1bcd0bc2f6ce4bda57bb29383a31f39 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 18:24:18 +0800 Subject: [PATCH 07/14] Convert .pot file line endings to Unix on Windows --- lang/extract_json_strings.py | 2 +- lang/update_pot.sh | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 4ce86c53dc1ea..624e89f34d6fb 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -809,7 +809,7 @@ def writestr(filename, string, plural=None, context=None, format_strings=False, # don't write empty strings if not string: return - with open(filename, 'a', encoding="utf-8") as fs: + with open(filename, 'a', encoding="utf-8", newline='\n') as fs: # Append developers comment if comment: tlcomment(fs, comment) diff --git a/lang/update_pot.sh b/lang/update_pot.sh index 8bc2a7d1fa3ba..24c990bfefe97 100755 --- a/lang/update_pot.sh +++ b/lang/update_pot.sh @@ -60,6 +60,17 @@ then exit 1 fi +# convert line endings to unix +if [[ $(uname -s) =~ ^(CYGWIN|MINGW)* ]] +then + echo "> Converting line endings to Unix" + if ! sed -i -e 's/\r$//' lang/po/cataclysm-dda.pot + then + echo "Line ending conversion failed. Aborting." + exit 1 + fi +fi + # Final compilation check echo "> Testing to compile the .pot file" if ! msgfmt -c -o /dev/null lang/po/cataclysm-dda.pot From 5bbe0e078da6f1f9064cbb64dbc93be17d0fe84e Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 18:25:18 +0800 Subject: [PATCH 08/14] Suppress warning when nothing translatable is found in objects copying from other objects --- lang/extract_json_strings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 624e89f34d6fb..ef2a250c895e3 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -983,7 +983,7 @@ def extract(item, infilename): if "footsteps" in item: writestr(outfile, item["footsteps"], **kwargs) wrote = True - if not wrote: + if not wrote and not "copy-from" in item: if not warning_supressed(infilename): print("WARNING: {}: nothing translatable found in item: {}".format(infilename, item)) From 621053c24c93a0095dce5d73fa8592a2c1564904 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 18:40:10 +0800 Subject: [PATCH 09/14] Update translation documentation --- doc/TRANSLATING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/TRANSLATING.md b/doc/TRANSLATING.md index 858f1ae819507..148d7a80d766e 100644 --- a/doc/TRANSLATING.md +++ b/doc/TRANSLATING.md @@ -250,6 +250,10 @@ new syntax "name" would be a `dict`, which may break unmigrated script. | Mutation names/descriptions | NPC class names/descriptions | Tool quality names +| Skill names/descriptions +| Bionic names/descriptions +| Terrain bash sound descriptions +| Trap-vehicle collision sound descriptions ### Recommendations From 3a91ffbbb841b85c2ec94b8e85470be8a0bd5370 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 18:56:40 +0800 Subject: [PATCH 10/14] Mark a string for translation --- src/activity_handlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 7e7c3aa9f5663..397dc0f598261 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2093,7 +2093,7 @@ void activity_handlers::start_engines_finish( player_activity *act, player *p ) "Some of the %s's engines start up.", non_muscle_started ), veh->name ); } else if( non_combustion_started > 0 ) { //Non-combustions "engines" started - add_msg( "The %s is ready for movement.", veh->name ); + add_msg( _( "The %s is ready for movement." ), veh->name ); } else { //All of the non-muscle engines failed add_msg( m_bad, ngettext( "The %s's engine fails to start.", From 4e0245c6803ee1e23090239748f22958ec4a9a30 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 19:34:53 +0800 Subject: [PATCH 11/14] Fix translation update - vehicle part names --- src/veh_type.cpp | 13 ++++--------- src/veh_type.h | 5 +++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/veh_type.cpp b/src/veh_type.cpp index fd2527cb5d413..3f16719fffae3 100644 --- a/src/veh_type.cpp +++ b/src/veh_type.cpp @@ -436,12 +436,6 @@ void vpart_info::finalize() DynamicDataLoader::get_instance().load_deferred( deferred ); for( auto &e : vpart_info_all ) { - // if part name specified ensure it is translated - // otherwise the name of the base item will be used - if( !e.second.name_.empty() ) { - e.second.name_ = _( e.second.name_ ); - } - if( e.second.folded_volume > 0_ml ) { e.second.set_flag( "FOLDABLE" ); } @@ -707,9 +701,10 @@ const std::map &vpart_info::all() std::string vpart_info::name() const { if( name_.empty() ) { - name_ = item::nname( item ); // cache on first request + return item::nname( item ); + } else { + return name_.translated(); } - return name_; } int vpart_info::format_description( std::ostringstream &msg, const std::string &format_color, @@ -721,7 +716,7 @@ int vpart_info::format_description( std::ostringstream &msg, const std::string & std::ostringstream long_descrip; if( ! description.empty() ) { - long_descrip << _( description ); + long_descrip << description; } for( const auto &flagid : flags ) { if( flagid == "ALARMCLOCK" || flagid == "WATCH" ) { diff --git a/src/veh_type.h b/src/veh_type.h index c6ed9294e6a1d..9f39e0ae6e33c 100644 --- a/src/veh_type.h +++ b/src/veh_type.h @@ -22,6 +22,7 @@ #include "vehicle.h" #include "requirements.h" #include "point.h" +#include "translations.h" using itype_id = std::string; @@ -173,7 +174,7 @@ class vpart_info int durability = 0; /** A text description of the part as a vehicle part */ - std::string description; + translation description; /** Damage modifier (percentage) used when damaging other entities upon collision */ int dmg_mod = 100; @@ -305,7 +306,7 @@ class vpart_info private: /** Name from vehicle part definition which if set overrides the base item name */ - mutable std::string name_; + translation name_; std::set flags; // flags std::bitset bitflags; // flags checked so often that things slow down due to string cmp From b863e82c7b72505a2788ef489f78a71980676cb7 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 20:29:03 +0800 Subject: [PATCH 12/14] Fix translation update - text snippets --- src/text_snippets.cpp | 10 +++++----- src/text_snippets.h | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/text_snippets.cpp b/src/text_snippets.cpp index a2d18ea46b126..155d2971170cf 100644 --- a/src/text_snippets.cpp +++ b/src/text_snippets.cpp @@ -30,7 +30,7 @@ void snippet_library::add_snippets_from_json( const std::string &category, JsonA { while( jarr.has_more() ) { if( jarr.test_string() ) { - const std::string text = _( jarr.next_string() ); + const std::string text = jarr.next_string(); add_snippet( category, text ); } else { JsonObject jo = jarr.next_object(); @@ -41,7 +41,7 @@ void snippet_library::add_snippets_from_json( const std::string &category, JsonA void snippet_library::add_snippet_from_json( const std::string &category, JsonObject &jo ) { - const std::string text = _( jo.get_string( "text" ) ); + const std::string text = jo.get_string( "text" ); const int hash = add_snippet( category, text ); if( jo.has_member( "id" ) ) { const std::string id = jo.get_string( "id" ); @@ -99,16 +99,16 @@ int snippet_library::assign( const std::string &category, const unsigned seed ) return it->second; } -const std::string &snippet_library::get( const int index ) const +std::string snippet_library::get( const int index ) const { const std::map::const_iterator chosen_snippet = snippets.find( index ); if( chosen_snippet == snippets.end() ) { return null_string; } - return chosen_snippet->second; + return _( chosen_snippet->second ); } -const std::string &snippet_library::random_from_category( const std::string &cat ) const +std::string snippet_library::random_from_category( const std::string &cat ) const { const auto iters = categories.equal_range( cat ); if( iters.first == iters.second ) { diff --git a/src/text_snippets.h b/src/text_snippets.h index b1ead49238f59..d69d0fc54ec74 100644 --- a/src/text_snippets.h +++ b/src/text_snippets.h @@ -28,10 +28,10 @@ class snippet_library * snippet out of the category is returned (same seed yields same snippet). */ int assign( const std::string &category, unsigned seed ) const; - const std::string &get( int index ) const; + std::string get( int index ) const; bool has_category( const std::string &category ) const; int get_snippet_by_id( const std::string &id ) const; - const std::string &random_from_category( const std::string &cat ) const; + std::string random_from_category( const std::string &cat ) const; std::vector all_ids_from_category( const std::string &cat ) const; /** * Load a single snippet text from the json object. The object should have @@ -56,10 +56,11 @@ class snippet_library * later see add_snippet_from_json). */ // Snippets holds a map from the strings hash to the string. + // The strings stored and used for hashing are untranslated in case the language changes. // This is so the reference to the string remains stable across // changes to the layout and contents of the snippets json file. std::map snippets; - // Key is an arbitrary id string (from json), value is the hash of the snippet. + // Key is an arbitrary id string (from json), value is the hash of the untranslated snippet. std::unordered_map snippets_by_id; // Categories groups snippets by well, category. std::multimap categories; From 2be1c21bb87d3f104df4872e1ba0d5de6bc5bb71 Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 21 Aug 2019 20:55:45 +0800 Subject: [PATCH 13/14] Update translation documentation --- doc/TRANSLATING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/TRANSLATING.md b/doc/TRANSLATING.md index 148d7a80d766e..bd4304ec581c0 100644 --- a/doc/TRANSLATING.md +++ b/doc/TRANSLATING.md @@ -254,6 +254,7 @@ new syntax "name" would be a `dict`, which may break unmigrated script. | Bionic names/descriptions | Terrain bash sound descriptions | Trap-vehicle collision sound descriptions +| Vehicle part names/descriptions ### Recommendations From 9f2cb6e3791b6298509cc3b8638707f2e045972a Mon Sep 17 00:00:00 2001 From: Qrox Date: Thu, 22 Aug 2019 00:42:20 +0800 Subject: [PATCH 14/14] Use no_translation for debug text --- src/bionics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index ccb2251f8e5b0..727d1a1c785fe 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -147,8 +147,8 @@ bool bionic_data::is_included( const bionic_id &id ) const return std::find( included_bionics.begin(), included_bionics.end(), id ) != included_bionics.end(); } -bionic_data::bionic_data() : name( translation( "bad bionic" ) ), - description( translation( "This bionic was not set up correctly, this is a bug" ) ) +bionic_data::bionic_data() : name( no_translation( "bad bionic" ) ), + description( no_translation( "This bionic was not set up correctly, this is a bug" ) ) { }