OSDN Git Service

Merge pull request #204 from dis-/feature/Fix-mon_hook_shallow_water
[hengbandforosx/hengbandosx.git] / src / wizard / monster-info-spoiler.c
1 #include "wizard/monster-info-spoiler.h"
2 #include "io/files-util.h"
3 #include "monster-race/monster-race.h"
4 #include "monster-race/race-flags1.h"
5 #include "monster-race/race-flags7.h"
6 #include "system/angband-version.h"
7 #include "term/term-color-types.h"
8 #include "util/angband-files.h"
9 #include "util/sort.h"
10 #include "view/display-lore.h"
11 #include "view/display-messages.h"
12
13 /*!
14  * @brief シンボル職の記述名を返す /
15  * Extract a textual representation of an attribute
16  * @param r_ptr モンスター種族の構造体ポインタ
17  * @return シンボル職の記述名
18  */
19 static concptr attr_to_text(monster_race *r_ptr)
20 {
21     if (r_ptr->flags1 & RF1_ATTR_CLEAR)
22         return _("透明な", "Clear");
23
24     if (r_ptr->flags1 & RF1_ATTR_MULTI)
25         return _("万色の", "Multi");
26
27     if (r_ptr->flags1 & RF1_ATTR_SEMIRAND)
28         return _("準ランダムな", "S.Rand");
29
30     switch (r_ptr->d_attr) {
31     case TERM_DARK:
32         return _("黒い", "Dark");
33     case TERM_WHITE:
34         return _("白い", "White");
35     case TERM_SLATE:
36         return _("青灰色の", "Slate");
37     case TERM_ORANGE:
38         return _("オレンジの", "Orange");
39     case TERM_RED:
40         return _("赤い", "Red");
41     case TERM_GREEN:
42         return _("緑の", "Green");
43     case TERM_BLUE:
44         return _("青い", "Blue");
45     case TERM_UMBER:
46         return _("琥珀色の", "Umber");
47     case TERM_L_DARK:
48         return _("灰色の", "L.Dark");
49     case TERM_L_WHITE:
50         return _("明るい青灰色の", "L.Slate");
51     case TERM_VIOLET:
52         return _("紫の", "Violet");
53     case TERM_YELLOW:
54         return _("黄色の", "Yellow");
55     case TERM_L_RED:
56         return _("明るい赤の", "L.Red");
57     case TERM_L_GREEN:
58         return _("明るい緑の", "L.Green");
59     case TERM_L_BLUE:
60         return _("明るい青の", "L.Blue");
61     case TERM_L_UMBER:
62         return _("明るい琥珀色の", "L.Umber");
63     }
64
65     return _("変な色の", "Icky");
66 }
67
68 /*!
69  * @brief モンスター簡易情報のスポイラー出力を行うメインルーチン /
70  * Create a spoiler file for monsters   -BEN-
71  * @param fname 生成ファイル名
72  */
73 spoiler_output_status spoil_mon_desc(concptr fname)
74 {
75     player_type dummy;
76     u16b why = 2;
77     MONRACE_IDX *who;
78     char buf[1024];
79     char nam[MAX_MONSTER_NAME + 10]; // ユニークには[U] が付くので少し伸ばす
80     char lev[80];
81     char rar[80];
82     char spd[80];
83     char ac[80];
84     char hp[80];
85     char symbol[80];
86     path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
87     spoiler_file = angband_fopen(buf, "w");
88     if (!spoiler_file) {
89         return SPOILER_OUTPUT_FAIL_FOPEN;
90     }
91
92     char title[200];
93     put_version(title);
94
95     C_MAKE(who, max_r_idx, MONRACE_IDX);
96     fprintf(spoiler_file, "Monster Spoilers for %s\n", title);
97     fprintf(spoiler_file, "------------------------------------------\n\n");
98     fprintf(spoiler_file, "%-162.162s    %4s %4s %4s %7s %7s  %19.19s\n", "Name", "Lev", "Rar", "Spd", "Hp", "Ac", "Visual Info");
99     fprintf(spoiler_file, "%-166.166s%4s %4s %4s %7s %7s  %4.19s\n",
100         "------------------------------------------------------------------------------------------------------------------------------------------------------"
101         "----"
102         "----------",
103         "---", "---", "---", "-----", "-----", "-------------------");
104
105     int n = 0;
106     for (int i = 1; i < max_r_idx; i++) {
107         monster_race *r_ptr = &r_info[i];
108         if (r_ptr->name)
109             who[n++] = (s16b)i;
110     }
111
112     ang_sort(&dummy, who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
113     for (int i = 0; i < n; i++) {
114         monster_race *r_ptr = &r_info[who[i]];
115         concptr name = (r_name + r_ptr->name);
116         if (r_ptr->flags7 & RF7_KAGE)
117             continue;
118         else if (r_ptr->flags1 & (RF1_UNIQUE))
119             sprintf(nam, "[U] %s", name);
120         else
121             sprintf(nam, _("    %s", "The %s"), name);
122
123         sprintf(lev, "%d", (int)r_ptr->level);
124         sprintf(rar, "%d", (int)r_ptr->rarity);
125         if (r_ptr->speed >= 110)
126             sprintf(spd, "+%d", (r_ptr->speed - 110));
127         else
128             sprintf(spd, "-%d", (110 - r_ptr->speed));
129
130         sprintf(ac, "%d", r_ptr->ac);
131         if ((r_ptr->flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1))
132             sprintf(hp, "%d", r_ptr->hdice * r_ptr->hside);
133         else
134             sprintf(hp, "%dd%d", r_ptr->hdice, r_ptr->hside);
135
136         sprintf(symbol, "%ld", (long)(r_ptr->mexp));
137         sprintf(symbol, "%s '%c'", attr_to_text(r_ptr), r_ptr->d_char);
138         fprintf(spoiler_file, "%-166.166s%4s %4s %4s %7s %7s  %19.19s\n", nam, lev, rar, spd, hp, ac, symbol);
139     }
140
141     fprintf(spoiler_file, "\n");
142     C_KILL(who, max_r_idx, s16b);
143     if (ferror(spoiler_file) || angband_fclose(spoiler_file)) {
144         return SPOILER_OUTPUT_FAIL_FCLOSE;
145     }
146     return SPOILER_OUTPUT_SUCCESS;
147 }
148
149 /*!
150  * @brief 関数ポインタ用の出力関数 /
151  * Hook function used in spoil_mon_info()
152  * @param attr 未使用
153  * @param str 文字列参照ポインタ
154  * @return なし
155  */
156 static void roff_func(TERM_COLOR attr, concptr str)
157 {
158     (void)attr;
159     spoil_out(str);
160 }
161
162 /*!
163  * @brief モンスター詳細情報をスポイラー出力するメインルーチン /
164  * Create a spoiler file for monsters (-SHAWN-)
165  * @param fname ファイル名
166  * @return なし
167  */
168 spoiler_output_status spoil_mon_info(concptr fname)
169 {
170     player_type dummy;
171     char buf[1024];
172     path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
173     spoiler_file = angband_fopen(buf, "w");
174     if (!spoiler_file) {
175         return SPOILER_OUTPUT_FAIL_FOPEN;
176     }
177
178     char title[200];
179     put_version(title);
180     sprintf(buf, "Monster Spoilers for %s\n", title);
181     spoil_out(buf);
182     spoil_out("------------------------------------------\n\n");
183
184     MONRACE_IDX *who;
185     C_MAKE(who, max_r_idx, MONRACE_IDX);
186     int n = 0;
187     for (int i = 1; i < max_r_idx; i++) {
188         monster_race *r_ptr = &r_info[i];
189         if (r_ptr->name)
190             who[n++] = (s16b)i;
191     }
192
193     u16b why = 2;
194     ang_sort(&dummy, who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
195     for (int i = 0; i < n; i++) {
196         monster_race *r_ptr = &r_info[who[i]];
197         BIT_FLAGS flags1 = r_ptr->flags1;
198         if (flags1 & (RF1_UNIQUE)) {
199             spoil_out("[U] ");
200         } else {
201 #ifdef JP
202 #else
203             spoil_out("The ");
204 #endif
205         }
206
207         sprintf(buf, _("%s/%s  (", "%s%s ("), (r_name + r_ptr->name), _(r_name + r_ptr->E_name, "")); /* ---)--- */
208         spoil_out(buf);
209         spoil_out(attr_to_text(r_ptr));
210         sprintf(buf, " '%c')\n", r_ptr->d_char);
211         spoil_out(buf);
212         sprintf(buf, "=== ");
213         spoil_out(buf);
214         sprintf(buf, "Num:%d  ", who[i]);
215         spoil_out(buf);
216         sprintf(buf, "Lev:%d  ", (int)r_ptr->level);
217         spoil_out(buf);
218         sprintf(buf, "Rar:%d  ", r_ptr->rarity);
219         spoil_out(buf);
220         if (r_ptr->speed >= 110)
221             sprintf(buf, "Spd:+%d  ", (r_ptr->speed - 110));
222         else
223             sprintf(buf, "Spd:-%d  ", (110 - r_ptr->speed));
224
225         spoil_out(buf);
226         if ((flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1))
227             sprintf(buf, "Hp:%d  ", r_ptr->hdice * r_ptr->hside);
228         else
229             sprintf(buf, "Hp:%dd%d  ", r_ptr->hdice, r_ptr->hside);
230
231         spoil_out(buf);
232         sprintf(buf, "Ac:%d  ", r_ptr->ac);
233         spoil_out(buf);
234         sprintf(buf, "Exp:%ld\n", (long)(r_ptr->mexp));
235         spoil_out(buf);
236         output_monster_spoiler(who[i], roff_func);
237         spoil_out(NULL);
238     }
239
240     C_KILL(who, max_r_idx, s16b);
241     if (ferror(spoiler_file) || angband_fclose(spoiler_file)) {
242         return SPOILER_OUTPUT_FAIL_FCLOSE;
243     }
244     return SPOILER_OUTPUT_SUCCESS;
245 }