OSDN Git Service

Merge pull request #2757 from sikabane-works/Deskull/fix-help-and-news
[hengbandforosx/hengbandosx.git] / src / view / display-lore-status.cpp
1 #include "view/display-lore-status.h"
2 #include "locale/japanese.h"
3 #include "lore/lore-calculator.h"
4 #include "lore/lore-util.h"
5 #include "monster-race/monster-race.h"
6 #include "monster-race/race-flags-resistance.h"
7 #include "monster-race/race-flags1.h"
8 #include "monster-race/race-flags2.h"
9 #include "monster-race/race-flags3.h"
10 #include "monster-race/race-flags7.h"
11 #include "system/monster-race-definition.h"
12 #include "system/monster-type-definition.h"
13 #include "term/term-color-types.h"
14
15 void display_monster_hp_ac(lore_type *lore_ptr)
16 {
17     if (!know_armour(lore_ptr->r_idx, lore_ptr->know_everything)) {
18         return;
19     }
20
21     hooked_roff(format(_("%^sは AC%d の防御力と", "%^s has an armor rating of %d"), Who::who(lore_ptr->msex), lore_ptr->r_ptr->ac));
22     if ((lore_ptr->flags1 & RF1_FORCE_MAXHP) || (lore_ptr->r_ptr->hside == 1)) {
23         auto hp = lore_ptr->r_ptr->hdice * (lore_ptr->nightmare ? 2 : 1) * lore_ptr->r_ptr->hside;
24         hooked_roff(format(_(" %d の体力がある。", " and a life rating of %d.  "), std::min(MONSTER_MAXHP, hp)));
25     } else {
26         hooked_roff(format(
27             _(" %dd%d の体力がある。", " and a life rating of %dd%d.  "), lore_ptr->r_ptr->hdice * (lore_ptr->nightmare ? 2 : 1), lore_ptr->r_ptr->hside));
28     }
29 }
30
31 void display_monster_concrete_abilities(lore_type *lore_ptr)
32 {
33     if (lore_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) {
34         lore_ptr->vp[lore_ptr->vn] = _("ダンジョンを照らす", "illuminate the dungeon");
35         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
36     }
37
38     if (lore_ptr->flags7 & (RF7_HAS_DARK_1 | RF7_HAS_DARK_2)) {
39         lore_ptr->vp[lore_ptr->vn] = _("ダンジョンを暗くする", "darken the dungeon");
40         lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
41     }
42
43     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::OPEN_DOOR)) {
44         lore_ptr->vp[lore_ptr->vn] = _("ドアを開ける", "open doors");
45         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
46     }
47
48     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::BASH_DOOR)) {
49         lore_ptr->vp[lore_ptr->vn] = _("ドアを打ち破る", "bash down doors");
50         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
51     }
52
53     if (lore_ptr->feature_flags.has(MonsterFeatureType::CAN_FLY)) {
54         lore_ptr->vp[lore_ptr->vn] = _("空を飛ぶ", "fly");
55         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
56     }
57
58     if (lore_ptr->feature_flags.has(MonsterFeatureType::CAN_SWIM)) {
59         lore_ptr->vp[lore_ptr->vn] = _("水を渡る", "swim");
60         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
61     }
62
63     if (lore_ptr->feature_flags.has(MonsterFeatureType::PASS_WALL)) {
64         lore_ptr->vp[lore_ptr->vn] = _("壁をすり抜ける", "pass through walls");
65         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
66     }
67
68     if (lore_ptr->feature_flags.has(MonsterFeatureType::KILL_WALL)) {
69         lore_ptr->vp[lore_ptr->vn] = _("壁を掘り進む", "bore through walls");
70         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
71     }
72
73     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::MOVE_BODY)) {
74         lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを押しのける", "push past weaker monsters");
75         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
76     }
77
78     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY)) {
79         lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを倒す", "destroy weaker monsters");
80         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
81     }
82
83     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM)) {
84         lore_ptr->vp[lore_ptr->vn] = _("アイテムを拾う", "pick up objects");
85         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
86     }
87
88     if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_ITEM)) {
89         lore_ptr->vp[lore_ptr->vn] = _("アイテムを壊す", "destroy objects");
90         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
91     }
92 }
93
94 void display_monster_abilities(lore_type *lore_ptr)
95 {
96     if (lore_ptr->vn <= 0) {
97         return;
98     }
99
100     hooked_roff(format(_("%^sは", "%^s"), Who::who(lore_ptr->msex)));
101     for (int n = 0; n < lore_ptr->vn; n++) {
102 #ifdef JP
103         if (n != lore_ptr->vn - 1) {
104             jverb(lore_ptr->vp[n], lore_ptr->jverb_buf, JVERB_AND);
105             hook_c_roff(lore_ptr->color[n], lore_ptr->jverb_buf);
106             hooked_roff("、");
107         } else {
108             hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
109         }
110 #else
111         if (n == 0) {
112             hooked_roff(" can ");
113         } else if (n < lore_ptr->vn - 1) {
114             hooked_roff(", ");
115         } else {
116             hooked_roff(" and ");
117         }
118
119         hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
120 #endif
121     }
122
123     hooked_roff(_("ことができる。", ".  "));
124 }
125
126 void display_monster_constitutions(lore_type *lore_ptr)
127 {
128     if (lore_ptr->feature_flags.has(MonsterFeatureType::AQUATIC)) {
129         hooked_roff(format(_("%^sは水中に棲んでいる。", "%^s lives in water.  "), Who::who(lore_ptr->msex)));
130     }
131
132     if (lore_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2)) {
133         hooked_roff(format(_("%^sは光っている。", "%^s is shining.  "), Who::who(lore_ptr->msex)));
134     }
135
136     if (lore_ptr->flags7 & (RF7_SELF_DARK_1 | RF7_SELF_DARK_2)) {
137         hook_c_roff(TERM_L_DARK, format(_("%^sは暗黒に包まれている。", "%^s is surrounded by darkness.  "), Who::who(lore_ptr->msex)));
138     }
139
140     if (lore_ptr->flags2 & RF2_INVISIBLE) {
141         hooked_roff(format(_("%^sは透明で目に見えない。", "%^s is invisible.  "), Who::who(lore_ptr->msex)));
142     }
143
144     if (lore_ptr->flags2 & RF2_COLD_BLOOD) {
145         hooked_roff(format(_("%^sは冷血動物である。", "%^s is cold blooded.  "), Who::who(lore_ptr->msex)));
146     }
147
148     if (lore_ptr->flags2 & RF2_EMPTY_MIND) {
149         hooked_roff(format(_("%^sはテレパシーでは感知できない。", "%^s is not detected by telepathy.  "), Who::who(lore_ptr->msex)));
150     } else if (lore_ptr->flags2 & RF2_WEIRD_MIND) {
151         hooked_roff(format(_("%^sはまれにテレパシーで感知できる。", "%^s is rarely detected by telepathy.  "), Who::who(lore_ptr->msex)));
152     }
153
154     if (lore_ptr->flags2 & RF2_MULTIPLY) {
155         hook_c_roff(TERM_L_UMBER, format(_("%^sは爆発的に増殖する。", "%^s breeds explosively.  "), Who::who(lore_ptr->msex)));
156     }
157
158     if (lore_ptr->flags2 & RF2_REGENERATE) {
159         hook_c_roff(TERM_L_WHITE, format(_("%^sは素早く体力を回復する。", "%^s regenerates quickly.  "), Who::who(lore_ptr->msex)));
160     }
161
162     if (lore_ptr->flags7 & RF7_RIDING) {
163         hook_c_roff(TERM_SLATE, format(_("%^sに乗ることができる。", "%^s is suitable for riding.  "), Who::who(lore_ptr->msex)));
164     }
165 }
166
167 void display_monster_concrete_weakness(lore_type *lore_ptr)
168 {
169     if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_ROCK)) {
170         lore_ptr->vp[lore_ptr->vn] = _("岩を除去するもの", "rock remover");
171         lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
172     }
173
174     if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_LITE)) {
175         lore_ptr->vp[lore_ptr->vn] = _("明るい光", "bright light");
176         lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
177     }
178
179     if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_FIRE)) {
180         lore_ptr->vp[lore_ptr->vn] = _("炎", "fire");
181         lore_ptr->color[lore_ptr->vn++] = TERM_RED;
182     }
183
184     if (lore_ptr->resistance_flags.has(MonsterResistanceType::HURT_COLD)) {
185         lore_ptr->vp[lore_ptr->vn] = _("冷気", "cold");
186         lore_ptr->color[lore_ptr->vn++] = TERM_L_WHITE;
187     }
188 }
189
190 void display_monster_weakness(lore_type *lore_ptr)
191 {
192     if (lore_ptr->vn <= 0) {
193         return;
194     }
195
196     hooked_roff(format(_("%^sには", "%^s"), Who::who(lore_ptr->msex)));
197     for (int n = 0; n < lore_ptr->vn; n++) {
198 #ifdef JP
199         if (n != 0) {
200             hooked_roff("や");
201         }
202 #else
203         if (n == 0) {
204             hooked_roff(" is hurt by ");
205         } else if (n < lore_ptr->vn - 1) {
206             hooked_roff(", ");
207         } else {
208             hooked_roff(" and ");
209         }
210 #endif
211         hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
212     }
213
214     hooked_roff(_("でダメージを与えられる。", ".  "));
215 }
216
217 void display_monster_concrete_resistances(lore_type *lore_ptr)
218 {
219     if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_ACID)) {
220         lore_ptr->vp[lore_ptr->vn] = _("酸", "acid");
221         lore_ptr->color[lore_ptr->vn++] = TERM_GREEN;
222     }
223
224     if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_ELEC)) {
225         lore_ptr->vp[lore_ptr->vn] = _("稲妻", "lightning");
226         lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
227     }
228
229     if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_FIRE)) {
230         lore_ptr->vp[lore_ptr->vn] = _("炎", "fire");
231         lore_ptr->color[lore_ptr->vn++] = TERM_RED;
232     }
233
234     if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_COLD)) {
235         lore_ptr->vp[lore_ptr->vn] = _("冷気", "cold");
236         lore_ptr->color[lore_ptr->vn++] = TERM_L_WHITE;
237     }
238
239     if (lore_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_POISON)) {
240         lore_ptr->vp[lore_ptr->vn] = _("毒", "poison");
241         lore_ptr->color[lore_ptr->vn++] = TERM_L_GREEN;
242     }
243
244     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_LITE)) {
245         lore_ptr->vp[lore_ptr->vn] = _("閃光", "light");
246         lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
247     }
248
249     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_DARK)) {
250         lore_ptr->vp[lore_ptr->vn] = _("暗黒", "dark");
251         lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
252     }
253
254     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_NETHER)) {
255         lore_ptr->vp[lore_ptr->vn] = _("地獄", "nether");
256         lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
257     }
258
259     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_WATER)) {
260         lore_ptr->vp[lore_ptr->vn] = _("水", "water");
261         lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
262     }
263
264     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_PLASMA)) {
265         lore_ptr->vp[lore_ptr->vn] = _("プラズマ", "plasma");
266         lore_ptr->color[lore_ptr->vn++] = TERM_L_RED;
267     }
268
269     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_SHARDS)) {
270         lore_ptr->vp[lore_ptr->vn] = _("破片", "shards");
271         lore_ptr->color[lore_ptr->vn++] = TERM_L_UMBER;
272     }
273
274     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_SOUND)) {
275         lore_ptr->vp[lore_ptr->vn] = _("轟音", "sound");
276         lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
277     }
278
279     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_CHAOS)) {
280         lore_ptr->vp[lore_ptr->vn] = _("カオス", "chaos");
281         lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
282     }
283
284     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_NEXUS)) {
285         lore_ptr->vp[lore_ptr->vn] = _("因果混乱", "nexus");
286         lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
287     }
288
289     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_DISENCHANT)) {
290         lore_ptr->vp[lore_ptr->vn] = _("劣化", "disenchantment");
291         lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
292     }
293
294     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_FORCE)) {
295         lore_ptr->vp[lore_ptr->vn] = _("フォース", "force");
296         lore_ptr->color[lore_ptr->vn++] = TERM_UMBER;
297     }
298
299     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_INERTIA)) {
300         lore_ptr->vp[lore_ptr->vn] = _("遅鈍", "inertia");
301         lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
302     }
303
304     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TIME)) {
305         lore_ptr->vp[lore_ptr->vn] = _("時間逆転", "time");
306         lore_ptr->color[lore_ptr->vn++] = TERM_L_BLUE;
307     }
308
309     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_GRAVITY)) {
310         lore_ptr->vp[lore_ptr->vn] = _("重力", "gravity");
311         lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
312     }
313
314     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL)) {
315         lore_ptr->vp[lore_ptr->vn] = _("あらゆる攻撃", "all");
316         lore_ptr->color[lore_ptr->vn++] = TERM_YELLOW;
317     }
318
319     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT) && lore_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
320         lore_ptr->vp[lore_ptr->vn] = _("テレポート", "teleportation");
321         lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
322     }
323 }
324
325 void display_monster_resistances(lore_type *lore_ptr)
326 {
327     if (lore_ptr->vn <= 0) {
328         return;
329     }
330
331     hooked_roff(format(_("%^sは", "%^s"), Who::who(lore_ptr->msex)));
332     for (int n = 0; n < lore_ptr->vn; n++) {
333 #ifdef JP
334         if (n != 0) {
335             hooked_roff("と");
336         }
337 #else
338         if (n == 0) {
339             hooked_roff(" resists ");
340         } else if (n < lore_ptr->vn - 1) {
341             hooked_roff(", ");
342         } else {
343             hooked_roff(" and ");
344         }
345 #endif
346         hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
347     }
348
349     hooked_roff(_("の耐性を持っている。", ".  "));
350 }
351
352 void display_monster_evolution(lore_type *lore_ptr)
353 {
354     if (!lore_ptr->r_ptr->r_can_evolve && !lore_ptr->know_everything) {
355         return;
356     }
357
358     if (MonsterRace(lore_ptr->r_ptr->next_r_idx).is_valid()) {
359         hooked_roff(format(_("%^sは経験を積むと、", "%^s will evolve into "), Who::who(lore_ptr->msex)));
360         hook_c_roff(TERM_YELLOW, format("%s", monraces_info[lore_ptr->r_ptr->next_r_idx].name.data()));
361
362         hooked_roff(_(format("に進化する。"), format(" when %s gets enough experience.  ", Who::who(lore_ptr->msex))));
363     } else if (lore_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
364         hooked_roff(format(_("%sは進化しない。", "%s won't evolve.  "), Who::who(lore_ptr->msex)));
365     }
366 }
367
368 void display_monster_concrete_immunities(lore_type *lore_ptr)
369 {
370     if (lore_ptr->flags3 & RF3_NO_STUN) {
371         lore_ptr->vp[lore_ptr->vn] = _("朦朧としない", "stunned");
372         lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
373     }
374
375     if (lore_ptr->flags3 & RF3_NO_FEAR) {
376         lore_ptr->vp[lore_ptr->vn] = _("恐怖を感じない", "frightened");
377         lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
378     }
379
380     if (lore_ptr->flags3 & RF3_NO_CONF) {
381         lore_ptr->vp[lore_ptr->vn] = _("混乱しない", "confused");
382         lore_ptr->color[lore_ptr->vn++] = TERM_L_UMBER;
383     }
384
385     if (lore_ptr->flags3 & RF3_NO_SLEEP) {
386         lore_ptr->vp[lore_ptr->vn] = _("眠らされない", "slept");
387         lore_ptr->color[lore_ptr->vn++] = TERM_BLUE;
388     }
389
390     if (lore_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT) && lore_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
391         lore_ptr->vp[lore_ptr->vn] = _("テレポートされない", "teleported");
392         lore_ptr->color[lore_ptr->vn++] = TERM_ORANGE;
393     }
394 }
395
396 void display_monster_immunities(lore_type *lore_ptr)
397 {
398     if (lore_ptr->vn <= 0) {
399         return;
400     }
401
402     hooked_roff(format(_("%^sは", "%^s"), Who::who(lore_ptr->msex)));
403     for (int n = 0; n < lore_ptr->vn; n++) {
404 #ifdef JP
405         if (n != 0) {
406             hooked_roff("し、");
407         }
408 #else
409         if (n == 0) {
410             hooked_roff(" cannot be ");
411         } else if (n < lore_ptr->vn - 1) {
412             hooked_roff(", ");
413         } else {
414             hooked_roff(" or ");
415         }
416 #endif
417         hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
418     }
419
420     hooked_roff(_("。", ".  "));
421 }
422
423 void display_monster_alert(lore_type *lore_ptr)
424 {
425     bool alert = ((int)lore_ptr->r_ptr->r_wake * (int)lore_ptr->r_ptr->r_wake) > lore_ptr->r_ptr->sleep;
426     alert |= lore_ptr->r_ptr->r_ignore == MAX_UCHAR;
427     alert |= (lore_ptr->r_ptr->sleep == 0) && (lore_ptr->r_ptr->r_tkills >= 10);
428     alert |= lore_ptr->know_everything;
429     if (!alert) {
430         return;
431     }
432
433     concptr act;
434     if (lore_ptr->r_ptr->sleep > 200) {
435         act = _("を無視しがちであるが", "prefers to ignore");
436     } else if (lore_ptr->r_ptr->sleep > 95) {
437         act = _("に対してほとんど注意を払わないが", "pays very little attention to");
438     } else if (lore_ptr->r_ptr->sleep > 75) {
439         act = _("に対してあまり注意を払わないが", "pays little attention to");
440     } else if (lore_ptr->r_ptr->sleep > 45) {
441         act = _("を見過ごしがちであるが", "tends to overlook");
442     } else if (lore_ptr->r_ptr->sleep > 25) {
443         act = _("をほんの少しは見ており", "takes quite a while to see");
444     } else if (lore_ptr->r_ptr->sleep > 10) {
445         act = _("をしばらくは見ており", "takes a while to see");
446     } else if (lore_ptr->r_ptr->sleep > 5) {
447         act = _("を幾分注意深く見ており", "is fairly observant of");
448     } else if (lore_ptr->r_ptr->sleep > 3) {
449         act = _("を注意深く見ており", "is observant of");
450     } else if (lore_ptr->r_ptr->sleep > 1) {
451         act = _("をかなり注意深く見ており", "is very observant of");
452     } else if (lore_ptr->r_ptr->sleep > 0) {
453         act = _("を警戒しており", "is vigilant for");
454     } else {
455         act = _("をかなり警戒しており", "is ever vigilant for");
456     }
457
458     hooked_roff(_(format("%^sは侵入者%s、 %d フィート先から侵入者に気付くことがある。", Who::who(lore_ptr->msex), act, 10 * lore_ptr->r_ptr->aaf),
459         format("%^s %s intruders, which %s may notice from %d feet.  ", Who::who(lore_ptr->msex), act, Who::who(lore_ptr->msex), 10 * lore_ptr->r_ptr->aaf)));
460 }