OSDN Git Service

For consistency, changed English diary entries to use simple past tense. In a couple...
[hengband/hengband.git] / src / io / write-diary.c
1 /*!
2  * @brief 日記へのメッセージ追加処理
3  * @date 2020/03/08
4  * @author Hourier
5  */
6
7 #include "io/write-diary.h"
8 #include "core.h"
9 #include "quest.h"
10 #include "files.h"
11 #include "dungeon.h"
12 #include "dungeon-file.h"
13 #include "world.h"
14
15 // todo *抹殺* したい…
16 bool write_level;
17
18 /*!
19  * todo files.c に移すことも検討する?
20  * @brief 日記ファイルを開く
21  * @param fff ファイルへのポインタ
22  * @param disable_diary 日記への追加を無効化する場合TRUE
23  * @return ファイルがあったらTRUE、なかったらFALSE
24  */
25 static bool open_diary_file(FILE **fff, bool *disable_diary)
26 {
27         GAME_TEXT file_name[MAX_NLEN];
28         sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
29         char buf[1024];
30         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
31         FILE_TYPE(FILE_TYPE_TEXT);
32         *fff = my_fopen(buf, "a");
33         if (*fff) return TRUE;
34
35         msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
36         msg_format(NULL);
37         *disable_diary = TRUE;
38         return FALSE;
39 }
40
41
42 /*!
43  * @brief フロア情報を日記に追加する
44  * @param creature_ptr プレーヤーへの参照ポインタ
45  * @return クエストID
46  */
47 static QUEST_IDX write_floor(player_type *creature_ptr, concptr *note_level)
48 {
49         floor_type *floor_ptr = creature_ptr->current_floor_ptr;
50         QUEST_IDX q_idx = quest_number(creature_ptr, floor_ptr->dun_level);
51         if (!write_level) return q_idx;
52
53         if (floor_ptr->inside_arena)
54                 *note_level = _("アリーナ:", "Arane:");
55         else if (!floor_ptr->dun_level)
56                 *note_level = _("地上:", "Surface:");
57         else if (q_idx && (is_fixed_quest_idx(q_idx) && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
58                 *note_level = _("クエスト:", "Quest:");
59         else
60         {
61                 char note_level_buf[40];
62 #ifdef JP
63                 sprintf(note_level_buf, "%d階(%s):", (int)floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
64 #else
65                 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)floor_ptr->dun_level);
66 #endif
67                 *note_level = note_level_buf;
68         }
69
70         return q_idx;
71 }
72
73
74 /*!
75  * @brief ペットに関する日記を追加する
76  * @param fff 日記ファイル
77  * @param num 日記へ追加する内容番号
78  * @param note 日記内容のIDに応じた文字列参照ポインタ
79  * @return なし
80  */
81 static void write_diary_pet(FILE *fff, int num, concptr note)
82 {
83         switch (num)
84         {
85         case RECORD_NAMED_PET_NAME:
86                 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
87                 break;
88         case RECORD_NAMED_PET_UNNAME:
89                 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
90                 break;
91         case RECORD_NAMED_PET_DISMISS:
92                 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
93                 break;
94         case RECORD_NAMED_PET_DEATH:
95                 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
96                 break;
97         case RECORD_NAMED_PET_MOVED:
98                 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
99                 break;
100         case RECORD_NAMED_PET_LOST_SIGHT:
101                 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
102                 break;
103         case RECORD_NAMED_PET_DESTROY:
104                 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
105                 break;
106         case RECORD_NAMED_PET_EARTHQUAKE:
107                 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
108                 break;
109         case RECORD_NAMED_PET_GENOCIDE:
110                 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
111                 break;
112         case RECORD_NAMED_PET_WIZ_ZAP:
113                 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
114                 break;
115         case RECORD_NAMED_PET_TELE_LEVEL:
116                 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
117                 break;
118         case RECORD_NAMED_PET_BLAST:
119                 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
120                 break;
121         case RECORD_NAMED_PET_HEAL_LEPER:
122                 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
123                 break;
124         case RECORD_NAMED_PET_COMPACT:
125                 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
126                 break;
127         case RECORD_NAMED_PET_LOSE_PARENT:
128                 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
129                 break;
130         default:
131                 fprintf(fff, "\n");
132                 break;
133         }
134 }
135
136
137 /*!
138  * @brief 日記にメッセージを追加する /
139  * Take note to the diary.
140  * @param type 日記内容のID
141  * @param num 日記内容のIDに応じた数値
142  * @param note 日記内容のIDに応じた文字列参照ポインタ
143  * @return エラーコード
144  */
145 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
146 {
147         static bool disable_diary = FALSE;
148
149         int day, hour, min;
150         extract_day_hour_min(creature_ptr, &day, &hour, &min);
151
152         if (disable_diary) return -1;
153
154         if (type == DIARY_FIX_QUEST_C ||
155                 type == DIARY_FIX_QUEST_F ||
156                 type == DIARY_RAND_QUEST_C ||
157                 type == DIARY_RAND_QUEST_F ||
158                 type == DIARY_TO_QUEST)
159         {
160                 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
161                 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
162                 init_flags = INIT_NAME_ONLY;
163                 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
164                 creature_ptr->current_floor_ptr->inside_quest = old_quest;
165         }
166
167         FILE *fff = NULL;
168         if (!open_diary_file(&fff, &disable_diary)) return -1;
169
170         concptr note_level = "";
171         QUEST_IDX q_idx = write_floor(creature_ptr, &note_level);
172
173         bool do_level = TRUE;
174         switch (type)
175         {
176         case DIARY_DIALY:
177         {
178                 if (day < MAX_DAYS)
179                         fprintf(fff, _("%d日目\n", "Day %d\n"), day);
180                 else
181                         fputs(_("*****日目\n", "Day *****\n"), fff);
182
183                 do_level = FALSE;
184                 break;
185         }
186         case DIARY_DESCRIPTION:
187         {
188                 if (num)
189                 {
190                         fprintf(fff, "%s\n", note);
191                         do_level = FALSE;
192                 }
193                 else
194                         fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
195
196                 break;
197         }
198         case DIARY_ART:
199         {
200                 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
201                 break;
202         }
203         case DIARY_ART_SCROLL:
204         {
205                 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
206                 break;
207         }
208         case DIARY_UNIQUE:
209         {
210                 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
211                 break;
212         }
213         case DIARY_FIX_QUEST_C:
214         {
215                 if (quest[num].flags & QUEST_FLAG_SILENT) break;
216
217                 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
218                         " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
219                 break;
220         }
221         case DIARY_FIX_QUEST_F:
222         {
223                 if (quest[num].flags & QUEST_FLAG_SILENT) break;
224
225                 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
226                         " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
227                 break;
228         }
229         case DIARY_RAND_QUEST_C:
230         {
231                 GAME_TEXT name[MAX_NLEN];
232                 strcpy(name, r_name + r_info[quest[num].r_idx].name);
233                 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
234                         " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
235                 break;
236         }
237         case DIARY_RAND_QUEST_F:
238         {
239                 GAME_TEXT name[MAX_NLEN];
240                 strcpy(name, r_name + r_info[quest[num].r_idx].name);
241                 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
242                         " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
243                 break;
244         }
245         case DIARY_MAXDEAPTH:
246         {
247                 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
248                         " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
249                         _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
250                         _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
251                 break;
252         }
253         case DIARY_TRUMP:
254         {
255                 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
256                         " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
257                         _(d_name + d_info[num].name, (int)max_dlv[num]),
258                         _((int)max_dlv[num], d_name + d_info[num].name));
259                 break;
260         }
261         case DIARY_STAIR:
262         {
263                 concptr to = q_idx && (is_fixed_quest_idx(q_idx)
264                         && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT)))
265                         ? _("地上", "the surface")
266                         : !(creature_ptr->current_floor_ptr->dun_level + num)
267                         ? _("地上", "the surface")
268                         : format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
269                 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
270                 break;
271         }
272         case DIARY_RECALL:
273         {
274                 if (!num)
275                         fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
276                                 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
277                                 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
278                 else
279                         fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
280
281                 break;
282         }
283         case DIARY_TO_QUEST:
284         {
285                 if (quest[num].flags & QUEST_FLAG_SILENT) break;
286
287                 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
288                         hour, min, note_level, quest[num].name);
289                 break;
290         }
291         case DIARY_TELEPORT_LEVEL:
292         {
293                 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s got out using teleport level.\n"),
294                         hour, min, note_level);
295                 break;
296         }
297         case DIARY_BUY:
298         {
299                 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
300                 break;
301         }
302         case DIARY_SELL:
303         {
304                 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
305                 break;
306         }
307         case DIARY_ARENA:
308         {
309                 if (num < 0)
310                 {
311                         int n = -num;
312                         fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
313                                 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
314                         break;
315                 }
316
317                 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
318                         hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
319
320                 if (num == MAX_ARENA_MONS)
321                 {
322                         fprintf(fff, _("                 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
323                                 "                 won all fights to become a Champion.\n"));
324                         do_level = FALSE;
325                 }
326
327                 break;
328         }
329         case DIARY_FOUND:
330         {
331                 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
332                 break;
333         }
334         case DIARY_WIZ_TELE:
335         {
336                 concptr to = !creature_ptr->current_floor_ptr->dun_level
337                         ? _("地上", "the surface")
338                         : format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
339                 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
340                         " %2d:%02d %20s wizard-teleported to %s.\n"), hour, min, note_level, to);
341                 break;
342         }
343         case DIARY_PAT_TELE:
344         {
345                 concptr to = !creature_ptr->current_floor_ptr->dun_level
346                         ? _("地上", "the surface")
347                         : format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
348                 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
349                         " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
350                 break;
351         }
352         case DIARY_LEVELUP:
353         {
354                 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
355                 break;
356         }
357         case DIARY_GAMESTART:
358         {
359                 time_t ct = time((time_t*)0);
360                 do_level = FALSE;
361                 if (num)
362                         fprintf(fff, "%s %s", note, ctime(&ct));
363                 else
364                         fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
365
366                 break;
367         }
368         case DIARY_NAMED_PET:
369         {
370                 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
371                 write_diary_pet(fff, num, note);
372                 break;
373         }
374         case DIARY_WIZARD_LOG:
375                 fprintf(fff, "%s\n", note);
376                 break;
377         default:
378                 break;
379         }
380
381         my_fclose(fff);
382         if (do_level) write_level = FALSE;
383
384         return 0;
385 }