OSDN Git Service

Merge pull request #2360 from Slimebreath6078/hotfix/breath_bug
[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         char temp[128];
91
92 #ifdef SAVEFILE_USE_UID
93         /* Rename the savefile, using the player_ptr->player_uid and player_ptr->base_name */
94         (void)sprintf(temp, "%d.%s", player_ptr->player_uid, player_ptr->base_name);
95 #else
96         /* Rename the savefile, using the player_ptr->base_name */
97         (void)sprintf(temp, "%s", player_ptr->base_name);
98 #endif
99         path_build(savefile, sizeof(savefile), ANGBAND_DIR_SAVE, temp);
100         is_modified = true;
101     }
102
103     if (is_modified || !savefile_base[0]) {
104         concptr s = savefile;
105         while (true) {
106             concptr t;
107             t = angband_strstr(s, PATH_SEP);
108             if (!t) {
109                 break;
110             }
111             s = t + 1;
112         }
113
114 #ifdef SAVEFILE_USE_UID
115         strcpy(savefile_base, angband_strstr(s, ".") + 1);
116 #else
117         strcpy(savefile_base, s);
118 #endif
119     }
120
121     if (w_ptr->character_generated && !streq(old_player_base, player_ptr->base_name)) {
122         autopick_load_pref(player_ptr, false);
123     }
124 }
125
126 /*!
127  * @brief プレイヤーの名前を変更するコマンドのメインルーチン
128  * Gets a name for the character, reacting to name changes.
129  * @param player_ptr プレイヤーへの参照ポインタ
130  * @details
131  * <pre>
132  * Assumes that "display_player()" has just been called
133  * Perhaps we should NOT ask for a name (at "birth()") on
134  * Unix machines?  XXX XXX
135  * What a horrible name for a global function.
136  * </pre>
137  */
138 void get_name(PlayerType *player_ptr)
139 {
140     char tmp[64];
141     strcpy(tmp, player_ptr->name);
142
143     if (get_string(_("キャラクターの名前を入力して下さい: ", "Enter a name for your character: "), tmp, 15)) {
144         strcpy(player_ptr->name, tmp);
145     }
146
147     if (strlen(player_ptr->name) == 0) {
148         strcpy(player_ptr->name, "PLAYER");
149     }
150
151     strcpy(tmp, ap_ptr->title);
152 #ifdef JP
153     if (ap_ptr->no == 1) {
154         strcat(tmp, "の");
155     }
156 #else
157     strcat(tmp, " ");
158 #endif
159     strcat(tmp, player_ptr->name);
160
161     term_erase(34, 1, 255);
162     c_put_str(TERM_L_BLUE, tmp, 1, 34);
163     clear_from(22);
164 }