OSDN Git Service

[Refactor] #39962 make_character_dump() の返り値をvoid に変更 / Changed return type to void...
[hengband/hengband.git] / src / character-dump.c
1 #include "character-dump.h"
2 #include "core.h"
3 #include "world.h"
4 #include "floor-town.h"
5 #include "dungeon.h"
6 #include "store.h"
7 #include "cmd/cmd-pet.h"
8 #include "cmd/cmd-magiceat.h"
9 #include "objectkind.h"
10 #include "monster-spell.h"
11 #include "monster-status.h"
12 #include "sort.h"
13 #include "quest.h"
14 #include "init.h"
15 #include "mutation.h"
16 #include "object-flavor.h"
17 #include "cmd/cmd-dump.h"
18 #include "avatar.h"
19
20 /*!
21  * @brief プレイヤーのステータス表示をファイルにダンプする
22  * @param creature_ptr プレーヤーへの参照ポインタ
23  * @param fff ファイルポインタ
24  * @return なし
25  */
26 static void dump_aux_display_player(player_type *creature_ptr, FILE *fff, void(*display_player)(player_type*, int))
27 {
28         TERM_COLOR a;
29         char c;
30         char buf[1024];
31         display_player(creature_ptr, 0);
32
33         for (TERM_LEN y = 1; y < 22; y++)
34         {
35                 TERM_LEN x;
36                 for (x = 0; x < 79; x++)
37                 {
38                         (void)(Term_what(x, y, &a, &c));
39                         buf[x] = c;
40                 }
41
42                 buf[x] = '\0';
43                 while ((x > 0) && (buf[x - 1] == ' '))
44                         buf[--x] = '\0';
45
46                 fprintf(fff, _("%s\n", "%s\n"), buf);
47         }
48
49         display_player(creature_ptr, 1);
50         for (TERM_LEN y = 10; y < 19; y++)
51         {
52                 TERM_LEN x;
53                 for (x = 0; x < 79; x++)
54                 {
55                         (void)(Term_what(x, y, &a, &c));
56                         buf[x] = c;
57                 }
58
59                 buf[x] = '\0';
60                 while ((x > 0) && (buf[x - 1] == ' '))
61                         buf[--x] = '\0';
62
63                 fprintf(fff, "%s\n", buf);
64         }
65
66         fprintf(fff, "\n");
67         display_player(creature_ptr, 2);
68         for (TERM_LEN y = 2; y < 22; y++)
69         {
70                 TERM_LEN x;
71                 for (x = 0; x < 79; x++)
72                 {
73                         (void)(Term_what(x, y, &a, &c));
74                         if (a < 128)
75                                 buf[x] = c;
76                         else
77                                 buf[x] = ' ';
78                 }
79
80                 buf[x] = '\0';
81                 while ((x > 0) && (buf[x - 1] == ' '))
82                         buf[--x] = '\0';
83
84                 fprintf(fff, "%s\n", buf);
85         }
86
87         fprintf(fff, "\n");
88         display_player(creature_ptr, 3);
89         for (TERM_LEN y = 1; y < 22; y++)
90         {
91                 TERM_LEN x;
92                 for (x = 0; x < 79; x++)
93                 {
94                         (void)(Term_what(x, y, &a, &c));
95                         if (a < 128)
96                                 buf[x] = c;
97                         else
98                                 buf[x] = ' ';
99                 }
100
101                 buf[x] = '\0';
102                 while ((x > 0) && (buf[x - 1] == ' '))
103                         buf[--x] = '\0';
104
105                 fprintf(fff, "%s\n", buf);
106         }
107
108         fprintf(fff, "\n");
109 }
110
111
112 /*!
113  * @brief プレイヤーのペット情報をファイルにダンプする
114  * @param creature_ptr プレーヤーへの参照ポインタ
115  * @param fff ファイルポインタ
116  * @return なし
117  */
118 static void dump_aux_pet(player_type *master_ptr, FILE *fff)
119 {
120         bool pet = FALSE;
121         bool pet_settings = FALSE;
122         for (int i = master_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
123         {
124                 monster_type *m_ptr = &master_ptr->current_floor_ptr->m_list[i];
125
126                 if (!monster_is_valid(m_ptr)) continue;
127                 if (!is_pet(m_ptr)) continue;
128                 pet_settings = TRUE;
129                 if (!m_ptr->nickname && (master_ptr->riding != i)) continue;
130                 if (!pet)
131                 {
132                         fprintf(fff, _("\n\n  [主なペット]\n\n", "\n\n  [Leading Pets]\n\n"));
133                         pet = TRUE;
134                 }
135
136                 GAME_TEXT pet_name[MAX_NLEN];
137                 monster_desc(master_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
138                 fprintf(fff, "%s\n", pet_name);
139         }
140
141         if (!pet_settings) return;
142
143         fprintf(fff, _("\n\n  [ペットへの命令]\n", "\n\n  [Command for Pets]\n"));
144
145         fprintf(fff, _("\n ドアを開ける:                       %s", "\n Pets open doors:                    %s"),
146                 (master_ptr->pet_extra_flags & PF_OPEN_DOORS) ? "ON" : "OFF");
147
148         fprintf(fff, _("\n アイテムを拾う:                     %s", "\n Pets pick up items:                 %s"),
149                 (master_ptr->pet_extra_flags & PF_PICKUP_ITEMS) ? "ON" : "OFF");
150
151         fprintf(fff, _("\n テレポート系魔法を使う:             %s", "\n Allow teleport:                     %s"),
152                 (master_ptr->pet_extra_flags & PF_TELEPORT) ? "ON" : "OFF");
153
154         fprintf(fff, _("\n 攻撃魔法を使う:                     %s", "\n Allow cast attack spell:            %s"),
155                 (master_ptr->pet_extra_flags & PF_ATTACK_SPELL) ? "ON" : "OFF");
156
157         fprintf(fff, _("\n 召喚魔法を使う:                     %s", "\n Allow cast summon spell:            %s"),
158                 (master_ptr->pet_extra_flags & PF_SUMMON_SPELL) ? "ON" : "OFF");
159
160         fprintf(fff, _("\n プレイヤーを巻き込む範囲魔法を使う: %s", "\n Allow involve player in area spell: %s"),
161                 (master_ptr->pet_extra_flags & PF_BALL_SPELL) ? "ON" : "OFF");
162
163         fputc('\n', fff);
164 }
165
166
167 /*!
168  * todo ここはenum/switchで扱いたい
169  * @brief プレイヤーの職業能力情報をファイルにダンプする
170  * @param creature_ptr プレーヤーへの参照ポインタ
171  * @param fff ファイルポインタ
172  * @return なし
173  */
174 static void dump_aux_class_special(player_type *creature_ptr, FILE *fff)
175 {
176         bool is_special_class = creature_ptr->pclass == CLASS_MAGIC_EATER;
177         is_special_class |= creature_ptr->pclass == CLASS_SMITH;
178         is_special_class |= creature_ptr->pclass != CLASS_BLUE_MAGE;
179         if (!is_special_class) return;
180
181         if (creature_ptr->pclass == CLASS_MAGIC_EATER)
182         {
183                 char s[EATER_EXT][MAX_NLEN];
184                 OBJECT_TYPE_VALUE tval = 0;
185                 fprintf(fff, _("\n\n  [取り込んだ魔法道具]\n", "\n\n  [Magic devices eaten]\n"));
186
187                 for (int ext = 0; ext < 3; ext++)
188                 {
189                         int eat_num = 0;
190
191                         /* Dump an extent name */
192                         switch (ext)
193                         {
194                         case 0:
195                                 tval = TV_STAFF;
196                                 fprintf(fff, _("\n[杖]\n", "\n[Staffs]\n"));
197                                 break;
198                         case 1:
199                                 tval = TV_WAND;
200                                 fprintf(fff, _("\n[魔法棒]\n", "\n[Wands]\n"));
201                                 break;
202                         case 2:
203                                 tval = TV_ROD;
204                                 fprintf(fff, _("\n[ロッド]\n", "\n[Rods]\n"));
205                                 break;
206                         }
207
208                         /* Get magic device names that were eaten */
209                         for (OBJECT_SUBTYPE_VALUE i = 0; i < EATER_EXT; i++)
210                         {
211                                 int idx = EATER_EXT * ext + i;
212                                 int magic_num = creature_ptr->magic_num2[idx];
213                                 if (!magic_num) continue;
214
215                                 KIND_OBJECT_IDX k_idx = lookup_kind(tval, i);
216                                 if (!k_idx) continue;
217                                 sprintf(s[eat_num], "%23s (%2d)", (k_name + k_info[k_idx].name), magic_num);
218                                 eat_num++;
219                         }
220
221                         /* Dump magic devices in this extent */
222                         if (eat_num <= 0)
223                         {
224                                 fputs(_("  (なし)\n", "  (none)\n"), fff);
225                                 continue;
226                         }
227
228                         OBJECT_SUBTYPE_VALUE i;
229                         for (i = 0; i < eat_num; i++)
230                         {
231                                 fputs(s[i], fff);
232                                 if (i % 3 < 2) fputs("    ", fff);
233                                 else fputs("\n", fff);
234                         }
235
236                         if (i % 3 > 0) fputs("\n", fff);
237                 }
238
239                 return;
240         }
241
242         if (creature_ptr->pclass == CLASS_SMITH)
243         {
244                 int i, id[250], n = 0, row;
245
246                 fprintf(fff, _("\n\n  [手に入れたエッセンス]\n\n", "\n\n  [Get Essence]\n\n"));
247                 fprintf(fff, _("エッセンス   個数     エッセンス   個数     エッセンス   個数",
248                         "Essence      Num      Essence      Num      Essence      Num "));
249                 for (i = 0; essence_name[i]; i++)
250                 {
251                         if (!essence_name[i][0]) continue;
252                         id[n] = i;
253                         n++;
254                 }
255
256                 row = n / 3 + 1;
257
258                 for (i = 0; i < row; i++)
259                 {
260                         fprintf(fff, "\n");
261                         fprintf(fff, "%-11s %5d     ", essence_name[id[i]], (int)creature_ptr->magic_num1[id[i]]);
262                         if (i + row < n) fprintf(fff, "%-11s %5d     ", essence_name[id[i + row]], (int)creature_ptr->magic_num1[id[i + row]]);
263                         if (i + row * 2 < n) fprintf(fff, "%-11s %5d", essence_name[id[i + row * 2]], (int)creature_ptr->magic_num1[id[i + row * 2]]);
264                 }
265
266                 fputs("\n", fff);
267                 return;
268         }
269
270         // Blue mage
271         int l1 = 0;
272         int l2 = 0;
273         int spellnum[MAX_MONSPELLS];
274         BIT_FLAGS f4 = 0, f5 = 0, f6 = 0;
275         char p[60][80];
276         int col = 0;
277         bool pcol = FALSE;
278
279         for (int i = 0; i < 60; i++)
280         {
281                 p[i][0] = '\0';
282         }
283
284         strcat(p[col], _("\n\n  [学習済みの青魔法]\n", "\n\n  [Learned Blue Magic]\n"));
285
286         for (int j = 1; j < 6; j++)
287         {
288                 col++;
289                 set_rf_masks(&f4, &f5, &f6, j);
290                 switch (j)
291                 {
292                 case MONSPELL_TYPE_BOLT:
293                         strcat(p[col], _("\n     [ボルト型]\n", "\n     [Bolt  Type]\n"));
294                         break;
295
296                 case MONSPELL_TYPE_BALL:
297                         strcat(p[col], _("\n     [ボール型]\n", "\n     [Ball  Type]\n"));
298                         break;
299
300                 case MONSPELL_TYPE_BREATH:
301                         strcat(p[col], _("\n     [ブレス型]\n", "\n     [  Breath  ]\n"));
302                         break;
303
304                 case MONSPELL_TYPE_SUMMON:
305                         strcat(p[col], _("\n     [召喚魔法]\n", "\n     [Summonning]\n"));
306                         break;
307
308                 case MONSPELL_TYPE_OTHER:
309                         strcat(p[col], _("\n     [ その他 ]\n", "\n     [Other Type]\n"));
310                         break;
311                 }
312
313                 int num = 0;
314                 for (int i = 0; i < 32; i++)
315                 {
316                         if ((0x00000001 << i) & f4) spellnum[num++] = i;
317                 }
318
319                 for (int i = 32; i < 64; i++)
320                 {
321                         if ((0x00000001 << (i - 32)) & f5) spellnum[num++] = i;
322                 }
323
324                 for (int i = 64; i < 96; i++)
325                 {
326                         if ((0x00000001 << (i - 64)) & f6) spellnum[num++] = i;
327                 }
328
329                 col++;
330                 pcol = FALSE;
331                 strcat(p[col], "       ");
332
333                 for (int i = 0; i < num; i++)
334                 {
335                         if (creature_ptr->magic_num2[spellnum[i]] == 0) continue;
336
337                         pcol = TRUE;
338                         /* Dump blue magic */
339                         l1 = strlen(p[col]);
340                         l2 = strlen(monster_powers_short[spellnum[i]]);
341                         if ((l1 + l2) >= 75)
342                         {
343                                 strcat(p[col], "\n");
344                                 col++;
345                                 strcat(p[col], "       ");
346                         }
347
348                         strcat(p[col], monster_powers_short[spellnum[i]]);
349                         strcat(p[col], ", ");
350                 }
351
352                 if (!pcol)
353                 {
354                         strcat(p[col], _("なし", "None"));
355                         strcat(p[col], "\n");
356                         continue;
357                 }
358
359                 if (p[col][strlen(p[col]) - 2] == ',')
360                 {
361                         p[col][strlen(p[col]) - 2] = '\0';
362                 }
363                 else
364                 {
365                         p[col][strlen(p[col]) - 10] = '\0';
366                 }
367
368                 strcat(p[col], "\n");
369         }
370
371         for (int i = 0; i <= col; i++)
372         {
373                 fputs(p[i], fff);
374         }
375 }
376
377
378 /*!
379  * @brief クエスト情報をファイルにダンプする
380  * @param creature_ptr プレーヤーへの参照ポインタ
381  * @param fff ファイルポインタ
382  * @return なし
383  */
384 static void dump_aux_quest(player_type *creature_ptr, FILE *fff)
385 {
386         fprintf(fff, _("\n\n  [クエスト情報]\n", "\n\n  [Quest Information]\n"));
387         QUEST_IDX *quest_num;
388         C_MAKE(quest_num, max_q_idx, QUEST_IDX);
389
390         for (QUEST_IDX i = 1; i < max_q_idx; i++)
391                 quest_num[i] = i;
392         int dummy;
393         ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
394
395         fputc('\n', fff);
396         do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
397         fputc('\n', fff);
398         do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
399         fputc('\n', fff);
400
401         C_KILL(quest_num, max_q_idx, QUEST_IDX);
402 }
403
404
405 /*!
406  * @brief 死の直前メッセージ並びに遺言をファイルにダンプする
407  * @param creature_ptr プレーヤーへの参照ポインタ
408  * @param fff ファイルポインタ
409  * @return なし
410  */
411 static void dump_aux_last_message(player_type *creature_ptr, FILE *fff)
412 {
413         if (!creature_ptr->is_dead) return;
414
415         if (!current_world_ptr->total_winner)
416         {
417                 fprintf(fff, _("\n  [死ぬ直前のメッセージ]\n\n", "\n  [Last Messages]\n\n"));
418                 for (int i = MIN(message_num(), 30); i >= 0; i--)
419                 {
420                         fprintf(fff, "> %s\n", message_str((s16b)i));
421                 }
422
423                 fputc('\n', fff);
424                 return;
425         }
426
427         if (creature_ptr->last_message)
428         {
429                 fprintf(fff, _("\n  [*勝利*メッセージ]\n\n", "\n  [*Winning* Message]\n\n"));
430                 fprintf(fff, "  %s\n", creature_ptr->last_message);
431                 fputc('\n', fff);
432         }
433 }
434
435
436 /*!
437  * @brief 帰還場所情報をファイルにダンプする
438  * @param fff ファイルポインタ
439  * @return なし
440  */
441 static void dump_aux_recall(FILE *fff)
442 {
443         fprintf(fff, _("\n  [帰還場所]\n\n", "\n  [Recall Depth]\n\n"));
444         for (int y = 1; y < current_world_ptr->max_d_idx; y++)
445         {
446                 bool seiha = FALSE;
447
448                 if (!d_info[y].maxdepth) continue;
449                 if (!max_dlv[y]) continue;
450                 if (d_info[y].final_guardian)
451                 {
452                         if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
453                 }
454                 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
455
456                 fprintf(fff, _("   %c%-12s: %3d 階\n", "   %c%-16s: level %3d\n"),
457                         seiha ? '!' : ' ', d_name + d_info[y].name, (int)max_dlv[y]);
458         }
459 }
460
461
462 /*!
463  * @brief オプション情報をファイルにダンプする
464  * @param fff ファイルポインタ
465  * @return なし
466  */
467 static void dump_aux_options(FILE *fff)
468 {
469         fprintf(fff, _("\n  [オプション設定]\n", "\n  [Option Settings]\n"));
470         if (preserve_mode)
471                 fprintf(fff, _("\n 保存モード:         ON", "\n Preserve Mode:      ON"));
472
473         else
474                 fprintf(fff, _("\n 保存モード:         OFF", "\n Preserve Mode:      OFF"));
475
476         if (ironman_small_levels)
477                 fprintf(fff, _("\n 小さいダンジョン:   ALWAYS", "\n Small Levels:       ALWAYS"));
478         else if (always_small_levels)
479                 fprintf(fff, _("\n 小さいダンジョン:   ON", "\n Small Levels:       ON"));
480         else if (small_levels)
481                 fprintf(fff, _("\n 小さいダンジョン:   ENABLED", "\n Small Levels:       ENABLED"));
482         else
483                 fprintf(fff, _("\n 小さいダンジョン:   OFF", "\n Small Levels:       OFF"));
484
485         if (vanilla_town)
486                 fprintf(fff, _("\n 元祖の町のみ:       ON", "\n Vanilla Town:       ON"));
487         else if (lite_town)
488                 fprintf(fff, _("\n 小規模な町:         ON", "\n Lite Town:          ON"));
489
490         if (ironman_shops)
491                 fprintf(fff, _("\n 店なし:             ON", "\n No Shops:           ON"));
492
493         if (ironman_downward)
494                 fprintf(fff, _("\n 階段を上がれない:   ON", "\n Diving Only:        ON"));
495
496         if (ironman_rooms)
497                 fprintf(fff, _("\n 普通でない部屋:     ON", "\n Unusual Rooms:      ON"));
498
499         if (ironman_nightmare)
500                 fprintf(fff, _("\n 悪夢モード:         ON", "\n Nightmare Mode:     ON"));
501
502         if (ironman_empty_levels)
503                 fprintf(fff, _("\n アリーナ:           ALWAYS", "\n Arena Levels:       ALWAYS"));
504         else if (empty_levels)
505                 fprintf(fff, _("\n アリーナ:           ENABLED", "\n Arena Levels:       ENABLED"));
506         else
507                 fprintf(fff, _("\n アリーナ:           OFF", "\n Arena Levels:       OFF"));
508
509         fputc('\n', fff);
510
511         if (current_world_ptr->noscore)
512                 fprintf(fff, _("\n 何か不正なことをしてしまっています。\n", "\n You have done something illegal.\n"));
513
514         fputc('\n', fff);
515 }
516
517
518 /*!
519  * @brief 闘技場の情報をファイルにダンプする
520  * @param creature_ptr プレーヤーへの参照ポインタ
521  * @param fff ファイルポインタ
522  * @return なし
523  */
524 static void dump_aux_arena(player_type *creature_ptr, FILE *fff)
525 {
526         if (lite_town || vanilla_town) return;
527
528         if (creature_ptr->arena_number < 0)
529         {
530                 if (creature_ptr->arena_number <= ARENA_DEFEATED_OLD_VER)
531                 {
532                         fprintf(fff, _("\n 闘技場: 敗北\n", "\n Arena: Defeated\n"));
533                 }
534                 else
535                 {
536 #ifdef JP
537                         fprintf(fff, "\n 闘技場: %d回戦で%sの前に敗北\n", -creature_ptr->arena_number,
538                                 r_name + r_info[arena_info[-1 - creature_ptr->arena_number].r_idx].name);
539 #else
540                         fprintf(fff, "\n Arena: Defeated by %s in the %d%s fight\n",
541                                 r_name + r_info[arena_info[-1 - creature_ptr->arena_number].r_idx].name,
542                                 -creature_ptr->arena_number, get_ordinal_number_suffix(-creature_ptr->arena_number));
543 #endif
544                 }
545
546                 fprintf(fff, "\n");
547                 return;
548         }
549
550         if (creature_ptr->arena_number > MAX_ARENA_MONS + 2)
551         {
552                 fprintf(fff, _("\n 闘技場: 真のチャンピオン\n", "\n Arena: True Champion\n"));
553                 fprintf(fff, "\n");
554                 return;
555         }
556
557         if (creature_ptr->arena_number > MAX_ARENA_MONS - 1)
558         {
559                 fprintf(fff, _("\n 闘技場: チャンピオン\n", "\n Arena: Champion\n"));
560                 fprintf(fff, "\n");
561                 return;
562         }
563
564 #ifdef JP
565         fprintf(fff, "\n 闘技場: %2d勝\n", (creature_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : creature_ptr->arena_number));
566 #else
567         fprintf(fff, "\n Arena: %2d Victor%s\n", (creature_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : creature_ptr->arena_number), (creature_ptr->arena_number > 1) ? "ies" : "y");
568 #endif
569         fprintf(fff, "\n");
570 }
571
572
573 /*!
574  * @brief 撃破モンスターの情報をファイルにダンプする
575  * @param fff ファイルポインタ
576  * @return なし
577  */
578 static void dump_aux_monsters(FILE *fff)
579 {
580         fprintf(fff, _("\n  [倒したモンスター]\n\n", "\n  [Defeated Monsters]\n\n"));
581
582         /* Allocate the "who" array */
583         MONRACE_IDX *who;
584         u16b why = 2;
585         C_MAKE(who, max_r_idx, MONRACE_IDX);
586
587         /* Count monster kills */
588         long uniq_total = 0;
589         long norm_total = 0;
590         for (IDX k = 1; k < max_r_idx; k++)
591         {
592                 /* Ignore unused index */
593                 monster_race *r_ptr = &r_info[k];
594                 if (!r_ptr->name) continue;
595
596                 if (r_ptr->flags1 & RF1_UNIQUE)
597                 {
598                         bool dead = (r_ptr->max_num == 0);
599                         if (dead)
600                         {
601                                 norm_total++;
602
603                                 /* Add a unique monster to the list */
604                                 who[uniq_total++] = k;
605                         }
606
607                         continue;
608                 }
609
610                 if (r_ptr->r_pkills > 0)
611                 {
612                         norm_total += r_ptr->r_pkills;
613                 }
614         }
615
616         /* No monsters is defeated */
617         if (norm_total < 1)
618         {
619                 fprintf(fff, _("まだ敵を倒していません。\n", "You have defeated no enemies yet.\n"));
620                 C_KILL(who, max_r_idx, s16b);
621                 return;
622         }
623
624         /* Defeated more than one normal monsters */
625         if (uniq_total == 0)
626         {
627 #ifdef JP
628                 fprintf(fff, "%ld体の敵を倒しています。\n", norm_total);
629 #else
630                 fprintf(fff, "You have defeated %ld %s.\n", norm_total, norm_total == 1 ? "enemy" : "enemies");
631 #endif
632                 C_KILL(who, max_r_idx, s16b);
633                 return;
634         }
635
636         /* Defeated more than one unique monsters */
637 #ifdef JP
638         fprintf(fff, "%ld体のユニーク・モンスターを含む、合計%ld体の敵を倒しています。\n", uniq_total, norm_total);
639 #else
640         fprintf(fff, "You have defeated %ld %s including %ld unique monster%s in total.\n", norm_total, norm_total == 1 ? "enemy" : "enemies", uniq_total, (uniq_total == 1 ? "" : "s"));
641 #endif
642
643         /* Sort the array by dungeon depth of monsters */
644         ang_sort(who, &why, uniq_total, ang_sort_comp_hook, ang_sort_swap_hook);
645         fprintf(fff, _("\n《上位%ld体のユニーク・モンスター》\n", "\n< Unique monsters top %ld >\n"), MIN(uniq_total, 10));
646
647         for (IDX k = uniq_total - 1; k >= 0 && k >= uniq_total - 10; k--)
648         {
649                 monster_race *r_ptr = &r_info[who[k]];
650                 fprintf(fff, _("  %-40s (レベル%3d)\n", "  %-40s (level %3d)\n"), (r_name + r_ptr->name), (int)r_ptr->level);
651         }
652
653         C_KILL(who, max_r_idx, s16b);
654 }
655
656
657 /*!
658  * @brief 元種族情報をファイルにダンプする
659  * @param creature_ptr プレーヤーへの参照ポインタ
660  * @param fff ファイルポインタ
661  * @return なし
662  */
663 static void dump_aux_race_history(player_type *creature_ptr, FILE *fff)
664 {
665         if (!creature_ptr->old_race1 && !creature_ptr->old_race2) return;
666
667         fprintf(fff, _("\n\n あなたは%sとして生まれた。", "\n\n You were born as %s."), race_info[creature_ptr->start_race].title);
668         for (int i = 0; i < MAX_RACES; i++)
669         {
670                 if (creature_ptr->start_race == i) continue;
671                 if (i < 32)
672                 {
673                         if (!(creature_ptr->old_race1 & 1L << i)) continue;
674                 }
675                 else
676                 {
677                         if (!(creature_ptr->old_race2 & 1L << (i - 32))) continue;
678                 }
679
680                 fprintf(fff, _("\n あなたはかつて%sだった。", "\n You were a %s before."), race_info[i].title);
681         }
682
683         fputc('\n', fff);
684 }
685
686
687 /*!
688  * @brief 元魔法領域情報をファイルにダンプする
689  * @param creature_ptr プレーヤーへの参照ポインタ
690  * @param fff ファイルポインタ
691  * @return なし
692  */
693 static void dump_aux_realm_history(player_type *creature_ptr, FILE *fff)
694 {
695         if (creature_ptr->old_realm) return;
696
697         fputc('\n', fff);
698         for (int i = 0; i < MAX_MAGIC; i++)
699         {
700                 if (!(creature_ptr->old_realm & 1L << i)) continue;
701                 fprintf(fff, _("\n あなたはかつて%s魔法を使えた。", "\n You were able to use %s magic before."), realm_names[i + 1]);
702         }
703
704         fputc('\n', fff);
705 }
706
707
708 /*!
709  * @brief 徳の情報をファイルにダンプする
710  * @param creature_ptr プレーヤーへの参照ポインタ
711  * @param fff ファイルポインタ
712  * @return なし
713  */
714 static void dump_aux_virtues(player_type *creature_ptr, FILE *fff)
715 {
716         fprintf(fff, _("\n\n  [自分に関する情報]\n\n", "\n\n  [HP-rate & Max stat & Virtues]\n\n"));
717
718         int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
719                 (2 * creature_ptr->hitdie +
720                 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
721
722 #ifdef JP
723         if (creature_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
724         else fprintf(fff, "現在の体力ランク : ???\n\n");
725         fprintf(fff, "能力の最大値\n");
726 #else
727         if (creature_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
728         else fprintf(fff, "Your current Life Rating is ???.\n\n");
729         fprintf(fff, "Limits of maximum stats\n");
730 #endif
731         for (int v_nr = 0; v_nr < A_MAX; v_nr++)
732         {
733                 if ((creature_ptr->knowledge & KNOW_STAT) || creature_ptr->stat_max[v_nr] == creature_ptr->stat_max_max[v_nr]) fprintf(fff, "%s 18/%d\n", stat_names[v_nr], creature_ptr->stat_max_max[v_nr] - 18);
734                 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
735         }
736
737         fprintf(fff, _("\n属性 : %s\n", "\nYour alignment : %s\n"), your_alignment(creature_ptr));
738         fprintf(fff, "\n");
739         dump_virtues(creature_ptr, fff);
740 }
741
742
743 /*!
744  * @brief 突然変異の情報をファイルにダンプする
745  * @param creature_ptr プレーヤーへの参照ポインタ
746  * @param fff ファイルポインタ
747  * @return なし
748  */
749 static void dump_aux_mutations(player_type *creature_ptr, FILE *fff)
750 {
751         if (creature_ptr->muta1 || creature_ptr->muta2 || creature_ptr->muta3)
752         {
753                 fprintf(fff, _("\n\n  [突然変異]\n\n", "\n\n  [Mutations]\n\n"));
754                 dump_mutations(creature_ptr, fff);
755         }
756 }
757
758
759 /*!
760  * @brief 所持品の情報をファイルにダンプする
761  * @param creature_ptr プレーヤーへの参照ポインタ
762  * @param fff ファイルポインタ
763  * @return なし
764  */
765 static void dump_aux_equipment_inventory(player_type *creature_ptr, FILE *fff)
766 {
767         GAME_TEXT o_name[MAX_NLEN];
768         if (creature_ptr->equip_cnt)
769         {
770                 fprintf(fff, _("  [キャラクタの装備]\n\n", "  [Character Equipment]\n\n"));
771                 for (int i = INVEN_RARM; i < INVEN_TOTAL; i++)
772                 {
773                         object_desc(creature_ptr, o_name, &creature_ptr->inventory_list[i], 0);
774                         if ((((i == INVEN_RARM) && creature_ptr->hidarite) || ((i == INVEN_LARM) && creature_ptr->migite)) && creature_ptr->ryoute)
775                                 strcpy(o_name, _("(武器を両手持ち)", "(wielding with two-hands)"));
776
777                         fprintf(fff, "%c) %s\n",
778                                 index_to_label(i), o_name);
779                 }
780
781                 fprintf(fff, "\n\n");
782         }
783
784         fprintf(fff, _("  [キャラクタの持ち物]\n\n", "  [Character Inventory]\n\n"));
785
786         for (int i = 0; i < INVEN_PACK; i++)
787         {
788                 if (!creature_ptr->inventory_list[i].k_idx) break;
789                 object_desc(creature_ptr, o_name, &creature_ptr->inventory_list[i], 0);
790                 fprintf(fff, "%c) %s\n", index_to_label(i), o_name);
791         }
792
793         fprintf(fff, "\n\n");
794 }
795
796
797 /*!
798  * @brief 我が家と博物館のオブジェクト情報をファイルにダンプする
799  * @param fff ファイルポインタ
800  * @return なし
801  */
802 static void dump_aux_home_museum(player_type *creature_ptr, FILE *fff)
803 {
804         store_type  *st_ptr;
805         st_ptr = &town_info[1].store[STORE_HOME];
806
807         GAME_TEXT o_name[MAX_NLEN];
808         if (st_ptr->stock_num)
809         {
810                 fprintf(fff, _("  [我が家のアイテム]\n", "  [Home Inventory]\n"));
811
812                 TERM_LEN x = 1;
813                 for (int i = 0; i < st_ptr->stock_num; i++)
814                 {
815                         if ((i % 12) == 0)
816                                 fprintf(fff, _("\n ( %d ページ )\n", "\n ( page %d )\n"), x++);
817                         object_desc(creature_ptr, o_name, &st_ptr->stock[i], 0);
818                         fprintf(fff, "%c) %s\n", I2A(i % 12), o_name);
819                 }
820
821                 fprintf(fff, "\n\n");
822         }
823
824         st_ptr = &town_info[1].store[STORE_MUSEUM];
825
826         if (st_ptr->stock_num == 0) return;
827
828         fprintf(fff, _("  [博物館のアイテム]\n", "  [Museum]\n"));
829
830         TERM_LEN x = 1;
831         for (int i = 0; i < st_ptr->stock_num; i++)
832         {
833 #ifdef JP
834                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
835                 object_desc(creature_ptr, o_name, &st_ptr->stock[i], 0);
836                 fprintf(fff, "%c) %s\n", I2A(i % 12), o_name);
837 #else
838                 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
839                 object_desc(creature_ptr, o_name, &st_ptr->stock[i], 0);
840                 fprintf(fff, "%c) %s\n", I2A(i % 12), o_name);
841 #endif
842         }
843
844         fprintf(fff, "\n\n");
845 }
846
847
848 /*!
849  * @brief ダンプ出力のメインルーチン
850  * Output the character dump to a file
851  * @param creature_ptr プレーヤーへの参照ポインタ
852  * @param fff ファイルポインタ
853  * @return エラーコード
854  */
855 void make_character_dump(player_type *creature_ptr, FILE *fff, void(*update_playtime)(void), void(*display_player)(player_type*, int))
856 {
857 #ifdef JP
858         fprintf(fff, "  [変愚蛮怒 %d.%d.%d キャラクタ情報]\n\n",
859                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
860 #else
861         fprintf(fff, "  [Hengband %d.%d.%d Character Dump]\n\n",
862                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
863 #endif
864         (*update_playtime)();
865
866         dump_aux_display_player(creature_ptr, fff, display_player);
867         dump_aux_last_message(creature_ptr, fff);
868         dump_aux_options(fff);
869         dump_aux_recall(fff);
870         dump_aux_quest(creature_ptr, fff);
871         dump_aux_arena(creature_ptr, fff);
872         dump_aux_monsters(fff);
873         dump_aux_virtues(creature_ptr, fff);
874         dump_aux_race_history(creature_ptr, fff);
875         dump_aux_realm_history(creature_ptr, fff);
876         dump_aux_class_special(creature_ptr, fff);
877         dump_aux_mutations(creature_ptr, fff);
878         dump_aux_pet(creature_ptr, fff);
879         fputs("\n\n", fff);
880         dump_aux_equipment_inventory(creature_ptr, fff);
881         dump_aux_home_museum(creature_ptr, fff);
882
883         fprintf(fff, _("  [チェックサム: \"%s\"]\n\n", "  [Check Sum: \"%s\"]\n\n"), get_check_sum());
884 }