OSDN Git Service

Replace sprintf() with std::string and/or format(). Does part of the work of resolvi...
[hengbandforosx/hengbandosx.git] / src / player / process-name.cpp
1 #include "player/process-name.h"
2 #include "autopick/autopick-reader-writer.h"
3 #include "core/asking-player.h"
4 #include "game-option/birth-options.h"
5 #include "io/files-util.h"
6 #include "player/player-personality.h"
7 #include "system/player-type-definition.h"
8 #include "term/screen-processor.h"
9 #include "term/term-color-types.h"
10 #include "util/angband-files.h"
11 #include "util/string-processor.h"
12 #include "world/world.h"
13
14 /*!
15  * @brief プレイヤーの名前をチェックして修正する
16  * Process the player name.
17  * @param player_ptr プレイヤーへの参照ポインタ
18  * @param sf セーブファイル名に合わせた修正を行うならばTRUE
19  * @details
20  * Extract a clean "base name".
21  * Build the savefile name if needed.
22  */
23 void process_player_name(PlayerType *player_ptr, bool is_new_savefile)
24 {
25     char old_player_base[32] = "";
26     if (w_ptr->character_generated) {
27         strcpy(old_player_base, player_ptr->base_name);
28     }
29
30     for (int i = 0; player_ptr->name[i]; i++) {
31 #ifdef JP
32         if (iskanji(player_ptr->name[i])) {
33             i++;
34             continue;
35         }
36
37         if (iscntrl((unsigned char)player_ptr->name[i]))
38 #else
39         if (iscntrl(player_ptr->name[i]))
40 #endif
41         {
42             quit_fmt(_("'%s' という名前は不正なコントロールコードを含んでいます。", "The name '%s' contains control chars!"), player_ptr->name);
43         }
44     }
45
46     int k = 0;
47     for (int i = 0; player_ptr->name[i]; i++) {
48 #ifdef JP
49         unsigned char c = player_ptr->name[i];
50 #else
51         char c = player_ptr->name[i];
52 #endif
53
54 #ifdef JP
55         if (iskanji(c)) {
56             if (k + 2 >= (int)sizeof(player_ptr->base_name) || !player_ptr->name[i + 1]) {
57                 break;
58             }
59
60             player_ptr->base_name[k++] = c;
61             i++;
62             player_ptr->base_name[k++] = player_ptr->name[i];
63         }
64 #ifdef SJIS
65         else if (iskana(c))
66             player_ptr->base_name[k++] = c;
67 #endif
68         else
69 #endif
70             if (!strncmp(PATH_SEP, player_ptr->name + i, strlen(PATH_SEP))) {
71             player_ptr->base_name[k++] = '_';
72             i += strlen(PATH_SEP);
73         }
74 #if defined(WINDOWS)
75         else if (angband_strchr("\"*,/:;<>?\\|", c))
76             player_ptr->base_name[k++] = '_';
77 #endif
78         else if (isprint(c)) {
79             player_ptr->base_name[k++] = c;
80         }
81     }
82
83     player_ptr->base_name[k] = '\0';
84     if (!player_ptr->base_name[0]) {
85         strcpy(player_ptr->base_name, "PLAYER");
86     }
87
88     auto is_modified = false;
89     if (is_new_savefile && (!savefile[0] || !keep_savefile)) {
90         std::string temp;
91
92 #ifdef SAVEFILE_USE_UID
93         /* Rename the savefile, using the player_ptr->player_uid and player_ptr->base_name */
94         temp = std::to_string(player_ptr->player_uid);
95         temp.append(".").append(player_ptr->base_name);
96 #else
97         /* Rename the savefile, using the player_ptr->base_name */
98         temp = player_ptr->base_name;
99 #endif
100         path_build(savefile, sizeof(savefile), ANGBAND_DIR_SAVE, temp.data());
101         is_modified = true;
102     }
103
104     if (is_modified || !savefile_base[0]) {
105         concptr s = savefile;
106         while (true) {
107             concptr t;
108             t = angband_strstr(s, PATH_SEP);
109             if (!t) {
110                 break;
111             }
112             s = t + 1;
113         }
114
115 #ifdef SAVEFILE_USE_UID
116         strcpy(savefile_base, angband_strstr(s, ".") + 1);
117 #else
118         strcpy(savefile_base, s);
119 #endif
120     }
121
122     if (w_ptr->character_generated && !streq(old_player_base, player_ptr->base_name)) {
123         autopick_load_pref(player_ptr, false);
124     }
125 }
126
127 /*!
128  * @brief プレイヤーの名前を変更するコマンドのメインルーチン
129  * Gets a name for the character, reacting to name changes.
130  * @param player_ptr プレイヤーへの参照ポインタ
131  * @details
132  * <pre>
133  * Assumes that "display_player()" has just been called
134  * Perhaps we should NOT ask for a name (at "birth()") on
135  * Unix machines?  XXX XXX
136  * What a horrible name for a global function.
137  * </pre>
138  */
139 void get_name(PlayerType *player_ptr)
140 {
141     char tmp[64];
142     strcpy(tmp, player_ptr->name);
143
144     if (get_string(_("キャラクターの名前を入力して下さい: ", "Enter a name for your character: "), tmp, 15)) {
145         strcpy(player_ptr->name, tmp);
146     }
147
148     if (strlen(player_ptr->name) == 0) {
149         strcpy(player_ptr->name, "PLAYER");
150     }
151
152     strcpy(tmp, ap_ptr->title);
153 #ifdef JP
154     if (ap_ptr->no == 1) {
155         strcat(tmp, "の");
156     }
157 #else
158     strcat(tmp, " ");
159 #endif
160     strcat(tmp, player_ptr->name);
161
162     term_erase(34, 1, 255);
163     c_put_str(TERM_L_BLUE, tmp, 1, 34);
164     clear_from(22);
165 }